Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make a browser display all datalist options when a default value is set?

I have an HTML form with a datalist and where the value is set with PHP, like

<input list="values" value="<?php echo $val; ?>">
 <datalist id="values">
  <option value="orange">
  <option value="banana">
 </datalist>

I want the user to see the options in the datalist, as well as the current value from the PHP. However, the "autocomplete" action causes values from the list that don't match (or start with) the current value to be hidden from the list, say if $val='apple'. Is there any way to avoid that, or is this behaviour fixed by the browser?

like image 368
Dave W Avatar asked May 27 '16 08:05

Dave W


People also ask

Is Datalist supported by all browsers?

Unfortunately, Internet Explorer and Chrome are the only browsers to support datalists on range inputs at this time.

How do you provide a native HTML autocomplete feature as a dropdown list of items we specify in the form inputs?

The <datalist> tag is used to provide an "autocomplete" feature for <input> elements. Users will see a drop-down list of pre-defined options as they input data. The <datalist> element's id attribute must be equal to the <input> element's list attribute (this binds them together).

Which element is to be used with predefined values in a Datalist?

The HTML <datalist> tag is is used to provide an auto complete feature on form element. It provides a list of predefined options to the users to select data. The datalist tag is introduced in HTML5. The <datalist> tag should be used with an <input< element that contains a "list" attribute.

Can you style Datalist?

Like select elements, the datalist element has very little flexibility in styling. You cannot style any of the suggested terms if that's what your question was asking. Browsers define their own styles for these elements.


Video Answer


3 Answers

<datalist> uses autocomplete functionality so this is normal behaviour.

For example if you set input value to be 'o' you will see just orange in datalist options. It checks word from first letter. But if you set input value to 'a' then you won't see options at all.

So if you already have value in input then nothing will be shown in datalist options except that value if it exists. It doesn't behave like select.

Workaround for this would be to use jquery like this for example:

$('input').on('click', function() {
  $(this).val('');
});
$('input').on('mouseleave', function() {
  if ($(this).val() == '') {
    $(this).val('apple');
  }
});

Full test here: https://jsfiddle.net/yw5wh4da/

Or you could use <select>. To me it is better solution in this case.

like image 155
Jakob Avatar answered Oct 16 '22 11:10

Jakob


I found using click and mouseleave events to be not ideal, as they won't work using keyboard controls.

So I came up with this helper function:

Update: trigger a blur() event after input

As commented by @Joe Platano we can improve the datalist behavior – by triggering a blur() after the input event (at least for chromium/blink based browsers).

keepDatalistOptions('.keepDatalist');

function keepDatalistOptions(selector = '') {
  // select all input fields by datalist attribute or by class/id
  selector = !selector ? "input[list]" : selector;
  let datalistInputs = document.querySelectorAll(selector);
  if (datalistInputs.length) {
    for (let i = 0; i < datalistInputs.length; i++) {
      let input = datalistInputs[i];
      input.addEventListener("input", function(e) {
        e.target.setAttribute("placeholder", e.target.value);
        e.target.blur();
      });
      input.addEventListener("focus", function(e) {
        e.target.setAttribute("placeholder", e.target.value);
        e.target.value = "";
      });
      input.addEventListener("blur", function(e) {
        e.target.value = e.target.getAttribute("placeholder");
      });
    }
  }
}
<div style="display:flex; gap:1em;">
  <div>
    <h3>Keep datalist options</h3>
    <input class="keepDatalist" type="text" list="data" value="apple">
    <datalist id="data">
  <option value="apple">
  <option value="orange">
  <option value="banana">
</datalist>
  </div>
  <div>
    <h3>Default behavior</h3>
    <input type="text" list="browser" value="">
    <datalist id="browser">
  <option value="firefox">
  <option value="opera">
  <option value="safari">
</datalist>
  </div>
</div>

The main concept is basically the same:

  1. save the current input value to placeholder attribute
  2. reset the value on focus to show all datalist options
  3. swap actual input value with placeholder on input

This function also updates the current value on input event – otherwise you would lose the current value after navigating via tab key to the next input.

Why you shouldn't mess with the default behavior of form elements

For instance, Firefox won't accept this hack – and probably for good reasons.

When working on forms your first priorities should always be:

  • reliability:
    Form data can successfully be submitted even in sh... less modern browsers
  • accessibility:
    custom hacks should also work for visually impaired people using a screen reader like NVDA or JAWS

So you should always "triple/quadruple check" if your customized form element behavior provides a reliable and predictable user experience.

like image 7
herrstrietzel Avatar answered Oct 16 '22 09:10

herrstrietzel


HTML:

<input list="values" placeholder="select">
<datalist id="values">
  <option value="orange">
  <option value="banana">
  <option value="lemon">
  <option value="apple">
</datalist>

JS:

$('input').on('click', function() {
    $(this).attr('placeholder',$(this).val());
  $(this).val('');
});
$('input').on('mouseleave', function() {
  if ($(this).val() == '') {
    $(this).val($(this).attr('placeholder'));
  }
});
like image 6
user7553218 Avatar answered Oct 16 '22 09:10

user7553218