3

When posting, I want the user to be able to select only one category. How can I achieve something like that?

Sorry, I should have been more clearer. When checking the boxes to select the categories the posts will go into, I'd like that to function as radio buttons where you get to select only one option.

jQuery would be a quick fix for that and found the jquery following code online and I'm trying to figure out where to add it to the post.php head tag:

var $t = jQuery.noConflict();
$t(document).ready(function() {   
  $t('#categorychecklist li input[type="checkbox"]').each(function(){
    $t(this).change(function(){
        //alert( $t('#categorychecklist li input[checked="checked"]').parent().html() );
        $t('#categorychecklist li input').attr('checked','');
        $t(this).attr('checked','checked');
    })
  })
});
Jared Rice
  • 184
  • 1
  • 9
Cris
  • 3,762
  • 16
  • 47
  • 72
  • You're gonna need more information than that if you want an answer. – Code Monkey Oct 17 '12 at 21:41
  • I mean I want to limit the user to only one category (either red-widgets or blue-widgets, not both). I don't know where to start. Maybe I can get a few pointers... – Cris Oct 17 '12 at 21:46
  • 1
    Took me 45 seconds to find this: http://wordpress.org/extend/plugins/members-category/ – Edgar Allan Pwn Oct 17 '12 at 21:59
  • So, you want exactly one (1) category selected -- the kind of behaviour you normally see with radio button groups? – user916011 Oct 19 '12 at 01:59

4 Answers4

1

I'm also looking for a good solution to such a problem. This topic shows a plugin(php) variant that turns the categories into radio buttons: http://wordpress.org/support/topic/select-only-one-category-1 but it doesn't do any validation of any sort so it can be manipulated by editing the html via webkit or firebug (type="radio" => type="checkbox") and you can end up with many categories for a post again, and js scripts also are susceptible to firebug manipulation.

EDIT: I found a good solution that turns category(and any other taxonomy) into a dropdown list which cant be cheated: http://wordpress.org/extend/plugins/acategory-dropdown-list/

@dpassage I don't seem to be able to comment

pesh
  • 11
  • 2
0

Why not just put it in functions.php like this; to register it in the admin area?

//All the rest of your php stuff above ^^
add_action( 'admin_head', 'jquery_for_categories' );

function jquery_for_categories(){ ?>
    <script type="text/javascript">
      var $t = jQuery.noConflict();
      $t(document).ready(function() {   
        $t('#categorychecklist li input[type="checkbox"]').each(function(){
          $t(this).change(function(){
            //alert( $t('#categorychecklist li input[checked="checked"]').parent().html() );
            $t('#categorychecklist li input').attr('checked','');
            $t(this).attr('checked','checked');
          })
        })
      });
    </script>
} <?
Xhynk
  • 12,250
  • 8
  • 29
  • 61
0

So assuming you want one, and exactly one category to be selected, I would consider changing the inout types from checkboxes to radio buttons. You can do that without cluttering up the admin area's <head /> any more than it already is. Here's a couple methods you can add to your functions file do that:

/**
 * Add scripts (JavaScript, etc.) to the admin area
 */
public function addAdminScripts()
{
    if( is_admin() )
    {
        wp_register_script( 'your-script-id', get_template_directory() . '/inc/javascript/jquery.script.name.js', array( 'jquery' ) );
        wp_enqueue_script( 'your-script-id' );
    }
}

/**
 * Add CSS files to the admin area
 */
public function addAdminStyles()
{
    if( is_admin() )
    {
        wp_enqueue_style( 'your-css-id' );
        wp_enqueue_style( 'your-css-id', get_template_directory(). '/inc/css/your_custom_base.css' );
    }
}

The condition is_admin() will ensure that the files are only included in the admin area, and you can extend the condition to check for the post/edit screen specifically. This ensures that you can include a js/css file from your theme's directory (or if you wrap this in a plugin, you could save it to your plugin directory). Either way, you'll be less invasive in the admin area.

Now, as far as your actual script goes, Alex had a good start, but you should take it a step further and actually change the input types to radio buttons so you inherit their natural behaviour rather than force a checkbox to act like a radio button. Here's a related post on SO that is a really great reference to do exactly that how to change an element type using jquery (bonus: the author of the selected answer wrapped it into a nice plugin)

Community
  • 1
  • 1
user916011
  • 495
  • 5
  • 8
0

I tried using radio button plugins like many suggest, but it ruins any functionality with ACF so keeping the checkboxes is essential.

In my example, which most code was adapted from jQuery checkbox change and click event & Make parent categories not selectable

In my functions.php I add actions for admin_footer-post and admin_footer-post-new (or else new posts wont be affected). I am sure you can add it to the header but don't forget to update the jquery with a .ready()

Anyways, the code is really simple: If its a post, on change of a category checkbox remove all checked and apply the clicked check.

add_action( 'admin_footer-post.php', 'only_allow_one_checkbox' );
add_action( 'admin_footer-post-new.php', 'only_allow_one_checkbox' );

function only_allow_one_checkbox()
{
    global $post_type;

    if ( 'post' != $post_type )
        return;
    ?>
        <script type="text/javascript">
            $('#categorychecklist>li>label input').change(function() {
                if(this.checked) {
                    $('#categorychecklist>li>label input').prop("checked", false);
                    $(this).prop("checked", true);
                }
            });
        </script>
    <?php
}

So far, it was very easy to implement and have run into no issues.

Jared Rice
  • 184
  • 1
  • 9