Search code examples
javascripthtmljqueryhtml-selectoptgroup

jquery/javascript to loop value and optgroup


data

0: {id: 1, banks: 'b1', code: 'active'}
1: {id: 2, banks: 'b2', code: 'parking'}
2: {id: 3, banks: 'b3', code: 'safe'}
3: {id: 4, banks: 'b4', code: 'active'}
4: {id: 5, banks: 'b5', code: 'safe'}
5: {id: 6, banks: 'b6', code: 'parking'}

//code start to append in html

 $('#selectiona').append($('<select name="bankselect" class="bankselect"></select>'));
      
    $.each(data.bank, function (i, item) {
       $('.bankselect').append($('<option>', { 
                                                    value: item.id,
                                                    text : item.banks
                                                }));
    });

outcome

<select name="bankselect" class="bankselect">
   <option value="1">b1</option>
   <option value="2">b2</option>
   <option value="3">b3</option>
   <option value="4">b4</option>
   <option value="5">b5</option>
   <option value="6">b6</option>
</select>

Question: I'm beginner of the JavaScript. The above code is work to use JavaScript code to append the selection box into html and the loop the data to insert option value into it. But I stuck at how to loop and assign it into optgroup in the selection. Anyone can help on that T.T?

Expected Final Outcome

<select name="bankselect" id="bankselect">
    <optgroup label="active">
      <option value="1">b1</option>
      <option value="4">b4</option>
    </optgroup>
    <optgroup label="parking">
      <option value="2">b2</option>
      <option value="6">b6</option>
    </optgroup>
    <optgroup label="safe">
      <option value="3">b3</option>
       <option value="5">b5</option>
    </optgroup>
  </select>

Solution

  • Your data is not ready for reproducible, next time please provide sample data that is able to reproduce.

    I use re-format the data first, to make it ready to iterate and render into HTML. Then I use for..loop to render in HTML string and then append into HTML element.

    Here is the code.

    let data = {
        bank: {
            0: {
                id: 1,
                banks: 'b1',
                code: 'active'
            },
            1: {
                id: 2,
                banks: 'b2',
                code: 'parking'
            },
            2: {
                id: 3,
                banks: 'b3',
                code: 'safe'
            },
            3: {
                id: 4,
                banks: 'b4',
                code: 'active'
            },
            4: {
                id: 5,
                banks: 'b5',
                code: 'safe'
            },
            5: {
                id: 6,
                banks: 'b6',
                code: 'parking'
            }
        }
    };
    
    // reformat data.
    let reformatted = {};
    $.each(data.bank, function(i, item) {
        if (!reformatted[item.code]) {
            reformatted[item.code] = [];
        }
        reformatted[item.code].push({
            value: item.id,
            text: item.banks,
        });
    });
    
    $('#selectiona').append($('<select name="bankselect" class="bankselect"></select>'));
    
    // render HTML string of select option and optgroup.
    let bankSelectbox = document.querySelector('.bankselect');
    let renderedHTMLString = '';
    // loop group names
    for (const [groupname, items] of Object.entries(reformatted)) {
        renderedHTMLString += '<optgroup label="' + groupname + '">';
        // loop items for select > option
        for (const eachItem of items) {
            renderedHTMLString += '<option value="' + eachItem.value + '">' + eachItem.text + '</option>';
        }
        renderedHTMLString += '</optgroup>';
    }
    // now append HTML string to HTML element.
    bankSelectbox.insertAdjacentHTML('beforeend', renderedHTMLString);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="selectiona"></div>

    I use your $.each() to re-format the data and then use pure JS for() loop to render HTML. This reduce usage of jQuery.

    See it work on jsfiddle.