|
|
@ -65,7 +65,7 @@ $.fn.search = function(parameters) { |
|
|
|
; |
|
|
|
if(settings.automatic) { |
|
|
|
$prompt |
|
|
|
.on(inputEvent + eventNamespace, module.search.throttle) |
|
|
|
.on(inputEvent + eventNamespace, module.throttle) |
|
|
|
; |
|
|
|
} |
|
|
|
$prompt |
|
|
@ -74,12 +74,12 @@ $.fn.search = function(parameters) { |
|
|
|
.on('keydown' + eventNamespace, module.handleKeyboard) |
|
|
|
; |
|
|
|
$searchButton |
|
|
|
.on('click' + eventNamespace, module.search.query) |
|
|
|
.on('click' + eventNamespace, module.query) |
|
|
|
; |
|
|
|
$results |
|
|
|
.on('mousedown' + eventNamespace, module.event.mousedown) |
|
|
|
.on('mouseup' + eventNamespace, module.event.mouseup) |
|
|
|
.on('click' + eventNamespace, selector.result, module.results.select) |
|
|
|
.on('mousedown' + eventNamespace, module.event.result.mousedown) |
|
|
|
.on('mouseup' + eventNamespace, module.event.result.mouseup) |
|
|
|
.on('click' + eventNamespace, selector.result, module.event.result.click) |
|
|
|
; |
|
|
|
module.instantiate(); |
|
|
|
}, |
|
|
@ -111,24 +111,57 @@ $.fn.search = function(parameters) { |
|
|
|
.addClass(className.focus) |
|
|
|
; |
|
|
|
clearTimeout(module.timer); |
|
|
|
module.search.throttle(); |
|
|
|
if(module.has.minimum()) { |
|
|
|
module.results.show(); |
|
|
|
module.throttle(); |
|
|
|
if( module.has.minimumCharacters() ) { |
|
|
|
module.showResults(); |
|
|
|
} |
|
|
|
}, |
|
|
|
mousedown: function() { |
|
|
|
module.resultsClicked = true; |
|
|
|
}, |
|
|
|
mouseup: function() { |
|
|
|
module.resultsClicked = false; |
|
|
|
}, |
|
|
|
blur: function(event) { |
|
|
|
module.search.cancel(); |
|
|
|
module.cancel(); |
|
|
|
$module |
|
|
|
.removeClass(className.focus) |
|
|
|
; |
|
|
|
if(!module.resultsClicked) { |
|
|
|
module.timer = setTimeout(module.results.hide, settings.hideDelay); |
|
|
|
module.timer = setTimeout(module.hideResults, settings.hideDelay); |
|
|
|
} |
|
|
|
}, |
|
|
|
result: { |
|
|
|
mousedown: function() { |
|
|
|
module.resultsClicked = true; |
|
|
|
}, |
|
|
|
mouseup: function() { |
|
|
|
module.resultsClicked = false; |
|
|
|
}, |
|
|
|
click: function(event) { |
|
|
|
module.debug('Search result selected'); |
|
|
|
var |
|
|
|
$result = $(this), |
|
|
|
$title = $result.find('.title'), |
|
|
|
title = $title.html() |
|
|
|
; |
|
|
|
if(settings.onSelect == 'default' || settings.onSelect.call(this, event) == 'default') { |
|
|
|
var |
|
|
|
$link = $result.find('a[href]').eq(0), |
|
|
|
$title = $result.find(selector.title).eq(0), |
|
|
|
href = $link.attr('href') || false, |
|
|
|
target = $link.attr('target') || false, |
|
|
|
name = ($title.length > 0) |
|
|
|
? $title.text() |
|
|
|
: false |
|
|
|
; |
|
|
|
module.hideResults(); |
|
|
|
if(name) { |
|
|
|
$prompt.val(name); |
|
|
|
} |
|
|
|
if(href) { |
|
|
|
if(target == '_blank' || event.ctrlKey) { |
|
|
|
window.open(href); |
|
|
|
} |
|
|
|
else { |
|
|
|
window.location.href = (href); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
@ -162,7 +195,7 @@ $.fn.search = function(parameters) { |
|
|
|
if(keyCode == keys.enter) { |
|
|
|
module.verbose('Enter key pressed, selecting active result'); |
|
|
|
if( $result.filter('.' + activeClass).length > 0 ) { |
|
|
|
$.proxy(module.results.select, $result.filter('.' + activeClass) )(event); |
|
|
|
module.event.result.click.call($result.filter('.' + activeClass), event); |
|
|
|
event.preventDefault(); |
|
|
|
return false; |
|
|
|
} |
|
|
@ -208,7 +241,7 @@ $.fn.search = function(parameters) { |
|
|
|
// query shortcuts
|
|
|
|
if(keyCode == keys.enter) { |
|
|
|
module.verbose('Enter key pressed, executing query'); |
|
|
|
module.search.query(); |
|
|
|
module.query(); |
|
|
|
$searchButton |
|
|
|
.addClass(className.down) |
|
|
|
; |
|
|
@ -222,64 +255,39 @@ $.fn.search = function(parameters) { |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
has: { |
|
|
|
minimum: function() { |
|
|
|
var |
|
|
|
searchTerm = $prompt.val(), |
|
|
|
numCharacters = searchTerm.length |
|
|
|
; |
|
|
|
return (numCharacters >= settings.minCharacters); |
|
|
|
|
|
|
|
query: function() { |
|
|
|
var |
|
|
|
searchTerm = $prompt.val(), |
|
|
|
cachedHTML = module.read.cache(searchTerm) |
|
|
|
; |
|
|
|
if(cachedHTML) { |
|
|
|
module.debug('Reading result for ' + searchTerm + ' from cache'); |
|
|
|
module.addResults(cachedHTML); |
|
|
|
} |
|
|
|
}, |
|
|
|
search: { |
|
|
|
cancel: function() { |
|
|
|
var |
|
|
|
xhr = $module.data('xhr') || false |
|
|
|
; |
|
|
|
if( xhr && xhr.state() != 'resolved') { |
|
|
|
module.debug('Cancelling last search'); |
|
|
|
xhr.abort(); |
|
|
|
else { |
|
|
|
module.debug('Querying for ' + searchTerm); |
|
|
|
if($.isPlainObject(settings.source) || $.isArray(settings.source)) { |
|
|
|
module.search.local(searchTerm); |
|
|
|
} |
|
|
|
}, |
|
|
|
throttle: function() { |
|
|
|
clearTimeout(module.timer); |
|
|
|
if(module.has.minimum()) { |
|
|
|
module.timer = setTimeout(module.search.query, settings.searchDelay); |
|
|
|
else if(settings.apiSettings) { |
|
|
|
module.search.remote(searchTerm); |
|
|
|
} |
|
|
|
else { |
|
|
|
module.results.hide(); |
|
|
|
} |
|
|
|
}, |
|
|
|
query: function() { |
|
|
|
var |
|
|
|
searchTerm = $prompt.val(), |
|
|
|
cachedHTML = module.search.cache.read(searchTerm) |
|
|
|
; |
|
|
|
if(cachedHTML) { |
|
|
|
module.debug("Reading result for '" + searchTerm + "' from cache"); |
|
|
|
module.results.add(cachedHTML); |
|
|
|
else if($.fn.api !== undefined && $.api.settings.api.search !== undefined) { |
|
|
|
module.debug('Searching with default search API endpoint'); |
|
|
|
settings.apiSettings = { |
|
|
|
action: 'search' |
|
|
|
}; |
|
|
|
module.search.remote(searchTerm); |
|
|
|
} |
|
|
|
else { |
|
|
|
module.debug("Querying for '" + searchTerm + "'"); |
|
|
|
if($.isPlainObject(settings.source) || $.isArray(settings.source)) { |
|
|
|
module.search.local(searchTerm); |
|
|
|
} |
|
|
|
else if(settings.apiSettings) { |
|
|
|
module.search.remote(searchTerm); |
|
|
|
} |
|
|
|
else if($.fn.api !== undefined && $.api.settings.api.search !== undefined) { |
|
|
|
module.debug('Searching with default search API endpoint'); |
|
|
|
settings.apiSettings = { |
|
|
|
action: 'search' |
|
|
|
}; |
|
|
|
module.search.remote(searchTerm); |
|
|
|
} |
|
|
|
else { |
|
|
|
module.error(error.source); |
|
|
|
} |
|
|
|
$.proxy(settings.onSearchQuery, $module)(searchTerm); |
|
|
|
module.error(error.source); |
|
|
|
} |
|
|
|
}, |
|
|
|
settings.onSearchQuery.call(element, searchTerm); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
search: { |
|
|
|
local: function(searchTerm) { |
|
|
|
var |
|
|
|
results = [], |
|
|
@ -311,14 +319,14 @@ $.fn.search = function(parameters) { |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
searchHTML = module.results.generate({ |
|
|
|
searchHTML = module.generateResults({ |
|
|
|
results: $.merge(results, fullTextResults) |
|
|
|
}); |
|
|
|
$module |
|
|
|
.removeClass(className.loading) |
|
|
|
; |
|
|
|
module.search.cache.write(searchTerm, searchHTML); |
|
|
|
module.results.add(searchHTML); |
|
|
|
module.write.cache(searchTerm, searchHTML); |
|
|
|
module.addResults(searchHTML); |
|
|
|
}, |
|
|
|
remote: function(searchTerm) { |
|
|
|
var |
|
|
@ -328,160 +336,163 @@ $.fn.search = function(parameters) { |
|
|
|
query: searchTerm |
|
|
|
}, |
|
|
|
onSuccess : function(response) { |
|
|
|
searchHTML = module.results.generate(response); |
|
|
|
module.search.cache.write(searchTerm, searchHTML); |
|
|
|
module.results.add(searchHTML); |
|
|
|
searchHTML = module.generateResults(response); |
|
|
|
module.write.cache(searchTerm, searchHTML); |
|
|
|
module.addResults(searchHTML); |
|
|
|
}, |
|
|
|
onFailure : module.error |
|
|
|
}, |
|
|
|
searchHTML |
|
|
|
; |
|
|
|
module.search.cancel(); |
|
|
|
module.cancel(); |
|
|
|
module.debug('Executing search'); |
|
|
|
$.extend(true, apiSettings, settings.apiSettings); |
|
|
|
$.api(apiSettings); |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
cache: { |
|
|
|
read: function(name) { |
|
|
|
var |
|
|
|
cache = $module.data('cache') |
|
|
|
; |
|
|
|
return (settings.cache && (typeof cache == 'object') && (cache[name] !== undefined) ) |
|
|
|
? cache[name] |
|
|
|
: false |
|
|
|
; |
|
|
|
}, |
|
|
|
write: function(name, value) { |
|
|
|
var |
|
|
|
cache = ($module.data('cache') !== undefined) |
|
|
|
? $module.data('cache') |
|
|
|
: {} |
|
|
|
; |
|
|
|
cache[name] = value; |
|
|
|
$module |
|
|
|
.data('cache', cache) |
|
|
|
; |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
throttle: function() { |
|
|
|
clearTimeout(module.timer); |
|
|
|
if(module.has.minimumCharacters()) { |
|
|
|
module.timer = setTimeout(module.query, settings.searchDelay); |
|
|
|
} |
|
|
|
else { |
|
|
|
module.hideResults(); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
results: { |
|
|
|
generate: function(response) { |
|
|
|
module.debug('Generating html from response', response); |
|
|
|
cancel: function() { |
|
|
|
var |
|
|
|
xhr = $module.data('xhr') || false |
|
|
|
; |
|
|
|
if( xhr && xhr.state() != 'resolved') { |
|
|
|
module.debug('Cancelling last search'); |
|
|
|
xhr.abort(); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
has: { |
|
|
|
minimumCharacters: function() { |
|
|
|
var |
|
|
|
template = settings.templates[settings.type], |
|
|
|
html = '' |
|
|
|
searchTerm = $prompt.val(), |
|
|
|
numCharacters = searchTerm.length |
|
|
|
; |
|
|
|
if(($.isPlainObject(response.results) && !$.isEmptyObject(response.results)) || ($.isArray(response.results) && response.results.length > 0) ) { |
|
|
|
if(settings.maxResults > 0) { |
|
|
|
response.results = $.isArray(response.results) |
|
|
|
? response.results.slice(0, settings.maxResults) |
|
|
|
: response.results |
|
|
|
; |
|
|
|
} |
|
|
|
if($.isFunction(template)) { |
|
|
|
html = template(response); |
|
|
|
} |
|
|
|
else { |
|
|
|
module.error(error.noTemplate, false); |
|
|
|
} |
|
|
|
return (numCharacters >= settings.minCharacters); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
read: { |
|
|
|
cache: function(name) { |
|
|
|
var |
|
|
|
cache = $module.data('cache') |
|
|
|
; |
|
|
|
return (settings.cache && (typeof cache == 'object') && (cache[name] !== undefined) ) |
|
|
|
? cache[name] |
|
|
|
: false |
|
|
|
; |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
write: { |
|
|
|
cache: function(name, value) { |
|
|
|
var |
|
|
|
cache = ($module.data('cache') !== undefined) |
|
|
|
? $module.data('cache') |
|
|
|
: {} |
|
|
|
; |
|
|
|
cache[name] = value; |
|
|
|
$module |
|
|
|
.data('cache', cache) |
|
|
|
; |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
addResults: function(html) { |
|
|
|
if(settings.onResultsAdd == 'default' || settings.onResultsAdd.call($results, html) == 'default') { |
|
|
|
$results |
|
|
|
.html(html) |
|
|
|
; |
|
|
|
} |
|
|
|
module.showResults(); |
|
|
|
}, |
|
|
|
|
|
|
|
showResults: function() { |
|
|
|
if( ($results.filter(':visible').length === 0) && ($prompt.filter(':focus').length > 0) && $results.html() !== '') { |
|
|
|
if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported') && !$results.transition('is inward')) { |
|
|
|
module.debug('Showing results with css animations'); |
|
|
|
$results |
|
|
|
.transition({ |
|
|
|
animation : settings.transition + ' in', |
|
|
|
duration : settings.duration, |
|
|
|
queue : true |
|
|
|
}) |
|
|
|
; |
|
|
|
} |
|
|
|
else { |
|
|
|
html = module.message(error.noResults, 'empty'); |
|
|
|
} |
|
|
|
$.proxy(settings.onResults, $module)(response); |
|
|
|
return html; |
|
|
|
}, |
|
|
|
add: function(html) { |
|
|
|
if(settings.onResultsAdd == 'default' || $.proxy(settings.onResultsAdd, $results)(html) == 'default') { |
|
|
|
module.debug('Showing results with javascript'); |
|
|
|
$results |
|
|
|
.html(html) |
|
|
|
.stop() |
|
|
|
.fadeIn(settings.duration, settings.easing) |
|
|
|
; |
|
|
|
} |
|
|
|
module.results.show(); |
|
|
|
}, |
|
|
|
show: function() { |
|
|
|
if( ($results.filter(':visible').length === 0) && ($prompt.filter(':focus').length > 0) && $results.html() !== '') { |
|
|
|
if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported') && !$results.transition('is inward')) { |
|
|
|
module.debug('Showing results with css animations'); |
|
|
|
$results |
|
|
|
.transition({ |
|
|
|
animation : settings.transition + ' in', |
|
|
|
duration : settings.duration, |
|
|
|
queue : true |
|
|
|
}) |
|
|
|
; |
|
|
|
} |
|
|
|
else { |
|
|
|
module.debug('Showing results with javascript'); |
|
|
|
$results |
|
|
|
.stop() |
|
|
|
.fadeIn(settings.duration, settings.easing) |
|
|
|
; |
|
|
|
} |
|
|
|
$.proxy(settings.onResultsOpen, $results)(); |
|
|
|
settings.onResultsOpen.call($results); |
|
|
|
} |
|
|
|
}, |
|
|
|
hideResults: function() { |
|
|
|
if($results.filter(':visible').length > 0) { |
|
|
|
if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported') && !$results.transition('is outward')) { |
|
|
|
module.debug('Hiding results with css animations'); |
|
|
|
$results |
|
|
|
.transition({ |
|
|
|
animation : settings.transition + ' out', |
|
|
|
duration : settings.duration, |
|
|
|
queue : true |
|
|
|
}) |
|
|
|
; |
|
|
|
} |
|
|
|
}, |
|
|
|
hide: function() { |
|
|
|
if($results.filter(':visible').length > 0) { |
|
|
|
if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported') && !$results.transition('is outward')) { |
|
|
|
module.debug('Hiding results with css animations'); |
|
|
|
$results |
|
|
|
.transition({ |
|
|
|
animation : settings.transition + ' out', |
|
|
|
duration : settings.duration, |
|
|
|
queue : true |
|
|
|
}) |
|
|
|
; |
|
|
|
} |
|
|
|
else { |
|
|
|
module.debug('Hiding results with javascript'); |
|
|
|
$results |
|
|
|
.stop() |
|
|
|
.fadeIn(settings.duration, settings.easing) |
|
|
|
; |
|
|
|
} |
|
|
|
$.proxy(settings.onResultsClose, $results)(); |
|
|
|
else { |
|
|
|
module.debug('Hiding results with javascript'); |
|
|
|
$results |
|
|
|
.stop() |
|
|
|
.fadeIn(settings.duration, settings.easing) |
|
|
|
; |
|
|
|
} |
|
|
|
}, |
|
|
|
select: function(event) { |
|
|
|
module.debug('Search result selected'); |
|
|
|
var |
|
|
|
$result = $(this), |
|
|
|
$title = $result.find('.title'), |
|
|
|
title = $title.html() |
|
|
|
; |
|
|
|
if(settings.onSelect == 'default' || $.proxy(settings.onSelect, this)(event) == 'default') { |
|
|
|
var |
|
|
|
$link = $result.find('a[href]').eq(0), |
|
|
|
$title = $result.find(selector.title).eq(0), |
|
|
|
href = $link.attr('href') || false, |
|
|
|
target = $link.attr('target') || false, |
|
|
|
name = ($title.length > 0) |
|
|
|
? $title.text() |
|
|
|
: false |
|
|
|
settings.onResultsClose.call($results); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
generateResults: function(response) { |
|
|
|
module.debug('Generating html from response', response); |
|
|
|
var |
|
|
|
template = settings.templates[settings.type], |
|
|
|
html = '' |
|
|
|
; |
|
|
|
if(($.isPlainObject(response.results) && !$.isEmptyObject(response.results)) || ($.isArray(response.results) && response.results.length > 0) ) { |
|
|
|
if(settings.maxResults > 0) { |
|
|
|
response.results = $.isArray(response.results) |
|
|
|
? response.results.slice(0, settings.maxResults) |
|
|
|
: response.results |
|
|
|
; |
|
|
|
module.results.hide(); |
|
|
|
if(name) { |
|
|
|
$prompt.val(name); |
|
|
|
} |
|
|
|
if(href) { |
|
|
|
if(target == '_blank' || event.ctrlKey) { |
|
|
|
window.open(href); |
|
|
|
} |
|
|
|
else { |
|
|
|
window.location.href = (href); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if($.isFunction(template)) { |
|
|
|
html = template(response); |
|
|
|
} |
|
|
|
else { |
|
|
|
module.error(error.noTemplate, false); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
html = module.displayMessage(error.noResults, 'empty'); |
|
|
|
} |
|
|
|
settings.onResults.call(element, response); |
|
|
|
return html; |
|
|
|
}, |
|
|
|
|
|
|
|
// displays mesage visibly in search results
|
|
|
|
message: function(text, type) { |
|
|
|
displayMessage: function(text, type) { |
|
|
|
type = type || 'standard'; |
|
|
|
module.results.add( settings.templates.message(text, type) ); |
|
|
|
module.debug('Displaying message', text, type); |
|
|
|
module.addResults( settings.templates.message(text, type) ); |
|
|
|
return settings.templates.message(text, type); |
|
|
|
}, |
|
|
|
|
|
|
|