From beda6cb8c8cb1aef21652fed4e961ed3ad5b551e Mon Sep 17 00:00:00 2001 From: taitus Date: Mon, 18 Jan 2021 10:57:46 +0100 Subject: [PATCH] Add JQuery library for input tags Source: https://github.com/amsify42/jquery.amsify.suggestags --- .../javascripts/jquery.amsify.suggestags.js | 897 ++++++++++++++++++ .../assets/stylesheets/amsify.suggestags.css | 198 ++++ 2 files changed, 1095 insertions(+) create mode 100644 vendor/assets/javascripts/jquery.amsify.suggestags.js create mode 100644 vendor/assets/stylesheets/amsify.suggestags.css diff --git a/vendor/assets/javascripts/jquery.amsify.suggestags.js b/vendor/assets/javascripts/jquery.amsify.suggestags.js new file mode 100644 index 000000000..bb429a2a7 --- /dev/null +++ b/vendor/assets/javascripts/jquery.amsify.suggestags.js @@ -0,0 +1,897 @@ +/** + * Amsify Suggestags + * https://github.com/amsify42/jquery.amsify.suggestags + */ + +var AmsifySuggestags; + +(function(factory) { + if(typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery'), window, document); + } else { + factory(jQuery, window, document); + } +} +(function($, window, document, undefined) { + + AmsifySuggestags = function(selector) { + this.selector = selector; + this.settings = { + type : 'bootstrap', + tagLimit : -1, + suggestions : [], + suggestMatch : {}, + suggestionsAction : {timeout: -1, minChars:2, minChange:-1, delay:100, type: 'GET'}, + defaultTagClass : '', + classes : [], + backgrounds : [], + colors : [], + whiteList : false, + afterAdd : {}, + afterRemove : {}, + //My changes + trimValue : false, + dashspaces : false, + lowercase : false, + selectOnHover : true, + triggerChange : false, + noSuggestionMsg : '', + showAllSuggestions: false, + keepLastOnHoverTag: true, + printValues : true, + checkSimilar : true, + delimiters : [], + showPlusAfter : 0 + }; + this.method = undefined; + this.name = null; + this.defaultLabel = 'Type here'; + this.classes = { + sTagsArea : '.amsify-suggestags-area', + inputArea : '.amsify-suggestags-input-area', + inputAreaDef : '.amsify-suggestags-input-area-default', + focus : '.amsify-focus', + sTagsInput : '.amsify-suggestags-input', + listArea : '.amsify-suggestags-list', + list : '.amsify-list', + listItem : '.amsify-list-item', + itemPad : '.amsify-item-pad', + inputType : '.amsify-select-input', + tagItem : '.amsify-select-tag', + plusItem : '.amsify-plus-tag', + colBg : '.col-bg', + removeTag : '.amsify-remove-tag', + readyToRemove : '.ready-to-remove', + noSuggestion : '.amsify-no-suggestion', + showPlusBg : '.show-plus-bg' + }; + this.selectors = { + sTagsArea : null, + inputArea : null, + inputAreaDef : null, + sTagsInput : null, + listArea : null, + list : null, + listGroup : null, + listItem : null, + itemPad : null, + inputType : null, + plusTag : null + }; + this.isRequired = false; + this.ajaxActive = false; + this.tagNames = []; + this.delayTimer = 0; + this.blurTgItems= null; + }; + AmsifySuggestags.prototype = { + /** + * Merging default settings with custom + * @type {object} + */ + _settings : function(settings) { + this.settings = $.extend(true, {}, this.settings, settings); + }, + + _setMethod : function(method) { + this.method = method; + }, + + _init : function() { + if(this.checkMethod()) { + this.name = ($(this.selector).attr('name'))? $(this.selector).attr('name')+'_amsify': 'amsify_suggestags'; + this.createHTML(); + this.setEvents(); + $(this.selector).hide(); + this.setDefault(); + } + }, + + createHTML : function() { + var HTML = '
'; + this.selectors.sTagsArea = $(HTML).insertAfter(this.selector); + var labelHTML = '
'; + this.selectors.inputArea = $(labelHTML).appendTo(this.selectors.sTagsArea); + this.defaultLabel = ($(this.selector).attr('placeholder') !== undefined)? $(this.selector).attr('placeholder'): this.defaultLabel; + var sTagsInput = ''; + this.selectors.sTagsInput = $(sTagsInput).appendTo(this.selectors.inputArea).attr('autocomplete', 'off'); + if($(this.selector).attr('required')) { + $(this.selector).removeAttr('required'); + this.isRequired = true; + this.updateIsRequired(); + } + var listArea = '
'; + this.selectors.listArea = $(listArea).appendTo(this.selectors.sTagsArea); + $(this.selectors.listArea).width($(this.selectors.sTagsArea).width()-3); + var list = ''; + this.selectors.list = $(list).appendTo(this.selectors.listArea); + this.updateSuggestionList(); + this.fixCSS(); + }, + + updateIsRequired : function() { + if(this.isRequired) { + if(this.tagNames.length){ + $(this.selectors.sTagsInput).removeAttr('required'); + } else { + $(this.selectors.sTagsInput).attr('required', 'required'); + } + } + }, + + updateSuggestionList : function() { + $(this.selectors.list).html(''); + $(this.createList()).appendTo(this.selectors.list); + }, + + setEvents : function() { + var _self = this; + $(this.selectors.inputArea).attr('style', $(this.selector).attr('style')).addClass($(this.selector).attr('class')); + this.setTagEvents(); + if(window !== undefined) { + $(window).resize(function(){ + $(_self.selectors.listArea).width($(_self.selectors.sTagsArea).width()-3); + }); + } + this.setSuggestionsEvents(); + this.setRemoveEvent(); + }, + + setTagEvents : function() { + var _self = this; + $(this.selectors.sTagsInput).focus(function(){ + /** + * Show all suggestions if setting set to true + */ + if(_self.settings.showAllSuggestions) { + _self.suggestWhiteList('', 0, true); + } + $(this).closest(_self.classes.inputArea).addClass(_self.classes.focus.substring(1)); + if(_self.settings.type == 'materialize') { + $(this).css({ + 'border-bottom': 'none', + '-webkit-box-shadow': 'none', + 'box-shadow': 'none', + }); + } + _self.checkPlusAfter(); + }); + $(this.selectors.sTagsInput).blur(function(){ + $(this).closest(_self.classes.inputArea).removeClass(_self.classes.focus.substring(1)); + if(!$(this).val()) { + $(_self.selectors.listArea).hide(); + } + _self.checkPlusAfter(true); + }); + $(this.selectors.sTagsInput).keyup(function(e){ + var keycode = (e.keyCode ? e.keyCode : e.which); + var key = ''; + if(e.key) { + key = e.key; + } else { + if(keycode == '13') { + key = 'Enter'; + } else if(keycode == '188') { + key = ','; + } + } + var isDelimiter = ($.inArray(key, _self.settings.delimiters) !== -1)? true: false; + if(key == 'Enter' || key == ',' || isDelimiter) { + var value = $.trim($(this).val().replace(/,/g , '')); + if(isDelimiter) { + $.each(_self.settings.delimiters, function(dkey, delimiter) { + value = $.trim(value.replace(delimiter, '')); + }); + } + $(this).val(''); + _self.addTag(_self.getValue(value)); + if(_self.settings.showAllSuggestions) { + _self.suggestWhiteList('', 0, true); + } + } else if(keycode == '8' && !$(this).val()) { + var removeClass = _self.classes.readyToRemove.substring(1); + if($(this).hasClass(removeClass)) { + $item = $(this).closest(_self.classes.inputArea).find(_self.classes.tagItem+':last'); + _self.removeTagByItem($item, false); + } else { + $(this).addClass(removeClass); + } + $(_self.selectors.listArea).hide(); + if(_self.settings.showAllSuggestions) { + _self.suggestWhiteList('', 0, true); + } + } else if((_self.settings.suggestions.length || _self.isSuggestAction()) && ($(this).val() || _self.settings.showAllSuggestions)) { + $(this).removeClass(_self.classes.readyToRemove.substring(1)); + _self.processWhiteList(keycode, $(this).val()); + } + }); + $(this.selectors.sTagsInput).keypress(function(e){ + var keycode = (e.keyCode ? e.keyCode : e.which); + if(keycode == 13) { + return false; + } + }); + $(this.selectors.sTagsArea).click(function(){ + $(_self.selectors.sTagsInput).focus(); + }); + }, + + setSuggestionsEvents : function() { + var _self = this; + if(this.settings.selectOnHover) { + $(this.selectors.listArea).find(this.classes.listItem).hover(function(){ + $(_self.selectors.listArea).find(_self.classes.listItem).removeClass('active'); + $(this).addClass('active'); + $(_self.selectors.sTagsInput).val($(this).text()); + }, function() { + $(this).removeClass('active'); + if(!_self.settings.keepLastOnHoverTag) { + $(_self.selectors.sTagsInput).val(''); + } + }); + } + $(this.selectors.listArea).find(this.classes.listItem).click(function(){ + _self.addTag($(this).data('val')); + $(_self.selectors.sTagsInput).val('').focus(); + }); + }, + + isSuggestAction : function() { + return (this.settings.suggestionsAction && this.settings.suggestionsAction.url); + }, + + getTag : function(value) { + if(this.settings.suggestions.length) { + var tag = value; + $.each(this.settings.suggestions, function(key, item){ + if(typeof item === 'object' && item.value == value) { + tag = item.tag + return false; + } + else if(item == value) { + return false; + } + }); + return tag; + } + return value; + }, + + getValue : function(tag) { + if(this.settings.suggestions.length) { + var value = tag; + var lower = tag.toString().toLowerCase(); + $.each(this.settings.suggestions, function(key, item){ + if(typeof item === 'object' && item.tag.toString().toLowerCase() == lower) { + value = item.value + return false; + } + else if(item.toString().toLowerCase() == lower) { + return false; + } + }); + return value; + } + return tag; + }, + + processAjaxSuggestion : function(value, keycode) { + var _self = this; + var actionURL = this.getActionURL(this.settings.suggestionsAction.url); + var params = {existingTags: this.tagNames, existing: this.settings.suggestions, term: value}; + var ajaxConfig = (this.settings.suggestionsAction.callbacks)? this.settings.suggestionsAction.callbacks: {}; + var ajaxFormParams = { + url : actionURL, + }; + if(this.settings.suggestionsAction.type == 'GET') { + ajaxFormParams.url = ajaxFormParams.url+'?'+$.param(params); + } else { + ajaxFormParams.type = this.settings.suggestionsAction.type; + ajaxFormParams.data = params; + } + if(this.settings.suggestionsAction.timeout !== -1) { + ajaxFormParams['timeout'] = this.settings.suggestionsAction.timeout*1000; + } + if(this.settings.suggestionsAction.beforeSend !== undefined && typeof this.settings.suggestionsAction.beforeSend == "function") { + ajaxFormParams['beforeSend'] = this.settings.suggestionsAction.beforeSend; + } + ajaxFormParams['success'] = function(data) { + if(data && data.suggestions) { + _self.settings.suggestions = $.merge(_self.settings.suggestions, data.suggestions); + _self.settings.suggestions = _self.unique(_self.settings.suggestions); + _self.updateSuggestionList(); + _self.setSuggestionsEvents(); + _self.suggestWhiteList(value, keycode); + } + if(_self.settings.suggestionsAction.success !== undefined && typeof _self.settings.suggestionsAction.success == "function") { + _self.settings.suggestionsAction.success(data); + } + }; + if(this.settings.suggestionsAction.error !== undefined && typeof this.settings.suggestionsAction.error == "function") { + ajaxFormParams['error'] = this.settings.suggestionsAction.error; + } + ajaxFormParams['complete'] = function(data) { + if(_self.settings.suggestionsAction.complete !== undefined && typeof _self.settings.suggestionsAction.complete == "function") { + _self.settings.suggestionsAction.complete(data); + } + _self.ajaxActive = false; + }; + $.ajax(ajaxFormParams); + }, + + processWhiteList : function(keycode, value) { + if(keycode == '40' || keycode == '38') { + var type = (keycode == '40')? 'down': 'up'; + this.upDownSuggestion(value, type); + } else { + clearTimeout(this.delayTimer); + var _self = this; + this.delayTimer = setTimeout(function() { + if(_self.isSuggestAction() && !_self.ajaxActive) { + var minChars = _self.settings.suggestionsAction.minChars; + var minChange = _self.settings.suggestionsAction.minChange; + var lastSearch= _self.selectors.sTagsInput.attr('last-search'); + if(value.length >= minChars && (minChange === -1 || !lastSearch || _self.similarity(lastSearch, value)*100 <= minChange)) { + _self.selectors.sTagsInput.attr('last-search', value); + _self.ajaxActive = true; + _self.processAjaxSuggestion(value, keycode); + } + } else { + _self.suggestWhiteList(value, keycode); + } + }, this.settings.suggestionsAction.delay); + } + }, + + upDownSuggestion : function(value, type) { + var _self = this; + var isActive = false; + $(this.selectors.listArea).find(this.classes.listItem+':visible').each(function(){ + if($(this).hasClass('active')) { + $(this).removeClass('active'); + if(type == 'up') { + $item = $(this).prevAll(_self.classes.listItem+':visible:first'); + } else { + $item = $(this).nextAll(_self.classes.listItem+':visible:first'); + } + if($item.length) { + isActive = true; + $item.addClass('active'); + $(_self.selectors.sTagsInput).val($item.text()); + } + return false; + } + }); + if(!isActive) { + var childItem = (type == 'down')? 'first': 'last'; + $item = $(this.selectors.listArea).find(this.classes.listItem+':visible:'+childItem); + if($item.length) { + $item.addClass('active'); + $(_self.selectors.sTagsInput).val($item.text()); + } + } + }, + + suggestWhiteList : function(value, keycode, showAll) { + var _self = this; + var found = false; + var all = (showAll)? true: false; + var lower = value.toString().toLowerCase(); + $(this.selectors.listArea).find(_self.classes.noSuggestion).hide(); + var $list = $(this.selectors.listArea).find(this.classes.list); + $list.find(this.classes.listItem).each(function(){ + var dataVal = $(this).data('val'); + if($.isNumeric(dataVal)) { + dataVal = (value.toString().indexOf('.') == -1)? parseInt(dataVal): parseFloat(dataVal); + } + + /** + * Suggest item matching result + */ + var suggestItemResult = 0; + if(_self.settings.suggestMatch && typeof _self.settings.suggestMatch == "function") { + suggestItemResult = _self.settings.suggestMatch($(this).text(), value); + } else { + suggestItemResult = ~$(this).text().toString().toLowerCase().indexOf(lower); + } + + if((all || suggestItemResult) && $.inArray(dataVal, _self.tagNames) === -1) { + $(this).attr('data-show', 1); + found = true; + } else { + $(this).removeAttr('data-show'); + } + $(this).hide(); + }); + if(found) { + /** + * Sorting the suggestions + */ + $dataShow = $list.find(this.classes.listItem+'[data-show]'); + if(lower) { + $dataShow.sort(function(a, b) { + return value.localeCompare($(a).text().toString()); + }).appendTo($list); + } else { + $dataShow.sort(function(a, b) { + return $(a).text().toString().localeCompare($(b).text().toString()); + }).appendTo($list); + } + $dataShow.each(function(){ + $(this).show(); + }); + + /** + * If only one item left in whitelist suggestions + */ + $item = $(this.selectors.listArea).find(this.classes.listItem+':visible'); + if($item.length == 1 && keycode != '8') { + if((this.settings.whiteList && this.isSimilarText(value.toLowerCase(), $item.text().toLowerCase(), 40)) || this.isSimilarText(value.toLowerCase(), $item.text().toLowerCase(), 60)) { + $item.addClass('active'); + $(this.selectors.sTagsInput).val($item.text()); + } + } else { + $item.removeClass('active'); + } + + $(this.selectors.listArea).show(); + + } else { + if(value && _self.settings.noSuggestionMsg) { + $(this.selectors.listArea).find(_self.classes.listItem).hide(); + $(this.selectors.listArea).find(_self.classes.noSuggestion).show(); + } else { + $(this.selectors.listArea).hide(); + } + } + }, + + setDefault : function() { + var _self = this; + var items = $(this.selector).val().split(','); + if(items.length) { + $.each(items, function(index, item){ + _self.addTag($.trim(item)); + }); + } + }, + + setRemoveEvent: function() { + var _self = this; + $(this.selectors.inputArea).find(this.classes.removeTag).click(function(e){ + e.stopImmediatePropagation(); + $tagItem = $(this).closest(_self.classes.tagItem); + _self.removeTagByItem($tagItem, false); + }); + }, + + createList : function() { + var _self = this; + var listHTML = ''; + $.each(this.settings.suggestions, function(index, item){ + var value = ''; + var tag = ''; + if(typeof item === 'object') { + value = item.value + tag = item.tag + } else { + value = item; + tag = item; + } + listHTML += '
  • '+tag+'
  • '; + }); + if(_self.settings.noSuggestionMsg) { + listHTML += '
  • '+_self.settings.noSuggestionMsg+'
  • '; + } + return listHTML; + }, + + addTag : function(value, animate=true) { + if(!value) { + return; + } + // Trim value + if (typeof value === "string" && this.settings.trimValue) { + value = $.trim(value); + } + + // lowercase and dash + if (typeof value === "string" && this.settings.lowercase && this.settings.dashspaces) { + value = value.replace(/\s+/g, '-').toLowerCase(); + } + else if (typeof value === "string" && this.settings.lowercase){ + value = value.toLowerCase(); + } + else if (typeof value === "string" && this.settings.dashspaces){ + value = value.replace(/\s+/g, '-'); + } + + var html = ''+this.getTag(value)+' '+this.setIcon()+''; + $item = $(html).insertBefore($(this.selectors.sTagsInput)); + if(this.settings.defaultTagClass) { + $item.addClass(this.settings.defaultTagClass); + } + if(this.settings.tagLimit != -1 && this.settings.tagLimit > 0 && this.tagNames.length >= this.settings.tagLimit) { + this.animateRemove($item, animate); + if(animate) { + this.flashItem(value); + } + return false; + } + var itemKey = this.getItemKey(value); + if(this.settings.whiteList && itemKey === -1) { + this.animateRemove($item, animate); + if(animate) { + this.flashItem(value); + } + return false; + } + if(this.isPresent(value)) { + this.animateRemove($item, animate); + if(animate) { + this.flashItem(value); + } + } else { + this.customStylings($item, itemKey); + var dataVal = value; + if($.isNumeric(dataVal)) { + dataVal = (value.toString().indexOf('.') == -1)? parseInt(dataVal): parseFloat(dataVal); + } + this.tagNames.push(dataVal); + this.setRemoveEvent(); + this.setInputValue(); + if(this.settings.afterAdd && typeof this.settings.afterAdd == "function") { + this.settings.afterAdd(value); + } + } + $(this.selector).trigger('suggestags.add', [value]); + $(this.selector).trigger('suggestags.change'); + if(this.settings.triggerChange) { + $(this.selector).trigger('change'); + } + $(this.selectors.listArea).find(this.classes.listItem).removeClass('active'); + $(this.selectors.listArea).hide(); + $(this.selectors.sTagsInput).removeClass(this.classes.readyToRemove.substring(1)); + this.checkPlusAfter(); + }, + + getItemKey : function(value) { + var itemKey = -1 + if(this.settings.suggestions.length) { + var lower = value.toString().toLowerCase(); + $.each(this.settings.suggestions, function(key, item){ + if(typeof item === 'object') { + if(item.value.toString().toLowerCase() == lower) { + itemKey = key; + return false; + } + } else if(item.toString().toLowerCase() == lower) { + itemKey = key; + return false; + } + }); + } + return itemKey; + }, + + isPresent : function(value) { + var present = false; + $.each(this.tagNames, function(index, tag){ + if(value.toString().toLowerCase() == tag.toString().toLowerCase()) { + present = true; + return false; + } + }); + return present; + }, + + customStylings : function(item, key) { + var isCutom = false; + if(this.settings.classes[key]) { + isCutom = true; + $(item).addClass(this.settings.classes[key]); + } + if(this.settings.backgrounds[key]) { + isCutom = true; + $(item).css('background', this.settings.backgrounds[key]); + } + if(this.settings.colors[key]) { + isCutom = true; + $(item).css('color', this.settings.colors[key]); + } + if(!isCutom) { + $(item).addClass(this.classes.colBg.substring(1)); + } + }, + + removeTag: function(value, animate=true) { + var _self = this; + $findTags = $(this.selectors.sTagsArea).find('[data-val="'+value+'"]'); + if($findTags.length) { + $findTags.each(function(){ + _self.removeTagByItem(this, animate); + }); + } + }, + + removeTagByItem : function(item, animate) { + this.tagNames.splice($(item).index(), 1); + this.animateRemove(item, animate); + this.setInputValue(); + $(this.selector).trigger('suggestags.remove', [$(item).attr('data-val')]); + $(this.selector).trigger('suggestags.change'); + if(this.settings.triggerChange) { + $(this.selector).trigger('change'); + } + if(this.settings.afterRemove && typeof this.settings.afterRemove == "function") { + this.settings.afterRemove($(item).attr('data-val')); + } + $(this.selectors.sTagsInput).removeClass(this.classes.readyToRemove.substring(1)); + this.checkPlusAfter(); + }, + + animateRemove : function(item, animate) { + $(item).addClass('disabled'); + if(animate) { + setTimeout(function(){ + $(item).slideUp(); + setTimeout(function(){ + $(item).remove(); + }, 500); + }, 500); + } else { + $(item).remove(); + } + }, + + flashItem : function(value) { + $tagItem = ''; + value = value.toString().toLowerCase(); + $(this.selectors.sTagsArea).find(this.classes.tagItem).each(function(){ + var tagName = $.trim($(this).attr('data-val')); + if(value == tagName.toString().toLowerCase()) { + $tagItem = $(this); + return false; + } + }); + if($tagItem) { + $tagItem.addClass('flash'); + setTimeout(function(){ + $tagItem.removeClass('flash'); + }, 1500, $tagItem); + } + }, + + setIcon : function() { + var removeClass = this.classes.removeTag.substring(1); + if(this.settings.type == 'bootstrap') { + return ''; + } else if(this.settings.type == 'materialize') { + return 'clear'; + } else { + return ''; + } + }, + + setInputValue: function() { + this.updateIsRequired(); + $(this.selector).val(this.tagNames.join(',')); + if(this.settings.printValues) { + this.printValues(); + } + }, + + fixCSS : function() { + if(this.settings.type == 'amsify') { + $(this.selectors.inputArea).addClass(this.classes.inputAreaDef.substring(1)).css({'padding': '5px 5px'}); + } else if(this.settings.type == 'materialize') { + $(this.selectors.inputArea).addClass(this.classes.inputAreaDef.substring(1)).css({'height': 'auto', 'padding': '5px 5px'}); + $(this.selectors.sTagsInput).css({'margin': '0', 'height': 'auto'}); + } + }, + + printValues : function() { + console.info(this.tagNames, $(this.selector).val()); + }, + + checkMethod : function() { + $findTags = $(this.selector).next(this.classes.sTagsArea); + if($findTags.length) { + $findTags.remove(); + } + $(this.selector).show(); + if(typeof this.method !== undefined && this.method == 'destroy') { + return false; + } else { + return true; + } + }, + + refresh : function() { + this._setMethod('refresh'); + this._init(); + }, + + destroy : function() { + this._setMethod('destroy'); + this._init(); + }, + + getActionURL : function(urlString) { + var URL = ''; + if(window !== undefined) { + URL = window.location.protocol+'//'+window.location.host; + } + if(this.isAbsoluteURL(urlString)) { + URL = urlString; + } else { + URL += '/'+urlString.replace(/^\/|\/$/g, ''); + } + return URL; + }, + + isAbsoluteURL : function(urlString) { + var regexURL = new RegExp('^(?:[a-z]+:)?//', 'i'); + return (regexURL.test(urlString))? true: false; + }, + + unique: function(list) { + var result = []; + var _self = this; + $.each(list, function(i, e) { + if(typeof e === 'object') { + if(!_self.objectInArray(e, result)) { + result.push(e); + } + } else { + if($.inArray(e, result) == -1) { + result.push(e); + } + } + }); + return result; + }, + + objectInArray : function(element, result) { + if(result.length) { + var present = false; + $.each(result, function(i, e) { + if(typeof e === 'object') { + if(e.value == element.value) { + present = true; + return false; + } + } else { + if(e == element.value) { + present = true; + return false; + } + } + }); + return present; + } else { + return false; + } + }, + + isSimilarText: function(str1, str2, perc) { + if(!this.settings.checkSimilar) { + return false; + } + var percent = this.similarity(str1, str2); + return (percent*100 >= perc)? true: false; + }, + + similarity: function(s1, s2) { + var longer = s1; + var shorter = s2; + if(s1.length < s2.length) { + longer = s2; + shorter = s1; + } + var longerLength = longer.length; + if(longerLength == 0) { + return 1.0; + } + return (longerLength - this.editDistance(longer, shorter))/parseFloat(longerLength); + }, + + editDistance: function(s1, s2) { + s1 = s1.toLowerCase(); + s2 = s2.toLowerCase(); + var costs = new Array(); + for(var i = 0; i <= s1.length; i++) { + var lastValue = i; + for(var j = 0; j <= s2.length; j++) { + if(i == 0) { + costs[j] = j; + } else { + if(j > 0) { + var newValue = costs[j-1]; + if(s1.charAt(i-1) != s2.charAt(j-1)) { + newValue = Math.min(Math.min(newValue, lastValue), costs[j]) + 1; + } + costs[j-1] = lastValue; + lastValue = newValue; + } + } + } + if(i > 0) + costs[s2.length] = lastValue; + } + return costs[s2.length]; + }, + + checkPlusAfter : function(fromBlur) { + if(this.settings.showPlusAfter > 0) { + if(this.tagNames.length > this.settings.showPlusAfter) { + var _self = this; + var plusNumber = this.tagNames.length - this.settings.showPlusAfter; + if(!this.selectors.plusTag) { + var html = ''; + this.selectors.plusTag = $(html).appendTo(this.selectors.inputArea); + $(this.selectors.plusTag).addClass(this.classes.showPlusBg.substring(1)); + /** + * Show input after focus on input area + */ + $(this.selectors.inputArea).click(function(){ + $(_self.selectors.sTagsInput).show(); + }); + } + $(this.selectors.plusTag).text('+ '+plusNumber); + $tagItems = $(this.selectors.inputArea).find(this.classes.tagItem); + $tagItems.show(); + if($(this.selectors.inputArea).hasClass(this.classes.focus.substring(1))){ + $(this.selectors.plusTag).hide(); + } else { + if(fromBlur && !this.blurTgItems) { + this.blurTgItems = $tagItems; + setTimeout(function(){ + if(_self.blurTgItems) { + _self.blurTgItems.slice(_self.settings.showPlusAfter).hide(); + } + }, 200); + } else { + this.blurTgItems = null; + $tagItems.slice(this.settings.showPlusAfter).hide(); + } + $(this.selectors.sTagsInput).hide(); + $(this.selectors.plusTag).show(); + } + } else if(this.selectors.plusTag) { + $(this.selectors.inputArea).find(this.classes.tagItem).show(); + $(this.selectors.plusTag).hide(); + } + } + } + }; + + $.fn.amsifySuggestags = function(options, method) { + return this.each(function() { + var amsifySuggestags = new AmsifySuggestags(this); + amsifySuggestags._settings(options); + amsifySuggestags._setMethod(method); + amsifySuggestags._init(); + }); + }; +})); diff --git a/vendor/assets/stylesheets/amsify.suggestags.css b/vendor/assets/stylesheets/amsify.suggestags.css new file mode 100644 index 000000000..766e32fde --- /dev/null +++ b/vendor/assets/stylesheets/amsify.suggestags.css @@ -0,0 +1,198 @@ +.amsify-suggestags-area +.amsify-suggestags-input-area-default { + cursor: pointer; + border: 1px solid #cccccc; + min-height: 20px; + padding: 8px 5px; +} + +.amsify-suggestags-area +.amsify-suggestags-input-area { + text-align: left; + height: auto; +} + +.amsify-suggestags-area +.amsify-suggestags-input-area:hover { + cursor: text; +} + +.amsify-suggestags-area +.amsify-suggestags-input-area +.amsify-suggestags-input { + max-width: 200px; + padding: 0px 4px; + border: 0; +} + +.amsify-suggestags-area +.amsify-suggestags-input-area +.amsify-suggestags-input:focus { + outline: 0; +} + +.amsify-focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6); +} + +.amsify-focus-light { + border-color: #cacaca; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(189, 189, 189, 0.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(189, 189, 189, 0.6); +} + +.amsify-suggestags-area +.amsify-suggestags-label { + cursor: pointer; + min-height: 20px; +} + +.amsify-toggle-suggestags { + float: right; + cursor: pointer; +} + +.amsify-suggestags-area .amsify-suggestags-list { + display: none; + position: absolute; + background: white; + border: 1px solid #dedede; + z-index: 1; +} + +.amsify-suggestags-area +.amsify-suggestags-list +ul.amsify-list { + list-style: none; + padding: 3px 0px; + max-height: 150px; + overflow-y: auto; +} + +.amsify-suggestags-area +.amsify-suggestags-list +ul.amsify-list +li.amsify-list-item { + text-align: left; + cursor: pointer; + padding: 0px 10px; +} + +.amsify-suggestags-area +.amsify-suggestags-list +ul.amsify-list +li.amsify-list-item:active { + background: #717171; + color: white; + -moz-box-shadow: inset 0 0 10px #000000; + -webkit-box-shadow: inset 0 0 10px #000000; + box-shadow: inset 0 0 10px #000000; +} + +.amsify-suggestags-area +.amsify-suggestags-list +ul.amsify-list +li.amsify-list-group { + text-align: left; + padding: 0px 10px; + font-weight: bold; +} + +.amsify-suggestags-area +.amsify-suggestags-list +ul.amsify-list +li.amsify-item-pad { + padding-left: 30px; +} + +.amsify-suggestags-area +.amsify-suggestags-list +ul.amsify-list +li.amsify-item-noresult { + display: none; + color: #ff6060; + font-weight: bold; + text-align: center; +} + +.amsify-suggestags-area +.amsify-suggestags-list +.amsify-select-input { + display: none; +} + +.amsify-suggestags-area +.amsify-suggestags-list +ul.amsify-list +li.active { + background: #d9d8d8; +} + +.amsify-suggestags-area +.amsify-suggestags-list +ul.amsify-list +li.amsify-item-pad.active { + font-weight: normal; +} + +.amsify-suggestags-input-area +.amsify-select-tag, +.amsify-suggestags-input-area +.amsify-plus-tag { + padding: 2px 7px; + margin: 0px 4px 1px 0px; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; + display: inline-block; +} + +.amsify-suggestags-input-area +.amsify-select-tag.col-bg { + background: #d8d8d8; + color: black; +} + +.amsify-suggestags-input-area +.amsify-plus-tag.show-plus-bg { + background: #767676; + color: white; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +/*.amsify-suggestags-input-area +.amsify-select-tag:hover { + background: #737373; + color: white; +}*/ + +.amsify-suggestags-input-area +.disabled.amsify-select-tag { + background: #eaeaea; + color: #b9b9b9; + pointer-events: none; +} + +.amsify-suggestags-input-area +.flash.amsify-select-tag { + background-color: #f57f7f; + -webkit-transition: background-color 200ms linear; + -ms-transition: background-color 200ms linear; + transition: background-color 200ms linear; +} + +.amsify-suggestags-input-area +.amsify-remove-tag { + cursor: pointer; +} + +.amsify-no-suggestion { + display: none; + opacity: 0.7; +} \ No newline at end of file