Как получить jQuery -UI автозаполнение для запуска при нажатии клавиши - PullRequest
2 голосов
/ 14 июля 2020

Я не совсем уверен, возможно ли то, что я хочу. Но в настоящее время у меня есть код, который заполняет список автозаполнения. Источник обрабатывается ajax вызовом веб-API, который возвращает набор элементов из базы данных (см. Код ниже).

$(".ItemSearch").on('keypress', function (event, ui) {
    var disabled = true;
    if (event.which === 13) {
        disabled = false;
    }
});

function BindItemNumberSearch(hostItemForm) {        
    if ($(".ItemSearch", hostItemForm).autocomplete({}).data("ui-autocomplete")) {
        $(".ItemSearch", hostItemForm).unbind("autocomplete");
        $(".ItemSearch", hostItemForm).autocomplete({
            close: function () {
                // some logic
            },
            response: function (event, ui) {
                // some logic if the item is empty
            },
            source: function (request, response) {
                // return if the search box is empty or is disabled
                if (request.term.trim().length <= 0 || disabled) {
                    return;
                }

                $.ajax({ 
                    // some ajax call
                });
            },
            delay: 500,
            focus: function (event, ui) {
                return false;
            },
            select: function (event, ui) {
                // return false if no item is selected
                if (ui.item.id != null) {
                    return false;
                }

                // some logic to select the item
            }
        }).data("ui-autocomplete")._renderItem = RenderSearchResultItem;
    }           
}

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

Итак, мы хотели бы добавить триггер при нажатии клавиши (например, клавиши ввода), чтобы начать поиск. Я нашел этот ответ , и, похоже, jQuery -ui его не поддерживает. Пробовал разные попытки, включенная последняя. Однако я не могу заставить его работать.

1 Ответ

2 голосов
/ 23 июля 2020

Вы можете установить флаг, когда ваш autocomplete должен начать поиск.

// this will be the flag if autocomplete should begin searching
// should become true when [Enter] key is pressed & input field is not empty
window.BeginSearch = false;

После этого прикрепите событие DOM к вашему autocomplete элементу, который обнаружит Enter ключ

$(document).on("keydown", "#tags", function(e) {
    ...
})

Программно проинструктировать autocomplete начать поиск по мере необходимости при нажатии клавиши Enter

$("#tags").autocomplete("search");

Внутри обратного вызова source, это когда появится переменная flag пригодится. Используйте это, чтобы определить, была ли нажата клавиша Enter, и поэтому для BeginSearch установлено значение true

$("#tags").autocomplete({
    source: function (request, response) {
        if (window.BeginSearch != true || request.term.trim().length <= 0) {
            response([]);
            window.BeginSearch = false; // reset the flag since searching is finished
            return;
        } else if (window.BeginSearch == true) {
            sample_async_function(request).then(function (return_data) {
                response(return_data);
                window.BeginSearch = false; // reset the flag since searching is finished
            });
        }
    },
    delay: 0 // no need for delay, as you can see
});

Пример демонстрации:

// this event will be responsible for tracking [Enter] key press
$(document).on("keydown", "#tags", function(e) {

  // additional checks so that autocomplete search won't occur if conditions are not met
  if (e.key == "Enter" && $("#tags").val().trim().length > 0 && $(".sample-loader:visible").length < 1) {
    window.BeginSearch = true;
    $("#tags").autocomplete("search");
  }
})

$(document).ready(function() {

  // this will be the flag if autocomplete should begin searching
  // should become true when [Enter] key is pressed & input field is not empty
  window.BeginSearch = false;

  $("#tags").autocomplete({
    source: function(request, response) {
      if (window.BeginSearch != true || request.term.trim().length <= 0) {
        response([]);
        window.BeginSearch = false; // reset the flag since searching is finished
        return;
      } else if (window.BeginSearch == true) {
        sample_async_function(request).then(function(return_data) {
          response(return_data);
          window.BeginSearch = false; // reset the flag since searching is finished
        });
      }
    },
    delay: 0 // no need for delay, as you can see
  });

});

// sample asynchronous function. mimics fetching data from server side (e.g., ajax) 
function sample_async_function(some_passed_string) {
  $(".sample-loader").show();
  return new Promise(resolve => setTimeout(() => {
    $(".sample-loader").hide();
    resolve(
      [
        "ActionScript",
        "AppleScript",
        "Asp",
        "BASIC",
        "C",
        "C++",
        "Clojure",
        "COBOL",
        "ColdFusion",
        "Erlang",
        "Fortran",
        "Groovy",
        "Haskell",
        "Java",
        "JavaScript",
        "Lisp",
        "Perl",
        "PHP",
        "Python",
        "Ruby",
        "Scala",
        "Scheme"
      ].filter((val, index) => {
        if (val.toLowerCase().includes(some_passed_string.term.toLowerCase())) {
          return val;
        }
      })
    );
  }, 500)); // arbitrary value. sample speed of the API XHR in unit milliseconds
}
.sample-loader {
  display: none;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1053;
  background: #000000dd;
  color: white;
  font-size: 20px;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>

<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>

<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">

<div class="ui-widget">
  <label for="tags">AutoComplete: </label>
  <input id="tags">
</div>

<div class="sample-loader">Loading...</div>

С точки зрения UX вы захотите выяснить, как временно отключить взаимодействие с элементом во время поиска. В этом примере я использовал простой экран «загрузки».

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