Is there An Input Checkbox Option That Works like `wp_dropdown_categories()` To Use In A WP Search Form?

Yes, there is a built-in WordPress function you can use to render a list of checkboxes (or simply, checklist) which then allows the user to select multiple terms, and the function is wp_terms_checklist().

However, the function only works for users who have the capability/permission to assign terms to a post, so you’d need to create your own function for public (i.e. front-end or non-admin side) use.

And you can try my custom function below which uses the Walker_Category_Checklist class which is the same class that’s used by wp_terms_checklist() to build the terms checklist. But do take note of these conditions:

  1. You’d need to style the checklist on your own, e.g. to remove the bullet next to each checkbox. (Because the checkbox is in an li element.)

  2. The checkboxes name is in the form of tax_input[<taxonomy>][], e.g. <input type="checkbox" name="tax_input[salary_level][]". So you can’t simply use get_query_var() to get the selected terms (which each is a term ID).

  3. You’d need to hook on pre_get_posts to make sure the selected terms are being included in the search query (i.e. its SQL statement).

The Code

  • In your theme’s functions.php file, add this custom function I mentioned above:

    /*
     * Based on wp_terms_checklist(), but this is simpler and without the very first parameter
     * (i.e. $post_id).
     *
     * @param array $args An array of arguments. See the second parameter for wp_terms_checklist()
     *                    for the list of arguments, but 'descendants_and_self' and 'walker' are
     *                    not included in this function.
     *
     * @return string|false $output HTML list of checkbox elements. false on get_terms() error.
     */
    function wpse_384435_checklist( array $args ) {
        require_once ABSPATH . 'wp-admin/includes/class-walker-category-checklist.php';
    
        $terms = get_terms( array(
            'taxonomy' => isset( $args['taxonomy'] ) ? $args['taxonomy'] : 'category',
            'get'      => 'all',
        ) );
    
        if ( is_wp_error( $terms ) || empty( $terms ) ) {
            return false;
        }
    
        $walker = new Walker_Category_Checklist;
    
        $output = $walker->walk( $terms, 0, $args );
    
        if ( ! isset( $args['echo'] ) || $args['echo'] ) { // this means echo is default
            echo $output;
        }
    
        return $output;
    }
    
  • Also in the functions file, add this which does the point #3 above:

    add_action( 'pre_get_posts', 'my_search_pre_get_posts' );
    function my_search_pre_get_posts( $query ) {
        // We're altering the MAIN query args only on search result pages.
        if ( is_admin() || ! is_search() || ! $query->is_main_query() ) {
            return;
        }
    
        // For other taxonomies, just add the slug to the $taxonomies array below.
        $taxonomies = array( 'salary_level', 'jobs_categories' );
    
        $tax_input = isset( $_GET['tax_input'] ) ? (array) $_GET['tax_input'] : array();
        $tax_query = (array) $query->get( 'tax_query' );
        $set_tax_query = false;
    
        foreach ( $taxonomies as $taxonomy ) {
            $selected_cats = ( ! empty( $tax_input[ $taxonomy ] ) ) ?
                wp_parse_id_list( $tax_input[ $taxonomy ] ) : array();
    
            if ( ! empty( $selected_cats ) ) {
                $tax_query[] = array(
                    'taxonomy' => $taxonomy,
                    'terms'    => $selected_cats,
                );
                $set_tax_query = true;
            }
        }
    
        if ( $set_tax_query ) {
                $query->set( 'tax_query', $tax_query );
        }
    }
    
  • And then in your form, replace the wp_dropdown_categories() part with this: (for other taxonomies, you can just copy-paste-edit the same code below)

    $taxonomy = 'salary_level';
    $tax_input = isset( $_GET['tax_input'] ) ? (array) $_GET['tax_input'] : array();
    
    $selected_cats = ( ! empty( $tax_input[ $taxonomy ] ) ) ?
        wp_parse_id_list( $tax_input[ $taxonomy ] ) : array();
    
    echo '<div><label>Filter by Salary Bands:</label>';
    wpse_384435_checklist( array(
        'taxonomy'      => $taxonomy,
        'selected_cats' => $selected_cats,
        'checked_ontop' => false,
    ) );
    echo '</div>';
    

PS: Be sure to use the correct taxonomy slugs! 🙂

Leave a Comment