Dynamic Dependent Dropdowns with ExpressionEngine’s Advanced Search Form
ExpressionEngine, as of version 1.6.6, doesn’t have a way to easily search for weblog entries belonging to a particular subcategory, or child category. Hopefully that’ll be fixed in the upcoming version 2.0.
Anyway, I’ve found a way to work around that.
One of my clients asked me to make a business listings website. Information about the business should be updateable by the person who listed the business. Furthermore, each business had to fit in to one parent category, an industry, and one subcategory, a particular industry segment. As well, each of the listings would need to be searchable, using a drop-down “select” menu to choose the primary industry and the secondary industry segment.
I tried several different ways to do this before I finally found one that worked the way I wanted it to. The other ways involved passing values between pages with PHP, which wasn’t ideal because ExpressionEngine’s very purpose is seemingly to hide query strings from developers and customers alike. There were several other AJAX ways, also, which would work… but they either didn’t play nice with EE’s templating engine, or they wouldn’t easily allow category customization by users through the Control Panel.
The way I did it is to use EE’s exp:weblog:category_archive tag and the “Subcategories” ExpressionEngine plugin to list the primary industry dropdown and all possible secondary dropdowns. All of the secondary dropdowns have a default CSS style of “display: none”, so they don’t appear on the page. Selection of a parent category in the first dropdown calls a jQuery function which changes the CSS of the appropriate dropdown (based on parent category ID) to “display:inline”. With that, the second dropdown box magically appears.
You can find the templates and code I used by clicking on the “Read More” link below. Although I’ve customized the code for my own purposes, the original code came from correspondence I had with Davor Prcovich, a.k.a. “davor” on the ExpressionEngine forums. The original forum postings can be found at http://expressionengine.com/forums/viewthread/85780/.
Here’s the code. I will be adding more “how this particular part works” explanations and comments in the next few days.
Main logic - first dropdown
<fieldset class="fieldset"><legend>Industry:</legend>
<table cellpadding='4' cellspacing='6' border='0' width='100%'>
<tr align="center">
<td valign="top" align="center">
{!-- FIRST DROP DOWN --}
<select id="parentCat">
<option>Choose Industry</option>
{exp:weblog:category_archive category_group="2" weblog="businesses"
style="linear" parent_only="yes" show_empty="no" disable="category_fields"}
{categories}
<option value="{category_id}" id="{category_url_title}" {if segment_2 == category_url_title}
selected="selected"{/if}>{category_name}</option>
{/categories}
{/exp:weblog:category_archive}
</select>
</td>
<td align="center">
{!-- This creates a repeating category_id. Its used as the ID to show and hide the particular subcategory. --}
{exp:weblog:category_archive category_group="2" weblog="businesses" style="linear"
parent_only="yes" show_empty="no" disable="category_fields"}
{categories}
{embed="listings_test/second_drop" my_parent="{category_id}"}
{/categories}
{/exp:weblog:category_archive}
</td>
</tr>
</table>
</fieldset>
Secondary logic - second dropdown
<span id="podKategorije">
<select id="{embed:my_parent}" class="podKategorijeSelect" name="cat_id[]"style="display:none;">
<option>Choose Segment</option>
{exp:subcategories root_node="{embed:my_parent}" count_entries_from_weblogs="7" disable="category_fields"}
{if entries_count > 0}
<option value="{category_id}" id="{category_id}"
{if segment_3 != ""}
<?php
$category_id = '{category_id}';
$category_id_c = "C$category_id";
$segment_3 = '{segment_3}';
if ( $category_id_c == $segment_3)
{echo "selected='selected' ";}
?>
{/if}>
{category_name}</option>
{/if}
{/exp:subcategories}
</select>
</span>
The magical jQuery part
//action for first select
$(document).ready(function(){
$("select#parentCat").change(function () {
//hide all sub selects
$("select.podKategorijeSelect").css({ display:"none" });
// I made function for taking the values because I wanted if someone enter to direct link, have all opened
uzmiVrijednosti();
//displaying the right select, "selektiran" is ID of category group
$("select#" + selektiran).css({ display:"block" });
//action for second select
$("#podKategorije select").change(function () {
//again taking values
uzmiVrijednosti();
//displaying "search" button
$("#idemo").css({ display:"inline" });
});
});
//taking values from selects
function uzmiVrijednosti() {
selektiran = $("select#parentCat option:selected").val();
imeSelektiranog = $("select#parentCat option:selected").attr("id");
selektiran2 = $("select#" + selektiran + " option:selected").val();
podSelektiran = $("select#" + selektiran + " option:selected").attr("id");
};
//it selects the first select if some category is opened
{if segment_2 != ""}
uzmiVrijednosti();
$("select#" + selektiran).css({ display:"inline" });
$("#idemo").css({ display:"inline" });
{/if}
});
Make sure that you turn caching off for the templates that you use! I embedded these templates in a larger “search” template, and when I did, the member name and keyword search boxes returned “No Results Found” errors until I turned template caching off for those particular templates.
Posted on Nov 26, 2008 - 01:26 AM
