|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function ($) { |
|
|
|
|
|
$.fn.autocomplete = function(settings) |
|
|
{ |
|
|
return this.each( function() |
|
|
{ |
|
|
var textInput = $(this); |
|
|
textInput.attr("name", textInput.attr("name") + "_text"); |
|
|
|
|
|
|
|
|
var hiddenInput = $('<input type=hidden name="' + textInput.attr("name") + '"/>'); |
|
|
hiddenInput.val( textInput.val() ); |
|
|
textInput.after(hiddenInput); |
|
|
|
|
|
var valueInput = $(this).next(); |
|
|
|
|
|
valueInput.after('<ul class="autocomplete"></ul>'); |
|
|
var list = valueInput.next(); |
|
|
|
|
|
var oldText = ''; |
|
|
var typingTimeout; |
|
|
var size = 0; |
|
|
var selected = -1; |
|
|
|
|
|
settings = $.extend( |
|
|
{ |
|
|
minChars : 1, |
|
|
timeout: 1000, |
|
|
after : null, |
|
|
before : null, |
|
|
validSelection : true, |
|
|
url : this.dataset.url, |
|
|
parameters : {'inputName' : valueInput.attr('name'), 'inputId' : textInput.attr('id')} |
|
|
} , settings); |
|
|
|
|
|
function getData(text) |
|
|
{ |
|
|
window.clearInterval(typingTimeout); |
|
|
if (text != oldText && (settings.minChars != null && text.length >= settings.minChars)) |
|
|
{ |
|
|
clear(); |
|
|
if (settings.before == "function") |
|
|
{ |
|
|
settings.before(textInput,text); |
|
|
} |
|
|
textInput.addClass('autocomplete-loading'); |
|
|
settings.parameters.text = text; |
|
|
|
|
|
$.getJSON(settings.url, settings.parameters, function(data) |
|
|
{ |
|
|
var items = ''; |
|
|
if (data) |
|
|
{ |
|
|
size = 0; |
|
|
|
|
|
for ( key in data ) |
|
|
{ |
|
|
items += '<li value="' + key + '">' + data[key].replace(new RegExp("(" + text + ")","i"),"<strong>$1</strong>") + '</li>'; |
|
|
size++; |
|
|
} |
|
|
|
|
|
list.css({ width: Math.max(100, textInput.outerWidth())}).html(items); |
|
|
|
|
|
list.show().children(). |
|
|
hover(function() { $(this).addClass("selected").siblings().removeClass("selected");}, function() { $(this).removeClass("selected") } ). |
|
|
click(function () { value = $(this).attr('value'); text = $(this).text();valueInput.val( value ); textInput.val( text ); textInput.trigger("autocomplete.change", [ value, text ]);clear(); }); |
|
|
|
|
|
if (settings.after == "function") |
|
|
{ |
|
|
settings.after(textInput,text); |
|
|
} |
|
|
|
|
|
} |
|
|
textInput.removeClass('autocomplete-loading'); |
|
|
}); |
|
|
oldText = text; |
|
|
} |
|
|
} |
|
|
|
|
|
function clear() |
|
|
{ |
|
|
list.hide(); |
|
|
size = 0; |
|
|
selected = -1; |
|
|
} |
|
|
|
|
|
textInput.keydown(function(e) |
|
|
{ |
|
|
window.clearInterval(typingTimeout); |
|
|
if(e.which == 27) |
|
|
{ |
|
|
clear(); |
|
|
} else if (e.which == 46 || e.which == 8) |
|
|
{ |
|
|
clear(); |
|
|
|
|
|
if (settings.validSelection) valueInput.val(''); |
|
|
} |
|
|
else if(e.which == 13) |
|
|
{ |
|
|
if ( list.css("display") == "none") |
|
|
{ |
|
|
getData(textInput.val()); |
|
|
} else |
|
|
{ |
|
|
clear(); |
|
|
} |
|
|
e.preventDefault(); |
|
|
return false; |
|
|
} |
|
|
else if(e.which == 40 || e.which == 9 || e.which == 38) |
|
|
{ |
|
|
switch(e.which) |
|
|
{ |
|
|
case 40: |
|
|
case 9: |
|
|
selected = (selected >= size - 1) ? 0 : selected + 1; break; |
|
|
case 38: |
|
|
selected = (selected < 0) ? size -1 : selected - 1; break; |
|
|
default: break; |
|
|
} |
|
|
|
|
|
textInput.val( list.children().removeClass('selected').eq(selected).addClass('selected').text() ); |
|
|
valueInput.val( list.children().eq(selected).attr('value') ); |
|
|
} else |
|
|
{ |
|
|
|
|
|
if (settings.validSelection) valueInput.val(''); |
|
|
typingTimeout = window.setTimeout(function() { getData(textInput.val()) },settings.timeout); |
|
|
} |
|
|
}); |
|
|
}); |
|
|
}; |
|
|
|
|
|
$.autocompleteList = function(el, settings) |
|
|
{ |
|
|
var autocomplete = $(el).autocomplete(settings); |
|
|
|
|
|
var list = $('<div class="autocomplete-list card border-top-0"></div>'); |
|
|
|
|
|
var autocomplete_hidden = autocomplete.next(); |
|
|
|
|
|
var name = autocomplete_hidden.attr("name"); |
|
|
|
|
|
autocomplete_hidden.next().after(list); |
|
|
var autocomplete_list_hidden = $('<input type=hidden name="' + name + '_list" value="' + autocomplete_hidden.val() + '"/>'); |
|
|
|
|
|
list.after(autocomplete_list_hidden); |
|
|
|
|
|
function addItem(value, text) |
|
|
{ |
|
|
list.append($('<div class=""><button type="button" class="remove-btn close text-muted" aria-label="Close"><div aria-hidden="true">×</div></button><span>' + text + '</span>\ |
|
|
<input name="list[]" value="' + value + '" type="hidden">\ |
|
|
</div>')); |
|
|
autocomplete.val(""); |
|
|
}; |
|
|
|
|
|
function setList() |
|
|
{ |
|
|
values = {}; |
|
|
$('input[name="list[]"]', list).each(function(i, el) |
|
|
{ |
|
|
values[this.value] = $("span", this.parentNode).text(); |
|
|
}); |
|
|
|
|
|
autocomplete_list_hidden.val( JSON.stringify(values) ); |
|
|
}; |
|
|
|
|
|
|
|
|
function setValue(value) { |
|
|
if (value == "" || value == undefined) return false; |
|
|
|
|
|
values = JSON.parse(value); |
|
|
|
|
|
for (key in values) |
|
|
{ |
|
|
addItem(key, values[key]); |
|
|
} |
|
|
|
|
|
setList(); |
|
|
}; |
|
|
|
|
|
autocomplete.on("autocomplete.change", function(event, value, text) { |
|
|
var autolist = $(this).data("autocompleteList"); |
|
|
|
|
|
autolist.addItem(value, text); |
|
|
autolist.setList(); |
|
|
autolist.trigger("autocompletelist.change", [ JSON.stringify(values) ]); |
|
|
}); |
|
|
|
|
|
list.on("click", ".remove-btn", function (event, value, text) |
|
|
{ |
|
|
this.parentNode.remove(); |
|
|
setList(); |
|
|
autocomplete.trigger("autocompletelist.change", [ JSON.stringify(values) ]); |
|
|
|
|
|
event.preventDefault(); |
|
|
return false; |
|
|
}); |
|
|
|
|
|
autocomplete.setValue = setValue; |
|
|
autocomplete.addItem = addItem; |
|
|
autocomplete.setList = setList; |
|
|
|
|
|
$.data(el, "autocompleteList", autocomplete); |
|
|
|
|
|
return autocomplete; |
|
|
} |
|
|
|
|
|
$.fn.autocompleteList = function(options) |
|
|
{ |
|
|
return this.each( function() |
|
|
{ |
|
|
$.autocompleteList(this, options); |
|
|
}); |
|
|
}; |
|
|
|
|
|
$.tagsInput = function(el, settings) |
|
|
{ |
|
|
var autocomplete = $(el).autocomplete(settings); |
|
|
|
|
|
var list = autocomplete.parent(); |
|
|
|
|
|
var autocomplete_hidden = autocomplete.next(); |
|
|
|
|
|
var name = autocomplete_hidden.attr("name"); |
|
|
|
|
|
autocomplete_hidden.next(); |
|
|
var autocomplete_list_hidden = $('<input type=hidden name="' + name + '_list" value="' + autocomplete_hidden.val() + '"/>'); |
|
|
|
|
|
list.append(autocomplete_list_hidden); |
|
|
|
|
|
function addItem(value, text) |
|
|
{ |
|
|
autocomplete.before($('<div class="badge border m-1"><a href="#" class="btn-link"><i class="la la-close"></i></a> <span>' + text + '</span>\ |
|
|
<input name="list[]" value="' + value + '" type="hidden">\ |
|
|
</div>')); |
|
|
autocomplete.val(""); |
|
|
}; |
|
|
|
|
|
function setList() |
|
|
{ |
|
|
var values = {}; |
|
|
|
|
|
$('input[name="list[]"]', list).each(function(i, el) |
|
|
{ |
|
|
values[this.value] = $("span", this.parentNode).text(); |
|
|
}); |
|
|
|
|
|
|
|
|
values = JSON.stringify(values); |
|
|
autocomplete_list_hidden.val( values ); |
|
|
return values; |
|
|
}; |
|
|
|
|
|
|
|
|
function setValue(value) { |
|
|
if (value == "" || value == undefined) return false; |
|
|
values = JSON.parse(value); |
|
|
|
|
|
for (key in values) |
|
|
{ |
|
|
addItem(key, values[key]); |
|
|
} |
|
|
|
|
|
setList(); |
|
|
}; |
|
|
|
|
|
autocomplete.on("autocomplete.change", function(event, value, text) { |
|
|
var autolist = $(this).data("tagsInput"); |
|
|
|
|
|
autolist.addItem(value, text); |
|
|
var values = autolist.setList(); |
|
|
autolist.trigger("tagsinput.change", [ values ]); |
|
|
}); |
|
|
|
|
|
list.on("click", ".remove-btn", function (event, value, text) |
|
|
{ |
|
|
this.parentNode.remove(); |
|
|
var values = autolist.setList(); |
|
|
autocomplete.trigger("tagsinput.change", [ values ]); |
|
|
|
|
|
event.preventDefault(); |
|
|
return false; |
|
|
}); |
|
|
|
|
|
autocomplete.setValue = setValue; |
|
|
autocomplete.addItem = addItem; |
|
|
autocomplete.setList = setList; |
|
|
|
|
|
$.data(el, "tagsInput", autocomplete); |
|
|
|
|
|
return autocomplete; |
|
|
} |
|
|
|
|
|
$.fn.tagsInput = function(options) |
|
|
{ |
|
|
return this.each( function() |
|
|
{ |
|
|
$.tagsInput(this, options); |
|
|
}); |
|
|
}; |
|
|
|
|
|
})(jQuery); |
|
|
|