Much better live filter implementation. updates #212

This commit is contained in:
JC Brand 2014-08-08 19:08:47 +02:00
parent aff91fc683
commit 52ce812694
2 changed files with 47 additions and 60 deletions

View File

@ -3282,7 +3282,41 @@
return view;
},
filter: function (q) {
var matches;
if (q.length === 0) {
if (this.model.get('state') === OPENED) {
this.model.contacts.each($.proxy(function (item) {
if (!(converse.show_only_online_users && item.get('chat_status') === 'online')) {
this.get(item.get('id')).$el.show();
}
}, this));
}
this.showIfInvisible();
} else {
q = q.toLowerCase();
matches = this.model.contacts.filter(function (item) {
return item.get('fullname').toLowerCase().indexOf(q) === -1;
});
if (matches.length === this.model.contacts.length) { // hide the whole group
this.$el.nextUntil('dt').addBack().hide();
} else {
_.each(matches, $.proxy(function (item) {
this.get(item.get('id')).$el.hide();
}, this));
this.showIfInvisible();
}
}
},
showIfInvisible: function () {
if (!this.$el.is(':visible')) {
this.$el.show();
}
},
toggle: function (ev) {
// TODO: Need to take filter query into consideration
if (ev && ev.preventDefault) { ev.preventDefault(); }
var $el = $(ev.target);
this.$el.nextUntil('dt').slideToggle();
@ -3349,6 +3383,9 @@
this.RosterView = Backbone.Overview.extend({
tagName: 'div',
id: 'converse-roster',
events: {
"keydown .roster-filter": "liveFilter"
},
initialize: function () {
this.registerRosterHandler();
@ -3372,10 +3409,19 @@
this.$el.html(converse.templates.roster({
placeholder: __('Type to filter contacts')
}));
this.$('.roster-filter').liveFilter('.roster-contacts', {hide: 'dt'});
this.$filter = this.$('.roster-filter');
this.$roster = this.$('.roster-contacts');
return this;
},
liveFilter: _.debounce(function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
var q = ev.target.value;
_.each(this.getAll(), function (view) {
view.filter(q);
});
}, 500),
showHideFilter: function () {
var $filter = this.$('.roster-filter');
if (this.$('.roster-contacts').hasScrollBar()) {

View File

@ -8,62 +8,3 @@ jQuery.fn.hasScrollBar = function() {
return false;
};
jQuery.fn.liveFilter = function(list, options) {
/**
* fastLiveFilter jQuery plugin 1.0.3
*
* Copyright (c) 2011, Anthony Bush
* License: <http://www.opensource.org/licenses/bsd-license.php>
* Project Website: http://anthonybush.com/projects/jquery_fast_live_filter/
**/
// Options: input, list, timeout, callback
options = options || {};
var input = this;
var lastFilter = '';
var timeout = options.timeout || 0;
var callback = options.callback || function() {};
var keyTimeout;
callback(); // do a one-time callback on initialization to make sure everything's in sync
input.change(function() {
var $list = jQuery(list);
var lis = $list.children();
var len = lis.length;
var filter = input.val().toLowerCase();
if (filter.length > 0) {
$list.find(options.hide).hide();
} else {
// TODO: remember original state and set back to that
$list.find(options.hide).show();
}
var li, innerText;
var numShown = 0;
for (var i = 0; i < len; i++) {
li = lis[i];
innerText = !options.selector ?
(li.textContent || li.innerText || "") :
$(li).find(options.selector).text();
if (innerText.toLowerCase().indexOf(filter) >= 0) {
if (li.style.display == "none") {
$(li).show();
}
numShown++;
} else {
if (li.style.display != "none") {
$(li).hide();
}
}
}
callback(numShown);
return false;
}).keydown(function() {
clearTimeout(keyTimeout);
keyTimeout = setTimeout(function() {
if( input.val() === lastFilter ) return;
lastFilter = input.val();
input.change();
}, timeout);
});
return this; // maintain jQuery chainability
};