PageSourceSearch

https://www.nsktv.ru/bitrix/templates/gtrk_main/js/jquery.core-ui-select.js?141598962516504

js nsktv.ru collected 2026-10-01 10:43:10 UTC 16,504 bytes, 442 lines download raw bytes

1/**
2 * jQuery CoreUISelect
3 * Special thanks to Artem Terekhin, Yuriy Khabarov, Alexsey Shein
4 *
5 * @author      Gennadiy Ukhanov
6 * @version     0.0.3
7 */
8(function ($) {
9
10    var defaultOption = {
11        appendToBody : false,
12        jScrollPane  : null,
13        onInit       : null,
14        onFocus      : null,
15        onBlur       : null,
16        onOpen       : null,
17        onClose      : null,
18        onChange     : null,
19        onDestroy    : null
20    }
21
22    var allSelects = [];
23
24    $.browser.mobile = (/iphone|ipad|ipod|android/i.test(navigator.userAgent.toLowerCase()));
25    $.browser.operamini = Object.prototype.toString.call(window.operamini) === "[object OperaMini]";
26
27    /**
28     * CoreUISelect - stylized standard select
29     * @constructor
30     */
31    function CoreUISelect(__elem, __options, __templates) {
32
33        this.domSelect = __elem;
34        this.settings = __options || defaultOption;
35        this.isSelectShow = false;
36        this.isSelectFocus = false;
37        this.isJScrollPane = this.isJScrollPane();
38
39        // templates
40        this.templates = __templates ||
41        {
42            select : {
43                container : '<div class="b-core-ui-select"></div>',
44                value : '<span class="b-core-ui-select__value"></span>',
45                button : '<span class="b-core-ui-select__button"></span>'
46            },
47            dropdown : {
48                container : '<div class="b-core-ui-select__dropdown"></div>',
49                wrapper : '<div class="b-core-ui-select__dropdown__wrap"></div>',
50                list : '<ul class="b-core-ui-select__dropdown__list"></ul>',
51                optionLabel : '<li class="b-core-ui-select__dropdown__label"></li>',
52                item : '<li class="b-core-ui-select__dropdown__item"></li>'
53            }
54        }
55
56        this.init(this.settings);
57    }
58
59    CoreUISelect.prototype.init = function() {
60        if($.browser.operamini) return this;
61        this.buildUI();
62        this.hideDomSelect();
63        if(this.domSelect.is(':disabled')) {
64            this.select.addClass('disabled');
65            return this;
66        }
67        if(this.isJScrollPane) this.buildJScrollPane();
68        this.bindUIEvents();
69        this.settings.onInit && this.settings.onInit.apply(this, [this.domSelect, 'init']);
70
71    }
72
73    CoreUISelect.prototype.buildUI = function() {
74
75        // Build select container
76        this.select = $(this.templates.select.container)
77            .insertBefore(this.domSelect);
78
79        this.selectValue = $(this.templates.select.value)
80            .appendTo(this.select);
81
82        // TODO Add custom states for button
83        this.selectButton = $(this.templates.select.button)
84            .appendTo(this.select);
85
86        // Build dropdown container
87        this.dropdown = $(this.templates.dropdown.container);
88        this.dropdownWrapper =  $(this.templates.dropdown.wrapper).appendTo(this.dropdown);
89
90        this.settings.appendToBody ? this.dropdown.appendTo($('body')) : this.dropdown.insertBefore(this.domSelect);
91
92        // Build dropdown
93        this.dropdownList =  $(this.templates.dropdown.list).appendTo(this.dropdownWrapper);
94        this.domSelect.find('option').each($.proxy(this, 'addItems'));
95
96
97        // Build dropdown
98        this.dropdownItem =  this.dropdown.find('.'+$(this.templates.dropdown.item).attr('class'));
99
100        // Add classes for dropdown
101        this.dropdownItem.filter(':first-child').addClass('first');
102        this.dropdownItem.filter(':last-child').addClass('last');
103
104        this.addOptionGroup();
105
106        // Add placeholder value by selected option
107        this.setSelectValue(this.getSelectedItem().text());
108        this.updateDropdownPosition();
109
110        // Set current item form option:selected
111        this.currentItemOfDomSelect = this.currentItemOfDomSelect || this.domSelect.find('option:selected');
112
113    }
114
115    CoreUISelect.prototype.hideDomSelect = function() {
116
117        this.domSelect.addClass('b-core-ui-select__select_state_hide');
118        this.domSelect.css({
119            'top' : this.select.position().top,
120            'left' : this.select.position().left
121        });
122    }
123
124    CoreUISelect.prototype.showDomSelect = function() {
125        this.domSelect.css({
126            'top' : 'auto',
127            'left' : 'auto'
128        })
129        this.domSelect.removeClass('b-core-ui-select__select_state_hide') ;
130    }
131
132    CoreUISelect.prototype.bindUIEvents = function() {
133        // Bind plugin elements
134        this.domSelect.bind('focus', $.proxy(this, 'onFocus'));
135        this.domSelect.bind('blur', $.proxy(this, 'onBlur'));
136        this.domSelect.bind('change', $.proxy(this, 'onChange'));
137
138        if( $.browser.mobile) this.domSelect.bind('change', $.proxy(this, 'changeDropdownData'));
139        this.select.bind('click', $.proxy(this, 'onSelectClick'));
140        this.dropdownItem.bind('click', $.proxy(this, 'onDropdownItemClick'));
141    }
142
143    CoreUISelect.prototype.getCurrentIndexOfItem = function(__item) {
144        return this.domSelect.find('option').index($(this.domSelect).find('option:selected'));
145    }
146
147    CoreUISelect.prototype.scrollToCurrentDropdownItem = function(__item) {
148        if(this.dropdownWrapper.data('jsp')) {
149            this.dropdownWrapper.data('jsp').scrollToElement(__item);
150            return this;
151        }
152        // Alternative scroll to element
153        $(this.dropdownWrapper)
154            .scrollTop($(this.dropdownWrapper)
155            .scrollTop() + __item.position().top - $(this.dropdownWrapper).height()/2 + __item.height()/2);
156    }
157
158    CoreUISelect.prototype.buildJScrollPane = function() {
159        this.dropdownWrapper.wrap($('<div class="j-scroll-pane"></div>'));
160    }
161
162    CoreUISelect.prototype.isJScrollPane = function() {
163        if(this.settings.jScrollPane) {
164            if($.fn.jScrollPane) return true;
165            else throw new Error('jScrollPane no found');
166        }
167    }
168
169    CoreUISelect.prototype.initJScrollPane = function () {
170        this.dropdownWrapper.jScrollPane(this.settings.jScrollPane);
171    }
172
173    CoreUISelect.prototype.showDropdown = function() {
174        this.domSelect.focus();
175        this.settings.onOpen && this.settings.onOpen.apply(this, [this.domSelect, 'open']);
176        if($.browser.mobile) return this;
177        if(!this.isSelectShow) {
178            this.isSelectShow = true;
179            this.select.addClass('open');
180            this.dropdown.addClass('show').removeClass('hide');
181            if(this.isJScrollPane) this.initJScrollPane();
182            this.scrollToCurrentDropdownItem(this.dropdownItem.eq(this.getCurrentIndexOfItem(
182)));
183            this.updateDropdownPosition();
184        }
185    }
186
187    CoreUISelect.prototype.hideDropdown = function() {
188        if(this.isSelectShow) {
189            this.isSelectShow = false;
190            this.select.removeClass('open');
191            this.dropdown.removeClass('show').addClass('hide');
192            this.settings.onClose && this.settings.onClose.apply(this, [this.domSelect, 'close']);
193        }
194        if(this.isSelectFocus) this.domSelect.focus();
195    }
196
197    CoreUISelect.prototype.hideAllDropdown = function() {
198        for(var i in allSelects) {
199            if(allSelects[i].hasOwnProperty(i)) {
200                allSelects.dropdown.isSelectShow = false;
201                allSelects.dropdown.domSelect.blur();
202                allSelects.dropdown.addClass('hide').removeClass('show');
203            }
204        }
205    }
206
207    CoreUISelect.prototype.changeDropdownData = function(event) {
208        if((this.isSelectShow || this.isSelectFocus)) {
209            this.currentItemOfDomSelect = this.domSelect.find('option:selected');
210            this.dropdownItem.removeClass("selected");
211            this.dropdownItem.eq(this.getCurrentIndexOfItem()).addClass("selected");
212            this.scrollToCurrentDropdownItem(this.dropdownItem.eq(this.getCurrentIndexOfItem()));
213            this.setSelectValue(this.currentItemOfDomSelect.text());
214
215        }
216        if($.browser.mobile) this.settings.onChange && this.settings.onChange.apply(this, [this.domSelect, 'change']);
217    }
218
219    CoreUISelect.prototype.onDomSelectChange = function(_is) {
220        this.domSelect.bind('change', $.proxy(this, 'onChange'));
221        dispatchEvent(this.domSelect.get(0), 'change');
222        if(!_is) this.settings.onChange && this.settings.onChange.apply(this, [this.domSelect, 'change']);
223    }
224
225    CoreUISelect.prototype.addListenerByServicesKey = function(event) {
226        if(this.isSelectShow) {
227            switch (event.which) {
228                case 9:   // TAB
229                case 13:  // ESQ
230                case 27:  // ENTER
231                    this.hideDropdown();
232                    break;
233            }
234        }
235    }
236
237    CoreUISelect.prototype.onSelectClick = function() {
238        if(!this.isSelectShow) this.showDropdown();
239        else this.hideDropdown();
240        return false;
241    }
242
243    CoreUISelect.prototype.onFocus = function () {
244        this.isDocumentMouseDown = false;
245        this.isSelectFocus = true;
246        this.select.addClass('focus');
247        this.settings.onFocus && this.settings.onFocus.apply(this, [this.domSelect, 'focus']);
248    }
249
250    CoreUISelect.prototype.onBlur = function() {
251        if(!this.isDocumentMouseDown) {
252            this.isSelectFocus = false;
253            this.select.removeClass('focus');
254            this.settings.onBlur && this.settings.onBlur.apply(this, [this.domSelect, 'blur']);
255            //this.hideDropdown();
256        }
257    }
258
259    CoreUISelect.prototype.onChange = function () {
260        this.settings.onChange && this.settings.onChange.apply(this, [this.domSelect, 'change']);
261    }
262
263    CoreUISelect.prototype.onDropdownItemClick = function(event) {
264        var item = $(event.currentTarget);
265        if(!(item.hasClass('disabled') || item.hasClass('selected'))) {
266            this.domSelect.unbind('change', $.proxy(this, 'onChange'));
267            var index = this.dropdown.find('.'+$(this.templates.dropdown.item).attr('class')).index(item)
268            this.dropdownItem.removeClass('selected');
269            this.dropdownItem.eq(index).addClass('selected');
270            this.domSelect.find('option').removeAttr('selected');
271            this.domSelect.find('option').eq(index).attr('selected', true);
272            this.setSelectValue(this.getSelectedItem().text());
273            this.onDomSelectChange(true);
274
275        }
276        this.hideDropdown();
277        return false;
278    }
279
280    CoreUISelect.prototype.onDocumentMouseDown = function(event) {
281        this.isDocumentMouseDown = true;
282        if($(event.target).closest(this.select).length == 0 && $(event.target).closest(this.dropdown).length== 0) {
283            if($(event.target).closest('option').length==0) {  // Hack for Opera
284                this.isDocumentMouseDown = false;
285                this.hideDropdown();
286            }
287        }
288        return false;
289    }
290
291    CoreUISelect.prototype.updateDropdownPosition = function() {
292        if(this.isSelectShow) {
293            if(this.settings.appendToBody) {
294                this.dropdown.css({
295                    'position' : 'absolute',
296                    'top' : this.select.offset().top+this.select.outerHeight(true),
297                    'left' : this.select.offset().left,
298                    'z-index' : '9999'
299                });
300            } else {
301                this.dropdown.css({
302                    'position' : 'absolute',
303                    'top' : this.select.position().top+this.select.outerHeight(true),
304                    'left' : this.select.position().left,
305                    'z-index' : '9999'
306                });
307            }
308
309            var marginDifferenceBySelect = this.select.outerWidth() - this.select.width();
310            var marginDifferenceByDropdown = this.dropdown.outerWidth() - this.dropdown.width();
311
312            this.dropdown.width(this.select.outerWidth(true));
313
314            if(this.dropdown.width() == this.select.outerWidth()) {
315                this.dropdown.width((this.select.width()+marginDifferenceBySelect)-marginDifferenceByDropdown);
316            }
317
318            if(this.isJScrollPane) this.initJScrollPane();
319        }
320    }
321
322    CoreUISelect.prototype.setSelectValue = function(_text) {
323        this.selectValue.text(_text);
324    }
325
326    CoreUISelect.prototype.isOptionGroup = function() {
327        return this.domSelect.find('optgroup').length>0;
328    }
329
330    CoreUISelect.prototype.addOptionGroup = function() {
331        var optionGroup = this.domSelect.find('optgroup');
332        for(var i=0; i<optionGroup.length; i++) {
333            var index = this.domSelect.find("option").index($(optionGroup[i]).find('option:first-child'))
334            $(this.templates.dropdown.optionLabel)
335                .text($(optionGroup[i]).attr('label'))
336                .insertBefore(this.dropdownItem.eq(index));
337        }
338    }
339
340    CoreUISelect.prototype.addItems = function(index, el) {
341        var el = $(el);
342        var item = $(this.templates.dropdown.item).text(el.text());
343        if(el.attr("disabled")) item.addClass('disabled');
344        if(el.attr("selected")) {
345            this.domSelect.find('option').removeAttr('selected');
346            item.addClass('selected');
347            el.attr('selected', 'selected');
348        }
349        item.appendTo(this.dropdownList);
350    }
351
352    CoreUISelect.prototype.getSelectedItem = function() {
353        return this.dropdown.find('.selected').eq(0);
354    }
355
356    CoreUISelect.prototype.update = function() {
357        this.destroy();
358        this.init();
359    }
360
361    CoreUISelect.prototype.destroy = function() {
362        // Unbind plugin elements
363        this.domSelect.unbind('focus', $.proxy(this, 'onFocus'));
364        this.domSelect.unbind('blur', $.proxy(this, 'onBlur'));
365        this.domSelect.unbind('change', $.proxy(this, 'onChange'));
366        this.select.unbind('click', $.proxy(this, 'onSelectClick'));
367        this.dropdownItem.unbind('click', $.proxy(this, 'onDropdownItemClick'));
368        // Remove select container
369        this.select.remove();
370        this.dropdown.remove();
371        this.showDomSelect();
372        this.settings.onDestroy && this.settings.onDestroy.apply(this, [this.domSelect, 'destroy']);
373    }
374
375
376    $.fn.coreUISelect = function(__options, __templates) {
377        return this.each(function () {
378            var select = $(this).data('coreUISelect');
379            if(__options == 'destroy' && !select) return;
380            if(select){
381                __options = (typeof __options == "string" && select[__options]) ? __options : 'update';
382                select[__options].apply(select);
383                if(__options == 'destroy') {
384                    $(this).removeData('coreUISelect');
385                    for(var i=0; i<allSelects.length; i++) {
386                        if(allSelects[i] == select) {
387                            allSelects.splice(i, 1);
388                            break;
389                        }
390                    }
391                }
392            } else {
393                select = new CoreUISelect($(this), __options, __templates);
394                allSelects.push(select);
395                $(this).data('coreUISelect', select);
396            }
397
398        });
399    };
400
401    function dispatchEvent(obj, evt, doc) {
402        var doc = doc || document;
403        if(obj!==undefined || obj!==null) {
404            if (doc.createEvent) {
405                var evObj = doc.createEvent('MouseEvents');
406                evObj.initEvent(evt, true, false);
407                obj.dispatchEvent(evObj);
408            } else if (doc.createEventObject) {
409                var evObj = doc.createEventObject();
410                obj.fireEvent('on' + evt, evObj);
411            }
412        }
413    }
414
415    $(document).bind('mousedown', function(event){
416        for(var i=0; i<allSelects.length; i++){
417            allSelects[i].onDocumentMouseDown(event);
418        }
419    });
420
421    $(document).bind('keyup', function(event){
422        for(var i=0; i<allSelects.length; i++){
423            if($.browser.safari || $.browser.msie || $.browser.opera) allSelects[i].changeDropdownData(event); // Hack for Safari
424            allSelects[i].addListenerByServicesKey(event);
425        }
426    });
427
428    $(document).bind($.browser.safari ? 'keydown' : 'keypress', function(event){
429        for(var i=0; i<allSelects.length; i++){
430            allSelects[i].changeDropdownData(event);
431        }
432    });
433
434    $(window).bind('resize', function(event){
435        for(var i=0; i<allSelects.length; i++){
436            allSelects[i].updateDropdownPosition(event);
437        }
438    });
439
440
441
442})(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.