У вас проблемы с вашим кодом. Во-первых, вам не нужно использовать каждую jQuery
функцию; в настоящее время браузеры поддерживают и поддерживают filter
вместо grep
, а для массивов по умолчанию используется метод map
. Кроме того, поскольку у вас есть простой текст, вам не нужно экранировать регулярное выражение, и, таким образом, вы можете избежать полизаполнения для функции RegExp.escape
. Метод jquery.grep
, как и filter
, ожидает логическое возвращаемое значение, а не строку, которую вы возвращаете. jQuery UI autocomplete
source
дополнительная функция response
может возвращать массив строк ([ "Choice1", "Choice2" ]
) или массив объектов со свойствами label
и value
([ { label: "Choice1", value: "value1" }, ... ]
) ).
Функция : третий вариант, обратный вызов, обеспечивает наибольшую гибкость и может использоваться для подключения любого источника данных к автозаполнению, включая JSONP. Обратный вызов получает два аргумента:
- A
request
объект с единственным свойством term
, которое ссылается на значение, которое в настоящее время находится в текстовом вводе. Например, если пользователь вводит "new yo"
в поле города, термин автозаполнения будет равен "new yo"
. - A
response
обратного вызова, который ожидает один аргумент: данные, которые предлагаются пользователю. Эти данные должны быть отфильтрованы на основе предоставленного термина и могут быть в любом из форматов, описанных выше для простых локальных данных. Это важно при предоставлении пользовательского обратного вызова источника для обработки ошибок во время запроса. Вы должны всегда вызывать обратный вызов response
, даже если вы столкнулись с ошибкой. Это гарантирует, что виджет всегда имеет правильное состояние.
Для рефакторинга вашего кода я буду использовать vanilla JS filter
и map
.
Пожалуйста, запустите ниже фрагмент, чтобы проверить его работу:
function setMembers(members) {
$('#member-search').autocomplete({
source: function (request, response) {
let regex = new RegExp(request.term, 'i');
let recs = members
// Filter members using request term
.filter(({ first, last, id }) => {
let term = `${first} ${last}`;
return regex.test(term);
})
// Map to the response supported object
.map(({ first, last, id }) => ({
label: `${first} ${last}`,
value: id
}));
console.log('recs', recs);
response(recs);
},
select: function (event, ui) {
event.preventDefault();
$("#member-search").val(ui.item.label);
$("#selection").text(`"${ui.item.label}" (ID: ${ui.item.value})`);
}
});
}
setMembers([{
first: 'Giorgos', last: 'Mihas', id: 1
}, {
first: 'Mike', last: 'Nakas', id: 2
}, {
first: 'Angela', last: 'Fox', id: 3
}, {
first: 'Maria', last: 'Pappou', id: 4
}, {
first: 'Vaggelis', last: 'Maggas', id: 5
}, {
first: 'Nikos', last: 'Stergiou', id: 6
}, {
first: 'Elvis', last: 'Presley', id: 7
}
]);
h3 { font-family: monospace; }
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<div class="ui-widget">
<label for="tags">Members: </label>
<input id="member-search" class="member-search">
<h3>Selection: <span id="selection"></span></h3>
</div>