diff --git a/www/js/search.js b/www/js/search.js index 1ad1cf35fc1e86516d321c4ff6fb22aa6fe7aba5..7df917209848bb85989cafea3877ca3a19488579 100644 --- a/www/js/search.js +++ b/www/js/search.js @@ -1,186 +1,301 @@ - -// Load the Google Search AJAX API -google.load("search", "1"); - -function searchInit() { - UNL_Search.peoplefinderCache = new UNL_Search.Cache(); - - //Parse the querystring for q - var qs = window.location.search.substr(1); - var args = qs.split('&'); - UNL_Search.query = ""; - for (var i = 0; i < args.length; i++) { - var pair = args[i].split('='); - if (decodeURIComponent(pair[0]) == "q") { - if (pair.length == 2) { - UNL_Search.query = decodeURIComponent(pair[1].replace(/\+/g, ' ')); - } - break; - } - } - - var unl_search = new google.search.CustomSearchControl("015236299699564929946:nk1siew10ie"); - unl_search.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET); - unl_search.setSearchCompleteCallback(UNL_Search, UNL_Search.onSearchComplete); - unl_search.setSearchStartingCallback(UNL_Search, UNL_Search.onSearchStart); +(function(window) { + "use strict"; - UNL_Search.unl_search = unl_search; + var + initCallback = 'searchInit', - drawOp = new google.search.DrawOptions(); - drawOp.enableSearchResultsOnly(); + // Service server (defaults to //directory.unl.edu) + directoryServer = null, + + unlContext = '015236299699564929946:nk1siew10ie', + + transitionDelay = 400, + + inputSel = '#search_q', + formSel = '#searchform form', + resultSel = '.search-results', + googleSel = '.google-results', + + wrapperMain = '#search_wrapper', + wrapperWeb = '#search_results', + wrapperDir = '#directory_results', + + dirResults = 'ppl_results', + unlResults = 'unl_results', + localResults = 'local_results'; - unl_search.draw('unl_results', drawOp); - - if (UNL_Search.do_local_search) { - var local_search = new google.search.CustomSearchControl(UNL_Search.local_search_context); - local_search.setResultSetSize('small'); - local_search.setSearchCompleteCallback(UNL_Search, UNL_Search.onSearchComplete); - local_search.draw('local_results', drawOp); - UNL_Search.local_search = local_search; - } - - WDN.loadJQuery(function() { - var $ = WDN.jQuery; - $('#search_q').attr('autocomplete', 'off').val(UNL_Search.query); - $('#searchform form').submit(function() { - var q = $.trim($('#search_q').val()); - UNL_Search.query = q; - UNL_Search.pfCancelFlag = false; - if (q !== '') { - unl_search.execute(q); - } else { - unl_search.cancelSearch(); - unl_search.clearAllResults(); - if (UNL_Search.do_local_search) { - local_search.cancelSearch(); - local_search.clearAllResults(); + window[initCallback] = function() { + delete window[initCallback]; + + require(['jquery', 'analytics'], function($, analytics) { + // Caching Class + var Cache = function() { + this.storage = {}; + }; + Cache.prototype.get = function(key) { + return this.storage[key] || undefined; + }; + Cache.prototype.save = function(key, value) { + this.storage[key] = value; + return this; + }; + + // Directory Controller Class + var Directory = function(server, containerId) { + var cntSel = '#' + containerId; + + this._server = server || '//directory.unl.edu'; + this._cache = new Cache(); + this._searchCanceled = false; + this._viewState = 0; + this._renderTo = cntSel; + + $(function() { + $(cntSel).on('click', '.fn a', function() { + if (this.target !== '_blank') { + this.target = '_blank'; + } + }); + }); + }; + Directory.prototype._render = function(data) { + if (this._searchCanceled) { + return; + } + + $(this._renderTo) + .html(data) + .addClass('active'); + + this._renderState(0); + }; + Directory.prototype._renderState = function(duration) { + var $innerRes = $('.results', $(this._renderTo)), + depFilter = '.departments'; + + $innerRes.slideUp(duration); + if (this._viewState === 0) { + $innerRes.not(depFilter).slideDown(); + } else { + $innerRes.filter(depFilter).slideDown(); + } + }; + Directory.prototype.cancelSearch = function() { + this._searchCanceled = true; + }; + Directory.prototype.execute = function(q) { + var cacheData = this._cache.get(q), + self = this; + + this._searchCanceled = false; + + if (cacheData) { + this._render(cacheData); + } else { + $.get(this._server + '/service.php?q=' + encodeURIComponent(q), function(data) { + self._cache.save(q, data); + self._render(data); + }); } - UNL_Search.pfCancelFlag = true; - $('#ppl_results').empty(); + }; + Directory.prototype.changeViewState = function(state) { + if (this._viewState == state) { + return; + } + + this._viewState = state; + this._renderState(); + }; + Directory.prototype.clearAllResults = function() { + $(this._renderTo).empty(); + }; + + var + // query related + query = '', + firstQ = window['INITIAL_QUERY'], + + actCls = 'active', + + // CustomSearchControl instances and config + unlSearch, + localSearch, + activeSearch, + directorySearch, + localContext = window['LOCAL_SEARCH_CONTEXT'], + drawOp = new google.search.DrawOptions(), + + trackQuery = function(q) { + var loc = window.location, + qs = loc.search.replace(/(?:(\?)|&)q=[^&]*(?:&|$)/, '$1'), + page = [ + loc.pathname, + qs || '?', + (qs && qs != '?') ? '&' : '', + 'q=', + encodeURIComponent(q) + ].join(''); + + //analytics.trackPageview(page); + + if (window.history.pushState) { + window.history.pushState({query: q}, '', page); + } + }, + queryComplete = function(control) { + $(control.root).closest(resultSel).addClass(actCls).end() + .closest(googleSel).slideDown(); + }, + fullQuery = function(q, track) { + if (track !== false) { + trackQuery(q); + } + activeSearch.execute(q); + directorySearch.execute(q); + $(wrapperMain).fadeIn(); + }, + fullStop = function() { + activeSearch.cancelSearch(); + directorySearch.cancelSearch(); + $(resultSel).removeClass(actCls); + $(wrapperMain).fadeOut(); + setTimeout(function() { + activeSearch.clearAllResults(); + directorySearch.clearAllResults(); + }, transitionDelay); + }, + queryStart = function(control, searcher, q) { + $(control.root).closest(googleSel).slideUp(0); + if (q !== query) { + trackQuery(q); + directorySearch.execute(q); + } + }; + + drawOp.enableSearchResultsOnly(); + + unlSearch = activeSearch = new google.search.CustomSearchControl(unlContext); + unlSearch.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET); + unlSearch.setSearchCompleteCallback(window, queryComplete); + unlSearch.setSearchStartingCallback(window, queryStart); + + if (localContext) { + localSearch = activeSearch = new google.search.CustomSearchControl(localContext); + localSearch.setResultSetSize('small'); + localSearch.setSearchCompleteCallback(window, queryComplete); + localSearch.setSearchStartingCallback(window, queryStart); } - return false; - }); - }); - - // Execute an inital search - if (UNL_Search.query) { - unl_search.execute(UNL_Search.query); - } -} - -//Attach search initializer to onLoad -google.setOnLoadCallback(searchInit, true); - - -// -// UNL_Search Namespace -// -if (typeof(UNL_Search) == "undefined") - UNL_Search = {}; - -UNL_Search.query = null; -UNL_Search.do_local_search = false; -UNL_Search.unl_search = null; -UNL_Search.local_search = null; -UNL_Search.local_search_context = null; -UNL_Search.peoplefinderCache = null; -UNL_Search.pfCancelFlag = false; - -//Caching Class -// -UNL_Search.Cache = {}; -UNL_Search.Cache = function() { - this.storage = new Object(); -}; - -UNL_Search.Cache.prototype.save = function(key, data) { - this.storage[key] = data; -}; - -UNL_Search.Cache.prototype.get = function (key) { - var val = null; - - if (this.storage[key] != null) { - val = this.storage[key]; - } - - return val; -}; - -UNL_Search.onSearchStart = function(control, searcher, query) { - UNL_Search.doPeoplefinderQuery(query); - if (UNL_Search.do_local_search) { - UNL_Search.local_search.execute(query); - } - UNL_Search.trackQuery(control, searcher, query); -}; - -UNL_Search.onSearchComplete = function(control, searcher) { - var $ = WDN.jQuery; - /* The more URL no longer works on google's host - if (searcher && searcher.cursor && searcher.cursor.pages.length >= 8) { - var $moreDiv = $("<div />").html('More…').addClass('gsc-cursor-page').click(function() { - window.location.href = searcher.cursor.moreResultsUrl; - return false; - }); - $('.gsc-cursor-box .gsc-cursor', control.root).append($moreDiv); - } - */ - - if (searcher.cursor && searcher.cursor.estimatedResultCount) { - var $resultHead = $("<div />").addClass('result_head').text('About ' + searcher.cursor.estimatedResultCount + ' results'); - $('.result_head', control.root).remove(); - $('.gsc-results', control.root).before($resultHead); - } - - if (mobileSearch) { //if we're doing a mobile search, rewrite link URLs to use mobile proxy - $('a.gs-title', control.root).each(function() { - $(this).attr('href', function(i, val) { - return 'http://m.unl.edu/?view=proxy&u=' + encodeURIComponent(val); - }) - }); - } -} - -UNL_Search.trackQuery = function(control, searcher, query) { - var loc = document.location; - var url = [ - loc.pathname, - loc.search, - loc.search ? '&' : '?', - 'q=', - encodeURIComponent(query) - ].join(''); - - try { - if (typeof WDN.analytics !== 'undefined') { - WDN.analytics.callTrackPageview(url); - } else { - _gaq.push(["_trackPageview", url]); - } - } catch (e) { - // do nothing - } -}; - -UNL_Search.doPeoplefinderQuery = function (val) { - var cacheData = this.peoplefinderCache.get(val) - if (cacheData) { - this.handlePeoplefinderResults(cacheData); - } else { - var pointer = this; - WDN.loadJQuery(function(){ - WDN.get("http://directory.unl.edu/service.php?q=" + encodeURIComponent(val), null, function(data, textStatus) { - pointer.peoplefinderCache.save(val, data); - UNL_Search.handlePeoplefinderResults(data); + directorySearch = new Directory(directoryServer, dirResults); + + // Setup DOM on ready + $(function() { + var $q = $(inputSel), + + tabsSel = '.result-tab', + selCls = 'selected', + stateClsPfx = 'state-', + + $resTabs = $('.result-tab'), + + googleOrigin = /^https?:\/\/www\.google\.com$/, + + passiveQuery = function(q, track) { + if (query === q) { + return; + } + + query = q; + $q.val(q); + + if (q) { + fullQuery(q, track); + } else { + fullStop(); + } + }; + + // draw the Google search controls + unlSearch.draw(unlResults, drawOp); + + if (localContext) { + localSearch.draw(localResults, drawOp); + } + + // setup the tab-like result filters + $('li:first-child', $resTabs).addClass(selCls); + $($resTabs).on('click', 'li', function(e) { + e.preventDefault(); + + if ($(this).hasClass(selCls)) { + return; + } + + var i = $(this).index(), + j = $(this).siblings('.' + selCls).index(), + $tab = $(this).closest(tabsSel), + $par = $(this).parents('.results-group'); + + $tab.removeClass(stateClsPfx + j); + $tab.addClass(stateClsPfx + i); + + $(this).siblings().removeClass(selCls); + $(this).addClass(selCls); + + if ($par.is(wrapperDir)) { + directorySearch.changeViewState(i); + } else if ($par.is(wrapperWeb)) { + $(activeSearch.root).closest(googleSel).slideUp(); + if (i === 0) { + activeSearch = localSearch; + } else { + activeSearch = unlSearch; + } + + activeSearch.execute(query); + } + }); + + // listen for the submit event + $(formSel).submit(function(e) { + e.preventDefault(); + + var q = $.trim($q.val()); + passiveQuery(q); + }); + + // issue an inital query + if (firstQ) { + passiveQuery(firstQ, false); + } + + // listen for message from parent frames + $(window).on('message', function(e) { + var oEvent = e.originalEvent, q; + + if (googleOrigin.test(oEvent.origin)) { + return; + } + + q = $.trim(oEvent.data); + passiveQuery(q); + }); + + $(window).on('popstate', function(e) { + var oEvent = e.originalEvent, + q = firstQ || ''; + + if (oEvent.state) { + q = oEvent.state.query || ''; + } + passiveQuery(q, false); + }); }); + }); - } -}; - -UNL_Search.handlePeoplefinderResults = function (peoplefinderText) { - if (!UNL_Search.pfCancelFlag) { - document.getElementById("ppl_results").innerHTML = peoplefinderText; - } -}; + }; + + window['pf_getUID'] = function() { + return true; + }; +}(window));