如何仅在多个自动完成文本框中的前 2 个字符之后才开始自动完成?

Posted

技术标签:

【中文标题】如何仅在多个自动完成文本框中的前 2 个字符之后才开始自动完成?【英文标题】:How to start autocomplete only after the first 2 first characters in a multiple autocomplete textbox? 【发布时间】:2021-07-02 07:01:36 【问题描述】:

我正在尝试使 JQuery UI 多次自动完成以与返回简单 json 字符串列表的 asp.net 核心 webapi 服务一起使用。

我确定代码看起来很糟糕。我试图弄清楚如何确保在我在文本框中输入 2 个字符后开始查询响应以避免从服务中返回所有内容。

请参阅下面的服务器和客户端代码:

查看:

@
    Layout = null;

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>jQuery UI Autocomplete - Multiple values</title>
    <link rel="stylesheet"
          href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
    <link rel="stylesheet" href="https://jqueryui.com/resources/demos/style.css" />
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <script>
        $(function () 
            var availableTags = [];

            $.ajax(
                type: "GET",
                url: "/api/customer",
                dataType: "json",
                success: function (response) 
                    console.table(response);
                    availableTags = response;
                
            );

            //var availableTags = [
            //    "ActionScript",
            //    "AppleScript",
            //    "Asp",
            //    "BASIC",
            //    "C",
            //    "C++",
            //    "Clojure",
            //    "COBOL",
            //    "ColdFusion",
            //    "Erlang",
            //    "Fortran",
            //    "Groovy",
            //    "Haskell",
            //    "Java",
            //    "javascript",
            //    "Lisp",
            //    "Perl",
            //    "php",
            //    "Python",
            //    "Ruby",
            //    "Scala",
            //    "Scheme",
            //];
            function split(val) 
                return val.split(/,\s*/);
            
            function extractLast(term) 
                return split(term).pop();
            

            $("#tags")
                // don't navigate away from the field on tab when selecting an item
                .on("keydown", function (event) 
                    if (
                        event.keyCode === $.ui.keyCode.TAB &&
                        $(this).autocomplete("instance").menu.active
                    ) 
                        event.preventDefault();
                    
                )
                .autocomplete(
                    minLength: 0,
                    source: function (request, response) 
                        // delegate back to autocomplete, but extract the last term
                        response(
                            $.ui.autocomplete.filter(availableTags, extractLast(request.term))
                        );
                    ,
                    focus: function () 
                        // prevent value inserted on focus
                        return false;
                    ,
                    select: function (event, ui) 
                        var terms = split(this.value);
                        // remove the current input
                        terms.pop();
                        // add the selected item
                        terms.push(ui.item.value);
                        // add placeholder to get the comma-and-space at the end
                        terms.push("");
                        this.value = terms.join(", ");
                        return false;
                    ,
                );
        );
    </script>
</head>
<body data-new-gr-c-s-check-loaded="14.1003.0" data-gr-ext-installed="">

<img  class="n3VNCb" src="https://upload.wikimedia.org/wikipedia/commons/b/b9/Marvel_Logo.svg" data-noaft="1" jsname="HiaYvf" jsaction="load:XAeZkd;" style="width: 320.896px; height: 129px; margin: 0px;">
    <br/><br/>
    <div class="ui-widget">
        <label for="tags">Marvel Characters: </label>
        <input id="tags"
               size="50"
               class="ui-autocomplete-input"
               autocomplete="off" />
    </div>

    <ul id="ui-id-1"
        tabindex="0"
        class="ui-menu ui-widget ui-widget-content ui-autocomplete ui-front"
        style="display: none; top: 33px; left: 219.688px; width: 441px">
        <li class="ui-menu-item">
            <div id="ui-id-17" tabindex="-1" class="ui-menu-item-wrapper">Scala</div>
        </li>
    </ul>
    <div role="status"
         aria-live="assertive"
         aria-relevant="additions"
         class="ui-helper-hidden-accessible">
        <div style="display: none">
            10 results are available, use up and down arrow keys to navigate.
        </div>
        <div style="display: none">
            5 results are available, use up and down arrow keys to navigate.
        </div>
        <div style="display: none">
            1 result is available, use up and down arrow keys to navigate.
        </div>
        <div>Scala</div>
    </div>
</body>

Webapi:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace WebApplication4.Controllers

    [Route("api/[controller]")]
    [ApiController]
    public class CustomerController : ControllerBase
    
        [HttpGet]
        public JsonResult Get()
        
            var list = new List<string>();
            list.Add("Aaron Stack");
            list.Add("Abomination (Emil Blonsky)");
            list.Add("Abomination (Ultimate)");
            list.Add("Absorbing Man");
            list.Add("Banshee");
            list.Add("Baron Strucker");
            list.Add("Baron Zemo (Heinrich Zemo)");
            list.Add("Barracuda");
            list.Add("Cable");
            list.Add("Calamity");
            list.Add("Caliban");
            list.Add("Calypso");
            

            var json = new JsonResult(list);

            return json;
        
    

【问题讨论】:

有了这个特定的代码,我不知道你能做到这一点。自动完成功能正在查看带有minLength 的字段中的文本长度,例如,如果您已经选择了Banshee,并且您开始输入ca,那么您已经有超过2 个字符。因此,您需要额外的函数来拆分值、检查最后一个条目的长度以及有条件地显示或隐藏结果列表。 【参考方案1】:

看起来您向源添加了一个条件,这将有助于做到这一点:

source: function(request, response) 
  var term = extractLast(request.term);
  if (term.length > 2) 
    response(
      $.ui.autocomplete.filter(availableTags, term)
    );
  

更完整的例子。

$(function() 
  var availableTags = [
    "ActionScript",
    "AppleScript",
    "Asp",
    "BASIC",
    "C",
    "C++",
    "Clojure",
    "COBOL",
    "ColdFusion",
    "Erlang",
    "Fortran",
    "Groovy",
    "Haskell",
    "Java",
    "JavaScript",
    "Lisp",
    "Perl",
    "PHP",
    "Python",
    "Ruby",
    "Scala",
    "Scheme",
  ];

  function split(val) 
    return val.split(/,\s*/);
  

  function extractLast(term) 
    return split(term).pop();
  

  $("#tags")
    .on("keydown", function(event) 
      if (
        event.keyCode === $.ui.keyCode.TAB &&
        $(this).autocomplete("instance").menu.active
      ) 
        event.preventDefault();
      
    )
    .autocomplete(
      minLength: 0,
      source: function(request, response) 
        var term = extractLast(request.term);
        if (term.length > 2) 
          // delegate back to autocomplete, but extract the last term
          response(
            $.ui.autocomplete.filter(availableTags, term)
          );
        
      ,
      focus: function() 
        // prevent value inserted on focus
        return false;
      ,
      select: function(event, ui) 
        var terms = split(this.value);
        // remove the current input
        terms.pop();
        // add the selected item
        terms.push(ui.item.value);
        // add placeholder to get the comma-and-space at the end
        terms.push("");
        this.value = terms.join(", ");
        return false;
      ,
    );
);
<link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
<link rel="stylesheet" href="https://jqueryui.com/resources/demos/style.css" />
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<img  class="n3VNCb" src="https://upload.wikimedia.org/wikipedia/commons/b/b9/Marvel_Logo.svg" data-noaft="1" jsname="HiaYvf" jsaction="load:XAeZkd;" style="width: 320.896px; height: 129px; margin: 0px;">
<br/><br/>
<div class="ui-widget">
  <label for="tags">Marvel Characters: </label>
  <input id="tags" size="50" class="ui-autocomplete-input" autocomplete="off" />
</div>

<ul id="ui-id-1" tabindex="0" class="ui-menu ui-widget ui-widget-content ui-autocomplete ui-front" style="display: none; top: 33px; left: 219.688px; width: 441px">
  <li class="ui-menu-item">
    <div id="ui-id-17" tabindex="-1" class="ui-menu-item-wrapper">Scala</div>
  </li>
</ul>
<div role="status" aria-live="assertive" aria-relevant="additions" class="ui-helper-hidden-accessible">
  <div style="display: none">
    10 results are available, use up and down arrow keys to navigate.
  </div>
  <div style="display: none">
    5 results are available, use up and down arrow keys to navigate.
  </div>
  <div style="display: none">
    1 result is available, use up and down arrow keys to navigate.
  </div>
  <div>Scala</div>
</div>

【讨论】:

以上是关于如何仅在多个自动完成文本框中的前 2 个字符之后才开始自动完成?的主要内容,如果未能解决你的问题,请参考以下文章

文本框中的自动完成文本

文本框中的自动完成 json

禁用文本框后 JQuery UI 自动完成功能不起作用

如何从自动完成文本框中单击名称?

将输入文本框中的文本替换为所选自动完成选项中的文本

如何在自动完成文本框中没有按钮的情况下回发?