3

I'm using WordPress as a CMS and would like to have categories selectable from multiple selections i.e <option>.

enter image description hereenter image description here

As a usage example, The first dropdown would contain parent categories. Then after selecting the parent a second select drop-down would appear with the child categories. There are a few plugins available on Wordpress.org but they all seem to be broken or out of date. Any help would be appreciated.

Broken plugin http://wordpress.org/extend/plugins/ajax-category-dropdown/

The code I'm using from wordpress.org

<form action="<?php bloginfo('url'); ?>/" method="get">
    <?php
    $select = wp_dropdown_categories('orderby=name&echo=0&depth=0&hierarchical=1&exclude=5,4');
    $select = preg_replace("#<select([^>]*)>#", "<select$1 onchange='return this.form.submit()'>", $select);
    echo $select;
    ?>
    <noscript><input type="submit" value="View" /></noscript>
</form>

2 Answers 2

4
+50
function parent_child_cat_select() { ?>
        <script type="text/javascript">
        /* <![CDATA[ */
            jQuery(document).ready(function() {     
                jQuery('#parent_cat').change(function(){
                    var parentCat=jQuery('#parent_cat').val();
                    // call ajax
                    jQuery.ajax({
                        url:"/wp-admin/admin-ajax.php",
                        type:'POST',
                        data:'action=category_select_action&parent_cat_ID=' + parentCat,
                        success:function(results)
                        {
                        jQuery("#sub_cat_div").html(results);
                        }
                     });
                });         
            });     
        /* ]]> */
        </script>

        <form action="<?php bloginfo('url'); ?>/" method="get">

        <div id="parent_cat_div"><?php wp_dropdown_categories("show_option_none=Select parent category&orderby=name&depth=1&hierarchical=1&id=parent_cat"); ?></div>

        <div id="sub_cat_div"><select name="sub_cat_disabled" id="sub_cat_disabled" disabled="disabled"><option>Select parent category first!</option></select></div>

        <div id="submit_div"><input type="submit" value="View" /></div>

        </form>
<?php }

function implement_ajax() {
    $parent_cat_ID = $_POST['parent_cat_ID'];
    if ( isset($parent_cat_ID) )
    {
        $has_children = get_categories("parent=$parent_cat_ID");
        if ( $has_children ) {
            wp_dropdown_categories("orderby=name&parent=$parent_cat_ID");
        } else {
            ?><select name="sub_cat_disabled" id="sub_cat_disabled" disabled="disabled"><option>No child categories!</option></select><?php
        }
        die();
    } // end if
}
add_action('wp_ajax_category_select_action', 'implement_ajax');
add_action('wp_ajax_nopriv_category_select_action', 'implement_ajax');//for users that are not logged in.

//this is optional, only if you are not already using jQuery  
function load_jquery() {
    wp_enqueue_script('jquery');            
}     
add_action('init', 'load_jquery');

For displaying the the drop-down menus use the parent_child_cat_select() function.

<?php parent_child_cat_select(); ?>
7
  • add_action('wp_ajax_category_select_action', 'implement_ajax');//for users that are not logged in. Should be add_action( 'wp_ajax_nopriv_category_select_action'. 'implement_ajax' );
    – Cristian
    Commented Apr 24, 2011 at 16:32
  • @Wild Phoenix yes you are right. I fixed it in my post. Commented Apr 24, 2011 at 16:36
  • Thanks! However, I'm getting a message that's indicating there are no child categories when there are several. Commented Apr 25, 2011 at 18:54
  • @Zach do you have posts assigned to these child categories? Also be aware this setting will list only strictly related sub-categories. Commented Apr 25, 2011 at 22:08
  • @JohnnyPea Yep, each has several custom posts. I'm ok with it listing strictly related categories. For instance Camera would have each of the categories that I've assigned products to. I updated the post with a shot of what my categories section looks like. Thanks again for your help. Commented Apr 25, 2011 at 22:13
1
<form action="<?php echo remove_query_arg(array('mycat_go', 'cat')); ?>" method="get">
    <?php
    // get selected category and do some initializations
    if (isset($_REQUEST['cat'])) $_REQUEST['mycat_go'] = $_REQUEST['cat'];
    $selected = $_REQUEST['mycat_go'];
    $selects = array();
    $last = 0;
    $top = false;
    $i = 0;
    // basically, we are looping from the selected up through the parents
    // till we have no parent anymore.
    while (!$top) {
        // prep query to generate field containing all child categories
        // of the selected one
        $args = array(
            'name' => 'mycat_'.$i,
            'orderby' => 'name',
            'echo' => 0,
            'hierarchical' => 1,
            'exclude' => '4,5',
            'child_of' => $selected,
            'depth' => 1,
            'show_option_none' => '--select--',
            'hide_if_empty' => true,
        );
        if(!empty($last)) $args['selected'] = $last;
        // prepare next loop iteration or stop if we are displaying children of 0
        if (!empty($selected)) {
            $last = $selected;
            $category = get_category($selected);
            $selected = $category->parent;
        } else {
            $top = true;
        }
        // generate output and store in reversed order as we are going bottom up
        $select = wp_dropdown_categories($args);
        $select = preg_replace("#<option([^>]*)>#", "<option$1 onclick=\"this.parentNode.name = 'mycat_go';return this.form.submit()\">", $select);
        array_unshift($selects, $select);
        $i++;
    }
    // print to screen
    foreach ($selects as $select) {
        echo $select;
    }
    ?>
</form>
<form action="<?php remove_query_arg(array('mycat_go', 'cat')); ?>" method="get">
    <input type="hidden" name="cat" value="<?php echo $_REQUEST['mycat_go']; ?>" />
    <input type="submit" value="Go there" />
</form>

Could use some polishing, but should work.

22
  • lol, that was pretty impressive and it totally makes sense! However there's an error on line 15 if(!empty($last) $args['selected'] = $last; I'm not sure what's causing it. Commented Feb 28, 2011 at 16:43
  • @Zach Shallbetter: Oops, that's a typo...missing closing bracket. Edited it.
    – wyrfel
    Commented Feb 28, 2011 at 17:23
  • So I went ahead and added it to the page and it returned an uncountable list of select boxes. It also had a huge load time. I thought it might be me so I nuked a few categories and wiped all other code off of the template. Didn't seem to resolve the issue. Commented Feb 28, 2011 at 18:15
  • @Zach Shallbetter: Looks like the loop condition doesn't grab and it keeps on looping. Ok...i made another edit that should avoid the loop from going endlessly when no initial selection is made.
    – wyrfel
    Commented Feb 28, 2011 at 18:18
  • Seems to only show a single select box with the child values. Also, when you select an item it doesn't perform an action. Commented Feb 28, 2011 at 18:33

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