0

I'm trying to learn WordPress Widget API. Everything looks great, except for the checkbox controls. Also, the checked() function puzzles me a bit, I'm confused about what value to propose if I have to default a checkbox unchecked.

Here's the bit of code I'm trying inside the Widget Class wrapper.

public function widget( $args, $instance ) {
  extract( $args );
  $checkbox1 = ! empty( $instance['checkbox1'] ) ? $instance['checkbox1'] : false;
  $checkbox2 = ! empty( $instance['checkbox2'] ) ? $instance['checkbox2'] : false;
  $checkbox3 = ! empty( $instance['checkbox3'] ) ? $instance['checkbox3'] : false;

  echo $args['before_widget'];
  echo "Hello world, just testing this out.";
  echo $args['after_widget'];
}

public function form( $instance ) {

  $defaults = array(
    'checkbox1' => true,
    'checkbox2' => true,
    'checkbox3' => true,
  );

  $instance = wp_parse_args( (array) $instance, $defaults ); 
  ?>

<p>
  <input 
    class="checkbox" 
    id="<?php echo esc_attr( $this->get_field_id( 'checkbox1' ) ); ?>" 
    name="<?php echo esc_attr( $this->get_field_name( 'checkbox1' ) ); ?>" 
    type="checkbox" 
    <?php checked( '1', $instance['checkbox1'] ); ?> 
    value="1">

  <label for="<?php echo esc_attr( $this->get_field_id( 'checkbox1' ) ); ?>">
    <?php _e( 'Checkbox #1', 'test' ); ?>
  </label> 
</p>

<p>
  <input 
    class="checkbox" 
    id="<?php echo esc_attr( $this->get_field_id( 'checkbox2' ) ); ?>" 
    name="<?php echo esc_attr( $this->get_field_name( 'checkbox2' ) ); ?>" 
    type="checkbox" 
    <?php checked( '1', $instance['checkbox2'] ); ?> 
    value="1">

  <label for="<?php echo esc_attr( $this->get_field_id( 'checkbox2' ) ); ?>">
    <?php _e( 'Checkbox #2', 'test' ); ?>
  </label> 
</p>

<p>
  <input 
    class="checkbox" 
    id="<?php echo esc_attr( $this->get_field_id( 'checkbox3' ) ); ?>" 
    name="<?php echo esc_attr( $this->get_field_name( 'checkbox3' ) ); ?>" 
    type="checkbox" 
    <?php checked( '1', $instance['checkbox3'] ); ?> 
    value="1">

  <label for="<?php echo esc_attr( $this->get_field_id( 'checkbox3' ) ); ?>">
    <?php _e( 'Checkbox #2', 'test' ); ?>
  </label> 
</p>

  <?php 
}

public function update( $new_instance, $old_instance ) {

  $instance = $old_instance;

  $instance['checkbox1'] = isset( $new_instance['checkbox1'] ) ? 1 : false;
  $instance['checkbox2'] = isset( $new_instance['checkbox2'] ) ? 1 : false;
  $instance['checkbox3'] = isset( $new_instance['checkbox3'] ) ? 1 : false;

  return $instance;
}

Thanks for your time :)

2

(Update #2)

Here's the full widget class that I previously shared via my comment. =)

In that class, the checkbox1 field is default to not checked, while the rest of the checkbox fields are checked by default.


(Update #1. Note that this update does not use your example code, but hopefully this answer would be of more help than the previous answer.)

First off, checkbox fields (i.e. <input type="checkbox">), as you may already know, normally would be of two values — a "on" value (set if the checkbox field is checked), and a "off" value (set if the field is not checked).

So let's say you have a widget with the following default options, which are all checkbox fields:

$defaults = array(
  'cb1' => 'yes',
  'cb2' => 'no',
);

And for both of the fields, the "on" value is yes, while the "off" value is no.

Then in your widget options form, you display the checkbox fields using the following markup: (other attributes such as id and name are intentionally not included)

<input type="checkbox" value="{A}"<?php checked( '{B}', '{C}' ); ?>>

Where {A} and {B} are always the "on" value, whereas {C} is the value as it is currently in the database or in the $defaults array if the widget options have not yet been changed — e.g. the widget has just been added to a sidebar.

So if you look at the (above) sample $defaults array:

  1. The cb1 field would be checked by default, because the default value is the "on" value — $defaults['cb1'] is yes.

  2. The cb2 field would be not checked by default, because the default value is the "off" value — $defaults['cb2'] is no.

Sample widget class for testing the checkbox fields: "My Widget"

<?php
class MY_Widget extends WP_Widget {

    public function __construct() {
        parent::__construct( 'my_widget', 'My Widget', array(
            'classname'   => 'my-widget',
            'description' => 'Testing checkbox fields.',
        ) );
    }

    public function widget( $args, $instance ) {
        echo $args['before_widget'];
            echo '<pre>'; var_dump( $instance ); echo '</pre>';
        echo $args['after_widget'];
    }

    public function update( $new_instance, $old_instance ) {
        $instance = $old_instance;

        $instance['cb1'] = isset( $new_instance['cb1'] ) ? 'yes' : 'no';
        $instance['cb2'] = isset( $new_instance['cb2'] ) ? 'yes' : 'no';

        return $instance;
    }

    public function form( $instance ) {
        $instance = wp_parse_args(
            (array) $instance,
            // The default options.
            array(
                'cb1' => 'yes', // checked by default
                'cb2' => 'no',  // not checked by default
            )
        );
        ?>
            <p>
                <input type="checkbox" id="<?php echo $this->get_field_id( 'cb1' ); ?>" name="<?php echo $this->get_field_name( 'cb1' ); ?>" value="yes"<?php checked( 'yes', $instance['cb1'] ); ?>>
                <label for="<?php echo $this->get_field_id( 'cb1' ); ?>">Checkbox #1</label><br>

                <input type="checkbox" id="<?php echo $this->get_field_id( 'cb2' ); ?>" name="<?php echo $this->get_field_name( 'cb2' ); ?>" value="yes"<?php checked( 'yes', $instance['cb2'] ); ?>>
                <label for="<?php echo $this->get_field_id( 'cb2' ); ?>">Checkbox #2</label>
            </p>
        <?php
    }
}
  • Hello there, Sally CJ. Thanks for your answer, that was just sample code I prepared in a jiffy replacing those embarrassing prefixes and text domains. Please ignore that 'checkbox1' repeat, and check it at your end if it's working. I have already been following this approach. – Bheemsen Aug 24 '18 at 10:39
  • 1
    Hi Bheemsen. Yes, it is working. Here's the full code I used: pastebin.com/CTewT5p9 Tried and tested on WordPress 4.9.8. The only changes are those in my answer, and that of course, my code is a full widget class. – Sally CJ Aug 24 '18 at 10:45
  • 1
    Well, it's working fine here as well, dunno what I was missing! Was not using the selective fresh too. Thank you Sally, for taking time to help me. I appreciate that. – Bheemsen Aug 24 '18 at 10:54
  • 1
    @Bheemsen I hope you don't mind that I edited my answer, and hopefully it will help you more. =) – Sally CJ Aug 25 '18 at 4:52
  • Hello Sally, it's good to see you explaining it with an example. However, I noticed that only the default states are being shown in the front-end of the widget in each of my efforts, and it doesn't actually follow the logic (based on those checkboxes) that goes inside the widget() function. I tried once more with that neatly written example of yours, still I have no luck. I'll be back after trying a couple more times. – Bheemsen Aug 25 '18 at 6:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.