/*
 * SOL - Searchable Option List jQuery plugin
 * Version 2.0.2
 * https://pbauerochse.github.io/searchable-option-list/
 *
 * Copyright 2015, Patrick Bauerochse
 *
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/MIT
 *
 */
!function(t,e,i){"use strict";var s=function(t,e){this.$originalElement=t,this.options=e,this.metadata=this.$originalElement.data("sol-options")};s.prototype={SOL_OPTION_FORMAT:{type:"option",value:void 0,selected:!1,disabled:!1,label:void 0,tooltip:void 0,cssClass:""},SOL_OPTIONGROUP_FORMAT:{type:"optiongroup",label:void 0,tooltip:void 0,disabled:!1,children:void 0},DATA_KEY:"sol-element",WINDOW_EVENTS_KEY:"sol-window-events",defaults:{data:void 0,name:void 0,texts:{noItemsAvailable:"No entries found",selectAll:"Select all",selectNone:"Select none",quickDelete:"&times;",searchplaceholder:"Click here to search",loadingData:"Still loading data...",itemsSelected:"{$a} items selected"},events:{onInitialized:void 0,onRendered:void 0,onOpen:void 0,onClose:void 0,onChange:void 0,onScroll:function(){var t=this.$input.offset().top-this.config.scrollTarget.scrollTop()+this.$input.outerHeight(!1),e=this.$selectionContainer.outerHeight(!1),s=t+e,n=this.config.displayContainerAboveInput||i.documentElement.clientHeight-this.config.scrollTarget.scrollTop()<s,o=this.$innerContainer.outerWidth(!1)-parseInt(this.$selectionContainer.css("border-left-width"),10)-parseInt(this.$selectionContainer.css("border-right-width"),10);if(n?(t=this.$input.offset().top-e-this.config.scrollTarget.scrollTop()+parseInt(this.$selectionContainer.css("border-bottom-width"),10),this.$container.removeClass("sol-selection-bottom").addClass("sol-selection-top")):this.$container.removeClass("sol-selection-top").addClass("sol-selection-bottom"),"block"!==this.$innerContainer.css("display"))o*=1.2;else{var l=n?"border-bottom-right-radius":"border-top-right-radius";this.$selectionContainer.css(l,"initial"),this.$actionButtons&&this.$actionButtons.css(l,"initial")}this.$selectionContainer.css("top",Math.floor(t)).css("left",Math.floor(this.$container.offset().left)).css("width",o),this.config.displayContainerAboveInput=n}},selectAllMaxItemsThreshold:30,showSelectAll:function(){return this.config.multiple&&this.config.selectAllMaxItemsThreshold&&this.items&&this.items.length<=this.config.selectAllMaxItemsThreshold},useBracketParameters:!1,multiple:void 0,showSelectionBelowList:!1,allowNullSelection:!1,scrollTarget:void 0,maxHeight:void 0,converter:void 0,asyncBatchSize:300,maxShow:0},init:function(){this.config=t.extend(!0,{},this.defaults,this.options,this.metadata);var i=this._getNameAttribute(),s=this;return i?("function"!=typeof String.prototype.trim&&(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),this.config.multiple=this.config.multiple||this.$originalElement.attr("multiple"),this.config.scrollTarget||(this.config.scrollTarget=t(e)),this._registerWindowEventsIfNeccessary(),this._initializeUiElements(),this._initializeInputEvents(),setTimeout(function(){s._initializeData(),s.$originalElement.data(s.DATA_KEY,s).removeAttr("name").data("sol-name",i)},0),this.$originalElement.hide(),this.$container.css("visibility","initial").show(),this):void this._showErrorLabel("name attribute is required")},_getNameAttribute:function(){return this.config.name||this.$originalElement.data("sol-name")||this.$originalElement.attr("name")},_showErrorLabel:function(e){var i=t('<div style="color: red; font-weight: bold;" />').html(e);this.$container?this.$container.append(i):i.insertAfter(this.$originalElement)},_registerWindowEventsIfNeccessary:function(){e[this.WINDOW_EVENTS_KEY]||(t(i).on("click",function(e){var i,n=t(e.target),o=n.closest(".sol-selection-container"),l=n.closest(".sol-inner-container");l.length?i=l.first().parent(".sol-container"):o.length&&(i=o.first().parent(".sol-container")),t(".sol-active").not(i).each(function(e,i){t(i).data(s.prototype.DATA_KEY).close()})}),e[this.WINDOW_EVENTS_KEY]=!0)},_initializeUiElements:function(){var e=this;this.internalScrollWrapper=function(){t.isFunction(e.config.events.onScroll)&&e.config.events.onScroll.call(e)},this.$input=t('<input type="text"/>').attr("placeholder",this.config.texts.searchplaceholder),this.$noResultsItem=t('<div class="sol-no-results"/>').html(this.config.texts.noItemsAvailable).hide(),this.$loadingData=t('<div class="sol-loading-data"/>').html(this.config.texts.loadingData),this.$xItemsSelected=t('<div class="sol-results-count"/>'),this.$caret=t('<div class="sol-caret-container"><b class="sol-caret"/></div>').on("click",function(t){return e.toggle(),t.preventDefault(),!1});var i=t('<div class="sol-input-container"/>').append(this.$input);this.$innerContainer=t('<div class="sol-inner-container"/>').append(i).append(this.$caret),this.$selection=t('<div class="sol-selection"/>'),this.$selectionContainer=t('<div class="sol-selection-container"/>').append(this.$noResultsItem).append(this.$loadingData).append(this.$selection),this.$container=t('<div class="sol-container"/>').hide().data(this.DATA_KEY,this).append(this.$selectionContainer).append(this.$innerContainer).insertBefore(this.$originalElement),this.$showSelectionContainer=t('<div class="sol-current-selection"/>'),this.config.showSelectionBelowList?this.$showSelectionContainer.insertAfter(this.$innerContainer):this.$showSelectionContainer.insertBefore(this.$innerContainer),this.config.maxHeight&&this.$selection.css("max-height",this.config.maxHeight);var s=this.$originalElement.attr("class"),n=this.$originalElement.attr("style"),o=[],l=[];if(s&&s.length>0){o=s.split(/\s+/);for(var a=0;a<o.length;a++)this.$container.addClass(o[a])}if(n&&n.length>0){l=n.split(/\;/);for(var a=0;a<l.length;a++){var r=l[a].split(/\s*\:\s*/g);2===r.length&&(r[0].toLowerCase().indexOf("height")>=0?this.$innerContainer.css(r[0].trim(),r[1].trim()):this.$container.css(r[0].trim(),r[1].trim()))}}"block"!==this.$originalElement.css("display")&&this.$container.css("width",this._getActualCssPropertyValue(this.$originalElement,"width")),t.isFunction(this.config.events.onRendered)&&this.config.events.onRendered.call(this,this)},_getActualCssPropertyValue:function(t,s){var n=t.get(0),o=t.css("display");return t.css("display","none"),n.currentStyle?n.currentStyle[s]:e.getComputedStyle?i.defaultView.getComputedStyle(n,null).getPropertyValue(s):(t.css("display",o),t.css(s))},_initializeInputEvents:function(){var e=this,i=this.$input.parents("form").first();if(i&&1===i.length&&!i.data(this.WINDOW_EVENTS_KEY)){var s=function(){var s=[];i.find(".sol-option input").each(function(e,i){var n=t(i),o=n.data("sol-item").selected;n.prop("checked")!==o&&(n.prop("checked",o).trigger("sol-change",!0),s.push(n))}),s.length>0&&t.isFunction(e.config.events.onChange)&&e.config.events.onChange.call(e,e,s)};i.on("reset",function(t){s.call(e),setTimeout(function(){s.call(e)},100)}),i.data(this.WINDOW_EVENTS_KEY,!0)}this.$input.focus(function(){e.open()}).on("propertychange input",function(t){var i=!0;"propertychange"==t.type&&(i="value"==t.originalEvent.propertyName.toLowerCase()),i&&e._applySearchTermFilter()}),this.$container.on("keydown",function(i){var s=i.keyCode;if(!e.$noResultsItem.is(":visible")){var n,o,l,a=!1,r=e.$selection.find(".sol-option:visible");if(40===s||38===s){e._setKeyBoardNavigationMode(!0),n=e.$selection.find(".sol-option.keyboard-selection"),l=38===s?-1:1;var c=r.index(n)+l;c<0?c=r.length-1:c>=r.length&&(c=0),n.removeClass("keyboard-selection"),o=t(r[c]).addClass("keyboard-selection"),e.$selection.scrollTop(e.$selection.scrollTop()+o.position().top),a=!0}else!0===e.keyboardNavigationMode&&32===s&&(n=e.$selection.find(".sol-option.keyboard-selection input"),n.prop("checked",!n.prop("checked")).trigger("change"),a=!0);if(a)return i.preventDefault(),!1}}).on("keyup",function(t){var i=t.keyCode;if(27===i)!0===e.keyboardNavigationMode?e._setKeyBoardNavigationMode(!1):""===e.$input.val()?(e.$caret.trigger("click"),e.$input.trigger("blur")):e.$input.val("").trigger("input");else if(16===i||17===i||18===i||20===i)return})},_setKeyBoardNavigationMode:function(t){t?(this.keyboardNavigationMode=!0,this.$selection.addClass("sol-keyboard-navigation")):(this.keyboardNavigationMode=!1,this.$selection.find(".sol-option.keyboard-selection"),this.$selection.removeClass("sol-keyboard-navigation"),this.$selectionContainer.find(".sol-option.keyboard-selection").removeClass("keyboard-selection"),this.$selection.scrollTop(0))},_applySearchTermFilter:function(){if(this.items&&0!==this.items.length){var e=this.$input.val(),i=(e||"").toLowerCase();this.$selectionContainer.find(".sol-filtered-search").removeClass("sol-filtered-search"),this._setNoResultsItemVisible(!1),i.trim().length>0&&this._findTerms(this.items,i),t.isFunction(this.config.events.onScroll)&&this.config.events.onScroll.call(this)}},_findTerms:function(e,i){if(e&&t.isArray(e)&&0!==e.length){var s=this;this._setKeyBoardNavigationMode(!1),t.each(e,function(t,e){if("option"===e.type){var n=e.displayElement;-1===(e.label+" "+e.tooltip).trim().toLowerCase().indexOf(i)&&n.addClass("sol-filtered-search")}else{s._findTerms(e.children,i);0===e.displayElement.find(".sol-option:not(.sol-filtered-search)").length&&e.displayElement.addClass("sol-filtered-search")}}),this._setNoResultsItemVisible(0===this.$selectionContainer.find(".sol-option:not(.sol-filtered-search)").length)}},_initializeData:function(){this.config.data?t.isFunction(this.config.data)?this.items=this._fetchDataFromFunction(this.config.data):t.isArray(this.config.data)?this.items=this._fetchDataFromArray(this.config.data):"string"==typeof this.config.data?this._loadItemsFromUrl(this.config.data):this._showErrorLabel("Unknown data type"):this.items=this._detectDataFromOriginalElement(),this.items&&this._processDataItems(this.items)},_detectDataFromOriginalElement:function(){if("select"===this.$originalElement.prop("tagName").toLowerCase()){var e=this,i=[];return t.each(this.$originalElement.children(),function(s,n){var o,l=t(n),a=l.prop("tagName").toLowerCase();"option"===a?(o=e._processSelectOption(l))&&i.push(o):"optgroup"===a?(o=e._processSelectOptgroup(l))&&i.push(o):e._showErrorLabel("Invalid element found in select: "+a+". Only option and optgroup are allowed")}),this._invokeConverterIfNeccessary(i)}if(this.$originalElement.data("sol-data")){var s=this.$originalElement.data("sol-data");return this._invokeConverterIfNeccessary(s)}this._showErrorLabel('Could not determine data from original element. Must be a select or data must be provided as data-sol-data="" attribute')},_processSelectOption:function(e){return t.extend({},this.SOL_OPTION_FORMAT,{value:e.val(),selected:e.prop("selected"),disabled:e.prop("disabled"),cssClass:e.attr("class"),label:e.html(),tooltip:e.attr("title"),element:e})},_processSelectOptgroup:function(e){var i=this,s=t.extend({},this.SOL_OPTIONGROUP_FORMAT,{label:e.attr("label"),tooltip:e.attr("title"),disabled:e.prop("disabled"),children:[]}),n=e.children("option");return t.each(n,function(e,n){var o=t(n),l=i._processSelectOption(o);s.disabled&&(l.disabled=!0),s.children.push(l)}),s},_fetchDataFromFunction:function(t){return this._invokeConverterIfNeccessary(t(this))},_fetchDataFromArray:function(t){return this._invokeConverterIfNeccessary(t)},_loadItemsFromUrl:function(e){var i=this;t.ajax(e,{success:function(t){i.items=i._invokeConverterIfNeccessary(t),i.items&&i._processDataItems(i.items)},error:function(t,s,n){i._showErrorLabel("Error loading from url "+e+": "+n)},dataType:"json"})},_invokeConverterIfNeccessary:function(e){return t.isFunction(this.config.converter)?this.config.converter.call(this,this,e):e},_processDataItems:function(e){if(!e)return void this._showErrorLabel("Data items not present. Maybe the converter did not return any values");if(0===e.length)return this._setNoResultsItemVisible(!0),void this.$loadingData.remove();var i=this,s=0,n=function(){this.$loadingData.remove(),this._initializeSelectAll(),t.isFunction(this.config.events.onInitialized)&&this.config.events.onInitialized.call(this,this,e)},o=function(){for(var t,l=0;l++<i.config.asyncBatchSize&&s<e.length;)if(t=e[s++],t.type===i.SOL_OPTION_FORMAT.type)i._renderOption(t);else{if(t.type!==i.SOL_OPTIONGROUP_FORMAT.type)return void i._showErrorLabel("Invalid item type found "+t.type);i._renderOptiongroup(t)}s>=e.length?n.call(i):setTimeout(o,0)};o.call(this)},_renderOption:function(e,i){var s,n,o,l=this,a=i||this.$selection,r=t('<div class="sol-label-text"/>').html(0===e.label.trim().length?"&nbsp;":e.label).addClass(e.cssClass),c=this._getNameAttribute();this.config.multiple?(s=t('<input type="checkbox" class="sol-checkbox"/>'),this.config.useBracketParameters&&(c+="[]")):s=t('<input type="radio" class="sol-radio"/>').on("change",function(){l.$selectionContainer.find('input[type="radio"][name="'+c+'"]').not(t(this)).trigger("sol-deselect")}).on("sol-deselect",function(){l._removeSelectionDisplayItem(t(this))}),s.on("change",function(e,i){t(this).trigger("sol-change",i)}).on("sol-change",function(e,i){l._selectionChange(t(this),i)}).data("sol-item",e).prop("checked",e.selected).prop("disabled",e.disabled).attr("name",c).val(e.value),n=t('<label class="sol-label"/>').attr("title",e.tooltip).append(s).append(r),o=t('<div class="sol-option"/>').append(n),e.displayElement=o,a.append(o),e.selected&&this._addSelectionDisplayItem(s)},_renderOptiongroup:function(e){var i=this,s=t('<div class="sol-optiongroup-label"/>').attr("title",e.tooltip).html(e.label),n=t('<div class="sol-optiongroup"/>').append(s);e.disabled&&n.addClass("disabled"),t.isArray(e.children)&&t.each(e.children,function(t,e){i._renderOption(e,n)}),e.displayElement=n,this.$selection.append(n)},_initializeSelectAll:function(){if(!0===this.config.showSelectAll||t.isFunction(this.config.showSelectAll)&&this.config.showSelectAll.call(this)){var e=this,i=t('<a href="#" class="sol-deselect-all"/>').html(this.config.texts.selectNone).on("click",function(t){return e.deselectAll(),t.preventDefault(),!1}),s=t('<a href="#" class="sol-select-all"/>').html(this.config.texts.selectAll).on("click",function(t){return e.selectAll(),t.preventDefault(),!1});this.$actionButtons=t('<div class="sol-action-buttons"/>').append(s).append(i).append('<div class="sol-clearfix"/>'),this.$selectionContainer.prepend(this.$actionButtons)}},_selectionChange:function(e,i){if(this.$originalElement&&"select"===this.$originalElement.prop("tagName").toLowerCase()){var s=this;this.$originalElement.find("option").each(function(i,n){var o=t(n);if(o.val()===e.val())return o.prop("selected",e.prop("checked")),void s.$originalElement.trigger("change")})}e.prop("checked")?this._addSelectionDisplayItem(e):this._removeSelectionDisplayItem(e),this.config.multiple?this.config.scrollTarget.trigger("scroll"):this.close();var n=this.$showSelectionContainer.children(".sol-selected-display-item");if(0!=this.config.maxShow&&n.length>this.config.maxShow){n.hide();var o=this.config.texts.itemsSelected.replace("{$a}",n.length);this.$xItemsSelected.html('<div class="sol-selected-display-item-text">'+o+"<div>"),this.$showSelectionContainer.append(this.$xItemsSelected),this.$xItemsSelected.show()}else n.show(),this.$xItemsSelected.hide();!i&&t.isFunction(this.config.events.onChange)&&this.config.events.onChange.call(this,this,e)},_addSelectionDisplayItem:function(e){var i,s=e.data("sol-item"),n=s.displaySelectionItem;n||(i=t('<span class="sol-selected-display-item-text" />').html(s.label),n=t('<div class="sol-selected-display-item"/>').append(i).attr("title",s.tooltip).appendTo(this.$showSelectionContainer),!this.config.multiple&&!this.config.allowNullSelection||e.prop("disabled")||t('<span class="sol-quick-delete"/>').html(this.config.texts.quickDelete).on("click",function(){e.prop("checked",!1).trigger("change")}).prependTo(n),s.displaySelectionItem=n)},_removeSelectionDisplayItem:function(t){var e=t.data("sol-item"),i=e.displaySelectionItem;i&&(i.remove(),e.displaySelectionItem=void 0)},_setNoResultsItemVisible:function(t){t?(this.$noResultsItem.show(),this.$selection.hide(),this.$actionButtons&&this.$actionButtons.hide()):(this.$noResultsItem.hide(),this.$selection.show(),this.$actionButtons&&this.$actionButtons.show())},isOpen:function(){return this.$container.hasClass("sol-active")},isClosed:function(){return!this.isOpen()},toggle:function(){this.isOpen()?this.close():this.open()},open:function(){this.isClosed()&&(this.$container.addClass("sol-active"),this.config.scrollTarget.bind("scroll",this.internalScrollWrapper).trigger("scroll"),t(e).on("resize",this.internalScrollWrapper),t.isFunction(this.config.events.onOpen)&&this.config.events.onOpen.call(this,this))},close:function(){this.isOpen()&&(this._setKeyBoardNavigationMode(!1),this.$container.removeClass("sol-active"),this.config.scrollTarget.unbind("scroll",this.internalScrollWrapper),t(e).off("resize"),this.$input.val(""),this._applySearchTermFilter(),this.config.displayContainerAboveInput=void 0,t.isFunction(this.config.events.onClose)&&this.config.events.onClose.call(this,this))},selectAll:function(){if(this.config.multiple){var e=this.$selectionContainer.find('input[type="checkbox"]:not([disabled], :checked)').prop("checked",!0).trigger("change",!0);this.close(),t.isFunction(this.config.events.onChange)&&this.config.events.onChange.call(this,this,e)}},deselectAll:function(){if(this.config.multiple){var e=this.$selectionContainer.find('input[type="checkbox"]:not([disabled]):checked').prop("checked",!1).trigger("change",!0);this.close(),t.isFunction(this.config.events.onChange)&&this.config.events.onChange.call(this,this,e)}},getSelection:function(){return this.$selection.find("input:checked")}},s.defaults=s.prototype.defaults,e.SearchableOptionList=s,t.fn.searchableOptionList=function(e){var i=[];return this.each(function(){var n=t(this),o=n.data(s.prototype.DATA_KEY);if(o)i.push(o);else{var l=new s(n,e);i.push(l),setTimeout(function(){l.init()},0)}}),1===i.length?i[0]:i}}(jQuery,window,document);