ソースを参照

Much better live filter implementation. updates #212

JC Brand 11 年 前
コミット
52ce812694
2 ファイル変更47 行追加60 行削除
  1. 47 1
      converse.js
  2. 0 59
      src/jquery.fastLiveFilter.js

+ 47 - 1
converse.js

@@ -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()) {

+ 0 - 59
src/jquery.fastLiveFilter.js

@@ -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
-};