PageSourceSearch

https://frais-mobilite.com/libs/jquery_mylibs/jquery.ddslick.js?fm_version=v461

js frais-mobilite.com collected 2026-10-02 00:29:38 UTC 28,375 bytes, 558 lines download raw bytes

1//Title: Custom DropDown plugin by PC
2//Documentation: http://designwithpc.com/Plugins/ddslick
3//Author: PC 
4//Website: http://designwithpc.com
5//Twitter: http://twitter.com/chaudharyp
6
7(function ($) {
8
9    $.fn.ddslick = function (method) {
10        if (methods[method]) {
11            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
12        } else if (typeof method === 'object' || !method) {
13            return methods.init.apply(this, arguments);
14        } else {
15            $.error('Method ' + method + ' does not exists.');
16        }
17    };
18
19    var methods = {},
20
21    //Set defauls for the control
22    defaults = {
23        data: [],
24        keepJSONItemsOnTop: false,
25        width: 260,
26        unfoldWidth:null,
27        textAlign:null,
28        height: null,
29        fixedHeight:true,
30        background: "#eee",
31        selectText: "",
32        defaultSelectedIndex: null,
33        truncateTitle: false,
34        truncateDescription: true,
35        imagePosition: "left",
36        roundImage:false,
37        showSelectedHTML: true,
38        clickOffToClose: true,
39        fireOnSelectedOnInit : true,
40        fireOnSelectedOnClick : true,
41        fireOnSelectedOnSelectMethod : true,
42        keyboardSearch:false,
43        keyboardTimeout:1000,
44        keyboardAutoSelect:false,
45        onSelected: function () { }
46    },
47
48    ddSelectHtml = '<div class="dd-select"><input class="dd-selected-value" type="hidden" /><a class="dd-selected"></a><span class="dd-pointer dd-pointer-down"></span></div>',
49    ddOptionsHtml = '<ul class="dd-options"></ul>',
50
51    //CSS for ddSlick
52    ddslickCSS = '<style id="css-ddslick" type="text/css">' +
53                '.dd-select{ border-radius:2px; border:solid 1px #ccc; position:relative; cursor:pointer;}' +
54                '.dd-desc { color:#aaa; display:block; overflow: hidden; font-weight:normal; line-height: 1.4em; }' +
55                '.dd-selected{ overflow:hidden; display:block; padding:10px; padding-right:20px; font-weight:bold;}' +
56                '.dd-pointer{ width:0; height:0; position:absolute; right:10px; top:50%; margin-top:-3px;}' +
57                '.dd-pointer-down{ border:solid 5px transparent; border-top:solid 5px #000; }' +
58                '.dd-pointer-up{border:solid 5px transparent !important; border-bottom:solid 5px #000 !important; margin-top:-8px;}' +
59                '.dd-options{ border:solid 1px #ccc; border-top:none; list-style:none; box-shadow:0px 1px 5px #ddd; display:none; position:absolute; z-index:2000; margin:0; padding:0;background:#fff; overflow:auto;}' +
60                '.dd-option{ padding:10px; display:block; border-bottom:solid 1px #ddd; overflow:hidden; text-decoration:none; color:#333; cursor:pointer;-webkit-transition: all 0.25s ease-in-out; -moz-transition: all 0.25s ease-in-out;-o-transition: all 0.25s ease-in-out;-ms-transition: all 0.25s ease-in-out; }' +
61                '.dd-option-text { cursor:pointer; }' +
62                '.dd-options > li:last-child > .dd-option{ border-bottom:none;}' +
63                '.dd-option:hover{ background:#f3f3f3; color:#000;}' +
64                '.dd-selected-title-truncated { text-overflow: ellipsis; white-space:nowrap; display:inherit; overflow:hidden; }' +
65                '.dd-selected-description-truncated { text-overflow: ellipsis; white-space:nowrap; }' +
66                '.dd-option-selected { background:#f6f6f6; }' +
67                '.dd-option-image, .dd-selected-image { vertical-align:middle; float:left; margin-right:5px; max-width:64px; max-height:40px;}' +
68                '.dd-image-round { border-radius: 40px; -webkit-border-radius: 40px; -moz-border-radius: 40px; }' +
69                '.dd-image-right { float:right; margin-right:15px; margin-left:5px;}' +
70                '.dd-container { position:relative; }​ ' +
71                '.dd-selected-text { font-weight:bold }​ ' +
72                '</style>';
73
74    //CSS styles are only added once.
75    if ($('#css-ddslick').length <= 0) {
76        $(ddslickCSS).appendTo('head');
77    }
78
79    //Public methods 
80    methods.init = function (options) {
81        //Preserve the original defaults by passing an empty object as the target
82        var options = $.extend({}, defaults, options);
83
84        //Apply on all selected elements
85        return this.each(function () {
86            var obj = $(this),
87                data = obj.data('ddslick');
88            //If the plugin has not been initialized yet
89            if (!data) {
90
91                var ddSelect = [], ddJson = options.data;
92
93                //Get data from HTML select options
94                obj.find('option').each(function () {
95                    var $this = $(this), thisData = $this.data();
96                    ddSelect.push({
97                        text: $.trim($this.text()),
98                        value: $this.val(),
99                        selected: $this.is(':selected'),
100                        description: thisData.description,
101                        imageSrc: thisData.imagesrc, //keep it lowercase for HTML5 data-attributes
102                        customValue: thisData.customvalue //keep it lowercase for HTML5 data-attributes
103                    });
104                });
105
106                //Update Plugin data merging both HTML select data and JSON data for the dropdown
107                if (options.keepJSONItemsOnTop)
108                    $.merge(options.data, ddSelect);
109                else options.data = $.merge(ddSelect, options.data);
110
111                //Replace HTML select with empty placeholder, keep the original
112                // (tabindex is added to allow div focusing for keyboard searching)
113                var original = obj, placeholder = $('<div id="' + obj.attr('id') + '" '+ (options.keyboardSearch ? 'tabindex=0' : '') +'></div>');
114                obj.replaceWith(placeholder);
115                obj = placeholder;
116
117                //Add classes and append ddSelectHtml & ddOptionsHtml to the container
118                obj.addClass('dd-container').append(ddSelectHtml).append(ddOptionsHtml);
119
120                //Get newly created ddOptions and ddSelect to manipulate
121                var ddSelect = obj.find('.dd-select'),
122                    ddOptions = obj.find('.dd-options');
123
124                //Set widths
125                ddOptions.css({ width: options.unfoldWidth === null ? options.width : options.unfoldWidth });
126                ddSelect.css({ width: options.width, background: options.background });
127                obj.css({ width: options.width });
128                
129                // Set text align into dropdown
130                if (options.textAlign != null) {
131                    ddOptions.css({ "text-align": options.textAlign });
132                    ddSelect.css({ "text-align": options.textAlign });
133                }
134
135                //Set height
136                if (options.height != null) {
137                    if (options.fixedHeight == true)
138                        ddOptions.css({ height: options.height, overflow: 'auto' });
139                    else
140                        ddOptions.css({ 'max-height': options.height, overflow: 'auto' });
141                }
142
143                //Add ddOptions to the container. Replace with template engine later.
144                $.each(options.data, function (index, item) {
145                    if (item.selected) options.defaultSelectedIndex = index;
146                    ddOptions.append('<li>' +
147                        '<a class="dd-option">' +
148                            (item.value ? ' <input class="dd-option-value" type="hidden" value="' + item.value + '" />' : '') +
149                            (item.customValue ? ' <input class="dd-option-customvalue" type="hidden" value="' + item.customValue + '" />' : '') +
150                            (item.imageSrc ? ' <img class="dd-option-image' + (options.imagePosition == "right" ? ' dd-image-right' : '') + (options.roundImage ? ' dd-image-round' : '') + '" src="' + item.imageSrc + '" />' : '') +
151                            (item.text ? ' <label class="dd-option-text">' + item.text + '</label>' : '') +
152                            (item.description ? ' <small class="dd-option-description dd-desc">' + item.description + '</small>' : '') +
153                        '</a>' +
154                    '</li>');
155                });
156
157                //Save plugin data.
158                var pluginData = {
159                    settings: options,
160                    original: original,
161                    selectedIndex: -1,
162                    selectedItem: null,
163                    selectedData: null
164                }
165                obj.data('ddslick', pluginData);
166
167                //Check if needs to show the select text, otherwise show selected or default selection
168                if (options.selectText.length > 0 && options.defaultSelectedIndex == null) {
169                    obj.find('.dd-selected').html(options.selectText);
170                }
171                else {
172                    var index = (options.defaultSelectedIndex != null && options.defaultSelectedIndex >= 0 && options.defaultSelectedIndex < options.data.length)
173                                ? options.defaultSelectedIndex
174                                : 0;
175                    selectIndex(obj, index, options.fireOnSelectedOnInit, "init");
176                }
177
178                //EVENTS
179                //Displaying options
180                obj.find('.dd-select').on('click.ddslick', function () {
181                    open(obj);
182                });
183
184                //Selecting an option
185                obj.find('.dd-option').on('click.ddslick', function () {
186                    selectIndex(obj, $(this).closest('li').index(), options.fireOnSelectedOnClick, "click");
187                });
188
189                //Click anywhere to close
190                if (options.clickOffToClose) {
191                    ddOptions.addClass('dd-click-off-close');
192                    obj.on('click.ddslick', function (e) { e.stopPropagation(); });
193                    $('body').on('click', function () {
194                        $('.dd-click-off-close').slideUp(50).siblings('.dd-select').find('.dd-pointer').removeClass('dd-pointer-up');
195                    });
196                }
197                
198                var searchedString = "";
199                var lastDateKeyDown = new Date().getTime();
200                var currentDisplayIndex = undefined;
201                
202                // if keyboard searching is allowed => bind the keydown event to catch it
203                if (pluginData.settings.keyboardSearch) {
204                    
205                    obj.keydown(function(event) {
206                        
207                        // on ne gère pas la touche "Tab"
208                        if (event.keyCode !== 9) {
209                            var $this = $(this),
210                                pluginData = $this.data('ddslick'),
211                                wasOpen = $this.find('.dd-options').is(':visible');
212
213                            // open dropdown only if keyboardAutoSelect is false
214                            if (!wasOpen && !pluginData.settings.keyboardAutoSelect)
215                                open($this);
216
217                            // set value to currentdisplayindex regarding dropdown mode
218                            if (currentDisplayIndex === undefined || pluginData.settings.keyboardAutoSelect)
219                                currentDisplayIndex = pluginData.selectedIndex;
220
221                            // enter OR escape touch is pressed (13 : enter, 27 : esc)
222                            if (event.keyCode === 13 || event.keyCode === 27) {
223
224                                // on enter select curent display value !
225                                if (event.keyCode === 13 && currentDisplayIndex !== undefined) {
226                                    selectIndex($this, currentDisplayIndex, true, "keyboard", false);
227                                }
228                                else {
229                                    // on escape, highlight the old selected value
230                                    var selectedOption = $this.find('.dd-option').eq(pluginData.selectedIndex);
231
232                                    //Highlight selected option
233                                    $this.find('.dd-option').removeClass('dd-option-selected');
234                                    selectedOption.addClass('dd-option-selected');
235                                }
236
237                                // reset currentdisplayindex and close the dropdown
238                                currentDisplayIndex = pluginData.selectedIndex;
239                                close($this);
240                            }
241                            // if arrow pressed (38 : up, 40 : down)
242                            else if (event.keyCode === 38 || event.keyCode === 40) { 
243
244                                // arrow up : check if we're again in table limits
245                                if (event.keyCode === 38 && currentDisplayIndex >= 1) {
246
247                                    currentDisplayIndex = parseInt(currentDisplayIndex) - 1;
248
249                                    if (pluginData.settings.keyboardAutoSelect)
250                                        selectIndex($this, currentDisplayIndex, true, "keyboard", true);
251                                }
252
253                                // arrow down : check if we're again in table limits
254                                if (event.keyCode === 40 && currentDisplayIndex < pluginData.settings.data.length - 1) {
255
256                                    currentDisplayIndex = parseInt(currentDisplayIndex) + 1;
257
258                                    if (pluginData.settings.keyboardAutoSelect)
259                                        selectIndex($this, currentDisplayIndex, true, "keyboard", true);
260                                }
261
262                                // if we don't have autoselect, highlight currentdisplayindex and autoscroll to display it
263                                if (!pluginData.settings.keyboardAutoSelect) {
264                                    var ddOptions = $this.find('.dd-options'),
265                                        selectedOption = $this.find('.dd-option').eq(currentDisplayIndex),
266                                        selectedLiItem = selectedOption.closest('li');
267
268                                    //Highlight selected option
269                                    $this.find('.dd-option').removeClass('dd-option-selected');
270                                    selectedOption.addClass('dd-option-selected');
271
272                                    // auto scroll to the selected item (place it on top of open ddOptions)
273                                    if (selectedLiItem !== undefined && selectedLiItem.offset() !== undefined && ddOptions !== undefined) {
274                                        ddOptions.scrollTop(selectedLiItem.offset().top + ddOptions.scrollTop() - ddOptions.offset().top);
275                                    }
276                                }
277                            }
278                            // else it's another key so we search it !
279                            else {
280                                currentDisplayIndex = pluginData.selectedIndex;
281                                //Check if plugin is initialized
282                                if (pluginData && pluginData.settings && pluginData.settings.data) {
283                                    if (pluginData.settings.data.length > 0) {
284
285                                        // get the current time
286                                        var newDateKeyDown = new Date().getTime();
287
288                                        // check if difference between last input time and current time allow  
289                                        // to continue the same searched string or starts a new one
290                                        if (newDateKeyDown - lastDateKeyDown > pluginData.settings.keyboardTimeout) {
291                                            searchedString = "";
292                                        }
293
294                                        // adding pressed key to searched string
295                                        searchedString += String.fromCharCode(event.keyCode);
296
297                                        // memorize current time as last input time
298                                        lastDateKeyDown = newDateKeyDown;
299
300                                        // in the entire list, check text and description to find a match that starts with the searched string
301                                        // PS : compare in lowercase to be case insensitive
302                                        for (var i = 0, max = pluginData.settings.data.length; i < max; i++) {
303
304                                            if ((pluginData.settings.data[i].text !== undefined && pluginData.settings.data[i].text.toLowerCase().indexOf(searchedString.toLowerCase()) === 0)
305                                                || (pluginData.settings.data[i].description !== undefined && pluginData.settings.data[i].description.toLowerCase().indexOf(searchedString.toLowerCase()) === 0)) {
306
307                                                // if autoselect, then select the item !
308                                                if (pluginData.settings.keyboardAutoSelect)
309                                                    selectIndex($this, i, true, "keyboard", true);
310                                                else {
311                                                    // else just highlight it and autoscroll to it
312                                                    currentDisplayIndex = i;
313
314                                                    var ddOptions = $this.find('.dd-options'),
315                                                        selectedOption = $this.find('.dd-option').eq(i),
316                                                        selectedLiItem = selectedOption.closest('li');
317
318                                                    //Highlight selected option
319                                                    $this.find('.dd-option').removeClass('dd-option-selected');
320                                                    selectedOption.addClass('dd-option-selected');
321
322                                                    // auto scroll to the selected item (place it on top of open ddOptions)
323                                                    if (selectedLiItem !== undefined && selectedLiItem.offset() !== undefined && ddOptions !== undefined) {
324                                                        ddOptions.scrollTop(selectedLiItem.offset().top + ddOptions.scrollTop() - ddOptions.offset().top);
325                                                    }
326                                                }
327                                                // then we break the for to increase performance
328                                                break;
329                                            }
330                                        }  
331                                    }
332                                }
333                            }
334
335                            // stop event propagation 
336                            event.preventDefault();
337                            event.stopPropagation();
338                        }
339                    });
340                }
341            }
342        });
343    };
344
345    //Public method to select an option by its index
346    methods.select = function (options) {
347        return this.each(function () {
348            if (options.index)
349            {
350                var $this = $(this),
351                pluginData = $this.data('ddslick');
352                
353                if (pluginData) {
354                    var fireEvent = pluginData.settings.fireOnSelectedOnSelectMethod;
355                    if (options.fireEvent !== undefined)
356                    {
357                        fireEvent = options.fireEvent;
358                    }
359                    selectIndex($(this), options.index, fireEvent, "select");
360                }
361            }
362        });
363    }
364
365    //Public method to open drop down
366    methods.open = function () {
367        return this.each(function () {
368            var $this = $(this),
369                pluginData = $this.data('ddslick');
370
371            //Check if plugin is initialized
372            if (pluginData) {
373                open($this);
374            }
375        });
376    };
377
378    //Public method to close drop down
379    methods.close = function () {
380        return this.each(function () {
381            var $this = $(this),
382                pluginData = $this.data('ddslick');
383
384            //Check if plugin is initialized
385            if (pluginData) {
386                close($this);
387            }
388        });
389    };
390
391    //Public method to destroy. Unbind all events and restore the original Html select/options
392    methods.destroy = function () {
393        return this.each(function () {
394            var $this = $(this),
395                pluginData = $this.data('ddslick');
396
397            //Check if already destroyed
398            if (pluginData) {
399                var originalElement = pluginData.original;
400                $this.removeData('ddslick').unbind('.ddslick').replaceWith(originalElement);
401            }
402        });
403    }
404    
405    //Public method to set dropdown value if it exists in data
406    methods.setValue = function (options) {
407        return this.each(function () {
408            
409            var $this = $(this),
410                pluginData = $this.data('ddslick');
411
412            if (pluginData) {
413                for (var i = 0, max = pluginData.settings.data.length - 1 ; i <= max; i++) {
414                    if (pluginData.settings.data[i].value == options.value) {
415                        var fireEvent = pluginData.settings.fireOnSelectedOnSelectMethod;
416                        if (options.fireEvent !== undefined)
417                        {
418                            fireEvent = options.fireEvent;
419                        }
420                        selectIndex($(this), i, fireEvent, "select");
421                        break;
422                    }
423                }
424            }
425        });
426    }
427
428    //Private: Select index
429    function selectIndex(obj, index, needToFireOnSelectedEvent, eventDescription, closeOptions) {
430
431        //Get plugin data
432        var pluginData = obj.data('ddslick');
433
434        //Get required elements
435        var ddSelected = obj.find('.dd-selected'),
436            ddSelectedValue = ddSelected.siblings('.dd-selected-value'),
437            ddOptions = obj.find('.dd-options'),
438            ddPointer = ddSelected.siblings('.dd-pointer'),
439            selectedOption = obj.find('.dd-option').eq(index),
440            selectedLiItem = selectedOption.closest('li'),
441            settings = pluginData.settings,
442            selectedData = pluginData.settings.data[index];
443
444        //Highlight selected option
445        obj.find('.dd-option').removeClass('dd-option-selected');
446        selectedOption.addClass('dd-option-selected');
447        
448        //Update or Set plugin data with new selection
449        pluginData.selectedIndex = index;
450        pluginData.selectedItem = selectedLiItem;
451        pluginData.selectedData = selectedData;        
452
453        // auto scroll to the selected item (place it on top of open ddOptions)
454        if (selectedLiItem !== undefined && selectedLiItem.offset() !== undefined && ddOptions !== undefined) {
455            ddOptions.scrollTop(selectedLiItem.offset().top + ddOptions.scrollTop() - ddOptions.offset().top);
456        }
457        
458        //If set to display to full html, add html
459        if (settings.showSelectedHTML) {
460            ddSelected.html(
461                    (selectedData.imageSrc ? '<img class="dd-selected-image' + (settings.imagePosition == "right" ? ' dd-image-right' : '') + (settings.roundImage ? ' dd-image-round' : '') + '" src="' + selectedData.imageSrc + '" />' : '') +
462                    (selectedData.text ? '<label class="dd-selected-text' + (settings.truncateTitle ? ' dd-selected-title-truncated' : '') + '">' + selectedData.text + '</label>' : '') +
463                    (selectedData.description ? '<small class="dd-selected-description dd-desc' + (settings.truncateDescription ? ' dd-selected-description-truncated' : '') + '" >' + selectedData.description + '</small>' : '')
464                );
465
466        }
467        //Else only display text as selection
468        else ddSelected.html(selectedData.text);
469
470        //Updating selected option value
471        ddSelectedValue.val(selectedData.value);
472
473        //BONUS! Update the original element attribute with the new selection
474        pluginData.original.val(selectedData.value);
475        obj.data('ddslick', pluginData);
476
477        //Close options on selection
478        if (closeOptions === undefined || closeOptions) {
479            close(obj);
480        }
481
482        //Adjust appearence for selected option
483        adjustSelectedHeight(obj);
484
485        if (needToFireOnSelectedEvent)
486        {
487            //Callback function on selection
488            if (typeof settings.onSelected == 'function') {
489                settings.onSelected.call(this, pluginData, eventDescription);
490            }
491        }
492    }
493
494    //Private: Open the drop down options
495    function open(obj) {
496        var $this = obj.find('.dd-select'),
497            ddOptions = $this.siblings('.dd-options'),
498            ddPointer = $this.find('.dd-pointer'),
499            wasOpen = ddOptions.is(':visible'),
500            selectedItem = obj.find('.dd-option-selected').closest('li');
501
502        //Close all open options (multiple plugins) on the page
503        $('.dd-click-off-close').not(ddOptions).slideUp(50);
504        $('.dd-pointer').removeClass('dd-pointer-up');
505
506        if (wasOpen) {
507            ddOptions.slideUp('fast');
508            ddPointer.removeClass('dd-pointer-up');
509        }
510        else {
511            ddOptions.slideDown('fast');
512            ddPointer.addClass('dd-pointer-up');
513        }
514        
515        // auto scroll to the selected item (place it on top of open ddOptions)
516        if (selectedItem !== undefined && selectedItem.offset() !== undefined && ddOptions !== undefined) {
517            ddOptions.scrollTop(selectedItem.offset().top + ddOptions.scrollTop() - ddOptions.offset().top);
518        }
519        
520        //Fix text height (i.e. display title in center), if there is no description
521        adjustOptionsHeight(obj);
522    }
523
524    //Private: Close the drop down options
525    function close(obj) {
526        //Close drop down and adjust pointer direction
527        obj.find('.dd-options').slideUp(50);
528        obj.find('.dd-pointer').removeClass('dd-pointer-up').removeClass('dd-pointer-up');
529    }
530
531    //Private: Adjust appearence for selected option (move title to middle), when no desripction
532    function adjustSelectedHeight(obj) {
533        
534        //Get height of dd-selected
535        var lSHeight = obj.find('.dd-select').css('height');
536
537        //Check if there is selected description
538        var descriptionSelected = obj.find('.dd-selected-description');
539        var imgSelected = obj.find('.dd-selected-image');
540        if (descriptionSelected.length <= 0 && imgSelected.length > 0) {
541            obj.find('.dd-selected-text').css('lineHeight', lSHeight);
542        }
543    }
544
545    //Private: Adjust appearence for drop down options (move title to middle), when no desripction
546    function adjustOptionsHeight(obj) {
547        obj.find('.dd-option').each(function () {
548            var $this = $(this);
549            var lOHeight = $this.css('height');
550            var descriptionOption = $this.find('.dd-option-description');
551            var imgOption = obj.find('.dd-option-image');
552            if (descriptionOption.length <= 0 && imgOption.length > 0) {
553                $this.find('.dd-option-text').css('lineHeight', lOHeight);
554            }
555        });
556    }
557
558})(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.