Javascript 选择项目或键入输入与列表中的项目匹配时 HTML5 数据列表的 jQuery 事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30151633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:44:38  来源:igfitidea点击:

jQuery event for HTML5 datalist when item is selected or typed input match with item in the list

javascriptjqueryhtmljquery-events

提问by Mohammad Adnan

I have datalist like below -

我有如下数据列表 -

<input id="name" list="allNames" />
<datalist id="allNames">
    <option value="Adnan1"/>  
    <option value="Faizan2"/>   
</datalist>

What I want is, when an item is typed in completely(for example say in input box when user completely type "Adnan1") or selected from list, then I want an event. I tried couple of approaches but both doesn't help me so far. Approaches are -

我想要的是,当一个项目被完全输入(例如,当用户完全输入“Adnan1”时在输入框中说)或从列表中选择,那么我想要一个事件。我尝试了几种方法,但到目前为止都没有帮助我。方法是——

$("#name").change(function(){
console.log("change");
}

problem with this is, the event only gets triggered when input gets out of focus I.e. when I click somewhere in the screen.

问题是,只有当输入失去焦点时才会触发事件,即当我点击屏幕上的某个地方时。

I also tried

我也试过

$("#name").bind('change', function () {
    console.log('changed'); 
});

but the callback gets triggered each time when I type in. I actually need to make an AJAX call when item is completely selected. Either via type-in or by selecting from dropdown.

但是每次输入时都会触发回调。我实际上需要在完全选择项目时进行 AJAX 调用。通过输入或从下拉列表中选择。

First approach is bad for user perspective because he has to make extra click and second has disadvantage as for every letter an event will be triggered.

第一种方法对用户视角不利,因为他必须进行额外的点击,第二种方法有缺点,因为对于每个字母都会触发一个事件。

All I want is an event when either user made a selection or typed complete sentence. is there a way to achieve this? any event that I missing and that can solve my problem.

我想要的只是用户进行选择或键入完整句子时的事件。有没有办法实现这一目标?我错过的任何事件都可以解决我的问题。

回答by A. Wolff

On modern browsers, you can use inputevent, e.g:

现代浏览器上,您可以使用input事件,例如:

$("#name").on('input', function () {
    var val = this.value;
    if($('#allNames option').filter(function(){
        return this.value.toUpperCase() === val.toUpperCase();        
    }).length) {
        //send ajax request
        alert(this.value);
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<input id="name" list="allNames" />
<datalist id="allNames">
    <option value="Adnan1" />
    <option value="Faizan2" />
</datalist>

PS: as inputevent has better support than datalistelement, there is indeed no reason to not use it if you are already using datalistelement.

PS:由于inputevent 比datalistelement有更好的支持,如果您已经在使用datalistelement ,确实没有理由不使用它。

回答by Ankit

You can use inputevent for achieving such functionality, as below :

您可以使用input事件来实现此类功能,如下所示:

$(document).ready(function() {
  $('#name').on('input', function() {
    var userText = $(this).val();

    $("#allNames").find("option").each(function() {
      if ($(this).val() == userText) {
        alert("Make Ajax call here.");
      }
    })
  })
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="name" list="allNames" />
<datalist id="allNames">
  <option value="Adnan1" />
  <option value="Faizan2" />
</datalist>

回答by Salman Haider

Simple solution

简单的解决方案

document.getElementById('name').addEventListener('input', function () {
   console.log('changed'); 
});

回答by WhiteKnight

Hacky as a sin, but works for me. (Note that if you are typing 'Rum-Cola' it doesn't stop on the 'Rum' option)

Hacky 是一种罪过,但对我有用。(请注意,如果您输入“Rum-Cola”,它不会停留在“Rum”选项上)

const opts = $("option").map(function(){return  this.value;}).get();

$("#favourite-drink").on("keydown", function(e){
  if(e.key){ // in case of mouse event e.key is 'undefined'
    if (e.key === "Enter") { // looks like user wants to confirm the choice
      if(opts.indexOf(this.value) >= 0){
        this.blur();
        console.log("Selected: " + this.value);
      }
    }
    else {
      this.setAttribute("data-keyboardinput", "true"); // remember that it's keyboard event

      setTimeout(function(){ //and keep it in memory for 100ms
        this.removeAttribute("data-keyboardinput")
      }.bind(this), 100);
    }
  }
});

$("#favourite-drink").on("input", function(){
  if(!this.dataset.keyboardinput && opts.indexOf(this.value) >= 0){ // if it's not a key press followed event
    console.log("Selected: " + this.value);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Choose a drink:</p>
  <input id="favourite-drink" list="drinks">
  <datalist id="drinks">
    <option value="Rum"></option>
    <option value="Rum-Cola"></option>
    <option value="Vodka"></option>
  </datalist>

回答by Mohmad Taher

Check if this works for you :

检查这是否适合您:

var dataList=[];
$("#allNames").find("option").each(function(){dataList.push($(this).val())})
console.log(dataList);
$("#name").on("keyup focus blur change",function(){
    if(dataList.indexOf($(this).val())!=-1)
console.log("change");
})

I pushed datalist options into array , and on change event keyup , blur or focus , i check if input value exists in my datalist array.

我将 datalist 选项推入数组,并在更改事件 keyup、blur 或 focus 时检查输入值是否存在于我的 datalist 数组中。