forms – Conditional 3 level dropdown filter for custom post type
I need help please with the following: I have a custom post type with a hierarchical taxonomy called location. Country is the parent of state which is the parent of city (Country -> state -> city). I’m trying to create 3 dropdowns:
- Select country (highest level)
- The states that are children of that country can be selected next
- Finally, the cities that are children of the selected state can then be selected
Once a city is selected, the user gets directed to that city term’s archive page: example.com/location/selected-city.
I found the following resource helpful:
Conditional two level dropdown filter for custom post type
And used it to create the below code. But, one thing is after selecting a state and the form submits, the state that displays resets back to the first option while the selected state value gets picked up by the city dropdown. Lastly, when the city is selected how can I pass that term’s slug to the URL so that the end result is redirecting to the page example.com/location/selected-city ?
<form method="POST" action="">
<div>
<?php
$args = array(
// hierarchical is needed to define depth
'hierarchical' => 1,
// regions are the top level in a hierarchical taxonomy
'depth' => 1,
'term_taxonomy_id' => array( 82, 83),
'orderby' => 'name',
// we're not echoing, because we want to construct a no button solution
'echo' => 0,
'taxonomy' => 'location',
// this leads to variable name $_POST['region']
'name' => 'country'
);
if( ! isset($_POST['country']) ):
// if no region was selected prior we show this by default
$args['show_option_none'] = 'Select Country';
else:
// otherwise make sure the region form shows what was selected before
$args['selected'] = $_POST['country'];
endif;
// we're putting the dropdown output into a variable
$country = wp_dropdown_categories( $args );
// this enables the buttonless js possibility
$country = preg_replace("#<select([^>]*)>#", "<select$1 onchange="return this.form.submit()">", $country);
// now echo the dropdown output
echo $country;
// the »<noscript>...</noscript> part makes sure there is a fallback in case there is no js
?>
<noscript>
<div>
<input type="submit" value="country" />
</div>
</noscript>
</div>
</form>
<?php
// the state dropdown is only shown if a country was selected
if( isset($_POST['country']) && $_POST['country'] ):
?>
<form method="POST" action="">
<?php // we add a hidden input to hand over the country selected ?>
<input type="hidden" name="country" value="<?php echo $_POST['country'] ?>">
<div>
<?php
$args = array(
// the states to show are children of the prior selected country
'parent' => $_POST['country'],
'hide_if_empty' => true,
'orderby' => 'name',
'echo' => 0,
'taxonomy' => 'location',
'name' => 'state'
);
if( ! isset($_POST['state']) ):
$args['show_option_none'] = 'Select State';
endif;
$state = wp_dropdown_categories( $args );
$state = preg_replace("#<select([^>]*)>#", "<select$1 onchange="return this.form.submit()">", $state);
echo $state;
?>
<noscript>
<div>
<input type="submit" value="state" />
</div>
</noscript>
</div>
</form>
<?php endif; ?>
<?php
// the area dropdown is only shown if a state was selected
if( isset($_POST['country']) && $_POST['country'] && isset($_POST['state']) && $_POST['state'] ):
?>
<form method="POST" action="">
<?php // we add a hidden input to hand over the state selected ?>
<input type="hidden" name="state" value="<?php echo $_POST['state'] ?>">
<div>
<?php
$args = array(
// the states to show are children of the prior selected state
'parent' => $_POST['state'],
'hide_if_empty' => true,
'orderby' => 'name',
'echo' => 0,
'taxonomy' => 'location',
'name' => 'city'
);
if( ! isset($_POST['city']) ):
$args['show_option_none'] = 'Select City';
endif;
$city = wp_dropdown_categories( $args );
$city = preg_replace("#<select([^>]*)>#", "<select$1 onchange="return this.form.submit()">", $city);
echo $city;
?>
<noscript>
<div>
<input type="submit" value="city" />
</div>
</noscript>
</div>
</form>
<?php endif; ?>
Leave an answer