JSONify Dropdown Element Using Vanilla JavaScript

This function converts a regular <select> element both into an intented ul/li structure and JSON. It’s light and it’s been developed for a specific internal purpose. If you find it useful, with a small change, it also allows for exporting the option state (selected or not).

Features

  • onclick convert select to indented ul/li including optgroup elements
  • onclick JSONify <select> to console.log() and it can further be passed to a Fetch event

Demo

See a live demo here.

HTML

The HTML structure builds a multiselect dropdown and an empty JSON container:

<div id="myselect">
    <select id="multiselect" name="languages[]" size="6" multiple>
        <optgroup label="More Cars">
            <option value="1">JavaScript</option>
            <option value="2">CSS</option>
            <option value="3">Script</option>
            <option value="4">Ruby</option>
            <option value="5">Go</option>
            <option value="6">PHP</option>
            <option value="7">.Com</option>
            <option value="8">Java</option>
        </optgroup>
        <optgroup label="Swedish Cars">
            <option value="volvo">Volvo</option>
            <option value="saab">Saab</option>
        </optgroup>
        <optgroup label="German Cars">
            <option value="mercedes">Mercedes</option>
            <option value="audi">Audi</option>
        </optgroup>
    </select>
    <div id="json"></div>
</div>

JavaScript

<script>
function jsonifySelect(selectId) {
    const theSelect = document.getElementById('multiselect'),
          optgroups = theSelect.getElementsByTagName('optgroup');
    let myObj = {};

    for (let i = 0; i < optgroups.length; i++) {
        myObj[optgroups[i].getAttribute('label')] = [];
        let options = optgroups[i].getElementsByTagName('option');
        for (let j = 0; j < options.length; j++) {
            myObj[optgroups[i].getAttribute('label')].push(options[j].innerHTML);
        }
    }

    return myObj;
}

function recurse(data) {
    let result = '<ul>';

    for (let key in data) {
        if (typeof(data[key]) == 'object' && data[key] != null) {
            let x = key*1;

            if (isNaN(x)) {
                result += `<li>${key}<ul>`;
            }
            result += recurse(data[key]);
            result += '</ul></li>';
        } else {
            result += (`<li data-value="${data[key]}">${data[key]}</li>'`);
        }
    }

    result += '</ul>';

    return result;
}

document.addEventListener('DOMContentLoaded', () => {
    document.getElementById('myselect').addEventListener('click', () => {
        console.log(jsonifySelect('multiselect'));

        let htmlStr = recurse(jsonifySelect('multiselect'));
        document.getElementById('json').innerHTML = htmlStr;
    });
});
</script>

Note: In the jsonifySelect() function, inside the for (let j = 0; j < options.length; j++) { loop, check for options[j].selected to see if the option has been selected by the user.

Example:

<script>
// code here

for (let j = 0; j < options.length; j++) {
    myObj[optgroups[i].getAttribute('label')].push([options[j].innerHTML, options[j].selected]);
        }

// more code here
</script>

In this case, I push an array containing the name of the item and the option state (boolean), true or false. This requires some changes to the ul/li structure, but if you’re not using and you’re only the JSON result, you should be good.

Find more JavaScript tutorials, code snippets and samples here or more jQuery tutorials, code snippets and samples here.

πŸ‘‹ Added by Ciprian on Wednesday, December 2, 2020 in Blog, JavaScript. Last modified on Wednesday, December 2, 2020.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Privacy Policy