OwlCyberSecurity - MANAGER
Edit File: visualselect.js
/*! * Visual Select - A jQuery plugin for replacing HTML select element with a visual selection tool. * * @version 1.3.0 * @requires jQuery 1.9+ * @author Averta [averta.net] * @package Axiom Framework * @copyright Copyright © 2017 Averta, all rights reserved */ ;(function ( $, window, document, undefined ) { "use strict"; // Create the defaults once var pluginName = 'avertaVisualSelect', defaults = { item : 'axi-select-item', // visual select item [class name] selected : 'axi-selected', // selected item [class name] caption : 'axi-select-caption', // caption under visual item [class name] container : 'axi-visual-select', // select items container [class name] insertCaption : false, // whether insert captions to visual items insertSymbol : true, // whether insert symbol to visual items insertTitleAttr : true, // adds title attribute to visual item autoHideElement : true, // hide HTML select element after init imgTest : /\.jpg|\.png|\.gif|.jpeg|\.svg/ // test for image src }, attributesMap = { 'type' : 'symbolType', 'title-attr' : 'insertTitleAttr', 'auto-hide' : 'autoHideElement', 'caption' : 'insertCaption' }; // The actual plugin constructor function Plugin( element, options ) { this.element = element; this.$element = $(element); this.options = $.extend( {}, defaults, options) ; // read attributes for ( var key in attributesMap ) { var value = attributesMap[ key ], dataAttr = this.$element.data( key ); if ( dataAttr === undefined ) { continue; } this.options[ value ] = dataAttr; } this._defaults = defaults; this._name = pluginName; this.init(); } $.extend(Plugin.prototype, { init : function(){ var self = this, st = self.options; self.multiple = self.$element.attr('multiple') === 'multiple'; if ( st.autoHideElement ) { self.$element.css('display', 'none'); } // generate select items self.$selectCont = $('<div class="' + st.container + '"></div>').insertAfter(self.$element); self.generate(); self.$element.on( 'change', this.update.bind( this ) ); }, /** * on visual select item clicked * @private * @param {jQuery Event} event */ _onItemClick : function (event) { var $visualItem = $(event.currentTarget), $selectOption = $visualItem.data('selectOption'), st = this.options; if ( this.multiple ) { if ( $visualItem.hasClass(st.selected) ) { $visualItem.removeClass(st.selected); $selectOption.removeAttr('selected'); } else { $visualItem.addClass(st.selected); $selectOption.attr('selected', 'selected'); var val = this.$element.val(); if ( val === null ) { val = []; } val.push( $selectOption.attr( 'value' ) ); this.$element.val( val ); } } else if ( !$visualItem.hasClass(st.selected) ) { $visualItem.addClass(st.selected); $selectOption.attr('selected', 'selected'); this.$element.val( $selectOption.attr( 'value' ) ); if ( this.$selectedItem ) { this.$selectedItem.removeClass(st.selected); this.$selectedItem.data('selectOption').removeAttr('selected'); } this.$selectedItem = $visualItem; } this._internalTrigger = true; this.$element.trigger('change'); }, /** * Generates video element sources by parsing the data-video-src attribute on element */ _generateVideoSource: function( videoSrc ) { var source = ''; videoSrc.split( ',' ).forEach( function( src ) { src = src.split( ' ' ); source += '<source src="' + src[0] + '" type="video/' + src[1] + '">'; } ); return source; }, /** * On video ready to play */ _videoInit: function( event ) { $(event.currentTarget).on( 'mouseenter', function() { this.play(); }).on( 'mouseleave', function() { this.pause(); this.currentTime = 0; }); }, /** * updates selected items in visual form */ update: function() { if ( this._internalTrigger ) { this._internalTrigger = false; return; } var self = this, st = this.options, $items = self.$selectCont.find( '.' + st.item ), val = self.$element.val(); self.$element.find( 'option' ).each( function( index, option ) { var $option = $(option), $visualItem = $items.eq( index ); if ( val.indexOf( $option.val() ) !== -1 ) { self.$selectedItem = $visualItem.addClass( st.selected ); } else { $visualItem.removeClass( st.selected ); } } ); }, /** * Add new item in visual form */ addItem: function ( value, text ) { var self = this, $lastOption = self.$element.find('option').last(), $newOption = $lastOption.clone(); if ( !$newOption.length ) { $newOption = $('<option></option>'); self.$element.val( value ); } $newOption.attr( 'value', value ); $newOption.text( text ); $newOption.appendTo( self.$element ); self.$element.val( value ); this.generate(true); this.update(); }, /** * create visual items from HTML select element * @param {boolean} reset Remove old visual items [it's useful for updating visual select] * @public */ generate : function (reset) { var self = this, st = self.options; if ( reset ) { this.$selectCont.find('.' + st.item).remove(); } self.$element.find('option').each(function(){ 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'); if ( cssClass ) { $visualItem.addClass(cssClass); } // insert visual symbol to select item if ( st.insertSymbol ) { if ( videoSrc ) { $visualItem.attr('item-type', 'video'); var $videoElement = $('<video></video>').attr( 'muted', '' ).attr( 'loop', '' ) .append( self._generateVideoSource( videoSrc ) ) .appendTo( $visualItem ); $videoElement[0].addEventListener( 'loadedmetadata', self._videoInit ); } else if ( st.imgTest.test( symbol ) || $selectOption.data( 'type' ) === 'image' ) { $('<img/>').attr('src', symbol) .attr('alt', caption) .appendTo($visualItem); } else { $('<span></span>').addClass(symbol) .appendTo($visualItem); } } // insert caption if ( st.insertCaption ) { $('<span class="' + st.caption + '">' + caption + '</span>').appendTo($visualItem); } $visualItem.on('click', self._onItemClick.bind( self )) .data('selectOption', $selectOption) .appendTo(self.$selectCont); if ( st.insertTitleAttr ) { $visualItem.attr('title', caption); } if ( $selectOption.attr('selected') === 'selected' ) { self.$selectedItem = $visualItem.addClass(st.selected); } }); } }); $.fn[pluginName] = function ( options ) { var args = arguments; // Is the first parameter an object (options), or was omitted, // instantiate a new instance of the plugin. if (options === undefined || typeof options === 'object') { return this.each(function () { // Only allow the plugin to be instantiated once, // so we check that the element has no plugin instantiation yet if (!$.data(this, 'plugin_' + pluginName)) { // if it has no instance, create a new one, // pass options to our plugin constructor, // and store the plugin instance // in the elements jQuery data object. $.data(this, 'plugin_' + pluginName, new Plugin( this, options )); } }); // If the first parameter is a string and it doesn't start // with an underscore or "contains" the `init`-function, // treat this as a call to a public method. } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') { // Cache the method call // to make it possible // to return a value var returns; this.each(function () { var instance = $.data(this, 'plugin_' + pluginName); // Tests that there's already a plugin-instance // and checks that the requested public method exists if (instance instanceof Plugin && typeof instance[options] === 'function') { // Call the method of our plugin instance, // and pass it the supplied arguments. returns = instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) ); } // Allow instances to be destroyed via the 'destroy' method if (options === 'destroy') { $.data(this, 'plugin_' + pluginName, null); } }); // If the earlier cached method // gives a value back return the value, // otherwise return this to preserve chainability. return returns !== undefined ? returns : this; } } }(jQuery, window, document));