Я написал базовую функцию автозаполнения, которая принимает массив данных и отображает его под строкой поиска. Когда пользователь вводит один символ, все работает нормально - в списке отображаются совпадения, а щелчок по элементу в списке закрывает список и добавляет выбранный элемент в строку поиска. Однако, если кто-то хотел изменить / уточнить значение поиска с помощью более чем одного символа, я заметил, что что-то происходит:
1. Функция будет рисовать дополнительные копии (с новыми значениями) списка результатов <ul>
вместо перерисовки исходного списка.
2. Нажатие на цель <li>
в списке не закрывает список.
Функция вызывается всякий раз, когда обнаруживается keyup
. filterAutocomplete
принимает ввод соответствующей строки поиска и получает массив элементов для передачи моей основной функции doAutocomplete
.
$(document).ready(function(){
$("#projectIDFrom").on('keyup', (function(){
var val = $(this).val().trim();
val = val.replace(/\s+/g, '');
var id = $("#projectIDFrom").attr('id');
filterAutoComplete(val, id);
}
));
})
Ниже представлена основная функция.
function doAutocomplete(list, storeInput){
var query = $("#"+storeInput).val()
var drew = false;
//assign unique ID to results (handles multiple search bars on a page)
var resID = storeInput+ "Res";
//Build the box only if there's a value greater than 0
//in the target search bar
if($("#"+storeInput).val().length > 0){
//Case insensitive search for our array
var results = $.grep(list, function(item){
return item.search(RegExp(query, "i")) != -1;
});
//First search (no pre-existing list)
if(drew == false){
//Create list for results
$("#"+storeInput).after("<ul class='autoResult' id='"+ resID +"'></ul>");
//Prevent redrawing/binding of list
drew = true;
//Bind click event to list elements in results
$("#"+resID).on("click", "li", function(){
$("#"+storeInput).val($(this).text());
$("#"+resID).remove();
});
}
//remove if the value in search bar changes
//redraw occurs on next keypress
else if (drew == true){
$("#"+resID).remove();
}
//Add matching results to the list
for(var i = 0; i < results.length; i++){
$("#"+resID).append("<li>" + results[i] + "</li>");
}
}
//Handle backspace/delete so results don't remain
else if($("#"+storeInput).val().length < 1){
$("#"+resID).remove();
}
}
Как мне избежать рисования нескольких копий списка результатов и заставить функцию просто рисовать / перерисовывать один список с новыми результатами?
Ссылка на JSFiddle, которая воспроизводит проблемы, описанные выше.
Любая помощь приветствуется.