mirror of
https://github.com/nikdoof/limetime.git
synced 2025-12-13 09:42:26 +00:00
149 lines
4.2 KiB
JavaScript
149 lines
4.2 KiB
JavaScript
(function ($) {
|
|
|
|
//The timeout has to live in this scope
|
|
var timeout;
|
|
|
|
function LiveSearch($elem, options) {
|
|
this.$elem = $elem;
|
|
this.$form = $elem.closest('form');
|
|
this.options = $.extend({
|
|
delay: 400,
|
|
minimum_characters: 3,
|
|
serialize: this.$form,
|
|
client_side_cache: true,
|
|
process_data: false
|
|
}, options);
|
|
if (this.options.file_extension) {
|
|
this.ajax_url = this.ensure_file_extension(this.options.file_extension);
|
|
} else {
|
|
this.ajax_url = this.url;
|
|
}
|
|
this.last_search = false;
|
|
this.search_xhr = false;
|
|
if (this.options.client_side_cache) {
|
|
this.cache = {};
|
|
} else {
|
|
this.cache = false;
|
|
}
|
|
this.active = true;
|
|
this._attach();
|
|
}
|
|
|
|
$.fn.livesearch = function (options) {
|
|
options = options || {};
|
|
return $(this).each(function () {
|
|
var livesearch = $(this).data('livesearch');
|
|
if (!livesearch) {
|
|
livesearch = new LiveSearch($(this), options);
|
|
$(this).data('livesearch', livesearch);
|
|
}
|
|
});
|
|
};
|
|
|
|
|
|
$.extend(LiveSearch.prototype, {
|
|
_attach: function () {
|
|
var _this = this;
|
|
|
|
this.$elem.attr('autocomplete', 'off'); //we got this, yall
|
|
|
|
this.$elem.bind("keypress cut paste input", function () {
|
|
if (!_this.active) { return; }
|
|
|
|
clearTimeout(timeout);
|
|
timeout = setTimeout(function () {
|
|
_this.search();
|
|
}, _this.options.delay);
|
|
});
|
|
this.options.serialize.bind('change', function () {
|
|
_this.search();
|
|
});
|
|
this.$elem.bind('livesearch:suspend', function () {
|
|
_this.active = false;
|
|
});
|
|
this.$elem.bind('livesearch:activate', function () {
|
|
_this.active = true;
|
|
});
|
|
this.$elem.bind('livesearch:cancel', function () {
|
|
if (_this.search_xhr) {
|
|
_this.search_xhr.abort();
|
|
}
|
|
_this.last_search = false;
|
|
});
|
|
},
|
|
|
|
ensure_file_extension: function (extension) {
|
|
var
|
|
host_regexp_string = window.location.host.replace(/[^\w\d]/g, function (m) { return '\\' + m; }),
|
|
file_extension_regexp = new RegExp("((?:" + host_regexp_string + ")?[^\\.$#\\?]+)(\\.\\w*|)($|#|\\?)");
|
|
|
|
return this.url.replace(file_extension_regexp, function (m, _1, _2, _3) { return _1 + '.' + extension + _3; });
|
|
},
|
|
|
|
suspend_while: function (func) {
|
|
this.active = false;
|
|
func();
|
|
// TODO: this timeout is to to allow events to bubble before re-enabling,
|
|
// but I'm not sure why bubbling doesn't occur synchronously.
|
|
var _this = this;
|
|
setTimeout(function () {
|
|
_this.active = true;
|
|
}, 100);
|
|
},
|
|
|
|
search: function () {
|
|
var _this = this,
|
|
form_data = this.options.serialize.serialize();
|
|
|
|
|
|
if (this.options.process_data) {
|
|
form_data = this.options.process_data.apply(this, [form_data]);
|
|
if (typeof form_data === 'object') {
|
|
form_data = $.param(form_data);
|
|
}
|
|
}
|
|
|
|
if (form_data === this.last_search) { return; }
|
|
if (this.$elem.val().length < this.options.minimum_characters) { return; }
|
|
|
|
if (this.search_xhr) {
|
|
this.search_xhr.abort();
|
|
}
|
|
|
|
if (this.cache && this.cache[form_data] && typeof (this.cache[form_data]) !== 'function') {
|
|
this.$elem.trigger('livesearch:results', [this.cache[form_data]]);
|
|
} else {
|
|
this.$elem.trigger('livesearch:searching');
|
|
this.$elem.addClass('searching');
|
|
|
|
this.search_xhr = $.ajax({
|
|
type: 'get',
|
|
url: this.options.url || this.$form.attr('action'),
|
|
dataType: 'json',
|
|
data: form_data,
|
|
global: false,
|
|
success: function (data, textStatus, xhr) {
|
|
// this is the best workaround I can think of for
|
|
// http://dev.jquery.com/ticket/6173
|
|
if (data === null) { return; }
|
|
|
|
_this.$elem.trigger('livesearch:results', [data]);
|
|
_this.$elem.removeClass('searching');
|
|
if (_this.cache) {
|
|
_this.cache[form_data] = data;
|
|
}
|
|
},
|
|
error: function () {
|
|
_this.$elem.trigger('livesearch:ajax_error');
|
|
_this.$elem.removeClass('searching');
|
|
}
|
|
});
|
|
}
|
|
|
|
this.last_search = form_data;
|
|
}
|
|
|
|
});
|
|
|
|
}(jQuery));
|