Автозаполнение JQuery - Как управлять списком на основе соседних элементов DOM без использования идентификатора? - PullRequest
3 голосов
/ 09 сентября 2011

Это в JQuery с использованием версии автозаполнения JQuery-UI

Я в каком-то крайнем случае. Я работаю внутри формы, которая должна быть неограниченно клонируемой, поэтому я не могу использовать теги id для уникальной идентификации, и я не могу просто искать сверху вниз, чтобы найти что-то похожее на элементы DOM, с которыми я работаю - Я должен использовать относительные функции (.closest, .find и т. Д.). Внутри этой формы у меня есть настройка с полем страны, полем состояния и полем местоположения, и поле местоположения должно быть автозаполнением, передаваемым по ссылке, где оно передает текущее значение полей страны и штата по ссылке, идущей вверх для фильтрации на стороне сервера. Я бы хотел бы , чтобы это было примерно так:

function locPrep(locNode) {
  $locNode.autocomplete({
    source: function (request, response) {
      $locDiv = $(this).closest("div.locWrapper");
      $stateNode = $locDiv.find("input.state");
      $countryNode = $locDiv.find("input.country");
      $.post("/FormHost/AutocompleteLocList",
        {state:$stateNode.val(), country:$countryNode.val(), term:request.term },
        function (data) {
          response(data);
        }
      );
    }
  });
}

... за исключением того, что это не работает, потому что $ (this) для исходной функции не является locNode, и я не могу просто объявить его снаружи и использовать внутри, потому что locPrep вызывается неоднократно, один раз для каждого автозаполнение в форме. Если я попробую это сделать, то, что Jquery сделает все глобальным, все автозаполнения в форме будут ссылаться на поля страны и штата для последнего. Я попытался использовать javascript vars, чтобы обойти проблемы с областями видимости, и это получилось странным. Кто-нибудь может помочь?


Редактировать: благодаря любезной помощи Дмитрия Наумова, я смог собрать функциональное решение (хотя я все еще не совсем уверен, , почему оно работает, учитывая некоторые вещи, которые я пытался, которые делали. не). Я включаю работающий код в надежде, что он может помочь кому-то еще позже. (Я, конечно, многому научился, отвечая на вопросы других.)

Сначала я прошел и изменил каждый экземпляр, где вызывал функцию из "locPrep (foo);" в "новый locPrep (foo);" Я также изменил его, чтобы взять locDiv, а не locNode. Затем я изменил код на следующий (хотя это несколько упрощенная версия).

function locPrep(locDiv) {
  $locNode = $(locDiv).find("input.locationAutofill")
  $locNode.autocomplete({
    source: function (request, response) {
      var stateVar = $(locDiv).find("input.state").val();
      var countryVar = $(locDiv).find("input.country").val();
      $.post("/FormHost/AutocompleteLocList",
        {state:stateVar, country:countryVar, term:request.term },
        function (data) {
          response(data);
        }
      );
    }
  });
}

Я не совсем уверен, какие биты этого были необходимы, но как группа они обрабатывают код, используя достаточно узкую область видимости для решения проблемы.

1 Ответ

2 голосов
/ 09 сентября 2011

Сохраните $ (this) в переменную и передайте ее в качестве параметра (locNode) вашей функции (во время инициализации).Кроме того, вместо $ (this) вы можете передать ссылку на элемент контейнера, чтобы каждый из ваших инициализированных автозаполнений знал своего родителя.

Обновление: Следующее может быть не 100%правильно с точки зрения автозаполнения инициализации, но это хорошая иллюстрация, как создать 2 уникальных экземпляра locPrep в <div id="myDiv1"> и <div id="myDiv2">

myContainer1 = $('#myDiv1');
myContainer2 = $('#myDiv2');

myAutocompleteInstance1 = new locPrep(myContainer1);
myAutocompleteInstance2 = new locPrep(myContainer2);

Update2 : как передать это

function locPrep(locNode, currentThis) {

 /// use currentThis instead of $(this) inside locPrep function

  $locNode.autocomplete({
    source: function (request, response) {
      $locDiv = currentThis.closest("div.locWrapper");
      $stateNode = $locDiv.find("input.state");
      $countryNode = $locDiv.find("input.country");
      $.post("/FormHost/AutocompleteLocList",
        {state:$stateNode.val(), country:$countryNode.val(), term:request.term },
        function (data) {
          response(data);
        }
      );
    }
  });
}

init:

myAutocompleteInstance1 = new locPrep(myContainer1, $(this));

new убедится, что значениеcurrentThis уникален в каждом экземпляре locPrep

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...