skip to Main Content

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>

3

Answers


  1. You can do it with an object and two for loops, something like this:

      const select = document.getElementById("bankselect");
      const sortedData = {};
      const data = [
        { id: 1, banks: "b1", code: "active" },
        { id: 2, banks: "b2", code: "parking" },
        { id: 3, banks: "b3", code: "safe" },
        { id: 4, banks: "b4", code: "active" },
        { id: 5, banks: "b5", code: "safe" },
        { id: 6, banks: "b6", code: "parking" }
      ];
      for (let i = 0; i < data.length; ++i) {
        sortedData[data[i].code] ??= [];
        sortedData[data[i].code].push(data[i]);
      }
      const entries = Object.entries(sortedData);
      for (let i = 0; i < entries.length; ++i) {
        const [key, values] = entries[i];
        const optGroup = document.createElement("optgroup");
        optGroup.label = key;
        for (let j = 0; j < values.length; ++j) {
          const opt = document.createElement("option");
          opt.value = values[j].id;
          opt.innerText = values[j].banks;
          optGroup.append(opt);
        }
        select.append(optGroup);
      }
    <div id="app">
          <select name="bankselect" class="bankselect" id="bankselect"> </select>
    </div>
    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
  3. Details are commented in example

    /**
     * data.banks
     */
    const data = {
      bank: [{
          id: 1,
          banks: 'b1',
          code: 'active'
        },
        {
          id: 2,
          banks: 'b2',
          code: 'parking'
        },
        {
          id: 3,
          banks: 'b3',
          code: 'safe'
        },
        {
          id: 4,
          banks: 'b4',
          code: 'active'
        },
        {
          id: 5,
          banks: 'b5',
          code: 'safe'
        },
        {
          id: 6,
          banks: 'b6',
          code: 'parking'
        }
      ]
    };
    
    /**
     * Define array
     * Add <select> to <form>
     */
    const array = data.bank;
    
    $('#form1').append(`<select name="bankselect" class="bankselect"></select>`);
    
    /**
     * .map() an array of item.code
     * Remove duplicate values and name the array "labels"
     */
    const groups = $.map(array, function(item) {
      return item.code;
    });
    const labels = [...new Set(groups)];
    
    /**
     * Create an <optgroup> with a label attribute of the 
     * current value of the "labels" array
     */
    $.each(labels, function(i, label) {
      $('.bankselect').append(
        `<optgroup label="${label}"></optgroup>`);
    });
    
    /**
     * For each <optgroup>
     * Define current <optgroup>
     * Define current <optgroup> label
     * Then for each item of array...
     * If item.code equals current <optgroup> label...
     * add am <option> with value of item.id and text of
     * item.banks
     */
    $('optgroup').each(function() {
      let currentOG = $(this);
      let code = currentOG.attr('label');
      $.each(array, function(i, item) {
        if (item.code === code) {
          currentOG.append(`<option value="${item.id}">${item.banks}</option>`);
        }
      });
    });
    <form id='form1'></form>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search