1(function ($) { 2 $.extend($.fn, { 3 toCustomSelectBox: function (options) { 4 var args = arguments; 5 6 this.each(function () { 7 if (this.nodeName.toLocaleLowerCase() !== 'select') 8 return; 9 10 if (options === 'destroy') { 11 $.removeData(this, 'customSelect'); 12 13 return new $.Destory_CustomSelectBox(this, options); 14 } 15 16 var customSelect = $.data(this, 'customSelect'); 17 18 if (options === 'selected' && customSelect) { 19 new $.Set_CustomSelectBox_Value(this, options, args[1]); 20 21 return customSelect; 22 } 23 24 if (customSelect) 25 return customSelect; 26 27 customSelect = new $.CustomSelectBox(this, options); 28 $.data(this, 'customSelect', customSelect); 29 }); 30 } 31 }); 32 33 var getOptionIdx = function (options, val) { 34 var texts = Array.prototype.slice.call(options) 35 .map(function (o) { return o.text }); 36 37 return texts.findIndex(function (t) { return String(t.toLowerCase()) === String(val || '').toLowerCase(); }); 38 }, 39 highlightSelectedOption = function (list, listItems, options, val) { 40 var idx = getOptionIdx(options, val); 41 42 if (idx < 0) 43 return; 44 45 listItems.removeClass('active'); 46 $(listItems[idx]).addClass('active'); 47 // listItems[idx].scrollIntoView(); 48 49 list.scrollTop($(listItems[idx]).position().top); 50 }; 51 52 $.Destory_CustomSelectBox = function(el, options) { 53 var $this = $(el); 54 55 if (!$this.hasClass('select-hidden')) 56 return; 57 58 $this.removeClass('select-hidden'); 59 $this.parent().find('.select-styled').remove(); 60 $this.parent().find('.select-options').remove(); 61 $this.parent().find('.arrow').remove(); 62 63 $this.unwrap(); 64 }; 65 66 $.CustomSelectBox = function (el, options) { 67 var $this = $(el), 68 numberOfOptions = $(el).children('option').length, 69 width = el.offsetWidth, 70 selectOptions = $this.children('option'), 71 selectedOptionIdx = getOptionIdx(selectOptions, $this.val()); 72 73 $this.addClass('select-hidden'); 74 $this.wrap('<div class="select"></div>'); 75 $this.after('<div class="select-styled"></div>'); 76 77 if (width !== 200) 78 $this.parent().width(width); 79 80 // bind select attributes to new select except name and id 81 for (var x = 0; attrs = el.attributes, len = attrs.length, x < len; x++) { 82 var nodeName = attrs[x].nodeName; 83 var nodeValue = attrs[x].value; 84 85 if (['id', 'name', 'class'].indexOf(nodeName.toLowerCase()) > -1) 86 continue; 87 88 $this.next('.select-styled').attr(nodeName, nodeValue); 89 } 90 91 var $styledSelect = $this.next('div.select-styled'); 92 if ($this.children('option:selected').length) 93 $styledSelect.text($this.children('option:selected').text()); 94 else 95 $styledSelect.text(selectOptions.eq(0).text()); 96 97 var $arrow = $('<i />', { 98 'class': 'arrow' 99 }).insertAfter($styledSelect); 100 101 var $list = $('<ul />', { 102 'class': 'select-options' 103 }).insertAfter($styledSelect); 104 105 106 for (var i = 0; i < numberOfOptions; i++) { 107 $('<li />', { 108 text: $this.children('option').eq(i).text(), 109 rel: $this.children('option').eq(i).val() 110 }).appendTo($list); 111 } 112 113 var $listItems = $list.children('li'); 114 115 var handleShowOptions = function (e) { 116 e.stopPropagation(); 117 118 var notThis = $('.select').not($(this).parent()), 119 currentIdx = getOptionIdx(selectOptions, $this.val()); 120 121 if (notThis && notThis.length) 122 $.each(notThis, function (i, el) { 123 if ($(el).hasClass('active')) { 124 $(el).find('div.select-styled').removeClass('active').next('ul.select-options').hide(); 125 $(el).removeClass('active'); 126 } 127 }); 128 129 $('div.select-styled.active').not($styledSelect[0]).each(function () { 130 $styledSelect.removeClass('active').next('ul.select-options').hide(); 131 $this.parent().removeClass('active'); 132 $list.toggleClass('hide'); 133 }); 134 135 $this.parent().toggleClass('active'); 136 $styledSelect.toggleClass('active').next('ul.select-options').toggle(); 137 $list.removeClass('hide'); 138 $styledSelect.attr('tabIndex', 0); 139 $styledSelect.focus(); 140 141 if (selectedOptionIdx > -1) { 142 $list.scrollTop($($listItems[currentIdx]).position().top); 143 // $listItems[currentIdx].scrollIntoView(); 144 } 145 }; 146 147 var preText = '', 148 timeout; 149 150 var handleKeyEvent = function (e) { 151 var val = e.key; 152 153 preText += val; 154 155 var texts = Array.prototype.slice.call(selectOptions) 156 .map(function (o) { return o.text }), 157 minTextLength = Math.min.apply(null, texts.map(function (t) { return t.length })), 158 idx = texts.findIndex(function (t) { return t.toLowerCase().startsWith(preText) }); 159 160 if (timeout) 161 clearTimeout(timeout); 162 163 if (idx > -1) { 164 var option = selectOptions[idx]; 165 166 $styledSelect.text($(option).text()); 167 $this.val($(option).val()); 168 $listItems.removeClass('active'); 169 $($listItems[idx]).addClass('active'); 170 // $listItems[idx].scrollIntoView(); 171 172 $list.scrollTop($($listItems[currentIdx]).position().top); 173 } 174 175 timeout = setTimeout(function () { 176 preText = ''; 177 }, 700); 178 }; 179 180 $styledSelect.click(handleShowOptions); 181 $arrow.click(handleShowOptions); 182 183 $listItems.click(function (e) { 184 e.stopPropagation(); 185 186 var $that = $(this), 187 idx = getOptionIdx(selectOptions, $that.text()); 188 189 $styledSelect.text($(this).text()).removeClass('active'); 190 $this.parent().removeClass('active'); 191 $this.val($(this).attr('rel')); 192 193 // trigger selectbox chang event 194 $this.trigger('change'); 195 196 if (idx > -1) { 197 $listItems.removeClass('active'); 198 $($listItems[idx]).addClass('active'); 199 } 200 201 if (!$list.hasClass('hide')) 202 $this.trigger('blur'); 203 204 //if ($(this).hasClass('active')) 205 // $(this).removeClass('active'); 206 207 $list.hide().toggleClass('hide'); 208 }); 209 210 211 $this.on('change', function (e) { 212 e.stopPropagation(); 213 $styledSelect.text($this.children('option:selected').text()); 214 215 //highlight ul li items base on selected value 216 highlightSelectedOption($list, $listItems, selectOptions, $this.children('option:selected').text()); 217 });
218 $styledSelect.on('keydown', handleKeyEvent); 219 220 //highlight initial value 221 highlightSelectedOption($list, $listItems, selectOptions, $this.children('option:selected').text()); 222 223 $(document).click(function () { 224 // to show custom validation error 225 if (!$list.hasClass('hide') && $styledSelect.hasClass('active')) 226 $this.trigger('blur'); 227 228 $styledSelect.removeClass('active'); 229 $this.parent().removeClass('active'); 230 231 $list.hide().toggleClass('hide'); 232 }); 233 }; 234 235 $.Set_CustomSelectBox_Value = function (el, options, val) { 236 var $this = $(el), 237 $styledSelect = $this.next('div.select-styled'), 238 options = $this.children('option'), 239 idx = getOptionIdx(options, val); 240 241 if (idx < 0) 242 return; 243 244 var option = options[idx]; 245 246 $styledSelect.text($(option).text()); 247 $this.val($(option).val()); 248 $this.trigger('change'); 249 }; 250})(jQuery || jquery || window.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.