mirror of
https://github.com/nikdoof/limetime.git
synced 2025-12-19 21:49:24 +00:00
Basic styling, lots of feature work
This commit is contained in:
148
app/timer/static/js/jquery.livesearch.js
Normal file
148
app/timer/static/js/jquery.livesearch.js
Normal file
@@ -0,0 +1,148 @@
|
||||
(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));
|
||||
Reference in New Issue
Block a user