web_interface/astpp/assets/js/jquery.searchabledropdown-1.0.8.src.js   F
last analyzed

Complexity

Total Complexity 116
Complexity/F 3.22

Size

Lines of Code 696
Function Count 36

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 0
nc 196608
dl 0
loc 696
rs 2.2242
c 0
b 0
f 0
wmc 116
mnd 5
bc 59
fnc 36
bpm 1.6388
cpm 3.2222
noi 15

2 Functions

Rating   Name   Duplication   Size   Complexity  
A jquery.searchabledropdown-1.0.8.src.js ➔ register 0 18 1
C plugin.execute 0 640 7

How to fix   Complexity   

Complexity

Complex classes like web_interface/astpp/assets/js/jquery.searchabledropdown-1.0.8.src.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/**
2
 * JQuery Searchable DropDown Plugin
3
 *
4
 * @required jQuery 1.3.x or above
5
 * @author Sascha Woo <[email protected]>
6
 * $Id: jquery.searchabledropdown.js 53 2012-11-22 08:48:14Z xhaggi $
7
 *
8
 * Copyright (c) 2012 xhaggi
9
 * https://sourceforge.net/projects/jsearchdropdown/
10
 *
11
 * Permission is hereby granted, free of charge, to any person obtaining
12
 * a copy of this software and associated documentation files (the
13
 * "Software"), to deal in the Software without restriction, including
14
 * without limitation the rights to use, copy, modify, merge, publish,
15
 * distribute, sublicense, and/or sell copies of the Software, and to
16
 * permit persons to whom the Software is furnished to do so, subject to
17
 * the following conditions:
18
 *
19
 * The above copyright notice and this permission notice shall be
20
 * included in all copies or substantial portions of the Software.
21
 *
22
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
 */
30
(function($) {
31
32
	// register plugin
33
	var plugin = register("searchable");
34
35
    // defaults
36
	plugin.defaults = {
37
        maxListSize: 100,
38
        maxMultiMatch: 50,
39
        exactMatch: false,
40
        wildcards: true,
41
        ignoreCase: true,
42
        warnMultiMatch: "top {0} matches ...",
43
        warnNoMatch: "no matches ...",
44
        latency: 200,
45
        zIndex: "auto"
46
    };
47
48
	/**
49
	 * Execute function
50
	 * element-specific code here
51
	 * @param {Options} settings Settings
52
	 */
53
	plugin.execute = function(settings, zindex) {
54
55
		var timer = null;
56
        var searchCache = null;
57
        var search = null;
58
59
		// do not attach on IE6 or lower
60
		if ($.browser.msie && parseInt(jQuery.browser.version) < 7)
61
			return this;
62
63
    	// only active select elements with drop down capability
64
        if (this.nodeName != "SELECT" || this.size > 1)
65
            return this;
66
67
        var self = $(this);
68
        var storage = {index: -1, options: null}; // holds data for restoring
69
        var idxAttr = "lang";
70
        var enabled = false;
71
72
        // detecting chrome
73
        $.browser.chrome = /chrome/.test(navigator.userAgent.toLowerCase());
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
74
        if($.browser.chrome) $.browser.safari = false;
75
76
        // lets you override the options
77
        // inside the dom objects class property
78
        // requires the jQuery metadata plugin
79
        // <div class="hello {color: 'red'}">ddd</div>
80
        if ($.meta){
81
            settings = $.extend({}, options, self.data());
0 ignored issues
show
Bug introduced by
The variable options seems to be never declared. If this is a global, consider adding a /** global: options */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
82
        }
83
84
        // objects
85
        var wrapper = $("<div/>");
86
        var overlay = $("<div/>");
87
        var input = $("<input/>");
88
        var selector = $("<select/>");
89
90
        // matching option items
91
        var topMatchItem = $("<option>"+settings.warnMultiMatch.replace(/\{0\}/g, settings.maxMultiMatch)+"</option>").attr("disabled", "true");
92
        var noMatchItem = $("<option>"+settings.warnNoMatch+"</option>").attr("disabled", "true");
93
94
95
        var selectorHelper = {
96
    		/**
97
             * Return DOM options of selector element
98
             */
99
			option: function(idx) {
100
	        	return $(selector.get(0).options[idx]);
101
	        },
102
	        /**
103
	         * Returns the selected item of selector element
104
	         */
105
	        selected: function() {
106
	        	return selector.find(":selected");
107
	        },
108
	        /**
109
	         * Get or Set the selectedIndex of the selector element
110
	         * @param {int} idx SelectedIndex
111
	         */
112
	        selectedIndex: function(idx) {
113
	        	if(idx > -1)
114
	        		selector.get(0).selectedIndex = idx;
115
	        	return selector.get(0).selectedIndex;
116
	        },
117
	        /**
118
	         * Resize selector depends on the parameter size
119
	         * @param {Number} size Size
120
	         */
121
	        size: function(size) {
122
	        	selector.attr("size", Math.max(2, Math.min(size, 20)));
123
	        },
124
	        /**
125
	         * Reset the entries, which can be choose to it's inital state depends on selectedIndex and maxMultiMatch
126
	         */
127
	        reset: function() {
128
	        	// return if selector has data and stored index equal selectedIndex of source select element
129
	        	if((self.get(0).selectedIndex-1) == self.data("index"))
130
	        		return;
131
132
	        	// calc start and length of iteration
133
	        	var idx = self.get(0).selectedIndex;
134
	        	var len = self.get(0).length;
135
	            var mc = Math.floor(settings.maxMultiMatch / 2);
136
	            var begin = Math.max(1, (idx - mc));
137
	            var end = Math.min(len, Math.max(settings.maxMultiMatch, (idx + mc)));
138
	            var si = idx - begin;
139
140
	            // clear selector select element
141
	            selector.empty();
142
	            this.size(end-begin);
143
144
	            // append options
145
	            for (var i=begin; i < end; i++)
146
	            	selector.append($(self.get(0).options[i]).clone().attr(idxAttr, i-1));
147
148
	            // append top match item if length exceeds
149
	            if(end > settings.maxMultiMatch)
150
	            	selector.append(topMatchItem);
151
152
	            // set selectedIndex of selector
153
	            selector.get(0).selectedIndex = si;
154
	        }
155
        };
156
157
        // draw it
158
        draw();
159
160
        /*
161
         * EVENT HANDLING
162
         */
163
        var suspendBlur = false;
164
        overlay.mouseover(function() {
165
        	suspendBlur = true;
166
        });
167
        overlay.mouseout(function() {
168
        	suspendBlur = false;
169
        });
170
        selector.mouseover(function() {
171
        	suspendBlur = true;
172
        });
173
        selector.mouseout(function() {
174
        	suspendBlur = false;
175
        });
176
        input.click(function(e) {
177
        	if(!enabled)
178
    			enable(e, true);
179
    		else
180
    			disable(e, true);
181
        });
182
        input.blur(function(e) {
183
        	if(!suspendBlur && enabled)
184
        		disable(e, true);
185
        });
186
        self.keydown(function(e) {
187
        	if(e.keyCode != 9 && !e.shiftKey && !e.ctrlKey && !e.altKey)
188
        		input.click();
189
        });
190
        self.click(function(e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
191
        	selector.focus();
192
        });
193
        selector.click(function(e) {
194
            if (selectorHelper.selectedIndex() < 0)
195
            	return;
196
            disable(e);
197
        });
198
        selector.focus(function(e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
199
        	input.focus();
200
        });
201
        selector.blur(function(e) {
202
        	if(!suspendBlur)
203
        		disable(e, true);
204
        });
205
        selector.mousemove(function(e) {
206
        	// Disabled on opera because of <select> elements always return scrollTop of 0
207
        	// Affects up to Opera 10 beta 1, can be removed if bug is fixed
208
            // http://www.greywyvern.com/code/opera/bugs/selectScrollTop
209
        	if($.browser.opera && parseFloat(jQuery.browser.version) >= 9.8)
210
        		return true;
211
212
        	// get font-size of option
213
        	var fs = Math.floor(parseFloat(/([0-9\.]+)px/.exec(selectorHelper.option(0).css("font-size"))));
214
        	// calc line height depends on browser
215
        	var fsdiff = 4;
216
        	if($.browser.opera)
217
        		fsdiff = 2.5;
218
        	if($.browser.safari || $.browser.chrome)
219
        		fsdiff = 3;
220
        	fs += Math.round(fs / fsdiff);
221
        	// set selectedIndex depends on mouse position and line height
222
        	selectorHelper.selectedIndex(Math.floor((e.pageY - selector.offset().top + this.scrollTop) / fs));
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
223
        });
224
225
        // toggle click event on overlay div
226
        overlay.click(function(e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
227
    		input.click();
228
        });
229
230
        // trigger event keyup
231
        input.keyup(function(e) {
232
233
        	// break searching while using navigation keys
234
        	if(jQuery.inArray(e.keyCode, new Array(9, 13, 16, 33, 34, 35, 36, 38, 40)) > -1)
0 ignored issues
show
Coding Style Best Practice introduced by
Using the Array constructor is generally discouraged. Consider using an array literal instead.
Loading history...
235
        		return true;
236
237
        	// set search text
238
        	search = $.trim(input.val().toLowerCase());
239
240
        	// if a previous timer is running, stop it
241
        	clearSearchTimer();
242
243
            // start new timer
244
            timer = setTimeout(searching, settings.latency);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
245
        });
246
247
        // trigger keydown event for keyboard usage
248
        input.keydown(function(e) {
249
250
        	// tab stop
251
        	if(e.keyCode == 9) {
252
        		disable(e);
253
        	}
254
255
        	// return on shift, ctrl, alt key mode
256
        	if(e.shiftKey || e.ctrlKey || e.altKey)
257
        		return;
258
259
        	// which key is pressed
260
            switch(e.keyCode) {
261
                case 13:  // enter
262
                	disable(e);
263
                	self.focus();
264
                    break;
265
                case 27: // escape
266
					disable(e, true);
267
					self.focus();
268
                	break;
269
                case 33: // pgup
270
                    if (selectorHelper.selectedIndex() - selector.attr("size") > 0) {
271
                        selectorHelper.selectedIndex(selectorHelper.selectedIndex() - selector.attr("size"));
272
                    }
273
                    else {
274
					    selectorHelper.selectedIndex(0);
275
				    }
276
                    synchronize();
277
                    break;
278
                case 34: // pgdown
279
                    if (selectorHelper.selectedIndex() + selector.attr("size") < selector.get(0).options.length - 1) {
280
                        selectorHelper.selectedIndex(selectorHelper.selectedIndex() + selector.attr("size"));
281
                    }
282
                    else {
283
					    selectorHelper.selectedIndex(selector.get(0).options.length-1);
284
				    }
285
                    synchronize();
286
                    break;
287
                case 38: // up
288
                    if (selectorHelper.selectedIndex() > 0){
289
                        selectorHelper.selectedIndex(selectorHelper.selectedIndex()-1);
290
                        synchronize();
291
                    }
292
                    break;
293
                case 40: // down
294
                    if (selectorHelper.selectedIndex() < selector.get(0).options.length - 1){
295
                    	selectorHelper.selectedIndex(selectorHelper.selectedIndex()+1);
296
                        synchronize();
297
                    }
298
                    break;
299
                default:
300
                    return true;
301
            }
302
303
            // we handled the key.stop
304
            // doing anything with it!
305
            return false;
306
        });
307
308
        /**
309
         * Draw the needed elements
310
         */
311
        function draw() {
312
313
            // fix some styles
314
            self.css("text-decoration", "none");
315
            self.width(self.outerWidth());
316
            self.height(self.outerHeight());
317
318
            // wrapper styles
319
            wrapper.css("position", "relative");
320
            /*wrapper.css("width", self.outerWidth());*/
321
            // relative div needs an z-index (related to IE z-index bug)
322
            if($.browser.msie)
323
            	wrapper.css("z-index", zindex);
324
325
            // overlay div to block events of source select element
326
            overlay.css({
327
                "position": "absolute",
328
                "top": 0,
329
                "left": "0px",
330
                "width":  self.outerWidth(),
331
                "height": self.outerHeight(),
332
                "background-color": "#FFFFFF",
333
                "opacity": "0.01"
334
            });
335
336
            // overlay text field for searching capability
337
            input.attr("type", "text");
338
            input.hide();
339
            input.height(self.outerHeight());
340
341
            // default styles for text field
342
	    input.attr("class", "col-md-5 form-control");
343
/*-    	    input.className = "col-md-5 form-control";*/
344
            input.css({
345
                "position": "absolute",
346
                "top": 0,
347
                "left": "0px",
348
                "margin": "0px",
349
                "padding": "0px",
350
                "outline-style": "none",
351
                "border-style": "solid",
352
                "border-bottom-style": "none",
353
                "border-color": "transparent",
354
                "background-color": "transparent"
355
356
//                "background-color": "red"
357
            });
358
359
            // copy selected styles to text field
360
    		var sty = new Array();
0 ignored issues
show
Coding Style Best Practice introduced by
Using the Array constructor is generally discouraged. Consider using an array literal instead.
Loading history...
361
    		sty.push("border-left-width");
362
    		sty.push("border-top-width");
363
    		//sty.push("font-family");
364
    		sty.push("font-size");
365
    		sty.push("font-stretch");
366
    		sty.push("font-variant");
367
    		sty.push("font-weight");
368
    		sty.push("color");
369
    		sty.push("text-align");
370
    		sty.push("text-indent");
371
    		sty.push("text-shadow");
372
    		sty.push("text-transform");
373
    		sty.push("padding-left");
374
    		sty.push("padding-top");
375
    		for(var i=0; i < sty.length;i++)
376
    			input.css(sty[i], self.css(sty[i]));
377
378
    		// adjust search text field
379
    		// IE7
380
    		if($.browser.msie && parseInt(jQuery.browser.version) < 8) {
381
    			input.css("padding", "0px");
382
    			input.css("padding-left", "3px");
383
    			input.css("border-left-width", "2px");
384
    			input.css("border-top-width", "3px");
385
    		}
386
    		// chrome
387
    		else if($.browser.chrome) {
388
    			input.height(self.innerHeight());
389
    			input.css("text-transform", "none");
390
    			input.css("padding-left", parseFloatPx(input.css("padding-left"))+3);
391
    			input.css("padding-top", 2);
392
    		}
393
    		// safari
394
    		else if($.browser.safari) {
395
    			input.height(self.innerHeight());
396
    			input.css("padding-top", 2);
397
    			input.css("padding-left", 3);
398
    			input.css("text-transform", "none");
399
    		}
400
    		// opera
401
    		else if($.browser.opera) {
402
    			input.height(self.innerHeight());
403
    			var pl = parseFloatPx(self.css("padding-left"));
404
    			input.css("padding-left", pl == 1 ? pl+1 : pl);
405
    			input.css("padding-top", 0);
406
    		}
407
    		else if($.browser.mozilla) {
408
    			input.css("padding-top", "0px");
409
    			input.css("border-top", "0px");
410
    			input.css("padding-left", parseFloatPx(self.css("padding-left"))+3);
411
    		}
412
    		// all other browsers
413
    		else {
414
    			input.css("padding-left", parseFloatPx(self.css("padding-left"))+3);
415
    			input.css("padding-top", parseFloatPx(self.css("padding-top"))+1);
416
    		}
417
418
    		// adjust width of search field
419
    		var offset = parseFloatPx(self.css("padding-left")) + parseFloatPx(self.css("padding-right")) +
420
    		parseFloatPx(self.css("border-left-width")) + parseFloatPx(self.css("border-left-width")) + 23;
421
            input.width(self.outerWidth() - offset);
422
423
    		// store css width of source select object then set width
424
    		// to auto to obtain the maximum width depends on the longest entry.
425
    		// this is nessesary to set the width of the selector, because min-width
426
    		// do not work in all browser.
427
            var w = self.css("width");
428
            var ow = self.outerWidth();
429
            self.css("width", "auto");
430
            ow = ow > self.outerWidth() ? ow : self.outerWidth();
0 ignored issues
show
Unused Code introduced by
The assignment to variable ow seems to be never used. Consider removing it.
Loading history...
431
            self.css("width", w);
432
433
            // entries selector replacement
434
            selector.hide();
435
436
            selectorHelper.size(self.get(0).length);
437
438
	    selector.attr("class", "col-md-5 form-control");	
439
            selector.css({
440
                "position": "absolute",
441
                "top": self.outerHeight(),
442
                "left": "0px",
443
/*                "width": ow,*/
444
               // "border": "0px solid #333",
445
                "font-weight": "normal",
446
                "padding": 0,
447
                "background-color": self.css("background-color"),
448
                "text-transform": self.css("text-transform")
449
            });
450
451
            // z-index handling
452
            var zIndex = /^\d+$/.test(self.css("z-index")) ? self.css("z-index") : 1;
453
            // if z-index option is defined, use it instead of select element z-index
454
            if (settings.zIndex && /^\d+$/.test(settings.zIndex))
455
            	zIndex = settings.zIndex;
456
            overlay.css("z-index", (zIndex).toString(10));
457
            input.css("z-index", (zIndex+1).toString(10));
458
            selector.css("z-index", (zIndex+2).toString(10));
459
460
            // append to container
461
            self.wrap(wrapper);
462
            self.after(overlay);
463
            self.after(input);
464
            self.after(selector);
465
        };
466
467
        /**
468
         * Enable the search facilities
469
         *
470
         * @param {Object} e Event
471
		 * @param {boolean} s Show selector
472
         * @param {boolean} v Verbose enabling
473
         */
474
        function enable(e, s, v) {
475
476
    		// exit event on disabled select element
477
    		if(self.attr("disabled"))
478
    			return false;
479
480
    		// prepend empty option
481
      		self.prepend("<option />");
482
483
    		// set state to enabled
484
    		if(typeof v == "undefined")
485
    			enabled = !enabled;
486
487
    		// reset selector
488
    		selectorHelper.reset();
489
490
    		// synchronize select and dropdown replacement
491
    		synchronize();
492
493
    		// store search result
494
        	store();
495
496
        	// show selector
497
        	if(s)
498
        		selector.show();
499
500
    		// show search field
501
    		input.show();
502
            input.focus();
503
            input.select();
504
505
            // select empty option
506
        	self.get(0).selectedIndex = 0;
507
508
        	if(typeof e != "undefined")
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if typeof e != "undefined" is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
509
        		e.stopPropagation();
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
510
        };
511
512
        /**
513
         * Disable the search facilities
514
         *
515
         * @param {Object} e Event
516
		 * @param {boolean} rs Restore last results
517
         */
518
        function disable(e, rs) {
519
520
        	// set state to disabled
521
        	enabled = false;
522
523
        	// remove empty option
524
        	self.find(":first").remove();
525
526
            // clear running search timer
527
        	clearSearchTimer();
528
529
			// hide search field and selector
530
			input.hide();
531
        	selector.hide();
532
533
			// restore last results
534
			if(typeof rs != "undefined")
535
				restore();
536
537
			// populate changes
538
			populate();
539
540
            if(typeof e != "undefined")
541
            	e.stopPropagation();
542
        };
543
544
        /**
545
         * Clears running search timer
546
         */
547
        function clearSearchTimer() {
548
        	// clear running timer
549
            if(timer != null)
550
            	clearTimeout(timer);
551
        };
552
553
        /**
554
         * Populate changes to select element
555
         */
556
        function populate() {
557
        	// invalid selectedIndex or disabled elements do not be populate
558
        	if(selectorHelper.selectedIndex() < 0 || selectorHelper.selected().get(0).disabled)
559
        		return;
560
561
        	// store selectedIndex
562
    		self.get(0).selectedIndex = parseInt(selector.find(":selected").attr(idxAttr));
563
564
        	// trigger change event
565
        	self.change();
566
567
        	// store selected index
568
        	self.data("index", new Number(self.get(0).selectedIndex));
569
        };
570
571
        /**
572
         * Synchronize selected item on dropdown replacement with source select element
573
         */
574
        function synchronize() {
575
        	if(selectorHelper.selectedIndex() > -1 && !selectorHelper.selected().get(0).disabled)
576
        		input.val(selector.find(":selected").text());
577
        	else
578
        		input.val(self.find(":selected").text());
579
        };
580
581
        /**
582
         * Stores last results of selector
583
         */
584
        function store() {
585
			storage.index = selectorHelper.selectedIndex();
586
			storage.options = new Array();
0 ignored issues
show
Coding Style Best Practice introduced by
Using the Array constructor is generally discouraged. Consider using an array literal instead.
Loading history...
587
        	for(var i=0;i<selector.get(0).options.length;i++)
588
        		storage.options.push(selector.get(0).options[i]);
589
        };
590
591
        /**
592
         * Restores last results of selector previously stored by store function
593
         */
594
        function restore() {
595
        	selector.empty();
596
        	for(var i=0;i<storage.options.length;i++)
597
				selector.append(storage.options[i]);
598
        	selectorHelper.selectedIndex(storage.index);
599
        	selectorHelper.size(storage.options.length);
600
        };
601
602
        /**
603
         * Escape regular expression string
604
         *
605
         * @param str String
606
         * @return escaped regexp string
607
         */
608
        function escapeRegExp(str) {
609
        	var specials = ["/", ".", "*", "+", "?", "|", "(", ")", "[", "]", "{", "}", "\\", "^", "$"];
610
        	var regexp = new RegExp("(\\" + specials.join("|\\") + ")", "g");
611
        	return str.replace(regexp, "\\$1");
612
    	};
613
614
        /**
615
         * The actual searching gets done here
616
         */
617
        function searching() {
618
            if (searchCache == search) { // no change ...
619
                timer = null;
620
                return;
621
            }
622
623
            var matches = 0;
624
            searchCache = search;
625
            selector.hide();
626
            selector.empty();
627
628
            // escape regexp characters
629
            var regexp = escapeRegExp(search);
630
            // exact match
631
            if(settings.exactMatch)
632
            	regexp = "^" + regexp;
633
            // wildcard support
634
            if(settings.wildcards) {
635
            	regexp = regexp.replace(/\\\*/g, ".*");
636
            	regexp = regexp.replace(/\\\?/g, ".");
637
            }
638
            // ignore case sensitive
639
            var flags = null;
640
            if(settings.ignoreCase)
641
            	flags = "i";
642
643
            // RegExp object
644
            search = new RegExp(regexp, flags);
645
646
			// for each item in list
647
            for(var i=1;i<self.get(0).length && matches < settings.maxMultiMatch;i++){
648
            	// search
649
                if(search.length == 0 || search.test(self.get(0).options[i].text)){
650
                	var opt = $(self.get(0).options[i]).clone().attr(idxAttr, i-1);
651
                	if(self.data("index") == i)
652
                		opt.text(self.data("text"));
653
                    selector.append(opt);
654
                    matches++;
655
                }
656
            }
657
658
            // result actions
659
            if(matches >= 1){
660
                selectorHelper.selectedIndex(0);
661
            }
662
            else if(matches == 0){
663
                selector.append(noMatchItem);
664
            }
665
666
            // append top match item if matches exceeds maxMultiMatch
667
            if(matches >= settings.maxMultiMatch){
668
                selector.append(topMatchItem);
669
            }
670
671
            // resize selector
672
            selectorHelper.size(matches);
673
            selector.show();
674
            timer = null;
675
        };
676
677
        /**
678
         * Parse a given pixel size value to a float value
679
         * @param value Pixel size value
680
         */
681
        function parseFloatPx(value) {
682
			try {
683
				value = parseFloat(value.replace(/[\s]*px/, ""));
684
				if(!isNaN(value))
685
					return value;
686
			}
687
			catch(e) {}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
688
			return 0;
689
		};
690
691
        return;
0 ignored issues
show
Unused Code introduced by
This return has no effect and can be removed.
Loading history...
692
    };
693
694
    /**
695
     * Register plugin under given namespace
696
     *
697
     * Plugin Pattern informations
698
     * The function creates the namespace under jQuery
699
     * and bind the function to execute the plugin code.
700
     * The plugin code goes to the plugin.execute function.
701
     * The defaults can setup under plugin.defaults.
702
     *
703
     * @param {String} nsp Namespace for the plugin
704
     * @return {Object} Plugin object
705
     */
706
    function register(nsp) {
707
708
    	// init plugin namespace
709
    	var plugin = $[nsp] = {};
710
711
    	// bind function to jQuery fn object
712
    	$.fn[nsp] = function(settings) {
713
    		// extend default settings
714
    		settings = $.extend(plugin.defaults, settings);
715
716
    		var elmSize = this.size();
717
            return this.each(function(index) {
718
            	plugin.execute.call(this, settings, elmSize-index);
719
            });
720
        };
721
722
        return plugin;
723
	};
724
725
})(jQuery);
726