1
|
(function ($) {
|
2
|
|
3
|
Drupal.ModuleFilter = {};
|
4
|
|
5
|
Drupal.ModuleFilter.explode = function(string) {
|
6
|
var queryArray = string.match(/([a-zA-Z]+\:(\w+|"[^"]+")*)|\w+|"[^"]+"/g);
|
7
|
if (!queryArray) {
|
8
|
queryArray = new Array();
|
9
|
}
|
10
|
var i = queryArray.length;
|
11
|
while (i--) {
|
12
|
queryArray[i] = queryArray[i].replace(/"/g, "");
|
13
|
}
|
14
|
return queryArray;
|
15
|
};
|
16
|
|
17
|
Drupal.ModuleFilter.getState = function(key) {
|
18
|
if (!Drupal.ModuleFilter.state) {
|
19
|
Drupal.ModuleFilter.state = {};
|
20
|
var cookie = $.cookie('DrupalModuleFilter');
|
21
|
var query = cookie ? cookie.split('&') : [];
|
22
|
if (query) {
|
23
|
for (var i in query) {
|
24
|
|
25
|
|
26
|
|
27
|
if (typeof(query[i]) == 'string' && query[i].indexOf('=') != -1) {
|
28
|
var values = query[i].split('=');
|
29
|
if (values.length === 2) {
|
30
|
Drupal.ModuleFilter.state[values[0]] = values[1];
|
31
|
}
|
32
|
}
|
33
|
}
|
34
|
}
|
35
|
}
|
36
|
return Drupal.ModuleFilter.state[key] ? Drupal.ModuleFilter.state[key] : false;
|
37
|
};
|
38
|
|
39
|
Drupal.ModuleFilter.setState = function(key, value) {
|
40
|
var existing = Drupal.ModuleFilter.getState(key);
|
41
|
if (existing != value) {
|
42
|
Drupal.ModuleFilter.state[key] = value;
|
43
|
var query = [];
|
44
|
for (var i in Drupal.ModuleFilter.state) {
|
45
|
query.push(i + '=' + Drupal.ModuleFilter.state[i]);
|
46
|
}
|
47
|
$.cookie('DrupalModuleFilter', query.join('&'), { expires: 7, path: '/' });
|
48
|
}
|
49
|
};
|
50
|
|
51
|
Drupal.ModuleFilter.Filter = function(element, selector, options) {
|
52
|
var self = this;
|
53
|
|
54
|
this.element = element;
|
55
|
this.text = $(this.element).val();
|
56
|
|
57
|
this.settings = Drupal.settings.moduleFilter;
|
58
|
|
59
|
this.selector = selector;
|
60
|
|
61
|
this.options = $.extend({
|
62
|
delay: 500,
|
63
|
striping: false,
|
64
|
childSelector: null,
|
65
|
empty: Drupal.t('No results'),
|
66
|
rules: new Array()
|
67
|
}, options);
|
68
|
if (this.options.wrapper == undefined) {
|
69
|
this.options.wrapper = $(self.selector).parent();
|
70
|
}
|
71
|
|
72
|
|
73
|
this.element.after('<div class="module-filter-clear"><a href="#" class="js-hide">' + Drupal.t('clear') + '</a></div>');
|
74
|
if (this.text) {
|
75
|
$('.module-filter-clear a', this.element.parent()).removeClass('js-hide');
|
76
|
}
|
77
|
$('.module-filter-clear a', this.element.parent()).click(function() {
|
78
|
self.element.val('');
|
79
|
self.text = '';
|
80
|
delete self.queries;
|
81
|
self.applyFilter();
|
82
|
self.element.focus();
|
83
|
$(this).addClass('js-hide');
|
84
|
return false;
|
85
|
});
|
86
|
|
87
|
this.updateQueries = function() {
|
88
|
var queryStrings = Drupal.ModuleFilter.explode(self.text);
|
89
|
|
90
|
self.queries = new Array();
|
91
|
for (var i in queryStrings) {
|
92
|
var query = { operator: 'text', string: queryStrings[i] };
|
93
|
|
94
|
if (self.operators != undefined) {
|
95
|
|
96
|
if (queryStrings[i].indexOf(':') > 0) {
|
97
|
|
98
|
var args = queryStrings[i].split(':', 2);
|
99
|
var operator = args.shift();
|
100
|
if (self.operators[operator] != undefined) {
|
101
|
query.operator = operator;
|
102
|
query.string = args.shift();
|
103
|
}
|
104
|
}
|
105
|
}
|
106
|
|
107
|
query.string = query.string.toLowerCase();
|
108
|
|
109
|
self.queries.push(query);
|
110
|
}
|
111
|
|
112
|
if (self.queries.length <= 0) {
|
113
|
|
114
|
self.queries.push({ operator: 'text', string: '' });
|
115
|
}
|
116
|
};
|
117
|
|
118
|
this.applyFilter = function() {
|
119
|
self.results = new Array();
|
120
|
|
121
|
self.updateQueries();
|
122
|
|
123
|
if (self.index == undefined) {
|
124
|
self.buildIndex();
|
125
|
}
|
126
|
|
127
|
self.element.trigger('moduleFilter:start');
|
128
|
|
129
|
$.each(self.index, function(key, item) {
|
130
|
var $item = item.element;
|
131
|
|
132
|
for (var i in self.queries) {
|
133
|
var query = self.queries[i];
|
134
|
if (query.operator == 'text') {
|
135
|
if (item.text.indexOf(query.string) < 0) {
|
136
|
continue;
|
137
|
}
|
138
|
}
|
139
|
else {
|
140
|
var func = self.operators[query.operator];
|
141
|
if (!(func(query.string, self, item))) {
|
142
|
continue;
|
143
|
}
|
144
|
}
|
145
|
|
146
|
var rulesResult = self.processRules(item);
|
147
|
if (rulesResult !== false) {
|
148
|
return true;
|
149
|
}
|
150
|
}
|
151
|
|
152
|
$item.addClass('js-hide');
|
153
|
});
|
154
|
|
155
|
self.element.trigger('moduleFilter:finish', { results: self.results });
|
156
|
|
157
|
if (self.options.striping) {
|
158
|
self.stripe();
|
159
|
}
|
160
|
|
161
|
if (self.results.length > 0) {
|
162
|
self.options.wrapper.find('.module-filter-no-results').remove();
|
163
|
}
|
164
|
else {
|
165
|
if (!self.options.wrapper.find('.module-filter-no-results').length) {
|
166
|
self.options.wrapper.append($('<p class="module-filter-no-results"/>').text(self.options.empty));
|
167
|
};
|
168
|
}
|
169
|
};
|
170
|
|
171
|
self.element.keyup(function(e) {
|
172
|
switch (e.which) {
|
173
|
case 13:
|
174
|
if (self.timeOut) {
|
175
|
clearTimeout(self.timeOut);
|
176
|
}
|
177
|
self.applyFilter();
|
178
|
break;
|
179
|
default:
|
180
|
if (self.text != $(this).val()) {
|
181
|
if (self.timeOut) {
|
182
|
clearTimeout(self.timeOut);
|
183
|
}
|
184
|
|
185
|
self.text = $(this).val();
|
186
|
|
187
|
if (self.text) {
|
188
|
self.element.parent().find('.module-filter-clear a').removeClass('js-hide');
|
189
|
}
|
190
|
else {
|
191
|
self.element.parent().find('.module-filter-clear a').addClass('js-hide');
|
192
|
}
|
193
|
|
194
|
self.element.trigger('moduleFilter:keyup');
|
195
|
|
196
|
self.timeOut = setTimeout(self.applyFilter, self.options.delay);
|
197
|
}
|
198
|
break;
|
199
|
}
|
200
|
});
|
201
|
|
202
|
self.element.keypress(function(e) {
|
203
|
if (e.which == 13) e.preventDefault();
|
204
|
});
|
205
|
};
|
206
|
|
207
|
Drupal.ModuleFilter.Filter.prototype.buildIndex = function() {
|
208
|
var self = this;
|
209
|
var index = new Array();
|
210
|
$(this.selector).each(function(i) {
|
211
|
var text = (self.options.childSelector) ? $(self.options.childSelector, this).text() : $(this).text();
|
212
|
var item = {
|
213
|
key: i,
|
214
|
element: $(this),
|
215
|
text: text.toLowerCase()
|
216
|
};
|
217
|
for (var j in self.options.buildIndex) {
|
218
|
var func = self.options.buildIndex[j];
|
219
|
item = $.extend(func(self, item), item);
|
220
|
}
|
221
|
$(this).data('indexKey', i);
|
222
|
index.push(item);
|
223
|
delete item;
|
224
|
});
|
225
|
this.index = index;
|
226
|
};
|
227
|
|
228
|
Drupal.ModuleFilter.Filter.prototype.processRules = function(item) {
|
229
|
var self = this;
|
230
|
var $item = item.element;
|
231
|
var rulesResult = true;
|
232
|
if (self.options.rules.length > 0) {
|
233
|
for (var i in self.options.rules) {
|
234
|
var func = self.options.rules[i];
|
235
|
rulesResult = func(self, item);
|
236
|
if (rulesResult === false) {
|
237
|
break;
|
238
|
}
|
239
|
}
|
240
|
}
|
241
|
if (rulesResult !== false) {
|
242
|
$item.removeClass('js-hide');
|
243
|
self.results.push(item);
|
244
|
}
|
245
|
return rulesResult;
|
246
|
};
|
247
|
|
248
|
Drupal.ModuleFilter.Filter.prototype.stripe = function() {
|
249
|
var self = this;
|
250
|
var flip = { even: 'odd', odd: 'even' };
|
251
|
var stripe = 'odd';
|
252
|
|
253
|
$.each(self.index, function(key, item) {
|
254
|
if (!item.element.hasClass('js-hide')) {
|
255
|
item.element.removeClass('odd even')
|
256
|
.addClass(stripe);
|
257
|
stripe = flip[stripe];
|
258
|
}
|
259
|
});
|
260
|
};
|
261
|
|
262
|
$.fn.moduleFilter = function(selector, options) {
|
263
|
var filterInput = this;
|
264
|
filterInput.parents('.module-filter-inputs-wrapper').show();
|
265
|
if (Drupal.settings.moduleFilter.setFocus) {
|
266
|
filterInput.focus();
|
267
|
}
|
268
|
filterInput.data('moduleFilter', new Drupal.ModuleFilter.Filter(this, selector, options));
|
269
|
};
|
270
|
|
271
|
})(jQuery);
|