Ask your WordPress questions! Pay money and get answers fast! (more info)

add "selected" to category parent dropdown menu WordPress

  • SOLVED

I have a dropdown menu in header.php that I want to modify. This dropdown menu lists only parent categories.

I want to add a "selected" to the option in the menu that has the same <strong>parent category</strong> as the current url. I want the current parent category to be visible in the menu.

Here is my current code that is generating the dropdown menu.

<form name="dropdown" id="sitenav-menu">
<select name="selected" id="target" accesskey="E" onchange="goToNewPage(document.dropdown.selected)">
<?php
$args = array(
'orderby' => 'name',
'parent' => 0
);
$categories = get_categories( $args );
foreach ( $categories as $category ) {
echo '<option value="' . get_category_link( $category->term_id ) . '">' . $category->name . '</option>';
} ?>
</select>
</form>


Here is a link to a demo of the code.

[[LINK href="http://opensort.net/category/music/"]]http://opensort.net/category/music/[[/LINK]]

Let me know if you have any questions. Thank you!

Answers (2)

2014-08-05

Kyle answers:

Try this:

<form name="dropdown" id="sitenav-menu">

<select name="selected" id="target" accesskey="E" onchange="goToNewPage(document.dropdown.selected)">

<?php

global $wp_query;

$args = array(

'orderby' => 'name',

'parent' => 0

);

$categories = get_categories( $args );

$name = $wp_query->query_vars['category_name'];

foreach ( $categories as $category ) {

if($category->name == $name){ $selected = 'selected'; }else{ $selected = ''; }

echo '<option value="' . get_category_link( $category->term_id ) . '" '.$selected.'>' . $category->name . '</option>';



} ?>

</select>

</form>


dirtcastle comments:

@Kyle

Thank you for the code. Unfortunately, it doesn't seem to be working.


Kyle comments:

Can you add:

echo $name;

Below this line $name = $wp_query->query_vars['category_name'];

If that is incorrect add var_dump($wp_query); outside the foreach and send the result


Kyle comments:

Another possible solution is...

$cat_id = $wp_query->get_queried_object_id();
$name = get_cat_name( $cat_id );


dirtcastle comments:

When I insert the following, it outputs the current category.

echo $name;

But I think it needs to output the parent category, correct? The dropdown menu shows parents, therefore we should be comparing parents with parents.

Note the following argument in the array.

'parent' => 0

Any thoughts?


Kyle comments:

Ah, my fault

$cat_id = $wp_query->get_queried_object_id();
$child = get_category($cat_id);
$parent = $child->parent;
$parent_ob = get_category($parent);
$name = $parent_ob->name;


dirtcastle comments:

Yes! You are awesome.

It's working on subcategories. Unfortunately, it doesn't work when the category is a parent.

Any thoughts?



Kyle comments:

Ah, do you mean like http://opensort.net/category/philosophy/areas/ vs http://opensort.net/category/philosophy/


Kyle comments:

Try this:


$cat_id = $wp_query->get_queried_object_id();
$child = get_category($cat_id);
$parent = $child->parent;
$parent_ob = get_category($parent);
if($parent>0){ $name = $parent_ob->name; }else{ $name = $child->name; }


dirtcastle comments:

Yes, there are three levels of categories (parent/child/grandchild). And this menu will show up on all three.


dirtcastle comments:

Boom!
Yes!
That did it!
Thank you!


Kyle comments:

See my last post


Kyle comments:

You're welcome! Happy to help


dirtcastle comments:

Doh! I spoke too soon. It's not working in a few places.

<strong>Where it works:</strong>
1. Parent level
[[LINK href="http://opensort.net/category/music/"]]http://opensort.net/category/music/[[/LINK]]
2. Child level
[[LINK href="http://opensort.net/category/music/genres/"]]http://opensort.net/category/music/genres/[[/LINK]]

<strong>Where it's not working:</strong>
3. Grandchild level
[[LINK href="http://opensort.net/category/music/genres/hip-hop/"]]http://opensort.net/category/music/genres/hip-hop/[[/LINK]]
4. Single.php
[[LINK href="http://opensort.net/music/genres/hip-hop/new-post-test/"]]http://opensort.net/music/genres/hip-hop/new-post-test/[[/LINK]]


Kyle comments:

Sent you a PM


Kyle comments:

Was @Dbranes able to solve the single.php problem?


dirtcastle comments:

Yes. Thank you for checking back. I appreciate all your help!


Kyle comments:

No problem, Dbranes always gets it done :)

2014-08-05

Dbranes answers:

Here's another approach:

You can try to use the <em>get_category_parents()</em> to get a support for any category child depth:


<?php
/**
* Construct the selected url for the selectbox:
*/

if( is_category() ) {

// Get the url of the top ancestor of the current category:
$ancestors = explode( ',', get_category_parents( $cat, false, ',' ) );
$select_menu_url = get_category_link( get_cat_id( array_shift( $ancestors ) ) );

}elseif( is_single() ){

// Get the url of the top ancestor of the first current post category:
$cats = get_the_category();
$ancestors = explode( ',', get_category_parents( $cats[0]->term_id, false, ',' ) );
$select_menu_url = get_category_link( get_cat_id( array_shift( $ancestors ) ) );

}else{

// Modify this to your needs:
$select_menu_url = home_url( '/' );
}

/**
* Display the selectbox:
*/
?>
<form name="dropdown" id="sitenav-menu">
<select name="selected" id="target" accesskey="E" onchange="goToNewPage(document.dropdown.selected)">
<?php
$args = array(
'orderby' => 'name',
'parent' => 0
);

$categories = get_categories( $args );
foreach ( $categories as $category ) {
$link = get_category_link( $category->term_id );
?>
<option value="<?php echo $link;?>" <?php selected( $link, $select_menu_url );?>><?php echo $category->name;?></option>
<?php
}
?>
</select>
</form>



where we use the WordPress function <em>selected()</em> to add the <em>selected</em> value.


dirtcastle comments:

Thank you! This is working on all of my category.php views.

Where it works:
1. Parent level
http://opensort.net/category/music/
2. Child level
http://opensort.net/category/music/genres/
3. Grandchild level
http://opensort.net/category/music/genres/hip-hop/

Where it's not working:
4. Single.php
http://opensort.net/music/genres/hip-hop/new-post-test/

Any thoughts on how I should get it working for single.php? Should I use an "if (is_single())" and deliver a separate form for single.php? Or should I add something to the code you've written here.


Dbranes comments:

@dirtcastle: ok sure, please see my updated the answer.

Regarding the <em>is_single(),</em> case, I find the url of the top ancestor of the first current post category (out of possible many others).

It works on my install.

ps: just let me know if this needs more adjustments, i.e. if @Kyle hasn't already solved it ;-)


dirtcastle comments:

This works for single.php! Thank you!