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 indentedul
/li
includingoptgroup
elementsonclick
JSONify<select>
toconsole.log()
and it can further be passed to aFetch
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.