我正在执行自动完成功能,该功能使用由端点查询组成的选项填充数据列表,该功能运行正常。但是我在 ajax 调用结束时遇到了一个问题,我的函数仅影响数组的最后一个元素,而不是正在单击的正确元素。我试图确保当用户单击列表中的选择时,它将对象的某些值发送到表单输入字段中进行保存。
现在,当我单击一个选项时,它确实会将正确的对象值放入表单中,但是,它们是与数组中的最终元素相对应的值,而不是与单击的元素相对应的值。
我已经评论了我的问题从哪里开始,但这是供引用的整个脚本。同样,列表填充正确(虽然有点慢),并且单击确实填写了表单输入,但值与单击的选项不对应,仅对应于数组中的最后一个选项。
我在这里做错了什么?
<script type="text/javascript">
//If user types, send their input in ajax POST on each keystroke
$('#productInput').on('input', function(){
if($(this).val() === ''){
return;
}else{
//their input is searchResult
const searchResult = $(this).val();
$.ajax({ //url
data: {
search_result:searchResult
},
type: "POST",
success: function(response){
//empty out old responses
$('#returnedProducts').empty();
//this starts my index
let searchResult = response.hits.hits;
for(let i = 0; i < searchResult.length; i++) {
//this puts matches into the datalist option, which works
$("#returnedProducts").append("<option value=" + searchResult[i]._source.category + ">" + searchResult[i]._source.category + "</option>");
/*This block is my issue*/
$("#productInput").on('input', function(){
var val = this.val = this.value;
if($('#returnedProducts option').filter(function(){
return this.value === val;
}).length){
//These elements do fill, but the values correspond to only the last array item, not the clicked one
document.getElementById("grpName").value = searchResult[i]._source.frm.grp.grp_name;
document.getElementById("grpNum").value = searchResult[i]._source.frm.grp.grp_code;
}
})
/*end of problem block*/
}
}
});
}
});
</script>
最佳答案
问题是,对于返回的每个搜索结果,您都将另一个“input”事件处理函数添加到“productInput”元素中。因此,如果有 5 个结果,您将再创建 5 个事件处理程序。然后,当向该框中输入某些内容时,所有 5 个处理程序(加上原始处理程序,即 6 个)将按顺序执行。由于每次它都会覆盖相同的文本框,因此您只能看到最后一个值。我很确定这与您想要的还相差甚远。
您正在将选项添加到“returnedProducts”选择列表中,当用户选择某个选项时,您希望一些数据进入表单,对吗?如果是这样,处理选择列表的“更改”事件(并在“成功”函数之外处理一次!!)并为额外值的选项设置数据属性会更有意义。当更改事件运行时,从当前选定的选项中检索数据属性并使用这些属性填充您的表单。
总体思路如下:
在结果循环中:
for(let i = 0; i < searchResult.length; i++) {
//this puts matches into the select list option
$("#returnedProducts").append("<option value='" + searchResult[i]._source.category + "' data-grpName='" + searchResult[i]._source.frm.grp.grp_name + "' data-grpNum='" + searchResult[i]._source.frm.grp.grp_code + "'>" + searchResult[i]._source.category + "</option>");
}
然后分别(完全在 $('#productInput').on('input', function(){
block 之外):
$("#returnedProducts").change(function() {
var selectedOption = $(this).find("option:selected");
$("#grpName").val(selectedOption.data("grpName"));
$("#grpNum").val(selectedOption.data("grpNum"));
});
关于单击时将 JavaScript 对象/数组值转换为表单输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52083429/