Is there a specific event in Javascript to detect when a <option> of a <datalist> is selected?

Asked

Viewed 459 times

0

In Javascript, it is possible, through the onchange, oninput and related, detect if a certain input is amended.

Example:

var qs = function (el) { return document.querySelector(el); }


qs("#input").addEventListener('input', function (e) {
     console.log('evento "input" %s', e.target.value);
});

qs("#input").addEventListener('change', function (e) {
     console.log('evento "change" %s', e.target.value);
});
<input type="text" id="input" />

By tag <datalist> it is also possible to suggest fillers for a input. It is also possible to detect these changes in the input, since selecting an item from a datalist fills the target input.

Example:

var qs = function (el) { return document.querySelector(el); }


qs("#input").addEventListener('input', function (e) {
     console.log('evento "input" %s', e.target.value);
});

qs("#input").addEventListener('change', function (e) {
     console.log('evento "change" %s', e.target.value);
});
<input type="text" id="input" list="datalist"/>

<datalist id="datalist">
 <option>Bola</option>
 <option>Peão</option>
 <option>Pipa</option>
</datalist>

However, in my scenario, the following need arose: Instead of detecting the changes in input, need to know specifically, through an event, when a option that datalist is selected.

I tried to use onclick and mousedown on the tag option that’s in that datalist, but to no avail.

I need exactly this, not to detect the changes, but to know if the option was selected or not.

Is there any solution ready for this in Javascript?

Observing: The second example I gave does not solve my problem, because the event detects the changes in input, and not if the datalist > option was selected.

  • I think the event onselect is what it takes to solve your case.

  • @mutlei This event is to detect text selection, not the choice of an option of a datalist. What I want is different.

  • Try the event change on the datalist

  • Good morning friend! When the event takes place change, does not mean that a option was selected? I could not get well what you want.

  • 1

    I already understood the context. rs

  • @dvd no, because in fact you could enter a value that is not in the option.

Show 1 more comment

3 answers

2


I believe there is no

I’d say you have to check with querySelectorAll to check all options


Change event

function qs(query, context) {
   return (context || document).querySelector(query);
}

function qsa(query, context) {
   return (context || document).querySelectorAll(query);
}

qs("#input").addEventListener('change', function (e) {

    var options = qsa('#' + e.target.getAttribute('list') + ' > option'),
        values = [];
    
    [].forEach.call(options, function (option) {
        values.push(option.value)
    });

    var currentValue = e.target.value;

    if (values.indexOf(currentValue) !== -1) {
         console.log('evento "change" %s', currentValue);
    }

});
<input type="text" id="input" list="datalist"/>

<datalist id="datalist">
 <option>Bola</option>
 <option>Peão</option>
 <option>Pipa</option>
</datalist>


Input event

function qs(query, context) {
   return (context || document).querySelector(query);
}
function qsa(query, context) {
   return (context || document).querySelectorAll(query);
}
  
var timerDataList = {};//Para usar com multiplos datalist

qs("#input").addEventListener('input', function (e) {
     var listAttr = e.target.getAttribute('list');
     
     if (timerDataList[listAttr]) clearTimeout(timerDataList[listAttr]);
  
     timerDataList[listAttr] = setTimeout(executeCheckin, 100, e.target, listAttr);
});
  
function executeCheckin(target, listAttr) {
    var options = qsa( 'option', qs('#' + listAttr) ),
        values = [];
    
    [].forEach.call(options, function (option) {
        values.push(option.value)
    });
    var currentValue = target.value;
    if (values.indexOf(currentValue) !== -1) {
         console.log('evento "input" %s', currentValue);
    }
}
<input type="text" id="input" list="datalist"/>

<datalist id="datalist">
 <option>Bola</option>
 <option>Peão</option>
 <option>Pipa</option>
</datalist>


2

There is no event that does what you ask, but nothing prevents the creation of one. Follows a proposal.

(function () {
  var event = new Event("selected")
  var inputs = document.querySelectorAll("[list]")
  var onInput = function (evt) {
    var index = this.options.indexOf(this.input.value.toUpperCase())
    if (index != this.input.selectedIndex) {
      this.input.selectedIndex = index
      this.input.dispatchEvent(event)
    }
  };
  [].forEach.call(inputs, function (input) {
    input.selectedIndex = -1
    var wrapper = {
      input: input,
      options: [].map.call(input.list.options, function (option) {
        return option.textContent.toUpperCase()
      })
    }
    input.addEventListener('input', onInput.bind(wrapper))
  })  
})()

input.addEventListener("selected", function (evt) {
  console.log(evt.target.selectedIndex)
})
<input type="text" id="input" list="datalist"/>

<datalist id="datalist">
 <option>Bola</option>
 <option>Peão</option>
 <option>Pipa</option>
</datalist>

1

You can do this way by using .map. It will create an array where you check whether the value of input exists in the array with indexOf. The example below is case sensitive; if you type "kite" you will not find "kite". But if you want, this can be easily adjusted. It will also make a difference with sharp words.

var qs = function (el) { return document.querySelector(el); }

qs("#input").addEventListener('change', function (e) {

   var datalist = document.body.querySelectorAll("#datalist option");
   var opt = [].map.call(datalist, function(o){
      return o.textContent
   });
   
   var optSel = ~opt.indexOf(e.target.value) ? true : false;
   
   // se optSel for true, significa que o valor existe no datalist
   console.log(optSel);
});
<input type="text" id="input" list="datalist"/>

<datalist id="datalist">
 <option>Bola</option>
 <option>Peão</option>
 <option>Pipa</option>
</datalist>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.