| 1 |
(function(){ |
| 2 |
; |
| 3 |
(function($, window2, document2, undefined$1) { |
| 4 |
"use strict"; |
| 5 |
var pluginName = "jltmaVisualSelect", defaults = { |
| 6 |
item: "jltma-select-item", |
| 7 |
// visual select item [class name] |
| 8 |
selected: "jltma-selected", |
| 9 |
// selected item [class name] |
| 10 |
caption: "jltma-select-caption", |
| 11 |
// caption under visual item [class name] |
| 12 |
container: "jltma-visual-select", |
| 13 |
// select items container [class name] |
| 14 |
insertCaption: false, |
| 15 |
// whether insert captions to visual items |
| 16 |
insertSymbol: true, |
| 17 |
// whether insert symbol to visual items |
| 18 |
insertTitleAttr: true, |
| 19 |
// adds title attribute to visual item |
| 20 |
autoHideElement: true, |
| 21 |
// hide HTML select element after init |
| 22 |
imgTest: /\.jpg|\.png|\.gif|.jpeg|\.svg/ |
| 23 |
// test for image src |
| 24 |
}, attributesMap = { |
| 25 |
"type": "symbolType", |
| 26 |
"title-attr": "insertTitleAttr", |
| 27 |
"auto-hide": "autoHideElement", |
| 28 |
"caption": "insertCaption" |
| 29 |
}; |
| 30 |
function Plugin(element, options) { |
| 31 |
this.element = element; |
| 32 |
this.$element = $(element); |
| 33 |
this.options = $.extend({}, defaults, options); |
| 34 |
for (var key in attributesMap) { |
| 35 |
var value = attributesMap[key], dataAttr = this.$element.data(key); |
| 36 |
if (dataAttr === undefined$1) { |
| 37 |
continue; |
| 38 |
} |
| 39 |
this.options[value] = dataAttr; |
| 40 |
} |
| 41 |
this._defaults = defaults; |
| 42 |
this._name = pluginName; |
| 43 |
this.init(); |
| 44 |
} |
| 45 |
$.extend(Plugin.prototype, { |
| 46 |
init: function() { |
| 47 |
var self = this, st = self.options; |
| 48 |
self.multiple = self.$element.attr("multiple") === "multiple"; |
| 49 |
if (st.autoHideElement) { |
| 50 |
self.$element.css("display", "none"); |
| 51 |
} |
| 52 |
self.$selectCont = $('<div class="' + st.container + '"></div>').insertAfter(self.$element); |
| 53 |
self.generate(); |
| 54 |
self.$element.on("change", this.update.bind(this)); |
| 55 |
}, |
| 56 |
/** |
| 57 |
* on visual select item clicked |
| 58 |
* @private |
| 59 |
* @param {jQuery Event} event |
| 60 |
*/ |
| 61 |
_onItemClick: function(event) { |
| 62 |
var $visualItem = $(event.currentTarget), $selectOption = $visualItem.data("selectOption"), st = this.options; |
| 63 |
if (this.multiple) { |
| 64 |
if ($visualItem.hasClass(st.selected)) { |
| 65 |
$visualItem.removeClass(st.selected); |
| 66 |
$selectOption.removeAttr("selected"); |
| 67 |
} else { |
| 68 |
$visualItem.addClass(st.selected); |
| 69 |
$selectOption.attr("selected", "selected"); |
| 70 |
var val = this.$element.val(); |
| 71 |
if (val === null) { |
| 72 |
val = []; |
| 73 |
} |
| 74 |
val.push($selectOption.attr("value")); |
| 75 |
this.$element.val(val); |
| 76 |
} |
| 77 |
} else if (!$visualItem.hasClass(st.selected)) { |
| 78 |
$visualItem.addClass(st.selected); |
| 79 |
$selectOption.attr("selected", "selected"); |
| 80 |
this.$element.val($selectOption.attr("value")); |
| 81 |
if (this.$selectedItem) { |
| 82 |
this.$selectedItem.removeClass(st.selected); |
| 83 |
this.$selectedItem.data("selectOption").removeAttr("selected"); |
| 84 |
} |
| 85 |
this.$selectedItem = $visualItem; |
| 86 |
} |
| 87 |
this._internalTrigger = true; |
| 88 |
this.$element.trigger("change"); |
| 89 |
}, |
| 90 |
/** |
| 91 |
* Generates video element sources by parsing the data-video-src attribute on element |
| 92 |
*/ |
| 93 |
_generateVideoSource: function(videoSrc) { |
| 94 |
var source = ""; |
| 95 |
videoSrc.split(",").forEach(function(src) { |
| 96 |
src = src.split(" "); |
| 97 |
source += '<source src="' + src[0] + '" type="video/' + src[1] + '">'; |
| 98 |
}); |
| 99 |
return source; |
| 100 |
}, |
| 101 |
/** |
| 102 |
* On video ready to play |
| 103 |
*/ |
| 104 |
_videoInit: function(event) { |
| 105 |
$(event.currentTarget).on("mouseenter", function() { |
| 106 |
this.play(); |
| 107 |
}).on("mouseleave", function() { |
| 108 |
this.pause(); |
| 109 |
this.currentTime = 0; |
| 110 |
}); |
| 111 |
}, |
| 112 |
/** |
| 113 |
* updates selected items in visual form |
| 114 |
*/ |
| 115 |
update: function() { |
| 116 |
if (this._internalTrigger) { |
| 117 |
this._internalTrigger = false; |
| 118 |
return; |
| 119 |
} |
| 120 |
var self = this, st = this.options, $items = self.$selectCont.find("." + st.item), val = self.$element.val(); |
| 121 |
self.$element.find("option").each(function(index, option) { |
| 122 |
var $option = $(option), $visualItem = $items.eq(index); |
| 123 |
if (val.indexOf($option.val()) !== -1) { |
| 124 |
self.$selectedItem = $visualItem.addClass(st.selected); |
| 125 |
} else { |
| 126 |
$visualItem.removeClass(st.selected); |
| 127 |
} |
| 128 |
}); |
| 129 |
}, |
| 130 |
/** |
| 131 |
* create visual items from HTML select element |
| 132 |
* @param {boolean} reset Remove old visual items [it's useful for updating visual select] |
| 133 |
* @public |
| 134 |
*/ |
| 135 |
generate: function(reset) { |
| 136 |
var self = this, st = self.options; |
| 137 |
if (reset) { |
| 138 |
this.$selectCont.find("." + st.item).remove(); |
| 139 |
} |
| 140 |
self.$element.find("option").each(function() { |
| 141 |
var $selectOption = $(this), $visualItem = $('<div class="' + st.item + '"></div>'), symbol = $selectOption.data("symbol"), videoSrc = $selectOption.data("video-src"), caption = $selectOption.html(), cssClass = $selectOption.data("class"); |
| 142 |
if (cssClass) { |
| 143 |
$visualItem.addClass(cssClass); |
| 144 |
} |
| 145 |
if (st.insertSymbol) { |
| 146 |
if (videoSrc) { |
| 147 |
$visualItem.attr("item-type", "video"); |
| 148 |
var $videoElement = $("<video></video>").attr("muted", "").attr("loop", "").append(self._generateVideoSource(videoSrc)).appendTo($visualItem); |
| 149 |
$videoElement[0].addEventListener("loadedmetadata", self._videoInit); |
| 150 |
} else if (st.imgTest.test(symbol) || $selectOption.data("type") === "image") { |
| 151 |
$("<img/>").attr("src", symbol).attr("alt", caption).appendTo($visualItem); |
| 152 |
} else { |
| 153 |
$("<span></span>").addClass(symbol).appendTo($visualItem); |
| 154 |
} |
| 155 |
} |
| 156 |
if (st.insertCaption) { |
| 157 |
$('<span class="' + st.caption + '">' + caption + "</span>").appendTo($visualItem); |
| 158 |
} |
| 159 |
$visualItem.click($.proxy(self._onItemClick, self)).data("selectOption", $selectOption).appendTo(self.$selectCont); |
| 160 |
if (st.insertTitleAttr) { |
| 161 |
$visualItem.attr("title", caption); |
| 162 |
} |
| 163 |
if ($selectOption.attr("selected") === "selected") { |
| 164 |
self.$selectedItem = $visualItem.addClass(st.selected); |
| 165 |
} |
| 166 |
}); |
| 167 |
} |
| 168 |
}); |
| 169 |
$.fn[pluginName] = function(options) { |
| 170 |
var args = arguments; |
| 171 |
if (options === undefined$1 || typeof options === "object") { |
| 172 |
return this.each(function() { |
| 173 |
if (!$.data(this, "plugin_" + pluginName)) { |
| 174 |
$.data(this, "plugin_" + pluginName, new Plugin(this, options)); |
| 175 |
} |
| 176 |
}); |
| 177 |
} else if (typeof options === "string" && options[0] !== "_" && options !== "init") { |
| 178 |
var returns; |
| 179 |
this.each(function() { |
| 180 |
var instance = $.data(this, "plugin_" + pluginName); |
| 181 |
if (instance instanceof Plugin && typeof instance[options] === "function") { |
| 182 |
returns = instance[options].apply(instance, Array.prototype.slice.call(args, 1)); |
| 183 |
} |
| 184 |
if (options === "destroy") { |
| 185 |
$.data(this, "plugin_" + pluginName, null); |
| 186 |
} |
| 187 |
}); |
| 188 |
return returns !== undefined$1 ? returns : this; |
| 189 |
} |
| 190 |
}; |
| 191 |
})(jQuery, window, document); |
| 192 |
})(); |
| 193 |
|