Search code examples
javascripthtml-datalist

How do I update dropdown options after input data change


I have dropdown list where options are filling with values inside js code. After click on submit button, I want my dropdown to be changed for updated values, but it will just add new values to already existed values.

My idea was in deleting all options before they are creating, so options with new values will be added from a scratch.

So I tried to receive the length of datalist, but something like var x = document.getElementById("browsers").options.length; from w3schools doesn't work.

In addition, I tried to receive all options with setting className for option and then get all options with const options = document.getElementsByClassName('datalist-option') and with this try I received all options, but then I can't iterate through them to do the following way:

const options = document.getElementsByClassName('datalist-option')

options.forEach(option => option.value = '')

which returns me error:

Uncaught TypeError: options.forEach is not a function
    at HTMLButtonElement.<anonymous>

Code:

const input = document.querySelector('#input')
const datalist = document.querySelector('#datalist')
const submitButton = document.querySelector('#submit-button')

const values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

values.forEach(value => {
      const option = document.createElement('option')
      option.value = value
      datalist.appendChild(option)
})

submitButton.addEventListener('click', (e) => {
      e.preventDefault()

      values.splice(0, 5)

      values.forEach(value => {
            const option = document.createElement('option')
            option.value = value
            datalist.appendChild(option)
      })
})
<!DOCTYPE html>
<html lang="en">
<head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <script src="./test.js" defer></script>
</head>
<body>
      <input type="text" list="datalist" id="input">
      <datalist id="datalist"></datalist>

      <button type="submit" id="submit-button">Submit</button>
</body>
</html>


Solution

  • Actually this question wasn't published just me to answer it, but actually I've found a solution.

    I iterated through datalist children which returns HTMLCollection

    for (let option of datalist.children)
                option.value = ''
    

    And now code works as it has to

    const input = document.querySelector('#input')
    const datalist = document.querySelector('#datalist')
    const submitButton = document.querySelector('#submit-button')
    
    const values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    
    values.forEach(value => {
          const option = document.createElement('option')
          option.value = value
          option.id = 'datalist-option'
          datalist.appendChild(option)
    })
    
    submitButton.addEventListener('click', (e) => {
          e.preventDefault()
    
          values.splice(0, 5)
    
          for (let option of datalist.children)
                option.value = ''
    
          values.forEach(value => {
                const option = document.createElement('option')
                option.value = value
                datalist.appendChild(option)
          })
    })
    <!DOCTYPE html>
    <html lang="en">
    <head>
          <meta charset="UTF-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
          <script src="./test.js" defer></script>
    </head>
    <body>
          <input type="text" list="datalist" id="input">
          <datalist id="datalist"></datalist>
    
          <button type="submit" id="submit-button">Submit</button>
    </body>
    </html>