Индексирование объекта в цикле for, сохранение информации по клику - PullRequest
0 голосов
/ 29 августа 2018

У меня есть javascript, включая вызов ajax, который принимает пустой ввод данных и использует то, что пользователь вводит для запроса объекта json. Он успешно возвращает соответствующие объекты и отображает их в списке данных.

Это все работает нормально, но теперь я пытаюсь убедиться, что, когда они нажимают на опцию списка, я получаю определенные поля ТОЛЬКО от этой выбранной опции, чтобы я мог в конечном итоге отправить их в форму.

Когда нажата опция, я получаю нужное значение в своей консоли (console.log(searchResult[i]._source.frm.grp.Name)), но оно дает мне каждый из предыдущих объектов, где я просто хочу получить данные от одного нажатого.

Я думаю, это может быть связано с тем фактом, что я выполняю эту функцию в цикле for или что-то связано с моим индексированием с использованием [i], но я не могу точно определить это.

Как сделать так, чтобы это влияло только на значения индексируемого объекта, по которому щелкают?

<script type="text/javascript">
//input event handler
$('#productInput').on('input', function(){
    if($(this).val() === ''){
       return;
    }else{

       const searchResult = $(this).val(); 

       $.ajax({ url: '/account/autocomplete', 
                data: {
                    search_result:searchResult
                },
                "_token": "{{ csrf_token() }}",
                type: "POST", 
                success: function(response){
                    $('#returnedProducts').empty();
                    let searchResult = response.hits.hits;

                    for(let i = 0; i < searchResult.length; i++) {
                        $("#returnedProducts").append("<option value=" + searchResult[i]._source.category + ">" + searchResult[i]._source.category + "</option>");

                        //Issue starts here//
                        $("#productInput").on('input', function(){
                            var val = this.val = this.value;
                            if($('#returnedProducts option').filter(function(){
                                return this.value === val;
                            }).length){
                                document.getElementById("grpName").value = searchResult[i]._source.frm.grp.grp_name;
                                document.getElementById("grpNum").value = searchResult[i]._source.frm.grp.grp_code; 
                            }
                        })   
                    }
                }
            });
    }

});
</script>

<form>
<input id="grpName">
<input id="grpNum">
</form>

1 Ответ

0 голосов
/ 29 августа 2018

Я не уверен в этом, но вот что я понимаю:

  • весь ваш код здесь уже обернут в слушатель на событии 'input', не должно быть необходимости добавлять другого слушателя, особенно для работы с тем же свойством (.val() или .value, кажется, ссылаются на тоже самое, да?)
  • у вас есть 3 случая: один, когда #productInput пуст, другой, когда это частичное совпадение (предложения), и вы добавляете один, когда это идеальное совпадение
  • чтобы "экспортировать" этот код на этот верхний уровень, вам понадобится более высокий доступ к тому, что у вас есть: searchResult (не const, а let)
  • для той же цели у вас будет способ связать <option> с элементом в вашем searchResult (например, добавить произвольный параметр srindex, содержащий индекс элемента в searchResult)

В итоге ваш верхний if блок должен выглядеть следующим образом:

let _this = $(this);
let foundOption;
if (_this.val() === '') {
  return;
} else if (foundOption = $('#returnedProducts option').find((option) => {
  return option.srindex === _this.val();
})) {
  console.log(searchResult[foundOption.srindex].blahblah);
} else {
  $.ajax(...);
}

Примечание:

  • с использованием .find(), как правило, быстрее и не может быть медленнее, чем .filter(), поскольку первый останавливается на первом соответствующем элементе, тогда как последний в любом случае обходит весь массив (так как он возвращает all соответствующие элементы, и здесь у вас есть ноль или один , который будет найден) пост-обновление спойлера: мы не говорим о Array.prototype.find, мы говорим о jQuery.find, но тссс Я пока не знаю!
  • Я не уверен, option.srindex работает как есть, может быть это что-то вроде option.getAttribute('srindex') пост-обновление спойлера: он не работает как есть

ОБНОВЛЕНИЕ (решение после долгого чата и множества попыток)

$('#productInput').on('input', function () {
  let _this = $(this);
  let foundOption;
  let searchResult = [];
  let optSelector = `option[value='${_this.val()}']`;
  if (_this.val() === '') {
    return;
  } else if ((foundOption = $('#returnedProducts').find(optSelector)).length) {
    $("#grpName").val(searchResult[$(foundOption).attr('srindex')]._source.frm.grp.grp_name);
    $("#grpNum").val(searchResult[$(foundOption).attr('srindex')]._source.frm.grp.grp_code);
  } else {
    $.ajax({ url: '/account/autocomplete', 
      data: {
        search_result: _this.val()
      },
      "_token": "{{ csrf_token() }}",
      type: "POST", 
      success: function (response) {
        $("#returnedProducts").empty();
        for(let i = 0; i < response.hits.hits.length; i++) {
          $("#returnedProducts").append(
            `<option srindex="${i}" value="${searchResult[i].cat}" />"`
          );
        }
      });
    });
  }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...