javascript对象/数组值在单击时转换为表单输入

时间:2018-08-29 17:47:44

标签: javascript html json ajax dom-events

我正在执行自动完成功能,该功能使用由端点查询组成的选项填充数据列表,该查询正常工作。但是我在ajax调用的末尾遇到一个问题,即我的函数仅影响数组的最后一个元素,而不是单击正确的元素。我试图确保当用户单击列表中的选择时,它将对象的某些值发送到表单输入字段进行保存。

现在,当我单击一个选项时,它确实将正确的对象值放入表单中,但是,它们是对应于数组中最后一个元素的值,而不是单击的那个值。

我已经评论了我的问题的开始位置,但这是整个脚本供参考。再次,列表正确填充(虽然有点慢),并且单击确实填充了表单输入,但是值并不对应于clicked选项,只是数组中的最后一个。

我在这里做什么错了?

<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>

1 个答案:

答案 0 :(得分:1)

问题在于,对于返回的每个搜索结果,您都将另一个“ 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(){块之外):

$("#returnedProducts").change(function() {
  var selectedOption = $(this).find("option:selected");
  $("#grpName").val(selectedOption.data("grpName"));
  $("#grpNum").val(selectedOption.data("grpNum"));
});