Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
10121 manish.sha 1
/* jshint forin:true, noarg:true, noempty:true, eqeqeq:true, boss:true, undef:true, curly:true, browser:true, jquery:true */
2
/*
3
 * jQuery MultiSelect UI Widget Filtering Plugin 1.5pre
4
 * Copyright (c) 2012 Eric Hynds
5
 *
6
 * http://www.erichynds.com/jquery/jquery-ui-multiselect-widget/
7
 *
8
 * Depends:
9
 *   - jQuery UI MultiSelect widget
10
 *
11
 * Dual licensed under the MIT and GPL licenses:
12
 *   http://www.opensource.org/licenses/mit-license.php
13
 *   http://www.gnu.org/licenses/gpl.html
14
 *
15
 */
16
(function($) {
17
  var rEscape = /[\-\[\]{}()*+?.,\\\^$|#\s]/g;
18
 
19
  $.widget('ech.multiselectfilter', {
20
 
21
    options: {
22
      label: 'Filter:',
23
      width: null, /* override default width set in css file (px). null will inherit */
24
      placeholder: 'Enter keywords',
25
      autoReset: false
26
    },
27
 
28
    _create: function() {
29
      var opts = this.options;
30
      var elem = $(this.element);
31
 
32
      // get the multiselect instance
33
      var instance = (this.instance = (elem.data('echMultiselect') || elem.data("multiselect") || elem.data("ech-multiselect")));
34
 
35
      // store header; add filter class so the close/check all/uncheck all links can be positioned correctly
36
      var header = (this.header = instance.menu.find('.ui-multiselect-header').addClass('ui-multiselect-hasfilter'));
37
 
38
      // wrapper elem
39
      var wrapper = (this.wrapper = $('<div class="ui-multiselect-filter">' + (opts.label.length ? opts.label : '') + '<input placeholder="'+opts.placeholder+'" type="search"' + (/\d/.test(opts.width) ? 'style="width:'+opts.width+'px"' : '') + ' /></div>').prependTo(this.header));
40
 
41
      // reference to the actual inputs
42
      this.inputs = instance.menu.find('input[type="checkbox"], input[type="radio"]');
43
 
44
      // build the input box
45
      this.input = wrapper.find('input').bind({
46
        keydown: function(e) {
47
          // prevent the enter key from submitting the form / closing the widget
48
          if(e.which === 13) {
49
            e.preventDefault();
50
          }
51
        },
52
        keyup: $.proxy(this._handler, this),
53
        click: $.proxy(this._handler, this)
54
      });
55
 
56
      // cache input values for searching
57
      this.updateCache();
58
 
59
      // rewrite internal _toggleChecked fn so that when checkAll/uncheckAll is fired,
60
      // only the currently filtered elements are checked
61
      instance._toggleChecked = function(flag, group) {
62
        var $inputs = (group && group.length) ?  group : this.labels.find('input');
63
        var _self = this;
64
 
65
        // do not include hidden elems if the menu isn't open.
66
        var selector = instance._isOpen ?  ':disabled, :hidden' : ':disabled';
67
 
68
        $inputs = $inputs
69
          .not(selector)
70
          .each(this._toggleState('checked', flag));
71
 
72
        // update text
73
        this.update();
74
 
75
        // gather an array of the values that actually changed
76
        var values = $inputs.map(function() {
77
          return this.value;
78
        }).get();
79
 
80
        // select option tags
81
        this.element.find('option').filter(function() {
82
          if(!this.disabled && $.inArray(this.value, values) > -1) {
83
            _self._toggleState('selected', flag).call(this);
84
          }
85
        });
86
 
87
        // trigger the change event on the select
88
        if($inputs.length) {
89
          this.element.trigger('change');
90
        }
91
      };
92
 
93
      // rebuild cache when multiselect is updated
94
      var doc = $(document).bind('multiselectrefresh', $.proxy(function() {
95
        this.updateCache();
96
        this._handler();
97
      }, this));
98
 
99
      // automatically reset the widget on close?
100
      if(this.options.autoReset) {
101
        doc.bind('multiselectclose', $.proxy(this._reset, this));
102
      }
103
    },
104
 
105
    // thx for the logic here ben alman
106
    _handler: function(e) {
107
      var term = $.trim(this.input[0].value.toLowerCase()),
108
 
109
      // speed up lookups
110
      rows = this.rows, inputs = this.inputs, cache = this.cache;
111
 
112
      if(!term) {
113
        rows.show();
114
      } else {
115
        rows.hide();
116
 
117
        var regex = new RegExp(term.replace(rEscape, "\\$&"), 'gi');
118
 
119
        this._trigger("filter", e, $.map(cache, function(v, i) {
120
          if(v.search(regex) !== -1) {
121
            rows.eq(i).show();
122
            return inputs.get(i);
123
          }
124
 
125
          return null;
126
        }));
127
      }
128
 
129
      // show/hide optgroups
130
      this.instance.menu.find(".ui-multiselect-optgroup-label").each(function() {
131
        var $this = $(this);
132
        var isVisible = $this.nextUntil('.ui-multiselect-optgroup-label').filter(function() {
133
          return $.css(this, "display") !== 'none';
134
        }).length;
135
 
136
        $this[isVisible ? 'show' : 'hide']();
137
      });
138
    },
139
 
140
    _reset: function() {
141
      this.input.val('').trigger('keyup');
142
    },
143
 
144
    updateCache: function() {
145
      // each list item
146
      this.rows = this.instance.menu.find(".ui-multiselect-checkboxes li:not(.ui-multiselect-optgroup-label)");
147
 
148
      // cache
149
      this.cache = this.element.children().map(function() {
150
        var elem = $(this);
151
 
152
        // account for optgroups
153
        if(this.tagName.toLowerCase() === "optgroup") {
154
          elem = elem.children();
155
        }
156
 
157
        return elem.map(function() {
158
          return this.innerHTML.toLowerCase();
159
        }).get();
160
      }).get();
161
    },
162
 
163
    widget: function() {
164
      return this.wrapper;
165
    },
166
 
167
    destroy: function() {
168
      $.Widget.prototype.destroy.call(this);
169
      this.input.val('').trigger("keyup");
170
      this.wrapper.remove();
171
    }
172
  });
173
 
174
})(jQuery);