/    Sign up×
Community /Pin to ProfileBookmark

How to get the “datapart” from a “datalist”

There is hundreds of questions like this on forums. Many of them with no answer.

It seems that there is no clear and simple answer. The selected data-id must be stored somewhere, or am I thinking wrong? If it is stored (like the value), how do I retrieve the data?

Can anybody explain how this work or even get me a solution?

“`
<input list=”options” onchange=”val(this)” />
<datalist id=”options”>
<option data-id=”1″>One</option>
<option data-id=”2″>Two</option>
<option data-id=”3″>Three</option>
</datalist>
<input type=”hidden” name=”hidden” id=”idhidden”>
“`

“`
function val(element) {
alert(element.value + ” OK value”);
alert(element.getAttribute(‘data-id’) + ” No value”);
alert(element.selectedIndex + ” No value undefined”);
//this does not work
alert(element.hiddenInput.value.getAttribute(‘data-id’) )
}
“`

https://jsfiddle.net/cnaxwkh9/2/

to post a comment
JavaScript

14 Comments(s)

Copy linkTweet thisAlerts:
@SempervivumJul 27.2020 — For a simple select there exists the property selectedIndex which indicates which option is currently selected. For a datalist this is not applicable: When the user modifies the value a relation to a specific option is not possible.
Copy linkTweet thisAlerts:
@sibertauthorJul 27.2020 — > @Sempervivum#1621320 For a datalist this is not applicable: When the user modifies the value a relation

So, basically datalists are pretty useless then? As you cannot reach the data directly?
Copy linkTweet thisAlerts:
@daveyerwinJul 27.2020 — <input list="options" onchange="val(this)" />

<datalist id="options">

<option data-id="1">One</option>

<option data-id="2">Two</option>

<option data-id="3">Three</option>

</datalist>

<input type="hidden" name="hidden" id="idhidden">

<script>

function val(element) {

list = options.childNodes;

for (var i=0;i<list.length;++i)

if( list[i].nodeName == "OPTION")alert(list[i].value)

}

</script>
Copy linkTweet thisAlerts:
@SempervivumJul 27.2020 — So, basically datalists are pretty useless then? As you cannot reach the data directly?[/quote]No, they are not useless, they are appropriate any time when you intend to allow the user for modfying the value. You can access the value directly by reading the value propery of the related input.
Copy linkTweet thisAlerts:
@daveyerwinJul 27.2020 — <input list="options" onchange="val(this)" />

<datalist id="options">

<option data-id="1">One</option>

<option data-id="2">Two</option>

<option data-id="3">Three</option>

</datalist>

<input type="hidden" name="hidden" id="idhidden">

<script>

function val(element) {

list = options.childNodes;

for (var i=0;i<list.length;++i)

if( list[i].nodeName == "OPTION")alert(list[i].value +" "+ list[i].dataset.id)

}
Copy linkTweet thisAlerts:
@sibertauthorJul 27.2020 — > @Sempervivum#1621326 You can access the value directly by reading the value propery of the related input.

But not the "data-id"? You have to iterate the list to find the value indirectly?
Copy linkTweet thisAlerts:
@sibertauthorJul 27.2020 — > @DaveyErwin#1621327 if( list.nodeName == "OPTION")alert(list.value +" "+ list.dataset.id)

Cannot get this to work: https://jsfiddle.net/uy5dnmow/

What am I missing?
Copy linkTweet thisAlerts:
@daveyerwinJul 27.2020 — if (list[i].nodeName == "OPTION") alert(list[i].value + " " + list[i].dataset.id)

I left off the code tags and the indices went away:(
Copy linkTweet thisAlerts:
@SempervivumJul 27.2020 — But not the "data-id"? You have to iterate the list to find the value indirectly?[/quote]I do not see any benefit in reading the data-id as once the user has edited the value in the input there is no longer a relation between that value and the options.
Copy linkTweet thisAlerts:
@sibertauthorJul 28.2020 — > @Sempervivum#1621333 I do not see any benefit in reading the data-id as once the user has edited the value in the input there is no longer a relation between that value and the options.

There are at least two options to select a country from a list in a form. "select" and "datalist".

  • 1. https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_select . The tag "select" lists are easy to use, but you cannot search the list. Having many countries to chose between, this is harder to find the correct country using keyboard and searching for a part of the country like "Korea".


  • 2. https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_datalist . The tag "datalist" adds a typeahead search function to the list. At the same time makes it harder to fetch the "id" of the country. The "data-id" tag is not stored anywhere and no line is selected. (AFAIK)


  • I do not want to change "Pakistan" to "USA". Or add another country "Longdistan". Both the country id and country names are fixed. Just use "datalist" as a "select". And fetch the "data-id" (country code) when submitting to the database.

    Using datalist in this "wrong"(?) way, the is a clear benefit in being able to read the data-id.

    Or is there an even smarter way to do this?
    Copy linkTweet thisAlerts:
    @daveyerwinJul 28.2020 — @sibert#1621347 said ...

    Or is there an even smarter way to do this?

    What is your objection to using select element ?

    ``<i>
    </i>&lt;select&gt;
    &lt;option value="4"&gt;Afghanistan&lt;/option&gt;
    &lt;option value="248"&gt;Åland Islands&lt;/option&gt;
    &lt;option value="8"&gt;Albania&lt;/option&gt;
    &lt;option value="12"&gt;Algeria&lt;/option&gt;
    &lt;option value="16"&gt;American Samoa&lt;/option&gt;
    &lt;option value="20"&gt;Andorra&lt;/option&gt;
    &lt;option value="24"&gt;Angola&lt;/option&gt;
    &lt;option value="660"&gt;Anguilla&lt;/option&gt;
    &lt;option value="10"&gt;Antarctica&lt;/option&gt;
    and so on<i>
    </i>
    ``
    Copy linkTweet thisAlerts:
    @sibertauthorJul 28.2020 — > @DaveyErwin#1621360 What is your objection to using select element ?

    <select> is user friendly up to a dozen items. Then they slowly become unmanageable. (read mobile unfriendly)

    Imaging that you have a list of 500 items. And you want to find a word within an item text...

    Typeahead and autocomplete makes life way simpler in this case.

    It is about UX.
    Copy linkTweet thisAlerts:
    @SempervivumJul 28.2020 — @sibert#1621347 You are wright, in this situation autocomplete is an appropriate approach. Unfortunately there is no way to prevent the user from editing the corresponding input. I checked the autocomplete of jQuery UI and the situation is the same.

    Unless coding a constraint by Javascript: Prevent any input that is not a substring in one of the options as described here:

    https://stackoverflow.com/questions/53618178/how-to-prevent-users-from-submitting-false-value-of-datalist-in-html
    Copy linkTweet thisAlerts:
    @JMRKERJul 28.2020 — Assuming I am understanding the problems of:
  • 1. wanting to use a data-list in a selection box because of numerous entries on mobile devices

  • 2. wanting to avoid user unique entries or incomplete entries in selection process

  • 3. and wanting to have pre-submit checks for incomplete user inputs.


  • Here is something I submitted on another forum question.

    (See comments for original question)

    It checks for invalid entries checked within a datalist dynamically created using JS

    The 'Notes' entry could possibly allow for free-format user input.

    <i>
    </i>
    &lt;!DOCTYPE html&gt;&lt;html lang="en"&gt;&lt;head&gt;
    &lt;title&gt; Datalist Demos &lt;/title&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width,initial-scale=1.0, user-scalable=yes"/&gt;

    &lt;!-- Highly Modified
    For: https://www.webdeveloper.com/d/390749-how-to-get-the-datapart-from-a-datalist/12
    From: https://www.sitepoint.com/community/t/validate-data-value-in-a-html-datalist/355469
    And: https://jsfiddle.net/brsf14yu/
    --&gt;
    &lt;link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300"&gt;
    &lt;style&gt;
    /* datalist { display: block; } /* for testing purposes only -- normally display: none */
    .hide { display: none; }

    * {
    font-family: 'Source Sans Pro', sans-serif;
    font-weight: 300;
    font-size: 18px;
    }
    input[type=text],
    input[list]{
    color: #f0f0f0;
    font-size: 18px;
    padding: 10px;
    max-height: 56px;
    width: 350px;
    background: #555;
    -webkit-appearance: none;
    appearance: none;
    border: none;
    }
    #submit{
    color: #f0f0f0;
    font-size: 18px;
    padding: 10px;
    max-height: 56px;
    width: 370px;
    background: #555;
    -webkit-appearance: none;
    appearance: none;
    border: none;
    }
    &lt;/style&gt;
    &lt;/head&gt;&lt;body&gt;
    &lt;form action="javascript:alert('Success')" method="post"
    onsubmit="return checkInputs()"&gt; &lt;!-- target="_self" --&gt;
    <br/>
    &lt;input id="job" list="jobs" placeholder="Select Job" required="data-value" autocomplete="off"&gt;
    &lt;datalist id="jobs"&gt;&lt;/datalist&gt;
    &lt;br&gt;
    &lt;input id="code" list="codes" placeholder="Select Code" required="data-value" autocomplete="off"&gt;
    &lt;datalist id="codes"&gt;&lt;/datalist&gt;
    &lt;br&gt; <br/>
    &lt;!-- following is a free-format text entry --&gt;
    &lt;input id="note" type="text" placeholder="Note" required autocomplete="off"&gt;
    &lt;br&gt;
    &lt;input type="submit" value="Submit"&gt; &lt;!-- onsubmit="return checkInputs()" --&gt;
    &lt;button id="clrBtn"&gt;Clear&lt;/button&gt;
    &lt;br&gt; <br/>
    &lt;/form&gt;

    &lt;script&gt;
    console.clear();

    const listJobs = ['President/CEO','Vice-President/CFO','Administrator',
    'Supervisor','Manager','Worker','Flunkey','Gopher'];
    const listCodes = ['ALGOL','Basic','C++','COBOL','FORTRAN','Forth',
    'Java','JavaScript','Lisp','PERL','Python'];
    var respJob = document.getElementById('job'),
    respCode = document.getElementById('code'),
    respNote = document.getElementById('note');

    function checkInputs() {
    const errMsg = 'Please select a valid value';

    var err = 0; // represents no errors
    if (!listJobs.includes(respJob.value)) { err = 1; respJob.focus(); }
    if (!listCodes.includes(respCode.value)) { err = 2; respCode.focus(); }

    if (err != 0) { // error noted
    alert('Error - invalid entry '+err+' - '+errMsg);
    return false;
    } else { // all OK
    alert(<span><code>${respJob.value} n${respCode.value} n${respNote.value}</code></span>);
    return true;
    }
    // return (err !== 0);
    }

    function createOptions(listIDS,Ary) {
    const list = document.getElementById(listIDS);
    Ary.forEach(item =&gt; {
    let option = document.createElement('option');
    option.value = item; option.textContent = item;

    /* following is alternative when value != option display for submission
    [n,v] = item.split(':'); option.value = item.replace(':',' '); option.textContent = v;
    /* Example array contents for 'Ary = listCars' for a new HTML element named 'Cars'
    // const listCars = ['1:Chevrolet','2:Dodge','3:Ford','4:General Motors','5:Nissan','6:Toyota'];

    /* */

    <i> </i>list.appendChild(option);
    });
    }

    function init() {
    createOptions('jobs',listJobs);
    createOptions('codes',listCodes);

    // optional display lists when element clicked
    // respJob.addEventListener('click',() =&gt; document.getElementById('jobs').classList.toggle('hide') );
    // respCode.addEventListener('click',() =&gt; document.getElementById('codes').classList.toggle('hide') );

    document.getElementById('clrBtn').addEventListener('click',
    () =&gt; { respJob.value=''; respCode.value=''; respNote.value=''; } );
    } init();
    &lt;/script&gt;

    &lt;/body&gt;&lt;/html&gt;


    There is optional code to display whole list using CSS 'hide' class (if list is shorter, like a <select> element.

    Substitute a server-side program to process completed input instead of the <form> JS success message.
    ×

    Success!

    Help @sibert spread the word by sharing this article on Twitter...

    Tweet This
    Sign in
    Forgot password?
    Sign in with TwitchSign in with GithubCreate Account
    about: ({
    version: 0.1.9 BETA 3.28,
    whats_new: community page,
    up_next: more Davinci•003 tasks,
    coming_soon: events calendar,
    social: @webDeveloperHQ
    });

    legal: ({
    terms: of use,
    privacy: policy
    });
    changelog: (
    version: 0.1.9,
    notes: added community page

    version: 0.1.8,
    notes: added Davinci•003

    version: 0.1.7,
    notes: upvote answers to bounties

    version: 0.1.6,
    notes: article editor refresh
    )...
    recent_tips: (
    tipper: @darkwebsites540,
    tipped: article
    amount: 10 SATS,

    tipper: @Samric24,
    tipped: article
    amount: 1000 SATS,

    tipper: Anonymous,
    tipped: article
    amount: 10 SATS,
    )...