We’re building a new website for the Park City Library, and one of the requirements is a search form that can search either the website or initiate a search of their online catalog.
The design we settled on looks like this:
The user can enter a search term, then select from the dropdown whether they want to search the library catalog, or the website.
The crux was figuring out how to get two separate form actions out of a single form. Here’s how we did it:
Here’s the entire form and related script to get us started:
<div class="app-search searchform" role="search">
<form method="get" id="site-search-form" class="app-search__search-form" action="javascript:void(0)" onsubmit="window.location='https://classic.parkcitylibrary.org/?config=ysm#section=search&term='+this.s.value;">
<input class="search-text" type="search" name="s" placeholder="<?php if ( is_search() ) echo esc_attr( get_search_query() ); else esc_attr_e( 'Search the library...', 'pclibrary' ); ?>" <?php if(is_search()) { ?> value="<?php if ( is_search() ) echo esc_attr( get_search_query() ); else esc_attr_e( 'Search the library...', 'pclibrary' ); ?>"<?php } ?> onfocus="if(this.value==this.defaultValue)this.value='';" onblur="if(this.value=='')this.value=this.defaultValue;" />
<select name="searchSwitch" class="search-switch">
<option value="javascript:void(0)">Catalog</option>
<option value="<?php echo trailingslashit( home_url() ); ?>">Website</option>
</select>
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="5" viewBox="0 0 9 5" class="search-switch__indicate">
<path fill="none" stroke="#FFF" stroke-linecap="round" stroke-linejoin="round" d="M7.54951657e-14,-1.55431223e-15 L3.24479167,3.667125 C3.27247214,3.69841629 3.31224341,3.71633354 3.35402083,3.71633354 C3.39579826,3.71633354 3.43556953,3.69841629 3.46325,3.667125 L6.70833333,-1.55431223e-15" transform="translate(1)"/>
</svg>
<input class="search-submit" name="submit" type="submit" value="<?php esc_attr_e( 'Go', 'pclibrary' ); ?>" />
</form>
</div>
<script>
document.getElementById('site-search-form').searchSwitch.onchange = function() {
document.getElementById('site-search-form').action = this.value;
};
</script>
Let’s break each one down a bit and explain what’s going on…
The form element
<form method="get" id="site-search-form" class="app-search__search-form" action="javascript:void(0)" onsubmit="window.location='https://classic.parkcitylibrary.org/?config=ysm#section=search&term='+this.s.value;">
The form element contains a method="get"
, class and ID names, and an action="javascript:void(0)"
. We’re also using an onsubmit
that is the default option to open the library’s catalog and use the data entered into the input field as the catalog query. We could use the same onsubmit
URL as the default action
here, omitting the onsubmit
, but we’re using javascript:void(0)
instead for specific reasons that I’ll get into later.
The input element
<input class="search-text" type="search" name="s" placeholder="<?php if ( is_search() ) echo esc_attr( get_search_query() ); else esc_attr_e( 'Search the library...', 'pclibrary' ); ?>" <?php if(is_search()) { ?> value="<?php if ( is_search() ) echo esc_attr( get_search_query() ); else esc_attr_e( 'Search the library...', 'pclibrary' ); ?>"<?php } ?> onfocus="if(this.value==this.defaultValue)this.value='';" onblur="if(this.value=='')this.value=this.defaultValue;" />
The input element contains standard input attributes, plus placeholder
and value
attributes that try to maintain consistency and usability as the user interacts with the search form. For example, if the user enters ‘cats’ to search the website, they will end up on the search page. The form knows to set the value of the input field to ‘cats’ on that page, as it is the current search query term.
So far so good.
Dropdown select
<select name="searchSwitch" class="search-switch">
<option value="javascript:void(0)">Catalog</option>
<option value="<?php echo trailingslashit( home_url() ); ?>">Website</option>
</select>
This is a fairly straight forward select element, with the specific values we need to help coordinate the correct actions for the correct form outcome. Running javascript:void(0)
allows the the form onsubmit
to work in a variety of situations.
Dropdown indicator SVG
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="5" viewBox="0 0 9 5" class="search-switch__indicate">
<path fill="none" stroke="#FFF" stroke-linecap="round" stroke-linejoin="round" d="M7.54951657e-14,-1.55431223e-15 L3.24479167,3.667125 C3.27247214,3.69841629 3.31224341,3.71633354 3.35402083,3.71633354 C3.39579826,3.71633354 3.43556953,3.69841629 3.46325,3.667125 L6.70833333,-1.55431223e-15" transform="translate(1)"/>
</svg>
This SVG is the simple dropdown arrow that you see above. It is here merely for looks, as we’ve stripped all styling from the standard dropdown. I thought it might be cool to make it rotate but there’s no need as it gets covered by the option list overlay.
The submit button
<input class="search-submit" name="submit" type="submit" value="<?php esc_attr_e( 'Go', 'pclibrary' ); ?>" />
This is a simple submit input.
The switcher script
<script>
document.getElementById('site-search-form').searchSwitch.onchange = function() {
document.getElementById('site-search-form').action = this.value;
};
</script>
This is the magic script that makes the switch. It listens for an onchange
event on the select
element, and performs a simple action switch on the form, based on the value of the selected option item.
Why use onsubmit
Initially I avoided using the the voided action and the onsubmit, and for the most part the form worked fine. But if a user chose to search the website, and then changed it back to search the catalog, the onchange
event was mismatched for the catalog and borked the query. Since a form action
will override an onsubmit
event, the route I settled on worked in all cases.
A few notes to consider
- The
onchange
event is relatively simple because the event will always reset itself when the page reloads to the search page. - Yes, this switcher uses Javascript. If there is a way to avoid it, please leave tips in the comments.
- I’ve tried to use WordPress best practices in terms of escaping and sanitizing data. Let me know if I’ve missed something.
- You can see this live sometime soon at https://parkcitylibrary.org
Any questions, asides, or rude-dood retorts, please leave them in the comments!