trigger event on selecting item from datalist, not when typing

Viewed 2308

I have a form like this:

<input list='data-list' id='list'>
<datalist id='data-list'>
  <option>first</option>
  <option>second</option>
</datalist>

The user can select an item from the datalist -or- can type in it's own value. I am connection to a database through a JSON call to a PHP script to fill in other information in the rest of the form. I want this to trigger when a user typed a name in the list-input (so when the content is blurred) OR when the user clicked an option from datalist.

Using $( ':input#list' ).on( 'change', function... the function is triggered when the input loses focus, but when an item from the data-list is selected it also waits 'till the input loses focus, I want the event to fire straight away

using $( ':input#list' ).on( 'input', function... clicking an item from the datalist triggers the function straight away, which is what I want, but typing will trigger the event as well, with each keystroke, sending a lot of unwanted requests to my PHP script.

I have tried binding an event to the datalist directly, but that didn't work.

I am looking to trigger the function when a user clicks (or uses the keyboard to select) an item from the datalist OR when a user entered a word and moves to the next input.

3 Answers

I had a similar problem, here is the solution. Basically I want to trigger change event, either by sole input or input+keyup event, so new variable is introduced to track this, with small help of setTimeout.

HTML

<input list="search-list" value="" class="form-control search-list custom-select custom-select-sm" placeholder="...">
<datalist id="search-list">
  <!-- filled with javascript, eg: <option value="ISO-8859-1">ISO-8859-1</option> -->
</datalist>

JS

window.onlyInput = false; // true if selecting
window.timeoutID;
window.timeoutIDs = [];    
$('.search-list')    
.on('focus', function(){        
    console.log('focus');
    onlyInput = false;
    $(this).val(""); // reset input
})
.on('change', function(){        
    console.log('change');
    // YOUR CODE HERE, ex:
    // eg: var text = $(this).val().toLowerCase();     
    // $.ajax ....
    onlyInput = false;
})
.on('keyup', function(){        
    console.log('keyup');        
    onlyInput = false;
    clearTimeoutIDs();
    $(this).trigger('change');
})
.on('input', function(){   
    console.log('input');
    var $that = $(this);
    onlyInput = true;        
    timeoutID = setTimeout(function(){            
        if(onlyInput) {
            $that.trigger('change');
            $that.trigger('blur');
        }            
        onlyInput = false;
    }, 300);
    timeoutIDs.push(timeoutID);
});

function clearTimeoutIDs() {
    $.each(timeoutIDs, function(i, d){
        clearTimeout(d);
    });
}
Related