The solution I went for is a combination of both events...
I keep track of a variable window.latest_autofill_qeury
to prevent loading the same thing twice in a row. I have the following onchange
function, this triggers when a user puts the focus out of the input (tabs out, or clicks elsewhere)
$( ':input#list' ).on( 'change', function(){
var current = $( this ).val();
if( window.latest_autofill_query != current )
load_autofill();
} );
Then there's another function that keeps track of what the user types, and checks if the value entered is in the datalist. If so, we assume that's what the user wants and the next datalist is queried. This is also triggered when a user clicks an item from the datalist which will always result in the value of the input being present in the datalist and thus immediately triggering the load_autofill:
$( ':input#list' ).on( 'input', function(){
var current = $( this ).val();
$( 'datalist#data-list option' ).each( function(){
if( $( this ).text() == current ){
load_autofill();
returnfalse;
} );
} );
the load_autofill
function keeps track of what it loaded last to prevent double loads. I won't go into the details of this load_autofill 'cause it's very application specific, but the framework is like this:
functionload_autofill(){
var current = $( ':input#list' ).val();
window.latest_autofill_query = current;
}
Now the next datalist will be loaded as soon as a user selected an item from the datalist, but not after every keystroke a user makes, only when the text entered is present in the datalist.
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="...">
<datalistid="search-list"></datalist>
JS
window.onlyInput = false; window.timeoutID;
window.timeoutIDs = [];
$('.search-list')
.on('focus', function(){
console.log('focus');
onlyInput = false;
$(this).val("");
})
.on('change', function(){
console.log('change');
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);
});
functionclearTimeoutIDs() {
$.each(timeoutIDs, function(i, d){
clearTimeout(d);
});
}
You can set up two separate event listeners.
One listens for new inputs and checks if the new input corresponds with any of the options on the datalist.
The other listens for when the user enters a word and moves on to the next input.
Working Example:
var myForm = document.getElementsByTagName('form')[0];
var myInput = myForm.getElementsByTagName('input')[0];
var myDataList = myForm.getElementsByTagName('datalist')[0];
var myOptions = myDataList.getElementsByTagName('option');
functionlistOptionSelected() {
var myValue = myInput.value;
for (var i = 0; i < myOptions.length; i++) {
if (myOptions[i].value === myValue) {
console.log('Option Selected: ' + myValue);
}
}
}
functiontypedOptionSelected() {
var myValue = myInput.value;
if (myValue !== '') {
console.log('Option Selected: ' + myInput.value);
}
}
myInput.addEventListener('input', listOptionSelected, false);
myInput.addEventListener('blur', typedOptionSelected, false);
input {
display: block;
margin: 0012px0;
}
<formaction="#"><inputlist='data-list'id='list'><datalistid='data-list'><option>first</option><option>second</option></datalist><inputid="next-input" /></form>
Post a Comment for "Trigger Event On Selecting Item From Datalist, Not When Typing"