PageSourceSearch

https://www.kinderliteraturfestival.at/modules/mod_k2_filter/assets/js/jquery.multiselect.filter.js

js kinderliteraturfestival.at collected 2026-10-05 10:36:38 UTC 5,652 bytes, 180 lines download raw bytes

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		  //for match only first letter
126          //if(v.toUpperCase().indexOf(term.toUpperCase()) == 0){
127			//rows.eq(i).show();
128            //return inputs.get(i);
129          //}		  	  
130
131          return null;
132        }));
133      }
134
135      // show/hide optgroups
136      this.instance.menu.find(".ui-multiselect-optgroup-label").each(function() {
137        var $this = $(this);
138        var isVisible = $this.nextUntil('.ui-multiselect-optgroup-label').filter(function() {
139          return $.css(this, "display") !== 'none';
140        }).length;
141
142        $this[isVisible ? 'show' : 'hide']();
143      });
144    },
145
146    _reset: function() {
147      this.input.val('').trigger('keyup');
148    },
149
150    updateCache: function() {
151      // each list item
152      this.rows = this.instance.menu.find(".ui-multiselect-checkboxes li:not(.ui-multiselect-optgroup-label)");
153
154      // cache
155      this.cache = this.element.children().map(function() {
156        var elem = $(this);
157
158        // account for optgroups
159        if(this.tagName.toLowerCase() === "optgroup") {
160          elem = elem.children();
161        }
162
163        return elem.map(function() {
164          return this.innerHTML.toLowerCase();
165        }).get();
166      }).get();
167    },
168
169    widget: function() {
170      return this.wrapper;
171    },
172
173    destroy: function() {
174      $.Widget.prototype.destroy.call(this);
175      this.input.val('').trigger("keyup");
176      this.wrapper.remove();
177    }
178  });
179
180})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.