limit selection of custom taxonomies to one?

I have a site with CPT (short for custom post type) “bagp_deals” and custom taxonomies
“ba_locations” and “ba_cats”
basically Its post type of “Deals” with “Location” and “Categories” as hierarchical taxonomies.
On the default edit screen i want to limit the selection to just one of each (one location and one category) and i’m trying to do that with JQuery,
i notice that the field custom taxonomy of ba_locations is named “tax_input[ba_locations][]” and so far i have this code:

jQuery("input[name=tax_input[ba_locations][]]").click(function () {
    selected = jQuery("input[name=tax_input[ba_locations][]]").filter(":checked").length;
    if (selected > 1){
        jQuery("input[name=tax_input[ba_locations][]]").each(function () {
                jQuery(this).attr("checked", false);
        });
        jQuery(this).attr("checked", true);
    }
});

witch is suppose to limit the checkbox selection to one.
For some reason i can’t get this to work.

Read More

The Question

So the question is why isn’t this working ?
or do you have a better solution to limit the selection to just one?

any help is appreciated.

update:

this is the working code i used:

jQuery("input[name="tax_input[ba_locations][]"]").click(function () {
    selected = jQuery("input[name="tax_input[ba_locations][]"]").filter(":checked").length;
    if (selected > 1){
        jQuery("input[name="tax_input[ba_locations][]"]").each(function () {
                jQuery(this).attr("checked", false);
        });
        jQuery(this).attr("checked", true);
    }
});

Related posts

Leave a Reply

5 comments

  1. i have a php solution for you:

    add_filter('wp_terms_checklist_args', 'htmlandcms_select_one_category');
    function htmlandcms_select_one_category($args) {
        if (isset($args['taxonomy']) && $args['taxonomy'] == 'category_portfolio') {
            $args['walker'] = new Walker_Category_Radios;
            $args['checked_ontop'] = false;
        }
        return $args;
    }
    
    class Walker_Category_Radios extends Walker {
        var $tree_type = 'category';
        var $db_fields = array ('parent' => 'parent', 'id' => 'term_id');
    
        function start_lvl( &$output, $depth = 0, $args = array() ) {
            $indent = str_repeat("t", $depth);
            $output .= "$indent<ul class='children'>n";
        }
    
        function end_lvl( &$output, $depth = 0, $args = array() ) {
            $indent = str_repeat("t", $depth);
            $output .= "$indent</ul>n";
        }
    
        function start_el( &$output, $category, $depth, $args, $id = 0 ) {
            extract($args);
            if ( empty($taxonomy) )
                $taxonomy = 'category';
    
            if ( $taxonomy == 'category' )
                $name = 'post_category';
            else
                $name = 'tax_input['.$taxonomy.']';
    
            /** @var $popular_cats */
            $class = in_array( $category->term_id, $popular_cats ) ? ' class="popular-category"' : '';
            /** @var $selected_cats */
            $output .= "n<li id='{$taxonomy}-{$category->term_id}'$class>" . '<label class="selectit"><input value="' . $category->term_id . '" type="radio" name="'.$name.'[]" id="in-'.$taxonomy.'-' . $category->term_id . '"' . checked( in_array( $category->term_id, $selected_cats ), TRUE, FALSE ) . disabled( empty( $args['disabled'] ), FALSE, FALSE ) . ' /> ' . esc_html( apply_filters('the_category', $category->name )) . '</label>';
        }
    
        function end_el( &$output, $category, $depth = 0, $args = array() ) {
            $output .= "</li>n";
        }
    }
    
  2. Not sure if you ever found a solution to this, but I needed to do the same thing. I took your jQuery and added quotations for the name + escaped them. Seems to work fine for me, so thanks for the original jQuery 🙂

        jQuery("input[name="tax_input[location][]"]").click(function () {
            selected = jQuery("input[name="tax_input[location][]"]").filter(":checked").length;
            if (selected > 1){
                jQuery("input[name="tax_input[location][]"]").each(function () {
                        jQuery(this).attr("checked", false);
                });
                jQuery(this).attr("checked", true);
            }
        });
    

    My taxonomy input was called location and not ba_locations.

  3. This is what I threw in my functions, but I don’t seem to be getting the results expected.

    <?php add_action( 'admin_head', 'cat_sel' ); function cat_sel() {    ?>
    
    <script type="text/javascript">
    jQuery(document).ready(function($) {
      jQuery("input[name="tax_input[rooms][]"]").click(function () {
        selected = jQuery("input[name="tax_input[rooms][]"]").filter(":checked").length;
        if (selected > 1){
            jQuery("input[name="tax_input[rooms][]"]").each(function () {
                    jQuery(this).attr("checked", false);
            });
            jQuery(this).attr("checked", true);
        }
      });
    });
    
    </script>
    <?php } ?>
    
  4. A simplified version of @sviryatko‘s PHP solution:

    namespace {
        require_once(ABSPATH . 'wp-admin/includes/class-walker-category-checklist.php');
        class Walker_Category_Radioset extends Walker_Category_Checklist {
            public function start_el(&$output, $category, $depth = 0, $args = array(), $id = 0) {
                $parent_output = '';
                parent::start_el($parent_output, $category, $depth, $args, $id);
                $output .= str_replace('checkbox', 'radio', $parent_output);
            }
        }
    }
    

    and

    add_filter(
        'wp_terms_checklist_args'
        , function($args) {
            if (isset($args['taxonomy']) && $args['taxonomy'] == YOUR_TAXONOMY) {
                $args['walker'] = new Walker_Category_Radioset;
                $args['checked_ontop'] = false;
            }
            return $args;
        }
    );