Making HTML5 datalist visible when focus event fires on input
Asked Answered
W

5

27

As some might know already styling select element is a nightmare, literally impossible without some javascript trickery. The new datalist in HTML5 could serve the same purpose since the user is presented with a list of options and the value is recorded in an input text field.

The limitation here is the list does not appear until the user start typing something in the text field and even then is only shown possible matches based on their input. The behavior I want is that as soon as there is focus on the field the entire list of options become visible.

So I have this code - view on jsbin

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Input - Datalist</title>
</head>
<body>
  <input list="categories">
  <datalist id="categories">
    <option value="Breakfast">Breakfast</option>
    <option value="Brunch">Brunch</option>
    <option value="Lunch">Lunch</option>
    <option value="Dinner">Dinner</option>
    <option value="Desserts">Desserts</option>
  </datalist>
</body>
</html>

and I'm trying to get that to show with this Javascript:

    var catVal = document.getElementsByTagName("input")[0],
    cat = document.getElementById("categories");

    catVal.style.fontSize = "1.3em";

    catVal.addEventListener("focus", function(event){
     cat.style.display = "block";
    }, false);

Any help would be appreciated,

Cheers

Weylin answered 25/3, 2013 at 18:27 Comment(1)
I'm trying to achieve the same, did you have any luck so far?Gynecic
P
12

I use the following code:

<input name="anrede" 
    list="anrede" value="Herr" 
    onmouseover="focus();old = value;" 
    onmousedown = "value = '';" 
    onmouseup="value = old;"/>

<datalist id="anrede">
    <option value="Herr" selected></option>
    <option value="Frau"></option>
    <option value="Fraulein"></option>
</datalist>

mouseover:
Set focus and memorize old value in a -- g l o b a l -- variable

mousedown:
Delete value and show datalist (built in functionality)

mouseup:
Restore old value

Then select new value.

Find this an acceptable workaround towards a combobox.

Precedent answered 17/12, 2013 at 23:15 Comment(2)
how does this do what the OP asked for?Telfore
Is any of jquery code needed at all. I think datalist and input with list association shall be enough to do the needed(in chrome) or is there any browser compatibility issue here i am missing ?Ruelas
C
7

I hope you like this solution:

I added a “temp” attribute to the input field for storage and once the mouse hovers over the input filed it will save its current value in temp and then delete the value so as to allow the datalist to open.

On mouseout it will restore the field’s value from the variable temp. This solution works great under Chromium that I tested.

As a bonus you can add a placeholder="Click to see all your options"

<input value="Classic" list="myDatalist" temp="" onmouseover="this.temp=this.value; this.value='';" onmouseout="this.value=this.temp;">
<datalist id="myDatalist" open="open"> 
        <option value="Internet Explorer">
        <option value="Firefox">
        <option value="Chrome">
        <option value="Opera">
        <option value="Safari">
      </datalist>
Commensurate answered 25/10, 2017 at 12:48 Comment(2)
I feel like the spec should have another INPUT attribute that directs the browser to supply this behavior or something. From a usability standpoint, the list/datalist spec is lacking in my opinion. Your solution is a clean, simple workaround! Thanks!Adipocere
When the dropdown is open in your example and I scroll the page, the drop down is scrolled down as well (with chromium). Never saw this behaviour before with datalist.Iwo
C
0

Question is pretty old, but it's top search on google and there are no answers to be found so I'll add it here.

To expand datalist on first click you need to set

dataListElement.style.display = "block";

and immediately hide it in next line, so it does not appear as element in your DOM, but it will only expand it under input element.

dataListElement.style.display = "none";

As of today it's not expanded on first click only in Firefox.

Churchly answered 14/2, 2020 at 13:6 Comment(1)
Thank you this is working indeed ! (Firefox) I'm shock that we don't have the choice to open the list on click or not and have a JS trick :/ <p> Anyway I'll stay on Libre browser (Firefox) no matter what</p>. To quote Richard Stallman (TEDx 2014) "To keep your freedom, sometimes it require a sacrifice. But in our campain (IT) they then to be little sacrifices."Ane
A
0

In the "Ulrich Berth" response, when clicking on the input, the value in the input will be reset and it will not be possible to select the text inside. You can use this to avoid the problem:

<input id = "input" name="anrede" 
    list="anrede" value="Herr" 
    onmouseover="focus();old = value;" 
    onmousedown = "inputFocus();" 
    onmouseup="value = old;"/>

<datalist id="anrede">
    <option value="Herr" selected></option>
    <option value="Frau"></option>
    <option value="Fraulein"></option>
</datalist>
function inputFocus(){
    var input = document.getElementById("input");
    if(input.value == ""){
        value = '';
    }else{
        old = value = input.value;
    }
}
Affiliation answered 6/6, 2022 at 7:29 Comment(0)
H
-3

HTML:

<!DOCTYPE html>
<html>
<head>
   <script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>

   <meta charset=utf-8 />
   <title>Input - Datalist</title>
</head>
<body>

  <input list="categories" id="categories2" type="text">
  <div id="result"></div>
  <datalist id="categories">
     <option value="Breakfast">Breakfast</option>
     <option value="Brunch">Brunch</option>
     <option value="Lunch">Lunch</option>
     <option value="Dinner">Dinner</option>
     <option value="Desserts">Desserts</option>
  </datalist>
</body>
</html>

jQuery:

var result='';
$(document).ready(function(){  
   $('input[type=text]').focus(function(){
      $('#categories option').each(function(){
      result=result+" "+$(this).val();
      });

      $('#result').show().html(result);
      $('input[type=text]').unbind('focus');
   });
   $('input[type=text]').blur(function(){
       $('#result').hide();  
       $('input[type=text]').focus(function(){
           $('#result').show();
       });

   });  
});

Working JS bin

http://jsbin.com/urupit/4/watch

Hornet answered 26/3, 2013 at 20:36 Comment(4)
good thinking but that is not the behavior I'm after, for our UX we do not want to create a holder div since we will have at least 3 of these inputs side by side. I want the datalist to show when the input get the focus event.Weylin
Why not double click the input type text? it will show the whole list.Hornet
as the developer I know that's what I need to do to get to that, but it's not obvious to the user who most likely is used to click once in an input box and start typing, reason why I'm trying to trigger the second click as soon as they focusWeylin
They will only know to double click if they are told, otherwise it is not obvioiusReckoning

© 2022 - 2024 — McMap. All rights reserved.