- Both have a form, a result count, and a results block.
- Both update the results and result count after ajax requests
- Both use mustache to render parts of the page dynamically
- Both track ajax updates as new page views
- Both support the history API
- Both have a fallback if the history API isn't available
- Neither refresh filters dynamically, except to change what is selected/deselected. This means the list of available options doesn't take into account what you have selected since loading the page.
- There are differences in what triggers an update. Site search does a hard refresh when the search term changes, which mitigates the above issue.
- Finder frontend dynamically updates atom feed URLs to match the search (this could be extracted into a separate plugin)
- Site search has additional GA stuff which may not be needed anymore
Binds to .js-live-search-form
and .js-aria-live-count
and .js-live-search-results-block
Falls back to .js-live-search-fallback
if history support is missing.
There is a limit of 15 filters for some reason. If you select 16, page shows an alert box!
There is Google Analytics tracking that works with the "live search" code.
The AJAX rendering only works with filters. There is a wide search bar, and enter/button click submits the form, which fully reloads the page.
liveSearch.action = liveSearch.$form.attr('action') + '.json';
liveSearch.saveState();
liveSearch.$form.on('change', 'input[type=checkbox]', liveSearch.checkboxChange);
$(window).on('popstate', liveSearch.popState);
if(event.originalEvent.state){
liveSearch.saveState(state); // Synchronise internal state
liveSearch.updateResults(); // Cached ajax request
liveSearch.restoreCheckboxes(); // Sets checked state for each checkbox
liveSearch.pageTrack(); // Trigger google analytics pageview
}
var pageUpdated;
if(liveSearch.checkFilterLimit(e) && liveSearch.isNewState()){ // Does nothing if the form is still the same as the internal state
liveSearch.saveState(); // Synchronise internal state
pageUpdated = liveSearch.updateResults(); // Cached ajax request
pageUpdated.done(function(){
history.pushState(liveSearch.state, '', window.location.pathname + "?" + $.param(liveSearch.state)); // Record in browser history
liveSearch.pageTrack(); // Trigger google analytics pageview
});
}
if(liveSearch.searchTermValue(liveSearch.previousState) === liveSearch.searchTermValue(liveSearch.state)){
// Only render results
liveSearch.$resultsBlock.find('.js-live-search-results-list').mustache('search/_results_list', results);
} else {
// Search term has changed
liveSearch.$resultsBlock.mustache('search/_results_block', results);
liveSearch.$resultsBlock.find('.js-openable-filter').each(function(){
// Resets open/closed state of the filter unless something is selected
// and also rebinds event handlers
new GOVUK.CheckboxFilter({el:$(this)});
})
}
liveSearch.updateAriaLiveCount();
Tracks link and position for next pageview. Redundant with enhanced ecommerce?
GOVUK.analytics.setOptionsForNextPageview({
dimension21: 'position=' + position + sublink
});
This is also sent when navigating back through the browser history API.
GOVUK.analytics.trackEvent('searchResults', 'resultsShown', {
label: JSON.stringify(searchResultData),
nonInteraction: true,
page: window.location.pathname + window.location.search
});
Binds to #js-results
, #js-search-results-info
(count block).
Detects atom links with $("link[type='application/atom+xml']").eq('0');
.
Falls back to .js-live-search-fallback
if history support is missing.
There is a narrow search bar. A form change event is triggered on change or enter key is pressed. I don't think the change event fires for the text box until it loses focus.
this.action = this.$form.attr('action') + '.json';
this.saveState();
this.$form.on('change', 'input[type=checkbox], input[type=text], input[type=radio]', this.formChange.bind(this));
this.$form.find('input[type=text]').keypress(
function(e){
if(e.keyCode == 13) {
// 13 is the return key
this.formChange();
e.preventDefault();
}
}.bind(this)
);
$(window).on('popstate', this.popState.bind(this));
if(event.originalEvent.state){
this.saveState(event.originalEvent.state);
this.updateResults();
this.restoreBooleans();
this.restoreTextInputs();
}
var pageUpdated;
if(this.isNewState()){
this.saveState();
pageUpdated = this.updateResults();
pageUpdated.done(
function(){
var newPath = window.location.pathname + "?" + $.param(this.state);
history.pushState(this.state, '', newPath);
if (GOVUK.analytics && GOVUK.analytics.trackPageview) {
GOVUK.analytics.trackPageview(newPath);
}
}.bind(this)
);
}
// As search is asynchronous, check that the action associated with these results is
// still the latest to stop results being overwritten by stale data
if(action == $.param(this.state)) {
this.$resultsBlock.mustache('finders/_results', results);
this.$countBlock.mustache('finders/_result_count', results);
this.$atomAutodiscoveryLink.attr('href', results.atom_url);
}