DEV Community

JesseNReynolds
JesseNReynolds

Posted on

Iteratively Creating Select Options in JavaScript

I recently completed a Vanilla JavaScript app that charts music in a modified form of the Nashville Number System.

Alt Text

The composition is handled by a form that is a bunch of grouped selects, each measure is divided into two half measures which each have two selects representing interval from the tonic and any character modifications to the chord. The form is generated from a JSON object stored in a database row on my back end, and when modified and saved the form is transformed into a JSON object to be persisted in the same way.

The thing I want to talk about in this article, though, is the selects themselves. As you can see, even in a fairly simple song, there are a lot of them.
Intervals of chords

Modifiers to chords

And each of them has a lot of options. In the future, the second set of options, the chord modifiers, might well be expanded upon or referenced elsewhere, so we need to make sure that if there's an update to the supported modifiers it's an easy update in our app.

I addressed both concerns (the large list of options, and the probability that list would be added to later) by making each of these lists of options into arrays and then adding them to the selects when the selects are created and appended to the DOM.

const INTERVALS = ["", "1", "b2", "2", "b3", "3", "b4", "4", "b5", "5", "b6", "6", "b7", "7"]
const MODIFIERS = ["", "maj", "min", "maj7", "min7", "maj9", "min9", "dim"]

...

    static buildSelectsFromHalfMeasure(halfMeasure, targetDiv) {
        const intervalSelect = document.createElement('select')
        targetDiv.appendChild(intervalSelect)

        const modifierSelect = document.createElement('select')
        targetDiv.appendChild(modifierSelect)

        INTERVALS.forEach(interval => {
            const option = document.createElement('option')
            option.text = interval
            intervalSelect.add(option)
        })

        MODIFIERS.forEach(modifier => {
            const option = document.createElement('option')
            option.text = modifier
            modifierSelect.add(option)
        })

        intervalSelect.value = halfMeasure["interval"]
        modifierSelect.value = halfMeasure["modifier"]

        intervalSelect.addEventListener('change', Song.addSaveButtonIfNonePresent)
        modifierSelect.addEventListener('change', Song.addSaveButtonIfNonePresent)
    }
Enter fullscreen mode Exit fullscreen mode

For each half measure, we create a div. We append that div to the div that belongs to the measure, and to the half-measure div, we append two selects, then we iterate over our list of intervals and modifiers to populate the options for the selects. If in the future I want to add seemingly bizarre chord modifiers like "13sus4add2" I can do that in one place and know that everywhere I'm referencing all available modifiers, it's been addressed.

Top comments (0)