简体   繁体   English

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

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

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.我想要的是,当一个项目完全输入(例如,当用户完全输入“Adnan1”时在输入框中说)或从列表中选择时,我想要一个事件。 I tried couple of approaches but both doesn't help me so far.我尝试了几种方法,但到目前为止都没有帮助我。 Approaches are -方法是 -

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

problem with this is, the event only gets triggered when input gets out of focus Ie 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.但是每次我输入时都会触发回调。我实际上需要在完全选择项目时进行 AJAX 调用。 Either via type-in or by selecting from dropdown.通过输入或从下拉列表中选择。

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.我错过的任何可以解决我的问题的事件。

On modern browsers , you can use input event, eg:现代浏览器上,您可以使用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 input event has better support than datalist element, there is indeed no reason to not use it if you are already using datalist element. PS:由于input事件比datalist元素支持更好,如果你已经在使用datalist元素,确实没有理由不使用它。

You can use input event 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>

Simple solution简单的解决方案

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

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 选项推入 array ,并在更改事件 keyup 、 blur 或 focus 时,检查输入值是否存在于我的 datalist 数组中。

Hacky as a sin, but works for me.哈克是一种罪过,但对我有用。 (Note that if you are typing 'Rum-Cola' it doesn't stop on the 'Rum' option) (请注意,如果您输入“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>

In addition to what was said above, we can also check the inputType of the input which must correspond to "insertReplacementText"除了上面所说的,我们还可以检查输入的inputType必须对应于“insertReplacementText”

 function textThatComesFromADatalist (event){ const inputType = event.inputType; const isReplacingText = (typeof inputType === "undefined") || (inputType === "insertReplacementText"); return isReplacingText; } function onInput(event) { if(textThatComesFromADatalist(event)){ alert('selected: '+event.target.value); } }
 <input oninput="onInput(event)" list="ice-cream-flavors" id="ice-cream-choice" name="ice-cream-choice" /> <datalist id="ice-cream-flavors"> <option value="Chocolate"> <option value="Coconut"> <option value="Mint"> <option value="Strawberry"> <option value="Vanilla"> </datalist>

Simple solution is that check the input text value exist in datalist or not, and if it does, run an ajax request.简单的解决方案是检查输入文本值是否存在于 datalist 中,如果存在,则运行 ajax 请求。

$("#input_form").on('input', function(event){
   if ($("#input_datalist option[value='" + $('#input_form').val() + "']").val() != undefined) {
      //send ajax request
   }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM