1
0
mirror of https://github.com/e107inc/e107.git synced 2025-08-13 18:14:26 +02:00

Bootstrap-suggest library added.

This commit is contained in:
Cameron
2021-02-24 15:36:16 -08:00
parent 5f085c9446
commit 827af45c03
5 changed files with 742 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
/*!
* bootstra-suggest - v2.0.3 (https://github.com/lodev09/bootstrap-suggest#readme)
* Copyright 2013-2019 Jovanni Lo (lodev09@gmail.com)
* Licensed under MIT (https://github.com/lodev09/bootstrap-suggest/blob/master/LICENSE)
*/
.suggest {
/* position: relative; */
top: 7px;
z-index: 30;
text-align: left;
}
.suggest > .dropdown-menu {
margin-top: 15px;
position: absolute;
height: 200px;
overflow-y: scroll
}
.suggest > .dropdown-menu > a.dropdown-item {
border-top: 1px solid #eeeeee;
padding: 5px 10px;
}
.suggest > .dropdown-menu > a.dropdown-item:first-child {
border-top: 0;
}

View File

@@ -0,0 +1,592 @@
/* ===================================================
* bootstrap-suggest.js v2.0.3
* http://github.com/lodev09/bootstrap-suggest
* ===================================================
* Copyright 2019 Jovanni Lo @lodev09
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
(function ($) {
"use strict"; // jshint ;_;
var Suggest = function(el, key, options) {
var that = this;
this.$element = $(el);
this.$items = undefined;
this.options = $.extend(true, {}, $.fn.suggest.defaults, options, this.$element.data(), this.$element.data('options'));
this.key = key;
this.isShown = false;
this.query = '';
this._queryPos = [];
this._keyPos = -1;
this.$dropdown = $('<div />', {
'class': 'dropdown suggest ' + this.options.dropdownClass,
'html': $('<ul />', {'class': 'dropdown-menu', role: 'menu'}),
'data-key': this.key
});
this.load();
};
Suggest.prototype = {
__setListener: function() {
this.$element
.on('suggest.show', $.proxy(this.options.onshow, this))
.on('suggest.select', $.proxy(this.options.onselect, this))
.on('suggest.lookup', $.proxy(this.options.onlookup, this))
.on('keyup', $.proxy(this.__keyup, this));
return this;
},
__getCaretPos: function(posStart) {
// https://github.com/component/textarea-caret-position/blob/master/index.js
// The properties that we copy into a mirrored div.
// Note that some browsers, such as Firefox,
// do not concatenate properties, i.e. padding-top, bottom etc. -> padding,
// so we have to do every single property specifically.
var properties = [
'direction', // RTL support
'boxSizing',
'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does
'height',
'overflowX',
'overflowY', // copy the scrollbar for IE
'borderTopWidth',
'borderRightWidth',
'borderBottomWidth',
'borderLeftWidth',
'paddingTop',
'paddingRight',
'paddingBottom',
'paddingLeft',
// https://developer.mozilla.org/en-US/docs/Web/CSS/font
'fontStyle',
'fontVariant',
'fontWeight',
'fontStretch',
'fontSize',
'fontSizeAdjust',
'lineHeight',
'fontFamily',
'textAlign',
'textTransform',
'textIndent',
'textDecoration', // might not make a difference, but better be safe
'letterSpacing',
'wordSpacing'
];
var isFirefox = !(window.mozInnerScreenX == null);
var getCaretCoordinatesFn = function (element, position, recalculate) {
// mirrored div
var div = document.createElement('div');
div.id = 'input-textarea-caret-position-mirror-div';
document.body.appendChild(div);
var style = div.style;
var computed = window.getComputedStyle? getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9
// default textarea styles
style.whiteSpace = 'pre-wrap';
if (element.nodeName !== 'INPUT')
style.wordWrap = 'break-word'; // only for textarea-s
// position off-screen
style.position = 'absolute'; // required to return coordinates properly
style.visibility = 'hidden'; // not 'display: none' because we want rendering
// transfer the element's properties to the div
$.each(properties, function (index, value) {
style[value] = computed[value];
});
if (isFirefox) {
style.width = parseInt(computed.width) - 2 + 'px'; // Firefox adds 2 pixels to the padding - https://bugzilla.mozilla.org/show_bug.cgi?id=753662
// Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275
if (element.scrollHeight > parseInt(computed.height))
style.overflowY = 'scroll';
} else {
style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'
}
div.textContent = element.value.substring(0, position);
// the second special handling for input type="text" vs textarea: spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037
if (element.nodeName === 'INPUT')
div.textContent = div.textContent.replace(/\s/g, "\u00a0");
var span = document.createElement('span');
// Wrapping must be replicated *exactly*, including when a long word gets
// onto the next line, with whitespace at the end of the line before (#7).
// The *only* reliable way to do that is to copy the *entire* rest of the
// textarea's content into the <span> created at the caret position.
// for inputs, just '.' would be enough, but why bother?
span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all
div.appendChild(span);
var coordinates = {
top: span.offsetTop + parseInt(computed['borderTopWidth']),
left: span.offsetLeft + parseInt(computed['borderLeftWidth'])
};
document.body.removeChild(div);
return coordinates;
}
return getCaretCoordinatesFn(this.$element.get(0), posStart);
},
__keyup: function(e) {
// don't query special characters
// http://mikemurko.com/general/jquery-keycode-cheatsheet/
var specialChars = [38, 40, 37, 39, 17, 18, 9, 16, 20, 91, 93, 36, 35, 45, 33, 34, 144, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 145, 19];
switch (e.keyCode) {
case 27: // escape
this.hide();
return;
case 13: // enter/return
return true;
}
if ($.inArray(e.keyCode, specialChars) !== -1) return;
var $el = this.$element,
val = $el.val(),
currentPos = this.__getSelection($el.get(0)).start;
for (var i = currentPos; i >= 0; i--) {
var subChar = $.trim(val.substring(i-1, i));
if (!subChar) {
this.hide();
break;
}
if (subChar === this.key && $.trim(val.substring(i-2, i-1)) == '') {
this.query = val.substring(i, currentPos);
this._queryPos = [i, currentPos];
this._keyPos = i;
this.lookup(this.query);
break;
}
}
},
__getVisibleItems: function() {
return this.$items ? this.$items.not('.d-none') : $();
},
__build: function() {
var elems = [], $item,
$dropdown = this.$dropdown,
that = this;
var blur = function(e) {
that.hide();
}
$dropdown
.on('click', 'li:has(a)', function(e) {
e.preventDefault();
that.__select($(this).index());
that.$element.focus();
})
.on('mouseover', 'li:has(a)', function(e) {
that.$element.off('blur', blur);
})
.on('mouseout', 'li:has(a)', function(e) {
that.$element.on('blur', blur);
});
this.$element.before($dropdown).on('blur', blur).on('keydown', function(e) {
var $visibleItems;
if (that.isShown) {
switch (e.keyCode) {
case 13: // enter key
$visibleItems = that.__getVisibleItems();
$visibleItems.each(function(index) {
if ($(this).is('.active'))
that.__select($(this).index());
});
return false;
break;
case 40: // arrow down
$visibleItems = that.__getVisibleItems();
if ($visibleItems.last().is('.active')) return false;
$visibleItems.each(function(index) {
var $this = $(this),
$next = $visibleItems.eq(index + 1);
//if (!$next.length) return false;
if ($this.is('.active')) {
if (!$next.is('.hidden')) {
$this.removeClass('active');
$next.addClass('active');
}
return false;
}
});
return false;
case 38: // arrow up
$visibleItems = that.__getVisibleItems();
if ($visibleItems.first().is('.active')) return false;
$visibleItems.each(function(index) {
var $this = $(this),
$prev = $visibleItems.eq(index - 1);
//if (!$prev.length) return false;
if ($this.is('.active')) {
if (!$prev.is('.hidden')) {
$this.removeClass('active');
$prev.addClass('active');
}
return false;
}
})
return false;
}
}
});
},
__mapItem: function(dataItem) {
var itemHtml, that = this,
_item = {
text: '',
value: ''
};
if (this.options.map) {
dataItem = this.options.map(dataItem);
if (!dataItem) return false;
}
if (dataItem instanceof Object) {
_item.text = dataItem.text || '';
_item.value = dataItem.value || '';
} else {
_item.text = dataItem;
_item.value = dataItem;
}
return $('<li />', {'data-value': _item.value}).html($('<a />', {
href: '#',
html: _item.text
})).addClass('dropdown-item');
},
__select: function(index) {
var $el = this.$element,
el = $el.get(0),
val = $el.val(),
item = this.get(index),
setCaretPos = this._keyPos + item.value.length + 1;
$el.val(val.slice(0, this._keyPos) + item.value + this.options.endKey + val.slice(this.__getSelection(el).start));
if (el.setSelectionRange) {
el.setSelectionRange(setCaretPos, setCaretPos);
} else if (el.createTextRange) {
var range = el.createTextRange();
range.collapse(true);
range.moveEnd('character', setCaretPos);
range.moveStart('character', setCaretPos);
range.select();
}
$el.trigger($.extend({type: 'suggest.select'}, this), item);
this.hide();
},
__getSelection: function (el) {
//in IE9 selectionStart will always be 9 if not focused(when selecting using the mouse)
el.focus();
return {
start: el.selectionStart,
end: el.selectionEnd
};
},
__buildItems: function(data) {
var $dropdownMenu = this.$dropdown.find('.dropdown-menu');
$dropdownMenu.empty();
if (data && data instanceof Array) {
for (var i in data) {
var $item = this.__mapItem(data[i]);
if ($item) {
$dropdownMenu.append($item);
}
}
}
return $dropdownMenu.find('li:has(a)');
},
__lookup: function(q, $resultItems) {
var active = $resultItems.eq(0).addClass('active');
this.$element.trigger($.extend({type: 'suggest.lookup'}, this), [q, $resultItems]);
if ($resultItems && $resultItems.length) {
this.show();
} else {
this.hide();
}
},
__filterData: function(q, data) {
var options = this.options;
this.$items.addClass('hidden');
this.$items.filter(function (index) {
// return the limit if q is empty
if (q === '') return index < options.filter.limit;
var $this = $(this),
value = $this.find('a:first').text();
if (!options.filter.casesensitive) {
value = value.toLowerCase();
q = q.toLowerCase();
}
return value.indexOf(q) != -1;
}).slice(0, options.filter.limit).removeClass('hidden active');
return this.__getVisibleItems();
},
get: function(index) {
if (!this.$items) return;
var $item = this.$items.eq(index);
return {
text: $item.children('a:first').text(),
value: $item.attr('data-value'),
index: index,
$element: $item
};
},
lookup: function(q) {
var options = this.options,
that = this,
data;
var provide = function(data) {
// verify that we're still "typing" the query (no space)
if (that._keyPos !== -1) {
if (!that.$items) {
that.$items = that.__buildItems(data);
}
that.__lookup(q, that.__filterData(q, data));
}
};
if (typeof this.options.data === 'function') {
this.$items = undefined;
data = this.options.data(q, provide);
} else {
data = this.options.data;
}
if (data && typeof data.promise === 'function') {
data.done(provide);
} else if (data) {
provide.call(this, data);
}
},
load: function() {
this.__setListener();
this.__build();
},
hide: function() {
this.$dropdown.removeClass('open show');
this.isShown = false;
if(this.$items) {
this.$items.removeClass('active');
}
this._keyPos = -1;
},
show: function() {
var $el = this.$element,
$dropdownMenu = this.$dropdown.find('.dropdown-menu'),
el = $el.get(0),
options = this.options,
caretPos,
position = {
top: 'auto',
bottom: 'auto',
left: 'auto',
right: 'auto'
};
if (!this.isShown) {
this.$dropdown.addClass('open show');
if (options.position !== false) {
caretPos = this.__getCaretPos(this._keyPos);
if (typeof options.position == 'string') {
switch (options.position) {
case 'bottom':
position.top = $el.outerHeight() - parseFloat($dropdownMenu.css('margin-top'));
position.left = 0;
position.right = 0;
break;
case 'top':
position.top = -($dropdownMenu.outerHeight(true) + parseFloat($dropdownMenu.css('margin-top')));
position.left = 0;
position.right = 0;
break;
case 'caret':
position.top = caretPos.top - el.scrollTop;
position.left = caretPos.left - el.scrollLeft;
break;
}
} else {
position = $.extend(position, typeof options.position === 'function' ? options.position(el, caretPos) : options.position);
}
$dropdownMenu.css(position);
}
this.isShown = true;
$el.trigger($.extend({type: 'suggest.show'}, this));
}
}
};
var old = $.fn.suggest;
// .suggest( key [, options] )
// .suggest( method [, options] )
// .suggest( suggestions )
$.fn.suggest = function(arg1) {
var arg2 = arguments[1],
arg3 = arguments[2];
var createSuggestions = function(el, suggestions) {
var newData = {};
$.each(suggestions, function(keyChar, options) {
var key = keyChar.toString().charAt(0);
// remove existing suggest
// $('.suggest.dropdown[data-key="'+key+'"]').remove();
newData[key] = new Suggest(el, key, typeof options === 'object' && options);
});
return newData;
};
return this.each(function() {
var that = this,
$this = $(this),
data = $this.data('suggest'),
suggestions = {};
if (typeof arg1 === 'string') {
if (arg1.length == 1) {
// arg1 as key
if (arg2) {
// arg2 is a function name
if (typeof arg2 === 'string') {
if (arg1 in data && typeof data[arg1][arg2] !== 'undefined') {
return data[arg1][arg2].call(data[arg1], arg3);
} else {
console.error(arg1 + ' is not a suggest');
}
} else {
// inline data determined if it's an array
suggestions[arg1] = $.isArray(arg2) || typeof arg2 === 'function' ? {data: arg2} : arg2;
// if key is existing, update options
if (data && arg1 in data) {
data[arg1].options = $.extend({}, data[arg1].options, suggestions[arg1]);
} else {
data = $.extend(data, createSuggestions(this, suggestions));
}
$this.data('suggest', data);
}
}
} else {
console.error('you\'re not initializing suggest properly. arg1 should have length == 1');
}
} else {
// arg1 contains set of suggestions
if (!data) $this.data('suggest', createSuggestions(this, arg1));
else if (data) {
// create/update suggestions
$.each(arg1, function(key, value) {
if (key in data === false) {
suggestions[key] = value;
} else {
// extend (update) options
data[key].options = $.extend({}, data[key].options, value);
}
});
$this.data('suggest', $.extend(data, createSuggestions(that, suggestions)))
}
}
});
};
$.fn.suggest.defaults = {
data: [],
map: undefined,
filter: {
casesensitive: false,
limit: 5
},
endKey: ' ',
dropdownClass: '',
position: 'caret',
// events hook
onshow: function(e) {},
onselect: function(e, item) {},
onlookup: function(e, item) {}
}
$.fn.suggest.Constructor = Suggest;
$.fn.suggest.noConflict = function () {
$.fn.suggest = old;
return this;
}
}( jQuery ));

View File

@@ -0,0 +1,31 @@
/*!
* bootstra-suggest - v2.0.1 (https://github.com/lodev09/bootstrap-suggest#readme)
* Copyright 2013-2019 Jovanni Lo (lodev09@gmail.com)
* Licensed under MIT (https://github.com/lodev09/bootstrap-suggest/blob/master/LICENSE)
*/
(function($){"use strict";var Suggest=function(el,key,options){var that=this;this.$element=$(el);this.$items=undefined;this.options=$.extend(true,{},$.fn.suggest.defaults,options,this.$element.data(),this.$element.data('options'));this.key=key;this.isShown=false;this.query='';this._queryPos=[];this._keyPos=-1;this.$dropdown=$('<div />',{'class':'dropdown suggest '+this.options.dropdownClass,'html':$('<ul />',{'class':'dropdown-menu',role:'menu'}),'data-key':this.key});this.load();};Suggest.prototype={__setListener:function(){this.$element.on('suggest.show',$.proxy(this.options.onshow,this)).on('suggest.select',$.proxy(this.options.onselect,this)).on('suggest.lookup',$.proxy(this.options.onlookup,this)).on('keyup',$.proxy(this.__keyup,this));return this;},__getCaretPos:function(posStart){var properties=['direction','boxSizing','width','height','overflowX','overflowY','borderTopWidth','borderRightWidth','borderBottomWidth','borderLeftWidth','paddingTop','paddingRight','paddingBottom','paddingLeft','fontStyle','fontVariant','fontWeight','fontStretch','fontSize','fontSizeAdjust','lineHeight','fontFamily','textAlign','textTransform','textIndent','textDecoration','letterSpacing','wordSpacing'];var isFirefox=!(window.mozInnerScreenX==null);var getCaretCoordinatesFn=function(element,position,recalculate){var div=document.createElement('div');div.id='input-textarea-caret-position-mirror-div';document.body.appendChild(div);var style=div.style;var computed=window.getComputedStyle?getComputedStyle(element):element.currentStyle;style.whiteSpace='pre-wrap';if(element.nodeName!=='INPUT')
style.wordWrap='break-word';style.position='absolute';style.visibility='hidden';$.each(properties,function(index,value){style[value]=computed[value];});if(isFirefox){style.width=parseInt(computed.width)-2+'px';if(element.scrollHeight>parseInt(computed.height))
style.overflowY='scroll';}else{style.overflow='hidden';}
div.textContent=element.value.substring(0,position);if(element.nodeName==='INPUT')
div.textContent=div.textContent.replace(/\s/g,"\u00a0");var span=document.createElement('span');span.textContent=element.value.substring(position)||'.';div.appendChild(span);var coordinates={top:span.offsetTop+parseInt(computed['borderTopWidth']),left:span.offsetLeft+parseInt(computed['borderLeftWidth'])};document.body.removeChild(div);return coordinates;}
return getCaretCoordinatesFn(this.$element.get(0),posStart);},__keyup:function(e){var specialChars=[38,40,37,39,17,18,9,16,20,91,93,36,35,45,33,34,144,112,113,114,115,116,117,118,119,120,121,122,123,145,19];switch(e.keyCode){case 27:this.hide();return;case 13:return true;}
if($.inArray(e.keyCode,specialChars)!==-1)return;var $el=this.$element,val=$el.val(),currentPos=this.__getSelection($el.get(0)).start;for(var i=currentPos;i>=0;i--){var subChar=$.trim(val.substring(i-1,i));if(!subChar){this.hide();break;}
if(subChar===this.key&&$.trim(val.substring(i-2,i-1))==''){this.query=val.substring(i,currentPos);this._queryPos=[i,currentPos];this._keyPos=i;this.lookup(this.query);break;}}},__getVisibleItems:function(){return this.$items?this.$items.not('.d-none'):$();},__build:function(){var elems=[],$item,$dropdown=this.$dropdown,that=this;var blur=function(e){that.hide();}
$dropdown.on('click','li:has(a)',function(e){e.preventDefault();that.__select($(this).index());that.$element.focus();}).on('mouseover','li:has(a)',function(e){that.$element.off('blur',blur);}).on('mouseout','li:has(a)',function(e){that.$element.on('blur',blur);});this.$element.before($dropdown).on('blur',blur).on('keydown',function(e){var $visibleItems;if(that.isShown){switch(e.keyCode){case 13:$visibleItems=that.__getVisibleItems();$visibleItems.each(function(index){if($(this).is('.active'))
that.__select($(this).index());});return false;break;case 40:$visibleItems=that.__getVisibleItems();if($visibleItems.last().is('.active'))return false;$visibleItems.each(function(index){var $this=$(this),$next=$visibleItems.eq(index+1);if($this.is('.active')){if(!$next.is('.hidden')){$this.removeClass('active');$next.addClass('active');}
return false;}});return false;case 38:$visibleItems=that.__getVisibleItems();if($visibleItems.first().is('.active'))return false;$visibleItems.each(function(index){var $this=$(this),$prev=$visibleItems.eq(index-1);if($this.is('.active')){if(!$prev.is('.hidden')){$this.removeClass('active');$prev.addClass('active');}
return false;}})
return false;}}});},__mapItem:function(dataItem){var itemHtml,that=this,_item={text:'',value:''};if(this.options.map){dataItem=this.options.map(dataItem);if(!dataItem)return false;}
if(dataItem instanceof Object){_item.text=dataItem.text||'';_item.value=dataItem.value||'';}else{_item.text=dataItem;_item.value=dataItem;}
return $('<li />',{'data-value':_item.value}).html($('<a />',{href:'#',html:_item.text})).addClass('dropdown-item');},__select:function(index){var $el=this.$element,el=$el.get(0),val=$el.val(),item=this.get(index),setCaretPos=this._keyPos+item.value.length+1;$el.val(val.slice(0,this._keyPos)+item.value+this.options.endKey+val.slice(this.__getSelection(el).start));if(el.setSelectionRange){el.setSelectionRange(setCaretPos,setCaretPos);}else if(el.createTextRange){var range=el.createTextRange();range.collapse(true);range.moveEnd('character',setCaretPos);range.moveStart('character',setCaretPos);range.select();}
$el.trigger($.extend({type:'suggest.select'},this),item);this.hide();},__getSelection:function(el){el.focus();return{start:el.selectionStart,end:el.selectionEnd};},__buildItems:function(data){var $dropdownMenu=this.$dropdown.find('.dropdown-menu');$dropdownMenu.empty();if(data&&data instanceof Array){for(var i in data){var $item=this.__mapItem(data[i]);if($item){$dropdownMenu.append($item);}}}
return $dropdownMenu.find('li:has(a)');},__lookup:function(q,$resultItems){var active=$resultItems.eq(0).addClass('active');this.$element.trigger($.extend({type:'suggest.lookup'},this),[q,$resultItems]);if($resultItems&&$resultItems.length){this.show();}else{this.hide();}},__filterData:function(q,data){var options=this.options;this.$items.addClass('hidden');this.$items.filter(function(index){if(q==='')return index<options.filter.limit;var $this=$(this),value=$this.find('a:first').text();if(!options.filter.casesensitive){value=value.toLowerCase();q=q.toLowerCase();}
return value.indexOf(q)!=-1;}).slice(0,options.filter.limit).removeClass('hidden active');return this.__getVisibleItems();},get:function(index){if(!this.$items)return;var $item=this.$items.eq(index);return{text:$item.children('a:first').text(),value:$item.attr('data-value'),index:index,$element:$item};},lookup:function(q){var options=this.options,that=this,data;var provide=function(data){if(that._keyPos!==-1){if(!that.$items){that.$items=that.__buildItems(data);}
that.__lookup(q,that.__filterData(q,data));}};if(typeof this.options.data==='function'){this.$items=undefined;data=this.options.data(q,provide);}else{data=this.options.data;}
if(data&&typeof data.promise==='function'){data.done(provide);}else if(data){provide.call(this,data);}},load:function(){this.__setListener();this.__build();},hide:function(){this.$dropdown.removeClass('open show');this.isShown=false;if(this.$items){this.$items.removeClass('active');}
this._keyPos=-1;},show:function(){var $el=this.$element,$dropdownMenu=this.$dropdown.find('.dropdown-menu'),el=$el.get(0),options=this.options,caretPos,position={top:'auto',bottom:'auto',left:'auto',right:'auto'};if(!this.isShown){this.$dropdown.addClass('open show');if(options.position!==false){caretPos=this.__getCaretPos(this._keyPos);if(typeof options.position=='string'){switch(options.position){case'bottom':position.top=$el.outerHeight()-parseFloat($dropdownMenu.css('margin-top'));position.left=0;position.right=0;break;case'top':position.top=-($dropdownMenu.outerHeight(true)+parseFloat($dropdownMenu.css('margin-top')));position.left=0;position.right=0;break;case'caret':position.top=caretPos.top-el.scrollTop;position.left=caretPos.left-el.scrollLeft;break;}}else{position=$.extend(position,typeof options.position==='function'?options.position(el,caretPos):options.position);}
$dropdownMenu.css(position);}
this.isShown=true;$el.trigger($.extend({type:'suggest.show'},this));}}};var old=$.fn.suggest;$.fn.suggest=function(arg1){var arg2=arguments[1],arg3=arguments[2];var createSuggestions=function(el,suggestions){var newData={};$.each(suggestions,function(keyChar,options){var key=keyChar.toString().charAt(0);newData[key]=new Suggest(el,key,typeof options==='object'&&options);});return newData;};return this.each(function(){var that=this,$this=$(this),data=$this.data('suggest'),suggestions={};if(typeof arg1==='string'){if(arg1.length==1){if(arg2){if(typeof arg2==='string'){if(arg1 in data&&typeof data[arg1][arg2]!=='undefined'){return data[arg1][arg2].call(data[arg1],arg3);}else{console.error(arg1+' is not a suggest');}}else{suggestions[arg1]=$.isArray(arg2)||typeof arg2==='function'?{data:arg2}:arg2;if(data&&arg1 in data){data[arg1].options=$.extend({},data[arg1].options,suggestions[arg1]);}else{data=$.extend(data,createSuggestions(this,suggestions));}
$this.data('suggest',data);}}}else{console.error('you\'re not initializing suggest properly. arg1 should have length == 1');}}else{if(!data)$this.data('suggest',createSuggestions(this,arg1));else if(data){$.each(arg1,function(key,value){if(key in data===false){suggestions[key]=value;}else{data[key].options=$.extend({},data[key].options,value);}});$this.data('suggest',$.extend(data,createSuggestions(that,suggestions)))}}});};$.fn.suggest.defaults={data:[],map:undefined,filter:{casesensitive:false,limit:5},endKey:' ',dropdownClass:'',position:'caret',onshow:function(e){},onselect:function(e,item){},onlookup:function(e,item){}}
$.fn.suggest.Constructor=Suggest;$.fn.suggest.noConflict=function(){$.fn.suggest=old;return this;}}(jQuery));