Skip to main content
deleted 238 characters in body
Source Link
Sally CJ
  • 39.9k
  • 2
  • 26
  • 48

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. The function is defined in wp-admin/includes/template.php, so you need to load that file prior to using the function.

  2. 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.)

  3. 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).

  4. 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).

But getting the whole thing to work is not actually hard, and you can try my code below:

The Code

  • In your theme's functions.php file, add this which does the point #4custom function I mentioned above:

    add_action(/*
     'pre_get_posts',* 'my_search_pre_get_posts'Based );
    functionon my_search_pre_get_postswp_terms_checklist( $query ), {
    but this is simpler ifand (without !the is_admin()very &&first is_search()parameter
     &&* $query->is_main_query()i.e. $post_id).
     {*
     * @param array $args An array of $taxonomyarguments. =See 'salary_level';the second parameter for wp_terms_checklist()
     *       $tax_input = isset( $_GET['tax_input'] ) ? (array) $_GET['tax_input'] : array();
    
        for the list of $selected_catsarguments, =but ('descendants_and_self' !and empty('walker' $tax_input[are
     $taxonomy* ] ) ) ?
                wp_parse_id_list( $tax_input[ $taxonomy ] )not :included array();in this function.
     *
     * @return string|false $output HTML list of checkbox elements. iffalse on get_terms() !error.
     empty*/
    function wpse_384435_checklist( $selected_catsarray )$args ) {
         require_once ABSPATH . 'wp-admin/includes/class-walker-category-checklist.php';
    
        $tax_query$terms = get_terms(array) $query->getarray( 'tax_query' );
    
            'taxonomy' => isset( $args['taxonomy'] $tax_query[]) =? array(
    $args['taxonomy'] : 'category',
            'get'      'taxonomy' => $taxonomy'all',
          ) );
    
        if ( is_wp_error( $terms ) 'terms'|| empty( $terms ) =>) $selected_cats,{
            return false;
       ); }
    
        $walker = new Walker_Category_Checklist;
    
        $output = $query$walker->set>walk( 'tax_query'$terms, $tax_query0, $args ); 
    
        if ( ! isset( }$args['echo'] ) || $args['echo'] ) { // this means echo is default
            echo $output;
        }
    
        return $output;
    }
    
  • And thenAlso in your form, replace the wp_dropdown_categories() part withfunctions file, add this which does the point #3 above:

    require_once ABSPATH .add_action( 'wp-admin/includes/template.php';
    
    $taxonomy'pre_get_posts', ='my_search_pre_get_posts' 'salary_level';);
    $tax_input =function issetmy_search_pre_get_posts( $_GET['tax_input']$query ) ?{
     (array) $_GET['tax_input'] : array();
    
    $selected_cats =// (We're !altering empty(the $tax_input[MAIN $taxonomyquery ]args )only )on ?
    search result pages.
      wp_parse_id_list( $tax_input[ $taxonomyif ]( is_admin() :|| array! is_search();
    
    echo '<div><label>Filter by|| Salary! Bands:</label>';
    wp_terms_checklist$query->is_main_query() 0,) array({
        'taxonomy'      => $taxonomy,return;
        'selected_cats' => $selected_cats,}
      
       'checked_ontop' => false,
    ) );
    echo '</div>';
    

Alternate Function ( for front-end or non-admin side use )

If you don't want to having to load the (many unnecessary functions in the) wp-admin/includes/template.php file,

  • Then in your theme functions file, in addition to the my_search_pre_get_posts() part above, add this:

    /*
     * BasedFor onother wp_terms_checklist()taxonomies, but this is simpler andjust withoutadd the veryslug first
    to *the parameter$taxonomies (i.e.array $post_id)below.
     *
     * @param array $args$taxonomies An= array of arguments. See the( second'salary_level', parameter'jobs_categories' for);
     *  
        $tax_input = isset( $_GET['tax_input'] ) ? (array) $_GET['tax_input'] : array();
        $tax_query = wp_terms_checklist(array) for$query->get( the'tax_query' list);
     of arguments, but
     *$set_tax_query = false;
    
        foreach ( $taxonomies as $taxonomy ) {
            'descendants_and_self'$selected_cats and= 'walker'( are! notempty( included
    $tax_input[ *$taxonomy ] ) ) ?
                wp_parse_id_list( $tax_input[ $taxonomy ] in) this: function.array();
     *
     * @return string $output HTML list of checkboxif elements.
    ( */
    function! wpse_384435_checklistempty( array$selected_cats $args) ) {
        require_once ABSPATH . 'wp-admin/includes/class-walker-category-checklist.php';
    
        $terms =$tax_query[] get_terms(= array(
            'taxonomy' => isset( $args['taxonomy'] ) ? $args['taxonomy'] : 'category''taxonomy' => $taxonomy,
            'get'        'terms'    => 'all'$selected_cats,
        ) );
    
        $walker = new Walker_Category_Checklist;
    );
        $output = $walker->walk( $terms, 0, $args );
      $set_tax_query = true;
        if ( ! isset( $args['echo']}
     ) || $args['echo'] )}
    
     { // this meansif echo( is$set_tax_query default) {
            echo $output;
       $query->set( }
    
    'tax_query', $tax_query );
      return $output; }
    }
    
  • And then in your form, replace the wp_dropdown_categories() part with this — or instead of using: wp_terms_checklist()(for other taxonomies, useyou can just copy-paste-edit the custom function above (wpse_384435_checklist()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 slugslugs! :) ( And it's salary_level in my code, because that's what you used in yours in the question. )

However,

  1. The function is defined in wp-admin/includes/template.php, so you need to load that file prior to using the function.

  2. 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.)

  3. 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).

  4. 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).

But getting the whole thing to work is not actually hard, and you can try my code below:

  • In your theme's functions.php file, add this which does the point #4 above:

    add_action( 'pre_get_posts', 'my_search_pre_get_posts' );
    function my_search_pre_get_posts( $query ) {
        if ( ! is_admin() && is_search() && $query->is_main_query() ) {
            $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();
    
            if ( ! empty( $selected_cats ) ) {
                $tax_query = (array) $query->get( 'tax_query' );
    
                $tax_query[] = array(
                    'taxonomy' => $taxonomy,
                    'terms'    => $selected_cats,
                );
    
                $query->set( 'tax_query', $tax_query );
            }
        }
    }
    
  • And then in your form, replace the wp_dropdown_categories() part with this:

    require_once ABSPATH . 'wp-admin/includes/template.php';
    
    $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>';
    wp_terms_checklist( 0, array(
        'taxonomy'      => $taxonomy,
        'selected_cats' => $selected_cats,
        'checked_ontop' => false,
    ) );
    echo '</div>';
    

Alternate Function ( for front-end or non-admin side use )

If you don't want to having to load the (many unnecessary functions in the) wp-admin/includes/template.php file,

  • Then in your theme functions file, in addition to the my_search_pre_get_posts() part above, add this:

    /*
     * 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 $output HTML list of checkbox elements.
     */
    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',
        ) );
    
        $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;
    }
    
  • And then in your form, replace the wp_dropdown_categories() part with this — or instead of using wp_terms_checklist(), use the custom function above (wpse_384435_checklist()):

    $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 slug! :) ( And it's salary_level in my code, because that's what you used in yours in the question. )

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

Source Link
Sally CJ
  • 39.9k
  • 2
  • 26
  • 48

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,

  1. The function is defined in wp-admin/includes/template.php, so you need to load that file prior to using the function.

  2. 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.)

  3. 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).

  4. 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).

But getting the whole thing to work is not actually hard, and you can try my code below:

  • In your theme's functions.php file, add this which does the point #4 above:

    add_action( 'pre_get_posts', 'my_search_pre_get_posts' );
    function my_search_pre_get_posts( $query ) {
        if ( ! is_admin() && is_search() && $query->is_main_query() ) {
            $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();
    
            if ( ! empty( $selected_cats ) ) {
                $tax_query = (array) $query->get( 'tax_query' );
    
                $tax_query[] = array(
                    'taxonomy' => $taxonomy,
                    'terms'    => $selected_cats,
                );
    
                $query->set( 'tax_query', $tax_query );
            }
        }
    }
    
  • And then in your form, replace the wp_dropdown_categories() part with this:

    require_once ABSPATH . 'wp-admin/includes/template.php';
    
    $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>';
    wp_terms_checklist( 0, array(
        'taxonomy'      => $taxonomy,
        'selected_cats' => $selected_cats,
        'checked_ontop' => false,
    ) );
    echo '</div>';
    

Alternate Function ( for front-end or non-admin side use )

If you don't want to having to load the (many unnecessary functions in the) wp-admin/includes/template.php file,

  • Then in your theme functions file, in addition to the my_search_pre_get_posts() part above, add this:

    /*
     * 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 $output HTML list of checkbox elements.
     */
    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',
        ) );
    
        $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;
    }
    
  • And then in your form, replace the wp_dropdown_categories() part with this — or instead of using wp_terms_checklist(), use the custom function above (wpse_384435_checklist()):

    $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 slug! :) ( And it's salary_level in my code, because that's what you used in yours in the question. )