简体   繁体   中英

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. 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. So if there are 5 results, you create 5 more event handlers. Then when something is input into that box, all 5 handlers (plus the original one, so 6) will execute in sequence. 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? 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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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