(function ($) { $.fn.ddslick = function (method) { if (methods[method]) { return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof method === 'object' || !method) { return methods.init.apply(this, arguments); } else { $.error('Method ' + method + ' does not exists.'); } }; var methods = {}, //Set defauls for the control defaults = { data: [], keepJSONItemsOnTop: false, width: 260, height: null, background: "#eee", selectText: "", defaultSelectedIndex: null, truncateDescription: true, imagePosition: "left", showSelectedHTML: true, clickOffToClose: true, onSelected: function () {}}, ddSelectHtml = '
', ddOptionsHtml = '', //CSS for ddSlick ddslickCSS = ''; //CSS styles are only added once. if ($('#css-ddslick').length <= 0) {$(ddslickCSS).appendTo('head');} //Public methods methods.init = function (options) { //Preserve the original defaults by passing an empty object as the target var options = $.extend({}, defaults, options); //Apply on all selected elements return this.each(function () { var obj = $(this), data = obj.html //If the plugin has not been initialized yet if (!data) { var ddSelect = [], ddJson = options.data; //Get data from HTML select options obj.find('option').each(function () { var $this = $(this), thisData = $this.data(); ddSelect.push({ text: $.trim($this.text()), value: $this.val(), selected: $this.is(':selected'), description: thisData.description, imageSrc: thisData.imagesrc //keep it lowercase for HTML5 data-attributes }); }); //Update Plugin data merging both HTML select data and JSON data for the dropdown if (options.keepJSONItemsOnTop) $.merge(options.data, ddSelect); else options.data = $.merge(ddSelect, options.data); //Replace HTML select with empty placeholder, keep the original var original = obj, placeholder = $('
'); obj.replaceWith(placeholder); obj = placeholder; //Add classes and append ddSelectHtml & ddOptionsHtml to the container obj.addClass('dd-container').append(ddSelectHtml).append(ddOptionsHtml); //Get newly created ddOptions and ddSelect to manipulate var ddSelect = obj.find('.dd-select'), ddOptions = obj.find('.dd-options'); //Set widths ddOptions.css({ width: options.width }); ddSelect.css({ width: options.width, background: options.background }); obj.css({ width: options.width }); //Set height if (options.height != null) ddOptions.css({ height: options.height, overflow: 'auto' }); //Add ddOptions to the container. Replace with template engine later. // var len = options.data.length; $.each(options.data, function (index, item) { if (item.selected) options.defaultSelectedIndex = index; var inlineStyle = (index == len - 1) ? 'border-bottom: none !important;' : ''; ddOptions.append('
  • ' + '' + (item.value ? ' ' : '') + (item.imageSrc ? ' ' : '') + (item.text ? ' ' : '') + (item.description ? ' ' + item.description + '' : '') + '' + '
  • '); }); ddOptions.append('
    '); //Save plugin data. var pluginData = { settings: options, original: original, selectedIndex: -1, selectedItem: null, selectedData: null } obj.data('ddslick', pluginData); //Check if needs to show the select text, otherwise show selected or default selection if (options.selectText.length > 0 && options.defaultSelectedIndex == null) {obj.find('.dd-selected').html(options.selectText);} else { var index = (options.defaultSelectedIndex != null && options.defaultSelectedIndex >= 0 && options.defaultSelectedIndex < options.data.length) ? options.defaultSelectedIndex : 0; selectIndex(obj, index); } //EVENTS //Displaying options obj.find('.dd-select').on('click.ddslick', function () {open(obj);}); //Selecting an option obj.find('.dd-option').on('click.ddslick', function () { selectIndex(obj, $(this).closest('li').index()); }); //Click anywhere to close if (options.clickOffToClose) { ddOptions.addClass('dd-click-off-close'); obj.on('click.ddslick', function (e) {e.stopPropagation();}); $('body').on('click', function () {$('.dd-click-off-close').slideUp(50).siblings('.dd-select').find('.dd-pointer').removeClass('dd-pointer-up');}); } } }); }; //Public method to select an option by its index methods.select = function (options) { return this.each(function () { if (options.index) selectIndex($(this), options.index); }); } //Public method to open drop down methods.open = function () { return this.each(function () { var $this = $(this), pluginData = $this.data('ddslick'); //Check if plugin is initialized if (pluginData) open($this); }); }; //Public method to close drop down methods.close = function () { return this.each(function () { var $this = $(this), pluginData = $this.data('ddslick'); //Check if plugin is initialized if (pluginData) close($this); }); }; //Public method to destroy. Unbind all events and restore the original Html select/options methods.destroy = function () { return this.each(function () { var $this = $(this), pluginData = $this.data('ddslick'); //Check if already destroyed if (pluginData) { var originalElement = pluginData.original; $this.removeData('ddslick').unbind('.ddslick').replaceWith(originalElement); } }); } //Private: Select index function selectIndex(obj, index) { //Get plugin data var pluginData = obj.data('ddslick'); //Get required elements var ddSelected = obj.find('.dd-selected'), ddSelectedValue = ddSelected.siblings('.dd-selected-value'), ddOptions = obj.find('.dd-options'), ddPointer = ddSelected.siblings('.dd-pointer'), selectedOption = obj.find('.dd-option').eq(index), selectedLiItem = selectedOption.closest('li'), settings = pluginData.settings, selectedData = pluginData.settings.data[index]; //Highlight selected option obj.find('.dd-option').removeClass('dd-option-selected'); selectedOption.addClass('dd-option-selected'); //Update or Set plugin data with new selection pluginData.selectedIndex = index; pluginData.selectedItem = selectedLiItem; pluginData.selectedData = selectedData; //If set to display to full html, add html if (settings.showSelectedHTML) { ddSelected.html( (selectedData.imageSrc ? '' : '') + (selectedData.text ? '' : '') + (selectedData.description ? '' + selectedData.description + '' : '') ); } //Else only display text as selection else ddSelected.html(selectedData.text); //Updating selected option value ddSelectedValue.val(selectedData.value); //BONUS! Update the original element attribute with the new selection pluginData.original.val(selectedData.value); obj.data('ddslick', pluginData); //Close options on selection close(obj); //Adjust appearence for selected option adjustSelectedHeight(obj); //Callback function on selection if (typeof settings.onSelected == 'function') { settings.onSelected.call(this, pluginData); } } //Private: Close the drop down options function open(obj) { var $this = obj.find('.dd-select'), ddOptions = $this.siblings('.dd-options'), ddPointer = $this.find('.dd-pointer'), wasOpen = ddOptions.is(':visible'); //Close all open options (multiple plugins) on the page $('.dd-click-off-close').not(ddOptions).fadeOut(50); $('.dd-pointer').removeClass('dd-pointer-up'); if (wasOpen) { ddOptions.fadeOut('fast'); ddPointer.removeClass('dd-pointer-up'); } else { ddOptions.fadeIn('fast'); ddPointer.addClass('dd-pointer-up'); } //Fix text height (i.e. display title in center), if there is no description adjustOptionsHeight(obj); } //Private: Close the drop down options function close(obj) { //Close drop down and adjust pointer direction obj.find('.dd-options').slideUp(50); obj.find('.dd-pointer').removeClass('dd-pointer-up').removeClass('dd-pointer-up'); } //Private: Adjust appearence for selected option (move title to middle), when no desripction function adjustSelectedHeight(obj) { //Get height of dd-selected var lSHeight = obj.find('.dd-select').css('height'); //Check if there is selected description var descriptionSelected = obj.find('.dd-selected-description'); var imgSelected = obj.find('.dd-selected-image'); if (descriptionSelected.length <= 0 && imgSelected.length > 0) { obj.find('.dd-selected-text').css('lineHeight', lSHeight); } } //Private: Adjust appearence for drop down options (move title to middle), when no desripction function adjustOptionsHeight(obj) { obj.find('.dd-option').each(function () { var $this = $(this); var lOHeight = $this.css('height'); var descriptionOption = $this.find('.dd-option-description'); var imgOption = obj.find('.dd-option-image'); if (descriptionOption.length <= 0 && imgOption.length > 0) { $this.find('.dd-option-text').css('lineHeight', lOHeight); } }); } })(jQuery); (function ($) { $.fn.ddslick_footer = function (method) { if (methods_footer[method]) { return methods_footer[method].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof method === 'object' || !method) { return methods_footer.init.apply(this, arguments); } else { $.error('Method ' + method + ' does not exists.'); } }; var methods_footer = {}, //Set defauls for the control defaults = { data: [], keepJSONItemsOnTop: false, width: 260, height: null, background: "#eee", selectText: "", defaultSelectedIndex: null, truncateDescription: true, imagePosition: "left", showSelectedHTML: true, clickOffToClose: true, onSelected: function () {}}, ddSelectHtml = '
    ', ddOptionsHtml = '', //CSS for ddSlick ddslickCSS = ''; //CSS styles are only added once. if ($('#css-ddslick').length <= 0) {$(ddslickCSS).appendTo('head');} //Public methods methods_footer.init = function (options) { //Preserve the original defaults by passing an empty object as the target var options = $.extend({}, defaults, options); //Apply on all selected elements return this.each(function () { var obj = $(this), data = obj.html //If the plugin has not been initialized yet if (!data) { var ddSelect = [], ddJson = options.data; //Get data from HTML select options obj.find('option').each(function () { var $this = $(this), thisData = $this.data(); ddSelect.push({ text: $.trim($this.text()), value: $this.val(), selected: $this.is(':selected'), description: thisData.description, imageSrc: thisData.imagesrc //keep it lowercase for HTML5 data-attributes }); }); //Update Plugin data merging both HTML select data and JSON data for the dropdown if (options.keepJSONItemsOnTop) $.merge(options.data, ddSelect); else options.data = $.merge(ddSelect, options.data); //Replace HTML select with empty placeholder, keep the original var original = obj, placeholder = $('
    '); obj.replaceWith(placeholder); obj = placeholder; //Add classes and append ddSelectHtml & ddOptionsHtml to the container obj.addClass('dd-container').append(ddSelectHtml).append(ddOptionsHtml); //Get newly created ddOptions and ddSelect to manipulate var ddSelect = obj.find('.dd-select'), ddOptions = obj.find('.dd-options-white'); //Set widths ddOptions.css({ width: options.width }); ddSelect.css({ width: options.width, background: options.background }); obj.css({ width: options.width }); //Set height if (options.height != null) ddOptions.css({ height: options.height, overflow: 'auto' }); //Add ddOptions to the container. Replace with template engine later. // var len = options.data.length; $.each(options.data, function (index, item) { var inlineStyle = (index == len - 1) ? 'border-bottom: none !important;' : ''; if (item.selected) options.defaultSelectedIndex = index; ddOptions.append('
  • ' + '' + (item.value ? ' ' : '') + (item.imageSrc ? ' ' : '') + (item.text ? ' ' : '') + (item.description ? ' ' + item.description + '' : '') + '' + '
  • '); }); ddOptions.append('
    '); //Save plugin data. var pluginData = { settings: options, original: original, selectedIndex: -1, selectedItem: null, selectedData: null } obj.data('ddslick', pluginData); //Check if needs to show the select text, otherwise show selected or default selection if (options.selectText.length > 0 && options.defaultSelectedIndex == null) {obj.find('.dd-selected-white').html(options.selectText);} else { var index = (options.defaultSelectedIndex != null && options.defaultSelectedIndex >= 0 && options.defaultSelectedIndex < options.data.length) ? options.defaultSelectedIndex : 0; selectIndex_ftr(obj, index); } //EVENTS //Displaying options obj.find('.dd-select').on('click.ddslick', function () {open_ftr(obj);}); //Selecting an option obj.find('.dd-option').on('click.ddslick', function () { selectIndex_ftr(obj, $(this).closest('li').index()); }); //Click anywhere to close if (options.clickOffToClose) { ddOptions.addClass('dd-click-off-close'); obj.on('click.ddslick', function (e) {e.stopPropagation();}); $('body').on('click', function () {$('.dd-click-off-close').slideUp(50).siblings('.dd-select').find('.dd-pointer-white').removeClass('dd-pointer-up-white');}); } } }); }; //Public method to select an option by its index methods_footer.select = function (options) { return this.each(function () { if (options.index) selectIndex_ftr($(this), options.index); }); } //Public method to open drop down methods_footer.open = function () { return this.each(function () { var $this = $(this), pluginData = $this.data('ddslick'); //Check if plugin is initialized if (pluginData) open_ftr($this); }); }; //Public method to close drop down methods_footer.close = function () { return this.each(function () { var $this = $(this), pluginData = $this.data('ddslick'); //Check if plugin is initialized if (pluginData) close_ftr($this); }); }; //Public method to destroy. Unbind all events and restore the original Html select/options methods_footer.destroy = function () { return this.each(function () { var $this = $(this), pluginData = $this.data('ddslick'); //Check if already destroyed if (pluginData) { var originalElement = pluginData.original; $this.removeData('ddslick').unbind('.ddslick').replaceWith(originalElement); } }); } //Private: Select index function selectIndex_ftr(obj, index) { //Get plugin data var pluginData = obj.data('ddslick'); //Get required elements var ddSelected = obj.find('.dd-selected-white'), ddSelectedValue = ddSelected.siblings('.dd-selected-value'), ddOptions = obj.find('.dd-options-white'), ddPointer = ddSelected.siblings('.dd-pointer-white'), selectedOption = obj.find('.dd-option').eq(index), selectedLiItem = selectedOption.closest('li'), settings = pluginData.settings, selectedData = pluginData.settings.data[index]; //Highlight selected option obj.find('.dd-option').removeClass('dd-option-selected'); selectedOption.addClass('dd-option-selected'); //Update or Set plugin data with new selection pluginData.selectedIndex = index; pluginData.selectedItem = selectedLiItem; pluginData.selectedData = selectedData; //If set to display to full html, add html if (settings.showSelectedHTML) { ddSelected.html( (selectedData.imageSrc ? '' : '') + (selectedData.text ? '' : '') + (selectedData.description ? '' + selectedData.description + '' : '') ); } //Else only display text as selection else ddSelected.html(selectedData.text); //Updating selected option value ddSelectedValue.val(selectedData.value); //BONUS! Update the original element attribute with the new selection pluginData.original.val(selectedData.value); obj.data('ddslick', pluginData); //Close options on selection close_ftr(obj); //Adjust appearence for selected option adjustSelectedHeight_ftr(obj); //Callback function on selection if (typeof settings.onSelected == 'function') { settings.onSelected.call(this, pluginData); } } //Private: Close the drop down options function open_ftr(obj) { var $this = obj.find('.dd-select'), ddOptions = $this.siblings('.dd-options-white'), ddPointer = $this.find('.dd-pointer-white'), wasOpen = ddOptions.is(':visible'); //Close all open options (multiple plugins) on the page $('.dd-click-off-close').not(ddOptions).fadeOut(50); $('.dd-pointer-white').removeClass('dd-pointer-up-white'); if (wasOpen) { ddOptions.fadeOut('fast'); ddPointer.removeClass('dd-pointer-up-white'); } else { ddOptions.fadeIn('fast'); ddPointer.addClass('dd-pointer-up-white'); } //Fix text height (i.e. display title in center), if there is no description adjustOptionsHeight_ftr(obj); } //Private: Close the drop down options function close_ftr(obj) { //Close drop down and adjust pointer direction obj.find('.dd-options-white').slideUp(50); obj.find('.dd-pointer-white').removeClass('dd-pointer-up-white').removeClass('dd-pointer-up-white'); } //Private: Adjust appearence for selected option (move title to middle), when no desripction function adjustSelectedHeight_ftr(obj) { //Get height of dd-selected var lSHeight = obj.find('.dd-select').css('height'); //Check if there is selected description var descriptionSelected = obj.find('.dd-selected-description'); var imgSelected = obj.find('.dd-selected-image'); if (descriptionSelected.length <= 0 && imgSelected.length > 0) { obj.find('.dd-selected-text').css('lineHeight', lSHeight); } } //Private: Adjust appearence for drop down options (move title to middle), when no desripction function adjustOptionsHeight_ftr(obj) { obj.find('.dd-option').each(function () { var $this = $(this); var lOHeight = $this.css('height'); var descriptionOption = $this.find('.dd-option-description'); var imgOption = obj.find('.dd-option-image-white'); if (descriptionOption.length <= 0 && imgOption.length > 0) { $this.find('.dd-option-text').css('lineHeight', lOHeight); } }); } })(jQuery);