Custom selectbox (jScrollPane) werkt niet op iOS

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Jo Immanuel

Jo Immanuel

06/02/2018 11:56:18
Quote Anchor link
Beste mensen,

Ik maak op mijn website veel gebruik van customised selectboxen via de jquery-plugin "jScrollPane" van Kelvin Luck (zie http://jscrollpane.kelvinluck.com/).

Dit werkt allemaal prima op de desktop. Echter, op de iPad (en iPhone) werken deze customized selectboxen niet. Meer precies: op de iPad (en iPhone) worden de selectboxen wel gecustomized weergegeven, maar wanneer er op gedrukt wordt met je vinger dan opent de selectbox (selectList) niet.

Een voorbeeld op mijn site van deze selectbox(en) die wel werkt op desktop en niet op de iPad of iPhone:

http://www.devoetbalscout.nl/club.php?clubID=1&menu=statistieken

Hier zijn drie selectboxen: de seizoens-selectbox, competitie-selectbox en het onderwerp-selectbox.


Ik heb zelf al een hoop gezocht op internet en geprobeerd, maar krijg het niet werkend op de iPad. Wat het allemaal extra lastig maakt is dat ik de pagina niet kan inspecteren op de iPad.


Weet iemand wat hier verkeerd gaat op mijn website? En hoe ik dit op kan lossen?

Met vriendelijke groet,

Jo
Gewijzigd op 06/02/2018 11:58:54 door Jo Immanuel
 
PHP hulp

PHP hulp

29/04/2024 18:47:02
 
- Ariën  -
Beheerder

- Ariën -

06/02/2018 12:08:28
Quote Anchor link
Heb je dit al gelezen?

http://jscrollpane.kelvinluck.com/known_issues.html
Quote:
In Webkit browsers CSS must be included before Javascript

For jScrollPane to work correctly in Webkit based browsers (e.g. Safari, Chrome, iOS and Android) then the CSS must be included above your javascript includes. Otherwise jScrollPane can't correctly measure the size of the item you are applying jScrollPane to. See all of the example or theme pages for a reference as to the correct ordering of items in your <head>.

Ik heb geen idee of je dit ook al geprobeerd hebt?
Gewijzigd op 06/02/2018 12:09:37 door - Ariën -
 
Jo Immanuel

Jo Immanuel

06/02/2018 12:13:08
Quote Anchor link
He hallo,

Volgens mij wel:

ik heb op mijn pagina eerst in de <head>:
<link rel="stylesheet" type="text/css" href="customselectbox/jquery.jscrollpane.css" />
<link rel="stylesheet" type="text/css" href="customselectbox/customSelectBox.css" rel="NOFOLLOW"/>
<link rel="stylesheet" type="text/css" href="Templates/CSS/jquery.mCustomScrollbar.css"/>

Dan de <body>, en aan het eind van de body de <scripts>:
<script src="customselectbox/jScrollPane.js"></script>
<script src="customselectbox/jquery.mousewheel.js"></script>
<script src="customselectbox/SelectBox.js"></script>






Toevoeging op 06/02/2018 12:22:54:

Toevoeging:

De content waar de selectboxen in staan worden wel geladen met een ajax-post-request. Dus eerst wordt de linkerkant van de pagina geladen en op het einde worden dan (afhankelijk van de meegegeven variabelen in de URL) het middengedeelte en de rechterkant geladen (waar hier de selectboxen in staan).

Misschien dat dit het probleem veroorzaakt?
 
Adoptive Solution

Adoptive Solution

06/02/2018 13:00:23
Quote Anchor link
Op een iPad kan je o.a. dit programma gebruiken :

MIHTool Basic - Web Debugger van Gaolu Li

https://itunes.apple.com/nl/app/mihtool-basic-web-debugger/id584739126?mt=8
 
Jo Immanuel

Jo Immanuel

06/02/2018 19:43:46
Quote Anchor link
Thanx voor het programmatje om te kunnen inspecteren op de iPad.


Als voorbeeld neem ik de selectbox op de volgende pagina van mijn website: http://www.devoetbalscout.nl/competitiezoeken.php

Dit is wat er gebeurd:

A: Desktop:

Als ik de geparsde html-code van de selectbox genaamd "zoekmanier" inspecteer op de desktop, dan krijg ik initieel het volgende:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<div class="customSelect custom" id="select-zoekmanier" style="width: 280px; z-index: 100;">
    <select id="zoekmanier" class="custom"> ... met hierin de options & css: display="none" ... </select>
    <div class="selectValueWrap"> ... met selected value ... </div>
    <div class="selectList"> ... de lijst met options ... </div>
</div>  


Na klikken op de selectbox wordt de html-code:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<div class="customSelect custom select-open" id="select-zoekmanier" style="width: 280px; z-index: 101;">
    <select id="zoekmanier" class="custom"> ... met hierin de options & css: display="none" ... </select>
    <div class="selectValueWrap"> ... met selected value ... </div>
    <div class="selectList"> ... de lijst met options ... </div>
</div>  


Kortom: de class "select-open" wordt toegevoegd aan de buitenste div en de z-index van deze div wordt verhoogd van 100 naar 101. Gevolg is dat de selectList zichtbaar wordt.

B: iPad:

Als ik de geparsde html-code van de selectbox genaamd "zoekmanier" inspecteer op de iPad, dan krijg ik initieel het volgende:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<div class="customSelect custom use-default" id="select-zoekmanier" style="width: 280px; z-index: 100;">
    <select id="zoekmanier" class="custom"> ... met hierin de options & css: display="none" ... </select>
    <div class="selectValueWrap"> ... met selected value ... </div>
    <div class="selectList"> ... de lijst met options ... </div>
</div>  


Na drukken op de selectbox verandert de html-code op de iPad niet en de class "select-open" wordt ook niet toegevoegd. De selectList is dus ook niet zichtbaar. Het enige dat er gebeurd is dat de selectbox heel kort grijs wordt en daarna weer terug verandert.


Iemand een idee wat hier mis gaat en hoe ik dit kan oplossen?

Toevoeging op 06/02/2018 20:08:01:

Extra info:

De HTML-code van de selectbox:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<select id="zoekmanier" class="custom">
    <option value="normaal" default="default" selected="selected">normaal zoeken</option>
    <option value="normaal">normaal zoeken</option>
    <option value="uitgebreid">uitgebreid zoeken</option>
</select>



De customselect wordt 'geactiveerd' met volgende code:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
$(document).ready(function(){
    $("select#zoekmanier.custom").each(function() {
        var sb = new SelectBox({
            selectbox: $(this),
            height: 290,
            width: 280,
            changeCallback: function(val) {
                var manier = val;
                .. etc ...                
            }                
        });
    });                                
});    


Verder denk ik onderstaand bestandje van belang is (en vraag ik me af of ik scrollpane.js eigenlijk wel gebruik... ) aangezien daar de "select-open" class wordt toegevoegd.

(zie http://www.roblaplaca.com/docs/custom-selectbox/ )

"SelectBox.js"

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
  
/**
 * @classDescription    Custom selectbox with the option to use jScrollPane
 *                        for a custom scrollbar. Hides the original selectbox off
 *                        screen so that it will still get picked up as a form element.
 *
 * @version                1.1.0
 *
 * @author                Rob LaPlaca - [email protected]
 * @date                04/05/2010
 * @lastUpdate            03/09/2014
 * @dependency            jScrollPane.js            optional
 *                        jquery.mousewheel.js    optional
 *
 * @param {DOMElement}    options.selectbox            the selectbox that is being customized, REQUIRED (default undefined)
 * @param {Boolean}        options.customScrollbar        whether or not to use jScrollPane to restyle system scrollbar (default false)
 * @param {Number}        options.zIndex                The default z-index of the selectbox. (default 100)
 * @param {Function}    options.changeCallback        Function that gets executed on change of the selectbox (default empty function)
 * @param {Function}    options.manager                Optional reference to a class that manages all instances of the selectbox
 * @param {Object}        options.scrollOptions        jScrollPane options, refer to jscrollpane documentation for possible options
 *                                                    http://www.kelvinluck.com/assets/jquery/jScrollPane/scripts/jScrollPane.js
 */
(function($){
    window.SelectBoxManager = function(options){
        var sbs = [],
            self = this;

        $(document).click(function(e) {
            if($(e.target).parents(".customSelect").size() === 0) {
                self.close();
            }
        });

        this.add = function(sb) {
            sbs.push(sb);
        };

        this.close = function() {
            $(sbs).each(function() {
                this.close();
            });
        };
    };

    var sb_manager = new SelectBoxManager();

    window.SelectBox = function(options){
        var self = this,
        cfg = $.extend(true, {
            manager: sb_manager,
            customScrollbar: true,
            zIndex: 100,
            changeCallback: function(val) { },
            truncate: function(str) {return str;},
            scrollOptions: {}
        }, options);

        var $customSelect, $selectedValue, $selectValueWrap, $selectList, $dl, $options,
            FOCUSED_CLASS = "focused",
            SELECTED_CLASS = "selected",
            SELECT_OPEN_CLASS = "select-open",
            DISABLED_CLASS = "disabled",
            HOVERED_CLASS = "hovered",
            _useDefaultBehavior = false,
            _isOpen = false,
            _isEnabled = true,
            _isFocused = false,
            _selectedValue = "";

        /**
         * @constructor
         */

        function init() {
            // TODO: don't use userAgent matching to detect defaulting to device specific behavior
            _useDefaultBehavior = navigator.userAgent.match(/iPad|iPhone|Android|IEMobile|BlackBerry/i) ? true : false;

            if( _useDefaultBehavior ) {
                cfg.selectbox.addClass("use-default");
            }

            var selectId = "",
                selectedClass = cfg.selectbox.attr("class");
                
            if(typeof cfg.selectbox.attr("id") !== "undefined") {
                selectId = 'id="select-'+cfg.selectbox.attr("id")+'"';
            }

            cfg.selectbox.wrap('<div class="customSelect '+selectedClass+'" '+selectId+' />');

            $customSelect = cfg.selectbox.parents(".customSelect");
            $options = cfg.selectbox.find("option");

            var selectListHTML = ['<div class="selectList"><div class="selectListOuterWrap"><div class="selectListInnerWrap"><div class="selectListTop"></div><dl>'];
            selectListHTML.push(_renderOptions());
            selectListHTML.push('</dl><div class="selectListBottom"></div></div></div></div>');

            $customSelect.append('<div class="selectValueWrap"><div class="selectedValue">'+_selectedValue+'</div> <span class="caret"><img src="images/Icoontjes/selectarrowdown.jpg" class="arrowselectbox"></span></div>' + selectListHTML.join(""));

            $dl = $customSelect.find("dl");
            $selectedValue = $customSelect.find(".selectedValue");
            $selectValueWrap = $customSelect.find(".selectValueWrap");
            $selectList = $customSelect.find(".selectList");

            $customSelect.width(cfg.width);
            $dl.width(cfg.width - 2);

            _bindEvents();

            sb_manager.add(self);
        }

        /**
         * @private
         */

        function _bindEvents() {
            $selectValueWrap.click(function() {
                if(_isOpen) {
                    cfg.selectbox.focus();
                    self.close();
                } else if(_isEnabled) {
                    if( _useDefaultBehavior ) {
                        cfg.selectbox.focus();
                    } else {
                        self.open();
                        //NIEUW:
                        $(".itm-0").remove();
                        
                        //if ( $(".itm-0").parents.parents("#main-nav").length == 1 ) {
                        //   // YES, the child element is inside the parent
                        //} else {
                        //   // NO, it is not inside
                        //}
                        
                        
                    }
                }
            });

            // delegated events
            $dl.click(function(e) {
                var $target = $(e.target);

                if($target.is("dd") || $target.parents("dd")) {
                    if(e.target.tagName.toLowerCase() != "dd") {
                        $target = $target.parents("dd");
                    }

                    if(!$target.hasClass(DISABLED_CLASS) && $target.get(0)) {
                        self.jumpToIndex($target.get(0).className.split(" ")[0].split("-")[1]);
                        self.close();

                        if( ! _useDefaultBehavior ) {
                            cfg.selectbox.focus();
                        }
                    }
                }
            });

            cfg.selectbox.focus(function(e) {
                _isFocused = true;
                $customSelect.addClass(FOCUSED_CLASS);
            }).blur(function(e){
                _isFocused = false;
                $customSelect.removeClass(FOCUSED_CLASS);
            });

            if( _useDefaultBehavior ) {
                cfg.selectbox.change(function(e) {
                    _updateValue( $(this).find("option:selected").html() );
                });
            }

            cfg.selectbox.keyup(function(e){
                self.close();
                $options.each(function(i, itm){        
                    if(itm.selected) {
                        self.jumpToIndex(i);
                        return false;
                    }
                });
            });

            _bindHover();
        }

        /**
         * @private
         */

        function _bindHover() {
            var $dds = $(".customSelect dd");
            $dds.off("mouseover");
            $dds.off("mouseout");

            $dds.on("mouseover", function(e) {
                var $target = $(e.target);
                if(e.target.tagName.toLowerCase() != "dd") {
                    $target = $target.parents("dd");
                }
                $target.addClass(HOVERED_CLASS);
            });

            $dds.on("mouseout", function(e) {
                var $target = $(e.target);
                if(e.target.tagName.toLowerCase() != "dd") {
                    $target = $target.parents("dd");
                }
                $target.removeClass(HOVERED_CLASS);
            });
        }

        /**
         * @param {String} val
         * @private
         */

        function _updateValue(val) {
            if($selectedValue.html() != val) {
                $selectedValue.html(_truncate(val));
                cfg.changeCallback(cfg.selectbox.val());
            }
        }

        /**
         * @returns {String} HTML generated after processing options
         * @private
         */

        function _renderOptions() {
            var optionHTML = [];

            $options.each(function(i, itm) {
                var $this = $(this),
                    optgroup = $this.parents('optgroup'),
                    addlOptClasses = "",
                    iconMarkup = "";

                // render optgroups if present in original select
                if (optgroup.length > 0 && $this.prev().length === 0){
                    optionHTML.push('<dt>'+optgroup.attr('label')+'</dt>');
                }

                // if option has a classname add that to custom select as well
                if(itm.className !== "") {
                    $(itm.className.split(" ")).each(function() {
                        iconMarkup += '<span class="' + this + '"></span>';
                    });
                }

                // add selected class to whatever option is currently active
                if(itm.selected && !itm.disabled) {
                    _selectedValue = iconMarkup + _truncate($(itm).html());
                    addlOptClasses = " " + SELECTED_CLASS;
                }

                // Check for disabled options
                if( itm.disabled ) {
                    addlOptClasses += " " + DISABLED_CLASS;
                }

                optionHTML.push('<dd class="itm-'+i+' ' + addlOptClasses + '">' + iconMarkup + itm.innerHTML + '</dd>');
            });

            if($selectedValue && $selectedValue.get(0) !== null) {
                $selectedValue.html(_selectedValue);
            }

            return optionHTML.join("");
        }

        /**
         * @private
         */

        function _setupScrollbar() {
            $dl.css("height","auto");
            if(cfg.height && $dl.height() > cfg.height) {
                $dl.css("height", cfg.height);
                if(cfg.customScrollbar) {
                    self.scrollpane = $dl.jScrollPane($.extend({
                        contentWidth: 200
                    }, cfg.scrollOptions));
                } else {
                    $dl.addClass("defaultScrollbar");
                }
            } else {
                $dl.css({overflow: "hidden"});
            }
        }

        /**
         * @param {String} str
         * @returns truncated display string
         * @private
         */

        function _truncate(str) {
            var arr = str.split("</span>");
            var valToTrunc = arr[arr.length - 1];
            arr[arr.length - 1] = "";
            var spans = arr.join("</SPAN>");

            return spans + cfg.truncate(valToTrunc);
        }

        /**
         * @public
         */

        this.sync = function() {
            $options = cfg.selectbox.find("option");
            $dl.html(_renderOptions());
            _bindHover();
            _setupScrollbar();
        };

        /**
         * @public
         */

        this.disable = function() {
            _isEnabled = false;
            $customSelect.addClass(DISABLED_CLASS);
            cfg.selectbox.attr("disabled", "disabled");
        };

        /**
         * @public
         */

        this.enable = function() {
            _isEnabled = true;
            $customSelect.removeClass(DISABLED_CLASS);
            cfg.selectbox.removeAttr("disabled");
        };

        /**
         * @public
         */

        this.close = function() {
            $customSelect.removeClass(SELECT_OPEN_CLASS);
            $customSelect.css({"z-index": cfg.zIndex});
            _isOpen = false;
        };

        /**
         * @public
         */

        this.open = function() {
            _setupScrollbar();
            if(cfg.manager) {
                cfg.manager.close();
            }

            $customSelect.addClass(SELECT_OPEN_CLASS);

            if(self.scrollpane) {
                self.scrollpane.data('jsp').scrollToY($customSelect.find(".selected").position().top);
            }

            $customSelect.css({"z-index": cfg.zIndex + 1});
            _isOpen = true;
        };

        /**
         * @param {Number} index
         * @public
         */

        this.jumpToIndex = function(index) {
            cfg.selectbox.get(0).selectedIndex = index;
            $customSelect.find(".selected").removeClass(SELECTED_CLASS);
            $customSelect.find(".itm-" + index).addClass(SELECTED_CLASS);
            _updateValue($customSelect.find(".itm-" + index).html());
        };

        /**
         * @param {String} value
         * @returns {Number} index of the value
         * @public
         */

        this.jumpToValue = function(value) {
            var index = -1;

            $options.each(function(i) {
                if (this.innerHTML==value){
                    index = i;
                    return false;
                }
            });

            if (index!=-1){
                self.jumpToIndex(index);
            }

            return index;
        };

        init();
    };
})(jQuery);




Toevoeging op 07/02/2018 10:49:25:

Dit issue kan gesloten worden...

Gisterennacht een hoop gezocht en nu blijkt dat bij deze versie (SelectBox.js v1.1) van Rob LaPlaca het niet openen van selectboxen op iOS een known problem is.
(zie: https://github.com/roblaplaca/jQuery-Custom-Selectbox/issues/12 )

Rob LaPlaca heeft hier zelf het issue geclassificeerd als major bug en er is sinds 2014 geen nieuwere versie uitgekomen. Opvallend is dat bij versie 1.0 de selectboxen wel werken op de iPad (dit kun je testen door de volgende pagina te openen op de iPad: http://www.roblaplaca.com/docs/custom-selectbox/ .

Dus ik heb gezocht naar versie 1.0 en een beetje een mix document gemaakt van 1.0 en 1.1 en nnu werken de selectboxen zowel op de desktop als op de iPad.

Mocht iemand met hetzelfde probleem zitten, dit is de code van mijn mix-bestandje:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438

/**
 * @classDescription    Custom selectbox with the option to use jScrollPane
 *                        for a custom scrollbar. Hides the original selectbox off
 *                        screen so that it will still get picked up as a form element.
 *
 * @version                1.0.0 - let op: aangepast met enkele elementen van v1.1.0
 *
 * @author                Rob LaPlaca - [email protected] - let op: aangepast met enkele elementen van v1.1.0
 * @date                04/05/2010
 * @lastUpdate            07/02/2018
 * @dependency            jScrollPane.js            optional
 *                         jquery.mousewheel.js    optional
 *
 * @param {DOMElement}    options.selectbox            the selectbox that is being customized, REQUIRED (default undefined)
 * @param {Boolean}        options.customScrollbar        whether or not to use jScrollPane to restyle system scrollbar (default false)
 * @param {Number}        options.zIndex                The default z-index of the selectbox. (default 100)
 * @param {Function}    options.changeCallback        Function that gets executed on change of the selectbox (default empty function)
 * @param {Function}    options.manager                Optional reference to a class that manages all instances of the selectbox
 * @param {Object}        options.scrollOptions        jScrollPane options, refer to jscrollpane documentation for possible options
 *                                                     http://www.kelvinluck.com/assets/jquery/jScrollPane/scripts/jScrollPane.js
 */
(function($){

/*    
    // v1.0:
    var undefined;

    $.SelectBoxManager = function(options){
        var sbs = [],
            self = this;
            
        $(document).click(function(e) {
            if($(e.target).parents(".customSelect").get(0) == null) {
                self.close();
            }
        });
        
        this.add = function(sb) {
            sbs.push(sb);    
        };
        
        this.close = function() {
            $(sbs).each(function() {
                this.close();                    
            });
        };
    };  
*/

 /*
    // v1.verder:    
    window.SelectBoxManager = function(options){
        var sbs = [],
            self = this;

        $(document).click(function(e) {
            if($(e.target).parents(".customSelect").size() === 0) {
                self.close();
            }
        });

        this.add = function(sb) {
            sbs.push(sb);
        };

        this.close = function() {
            $(sbs).each(function() {
                this.close();
            });
        };
    };

 */
 
// /*
    // mix:
    window.SelectBoxManager = function(options){
        var sbs = [],
            self = this;
            
        $(document).click(function(e) {
            if($(e.target).parents(".customSelect").get(0) == null) {
                self.close();
            }
        });
        
        this.add = function(sb) {
            sbs.push(sb);    
        };
        
        this.close = function() {
            $(sbs).each(function() {
                this.close();                    
            });
        };
    };      
    
// */
    
/*    // v1.0:
    $.SelectBox = function(options){
        var self = this,
        cfg = $.extend(true, {
            customScrollbar: false,
            zIndex: 100,
            changeCallback: function(val) { },
            truncate: function(str) {return str;},
            scrollOptions: {}
        }, options);
        
        var $customSelect, $selectedValue, $selectValueWrap, $selectList, $dl, $options,
            _isOpen = false,
            _isEnabled = true,
            _isFocused = false,
            _selectedValue = "";    
*/    
    
 /*
    // v1.verder:
    var sb_manager = new SelectBoxManager();

    window.SelectBox = function(options){
        var self = this,
        cfg = $.extend(true, {
            manager: sb_manager,
            customScrollbar: true,
            zIndex: 100,
            changeCallback: function(val) { },
            truncate: function(str) {return str;},
            scrollOptions: {}
        }, options);

        var $customSelect, $selectedValue, $selectValueWrap, $selectList, $dl, $options,
            FOCUSED_CLASS = "focused",
            SELECTED_CLASS = "selected",
            SELECT_OPEN_CLASS = "select-open",
            DISABLED_CLASS = "disabled",
            HOVERED_CLASS = "hovered",
            _useDefaultBehavior = false,
            _isOpen = false,
            _isEnabled = true,
            _isFocused = false,
            _selectedValue = "";  
 */    

// /*
    // mix:
    var sb_manager = new SelectBoxManager();

    window.SelectBox = function(options){    
        var self = this,
        cfg = $.extend(true, {
            customScrollbar: false,
            zIndex: 100,
            changeCallback: function(val) { },
            truncate: function(str) {return str;},
            scrollOptions: {}
        }, options);
        
        var $customSelect, $selectedValue, $selectValueWrap, $selectList, $dl, $options,
            _isOpen = false,
            _isEnabled = true,
            _isFocused = false,
            _selectedValue = "";        
    
// */    
        
        // versie 1.0:
        function init(){
            var selectId = "";
            if(cfg.selectbox.attr("id") != "") {
                selectId = 'id="select-'+cfg.selectbox.attr("id")+'"';
            }
            cfg.selectbox.wrap('<div class="customSelect" '+selectId+' />');
            
            $customSelect = cfg.selectbox.parents(".customSelect");
            $options = cfg.selectbox.find("option");
            
            var selectListHTML = ['<div class="selectList"><div class="selectListOuterWrap"><div class="selectListInnerWrap"><div class="selectListTop"></div><dl>'];
            selectListHTML.push(_renderOptions());
            selectListHTML.push('</dl><div class="selectListBottom"></div></div></div></div>');
            
            $customSelect.append('<div class="selectValueWrap"><div class="selectedValue">'+_selectedValue+'</div></div>' + selectListHTML.join(""));
            
            $dl = $customSelect.find("dl");
            $selectedValue = $customSelect.find(".selectedValue");
            $selectValueWrap = $customSelect.find(".selectValueWrap");
            $selectList = $customSelect.find(".selectList");
            
            $customSelect.width(cfg.width);
            $dl.width(cfg.width);

            _bindEvents();

        }
        
        // versie 1.0:
        /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
         * start:private
         * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
        function _bindEvents() {
            $selectValueWrap.click(function() {
                if(_isOpen) {
                    cfg.selectbox.focus();
                    self.close();
                } else if(_isEnabled) {
                    self.open();
                }
            });
            
            // delegated events
            $dl.click(function(e) {
                var $target = $(e.target);
                if($target.is("dd") || $target.parents("dd")) {
                    if(e.target.tagName.toLowerCase() != "dd") {
                        $target = $target.parents("dd");    
                    }  
                    if($target.get(0)) {
                    self.jumpToIndex($target.get(0).className.split(" ")[0].split("-")[1]);
                
                    self.close();
                    cfg.selectbox.focus();
                    }
                }                
            });
            
            cfg.selectbox.focus(function(e){
                _isFocused = true;
                $customSelect.addClass("focused");
            }).blur(function(e){
                _isFocused = false;
                $customSelect.removeClass("focused");
            });

            cfg.selectbox.keyup(function(e){
                self.close();
                $options.each(function(i, itm){        
                    if(itm.selected) {
                        self.jumpToIndex(i);
                        return false;    
                    }
                });
            });
            
            _bindHover();
        }
        
/*        
        // versie 1.0:
        function _bindHover() {
            var $dds = $(".customSelect dd");
                $dds.die("mouseover");
            $dds.die("mouseout");
            
            $dds.live("mouseover", function(e) {
                var $target = $(e.target);
                if(e.target.tagName.toLowerCase() != "dd") {
                    $target = $target.parents("dd");
                }                                  
                $target.addClass("hovered");                                                        
            });

            $dds.live("mouseout", function(e) {
                var $target = $(e.target);
                if(e.target.tagName.toLowerCase() != "dd") {
                    $target = $target.parents("dd");    
                }
                $target.removeClass("hovered");
            });
        }
*/

        // versie 1.1:
        function _bindHover() {
            var $dds = $(".customSelect dd");
            $dds.off("mouseover");
            $dds.off("mouseout");

            $dds.on("mouseover", function(e) {
                var $target = $(e.target);
                if(e.target.tagName.toLowerCase() != "dd") {
                    $target = $target.parents("dd");
                }
                $target.addClass(HOVERED_CLASS);
            });

            $dds.on("mouseout", function(e) {
                var $target = $(e.target);
                if(e.target.tagName.toLowerCase() != "dd") {
                    $target = $target.parents("dd");
                }
                $target.removeClass(HOVERED_CLASS);
            });
        }    
        
        // versie 1.0:
        function _updateValue(val) {
            if($selectedValue.html() != val) {
                $selectedValue.html(_truncate(val));
                cfg.changeCallback(cfg.selectbox.val());
            }
        }
        
        // versie 1.0:
        function _renderOptions() {
            var optionHTML = [];
            
            $options.each(function(i, itm) {
                var $this = $(this);
                var optgroup = $this.parents('optgroup');
                if (optgroup.length > 0 && $this.prev().length === 0){
                    optionHTML.push('<dt>'+optgroup.attr('label')+'</dt>');
                }

                var iconMarkup = "";
                if(itm.className != "") {
                    $(itm.className.split(" ")).each(function() {
                        iconMarkup += '<span class="' + this + '"></span>';
                    });
                }

                if(itm.selected) {
                    _selectedValue = iconMarkup + _truncate($(itm).html());
                    optionHTML.push('<dd class="itm-'+i+' selected">' + iconMarkup + itm.innerHTML + '</dd>');
                } else {
                    optionHTML.push('<dd class="itm-'+i+'">' + iconMarkup + itm.innerHTML + '</dd>');    
                }

            });
            
            if($selectedValue && $selectedValue.get(0) != null) {
                $selectedValue.html(_selectedValue);
            }
            
            return optionHTML.join("");    
        }
        
        // versie 1.0:
        function _setupScrollbar() {
            $dl.css("height","auto");
            if(cfg.height && $dl.height() > cfg.height) {
                $dl.css("height", cfg.height);
                if(cfg.customScrollbar) {
                    self.scrollpane = $dl.jScrollPane($.extend({tabIndex: -1, scrollbarMargin: 0}, cfg.scrollOptions));                    
                } else {
                    $dl.addClass("defaultScrollbar");    
                }
            } else {
                $dl.css({overflow: "hidden"});    
            }    
        }
        
        // versie 1.0:
        function _truncate(str) {
            var arr = str.split("</span>");
            var valToTrunc = arr[arr.length - 1];
            arr[arr.length - 1] = "";
            var spans = arr.join("</SPAN>");

            return spans + cfg.truncate(valToTrunc);
        }
        // end:private
        
        // versie 1.0:
        /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
         * start:public
         * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
            this.sync = function() {
                $options = cfg.selectbox.find("option");
                $dl.html(_renderOptions());
                $dl.jScrollPaneRemove();
                _bindHover();
                _setupScrollbar();
            };
            
            this.disable = function() {
                _isEnabled = false;
                $customSelect.addClass("disabled");
                cfg.selectbox.attr("disabled", "disabled");
            };
            
            this.enable = function() {
                _isEnabled = true;
                $customSelect.removeClass("disabled");
                cfg.selectbox.removeAttr("disabled");                
            };
            
            this.close = function() {
                $customSelect.removeClass("select-open");
                $customSelect.css({"z-index": cfg.zIndex});
                _isOpen = false;
            };
            
            this.open = function() {
                _setupScrollbar();
                if(cfg.manager) {
                    cfg.manager.close();    
                }
                
                $customSelect.addClass("select-open");
                if(self.scrollpane) {
                    self.scrollpane[0].scrollTo($customSelect.find(".selected").position().top);
                }
                
                $customSelect.css({"z-index": cfg.zIndex + 1});
                _isOpen = true;    
            };
            
            this.jumpToIndex = function(index) {
                cfg.selectbox.get(0).selectedIndex = index;
                $customSelect.find(".selected").removeClass("selected");
                $customSelect.find(".itm-" + index).addClass("selected");                                                                              
                _updateValue($customSelect.find(".itm-" + index).html());
            };
            
            this.jumpToValue = function(value) {
                var index = -1;
                
                $options.each(function(i){                              
                    if (this.innerHTML==value){
                        index = i;
                        return false;
                    }
                });

                if (index!=-1){
                    self.jumpToIndex(index);
                }
                
                return index;
            };
        // end:public
        
        init();
    };
    
})(jQuery);
Gewijzigd op 07/02/2018 10:50:15 door Jo Immanuel
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.