0

I have custom post type that is currently using the wp_dropdown_categories() function within a WP search form so people will be able to filter by salary band and job type.

Is there an equivalent function so a user can apply filters with input checkbox elements instead of a <select> element, so they can choose more than one job type or salary level when undertaking a search?

I can't seem to find anything in the developer docs.

What I'm looking for is something to allow checkboxes that would replace the dropdown element that uses select options in the code below.

<form method="get" action="<?php echo esc_url(site_url('/')); ?>">
    <div id="form-wrapper">
        <label id="searchlabel" for="s">Search</label>
        <input id="s" name="s" type="search">
        <input type="hidden" name="post_type" value="jobs" />

            <?php wp_dropdown_categories( array(
                'taxonomy'        => 'salary_level', // taxonomy slug
                'name'            => 'salary_level', // taxonomy slug
                'class'           => 'jobsearch-select',
                'value_field'     => 'slug',
                'selected'        => get_query_var( 'salary_level' ),
                'hierarchical'    => true, // place each term under their own parent
                'show_option_all' => 'Select Salary Band',
            ) ); ?>
            
        <input class="td search-jobs-button" type="submit" value="Search Jobs">
    </div>
</form>

Thanks in advance

Emily.

1 Answer 1

1

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! :)

7
  • 1
    hi @SallyCJ thanks ever so much for this. In the 1st example the checkboxes are disabled & have the disabled="disable" attribute added? The 2nd example doesn't have this. There is one other issue which is completely my fault (sorry) which is that I will also have another taxonomy list for job types which is jobs_categories. I added the form code above for a 2nd taxonomy and changed the $taxonomy variable (which does show as expected in the frontend). I can't work out how to the amend the functions.php code though to get it work (this comment is in relation to the 2nd example in your answer)
    – pjk_ok
    Commented Mar 5, 2021 at 0:22
  • Hi Emily :) I've revised the answer, so please try the new/updated code - the wpse_384435_checklist() and my_search_pre_get_posts() functions.
    – Sally CJ
    Commented Mar 5, 2021 at 9:36
  • Thanks @SallyCJ. When I add the new code I only get the salary levels showing snipboard.io/FxyPw8.jpg and the checkboxes have the disabled attribute added snipboard.io/HEbCOx.jpg (the checkboxes are also disabled if I only add the 'salary_level' code in the form on the front end and don't add the 'jobs_categories' at all).
    – pjk_ok
    Commented Mar 9, 2021 at 22:53
  • Hi Emily, sorry for the late reply.. So have you managed to fix the "disabled" issue? Are you sure you actually used wpse_384435_checklist() and not wp_terms_checklist()? Can you show your form code?
    – Sally CJ
    Commented Mar 16, 2021 at 8:29
  • 1
    Hi @TheChewy, that's a "cute"/nice website! :) And in reply to your question, yes, that's correct. But instead of repeating that second code, you might want to put the code in a function like this - that way, your code would be simpler and easier to maintain. =) Happy coding!
    – Sally CJ
    Commented Mar 18, 2021 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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