PageSourceSearch

https://www.bookoff.co.jp/common/js/jquery.core-ui-select.js

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