# Setting up a global site search using typeahead

I've written a "clever" bit of javascript that sets up typeahead and bloodhound for use as a global search facility.

To make this even more clever, I've stashed a date for when the search JSON that powers bloodhound, into an application variable so that I don't have to keep getting the JSON on each page load, however I have to access this stashed variable somehow. So I've gone and done something like this (using jQuery) and I've truncated it a little as some of the functions are pretty similar:

$(function(){ var accentedcharmap = {"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"Ae"... etc}; var normalize = function(str) {$.each(accentedcharmap, function(chars, normalized) {
var regex = new RegExp('[' + chars + ']', 'gi');
str = str.replace(regex, normalized);
});

return str;
}

var queryTokenizer = function(q) {
var normalized = normalize(q);
return Bloodhound.tokenizers.whitespace(normalized);
};

var coreObjects = coreObjects || {};

coreObjects.methods = {
dateRefreshed : '',
jurisdictionsObject : '',
practiceAreasObject : '',
contactsObject : '',
organisationsObject : '',
organisationsLookup : '',
contactsLookup : '',
practiceAreasLookup : '',
jurisdictionsLookup : '',
BloodHoundContacts : '',
BloodHoundOrganisations : '',
BloodHoundJurisdictions : '',
BloodHoundPracticeAreas : '',
setJurisdictions : function(){
if(this.jurisdictionsObject.length == 0 && typeof(sessionStorage) != 'undefined' && !sessionStorage.getItem('GTDT-coreObjects-Jurisdictions')){
this.jurisdictionsObject =  $.getJSON(core.appurl + 'app/controllers/concerns/concern.json.data.cfm?sType=jurisdictions') .done(function(data){ if(typeof(sessionStorage) != 'undefined' && !sessionStorage.getItem('GTDT-coreObjects-Jurisdictions')){ sessionStorage.setItem('GTDT-coreObjects-Jurisdictions', JSON.stringify(data)); } return JSON.stringify(data); }); } else { this.jurisdictionsObject = sessionStorage.getItem('GTDT-coreObjects-Jurisdictions'); } }, JurisdictionsBloodHound : function(){ var jurisdictionsLookup = {}; if(this.jurisdictionsObject.length == 0){ this.BloodHoundJurisdictions = new Bloodhound({ datumTokenizer: function(data){ return Bloodhound.tokenizers.whitespace(normalize(data.name)); }, queryTokenizer: Bloodhound.tokenizers.whitespace, prefetch: { url: core.appurl + 'app/controllers/concerns/concern.json.data.cfm?sType=jurisdictions', filter: function(parsedResponse){ return$.map(parsedResponse.DATA.NAME, function (data, index) {
jurisdictionsLookup[data] = parsedResponse.DATA.ID[index];
return {
name: [data]
};
});
},
ttl: 0,
thumbprint: 'jurisdictions'
},
limit: 3
});
} else {
var jurisdictionsJSON = JSON.parse(this.jurisdictionsObject);

this.BloodHoundJurisdictions = new Bloodhound({
datumTokenizer: function(data){
return Bloodhound.tokenizers.whitespace(normalize(data.name));
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: $.map(jurisdictionsJSON.DATA.NAME, function(data, index){ jurisdictionsLookup[data] = jurisdictionsJSON.DATA.ID[index]; return {name: data}; }) }); } this.jurisdictionsLookup = jurisdictionsLookup; }, initialize : function(){ var self = this; var finishedInit =$.ajax({
url: core.appurl + 'app/controllers/concerns/concern.json.data.cfm?sType=refreshdate',
dataType: 'json'
}).done(function(data){
//return data;
self.dateRefreshed = Date.now();

var applicationDateRefreshed = data.responseJSON;

if(applicationDateRefreshed >= self.dateRefreshed || self.jurisdictionsObject.length == 0){
self.setJurisdictions();
self.setPracticeAreas();
self.setContacts();
self.setOrganisations();
}
}).fail(function(){
self.setJurisdictions();
self.setPracticeAreas();
self.setContacts();
self.setOrganisations();
}).always(function(){
self.OrganisationBloodHound();
self.BloodHoundOrganisations.initialize();
self.PracticeAreasBloodHound();
self.BloodHoundPracticeAreas.initialize();
self.JurisdictionsBloodHound();
self.BloodHoundJurisdictions.initialize();
self.ContactsBloodHound();
self.BloodHoundContacts.initialize();
});

return finishedInit;
}
}

var finishedInit = coreObjects.methods.initialize();

finishedInit.always(function(){

2. Assuming that comes back with a 200, we check the response date to see if that is greater than now, we also check to see if there is anything in the jurisdictionsObject.
3. If either of those are false, we then check to see if the sessionstorage object exists and is blank, if it exists we grab from the sessionstorage, if not we make a JSON call and get the latest JSON. This is actually possibly the wrong thing I want to do...
5. We then return the original daterefreshed JSON call and do an .always to setup the typeahead.