简体   繁体   English

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

[英]javascript object/array values into form inputs on click

I'm doing an autocomplete functionality which fills a datalist with options comprised of an endpoint query, which is working properly. 我正在执行自动完成功能,该功能使用由端点查询组成的选项填充数据列表,该查询正常运行。 But I have a problem in the end of my ajax call where my function is affecting only the last element of an array, as opposed to the correct one that is being clicked. 但是我在ajax调用的末尾遇到一个问题,即我的函数仅影响数组的最后一个元素,而不是单击正确的元素。 I'm trying to make sure that when the user clicks their selection in the list, it sends certain values of the object into form input fields to save. 我试图确保当用户单击列表中的选择时,它将对象的某些值发送到表单输入字段中进行保存。

Right now, when i click an option it does put the correct object values into the form, HOWEVER, they are the values that correspond to the final element in the array and not the clicked one. 现在,当我单击一个选项时,它确实将正确的对象值放入表单中,但是,它们是对应于数组中最后一个元素的值,而不是单击的那个值。

I've commented where my issue starts, but this is the whole script for reference. 我已经评论了我的问题的开始位置,但这是整个脚本供参考。 Again, the list fills correctly (though a little slow) and the click does fill out the form inputs, but the values are not corresponding to the clicked option, just the last in the array. 再次,列表正确填充(虽然有点慢),并且单击确实填充了表单输入,但是值并不对应于被单击的选项,只是数组中的最后一个。

What am I doing wrong here? 我在这里做错了什么?

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

The problem is that for each search result which is returned, you add another "input" event handler function to the "productInput" element. 问题在于,对于返回的每个搜索结果,您都将另一个“输入”事件处理函数添加到“ productInput”元素。 So if there are 5 results, you create 5 more event handlers. 因此,如果有5个结果,则可以再创建5个事件处理程序。 Then when something is input into that box, all 5 handlers (plus the original one, so 6) will execute in sequence. 然后,当在该框中输入内容时,所有5个处理程序(加上原始处理程序,所以是6个)将依次执行。 Since each time it overwrites the same textboxes, hence you only ever see the the last value. 由于每次它都会覆盖相同的文本框,因此您只会看到最后一个值。 I'm pretty sure that's not even close to what you wanted. 我敢肯定,这与您想要的还差得很远。

You're adding options to the "returnedProducts" select list, and when the user selects an option you want some data to go into a form, is that right? 您正在向“ returnedProducts”选择列表中添加选项,并且当用户选择一个选项时,您希望一些数据进入表单,对吗? If so, it would make more sense to handle the "change" event of the select list (and handle it once outside of your "success" function!!), and set data attributes on the option for the extra values. 如果是这样,则处理选择列表的“更改”事件(并在“成功”功能之外处理它一次!!),然后在选项上设置数据属性以获取额外的值会更有意义。 When the change event runs, retrieve the data attributes from the currently selected option and use those to populate your form. 运行change事件时,请从当前选定的选项中检索数据属性,然后使用这些属性来填充表单。

Here's the general idea: 这是一般的想法:

In the loop through your results: 在结果循环中:

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>");
}

Then separately (outside your $('#productInput').on('input', function(){ block entirely): 然后分别(在$('#productInput').on('input', function(){完全块之外):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM