Using wp_category_checklist in a widget

I’m trying to use wp_category_checklist in a widget to display a list of checkboxes which, when saved, remain ticked. I’m having awful trouble at the moment getting them to save, as as far as I know it isn’t saving (the checkboxes remain unticked):-

Here’s the edited code I have at the moment.

Read More
function update($new_instance, $old_instance) {
    $instance = $old_instance;
    $instance['widget_categories'] = $new_instance['post_category'];
return $instance;
}


function form($instance) {
    $instance = wp_parse_args( (array) $instance, $default );
    $categories = get_categories();     

    $category_array = $instance['widget_categories'];

    if (!$category_array)
    {
        $category_array = array();
    }
    ?>
    <ul class="categorychecklist">
    <?php wp_category_checklist(0,0, $category_array,false, NULL , false);?>
    </ul>
    <?php
}

Any ideas? Please let me know if you need anything else.

Thanks 🙂

Related posts

1 comment

  1. The problem is that to make the update method of widget class work, the name inputs on the form method should be set via $this->get_get_field_name('name_of_the_field'); but wp_category_checklist has no argument to setup the name of the inputs (checkboxes).

    However, wp_category_checklist uses a walker class to print the checkboxes and allow customizing it. By default the class used is Walker_Category_Checklist, and the method that prints the checkboxes is start_el.

    That method has no filter to allow editing of the input names, but we can create a custom walker, that accepts params to setup the name. If this walker extends Walker_Category_Checklist, we only need to override start_el method (mostly copying from original).

    The code:

    // This is required to be sure Walker_Category_Checklist class is available
    require_once ABSPATH . 'wp-admin/includes/template.php';
    /**
     * Custom walker to print category checkboxes for widget forms
     */
    class Walker_Category_Checklist_Widget extends Walker_Category_Checklist {
    
        private $name;
        private $id;
    
        function __construct( $name = '', $id = '' ) {
            $this->name = $name;
            $this->id = $id;
        }
    
        function start_el( &$output, $cat, $depth = 0, $args = array(), $id = 0 ) {
            extract( $args );
            if ( empty( $taxonomy ) ) $taxonomy = 'category';
            $class = in_array( $cat->term_id, $popular_cats ) ? ' class="popular-category"' : '';
            $id = $this->id . '-' . $cat->term_id;
            $checked = checked( in_array( $cat->term_id, $selected_cats ), true, false );
            $output .= "n<li id='{$taxonomy}-{$cat->term_id}'$class>" 
                . '<label class="selectit"><input value="' 
                . $cat->term_id . '" type="checkbox" name="' . $this->name 
                . '[]" id="in-'. $id . '"' . $checked 
                . disabled( empty( $args['disabled'] ), false, false ) . ' /> ' 
                . esc_html( apply_filters( 'the_category', $cat->name ) ) 
                . '</label>';
          }
    }
    

    Now, probably in same file we can write the widget class:

    /**
     * An example of widget using wp_category_checklist on form
     */
    class TestCategoryWidget extends WP_Widget {
    
        function __construct(){
            parent::__construct( false, 'TestWidget');
        }
    
        function widget( $args, $instance ) { 
            // Displays the widget on frontend 
        }
    
        function update( $new_instance, $old_instance ) {
            $instance = $old_instance;
            $instance['widget_categories'] = $new_instance['widget_categories'];
            return $instance;
        }
    
        function form( $instance ) {
            $defaults = array( 'widget_categories' => array() );
            $instance = wp_parse_args( (array) $instance, $defaults );    
            // Instantiate the walker passing name and id as arguments to constructor
            $walker = new Walker_Category_Checklist_Widget(
                $this->get_field_name( 'widget_categories' ), 
                $this->get_field_id( 'widget_categories' )
            );
            echo '<ul class="categorychecklist">';
            wp_category_checklist( 0, 0, $instance['widget_categories'], FALSE, $walker, FALSE );
            echo '</ul>';
        }
    
    }
    

    Finally, register the widget:

    function TestCategoryWidgetInit() {
        register_widget( 'TestCategoryWidget' );
    }
    
    add_action( 'widgets_init', 'TestCategoryWidgetInit' );
    

Comments are closed.