Search code examples
javascriptjsonlocal-storagemulti-selectstringify

How to save multiple HTML multi-select option values into local storage?


I'm trying to provide a multi-select HTML element in which the user can select one or more payment methods. I also want to prevent data loss in case the user accidentally presses back button or equivalent and then comes back. I want to offer the users the freedom to change the URL (whether it's intended or not) and after return continuing from where they left.

The below code stores the latest multi-select option value into the local storage and fills it back on page load. That was easy. But how to store multiple values like for example "credit cards" and "cash" into the local storage?

I've studied JSON stringify function but so far I couldn't make it right, so I didn't leave my failed attempts into the code. I've also studied more or less related questions on this page but couldn't make use of the short replies the experts were pointing out.

(To make it shorter I didn't include styles. For the same reason, I didn't include the form that this is a part of. If it's not totally obvious, you can select multiple values by pressing CTRL [command should work on Mac] and clicking on the options.)

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    Select one or more payment methods:
    <br>
    <select multiple id="payment_methods" onchange="saveMultipleValues(this);">

        <option value="credit"> Credit cards</option>
        <option value="iban">   IBAN        </option>
        <option value="cash">   Cash        </option>
        
    </select>

    <script>
        // Passing multiselect id "payment_methods" to below function "getSavedValue" to 
        // check if local storage has a value for it. If value exists, selecting it on the
        // payment methods list above.
        document.getElementById("payment_methods").value = getSavedValue("payment_methods"); 

        function saveMultipleValues(currentObject){
            var id  = currentObject.id;     // get the requester's id to save it 
            var val = currentObject.value;  // get the value
            localStorage.setItem(id, val);  // On user input, the local storage's value will
                                            // override which should be fixed
        }
        
        function getSavedValue(v){
            if (localStorage.getItem(v)) // if there is a value for the current HTML id...
            {
                return localStorage.getItem(v); // value found, returning it
            }
        }
    </script>
</body>
</html>

Solution

  • this way:

    <select id="payment_methods"  multiple >
      <option value="credit"> Credit cards</option>
      <option value="iban">   IBAN        </option>
      <option value="cash">   Cash        </option>
    </select>
    
    const payMethSelect = document.querySelector('#payment_methods');
    
    // init
    let opts = (JSON.parse( localStorage.getItem('payment_methods') || '[]' ))
    Array.from( payMethSelect.options).forEach(opt => 
      {
      opt.selected = opts.includes(opt.value)
      });
    
    payMethSelect.onchange =_=>
      {
      let opts = Array.from(payMethSelect.selectedOptions).map(opt=>opt.value)
      localStorage.setItem('payment_methods', JSON.stringify(opts))
      }