How to build SELECT from JSON response

I need to build this select input dynamically from a JSON response:



HTML SAMPLE
 <select class="form-control select2 select2-hidden-accessible" tabindex="-1" aria-hidden="true">
                                                <option>Select</option>
                                                <optgroup label="Apple">
                                                    <option value="iPhone 5">iPhone 5</option>
                                                    <option value="iPhone 6">iPhone 6</option>
                                                </optgroup>
                                                <optgroup label="Samsung">
                                                    <option value="Galaxy S5">Galaxy S5</option>
                                                    <option value="Galaxy S5 Note">Galaxy S5 Note</option>
                                                </optgroup>
                                                <optgroup label="Another OEM Provicer Here">
                                                    <option value="">model name</option>
                                                    <option value="">model name</option>
                                                </optgroup>
                                                
                                            </select>

Open in new window


Based on that, this is what I am getting back from my JSON. The OEMID is the key manufacturer ( Apple, Samsung, etc ). So for each oemid, I need to loop through and build the above Select statement. And I am stumped.

JSON RESPONSE
[
  {
    "id": 1,
    "name": "iPhone 5",
    "oemId": 1,
    "rank": null,
    "oem": null,
    "active": true
  },
  {
    "id": 2,
    "name": "iPhone 6",
    "oemId": 1,
    "rank": null,
    "oem": null,
    "active": true
  },
  {
    "id": 3,
    "name": "iPhone 7",
    "oemId": 1,
    "rank": null,
    "oem": null,
    "active": true
  },
  {
    "id": 4,
    "name": "Galaxy S5",
    "oemId": 2,
    "rank": null,
    "oem": null,
    "active": true
  },
  {
    "id": 5,
    "name": "Galaxy S5 Note",
    "oemId": 2,
    "rank": null,
    "oem": null,
    "active": true
  },
  {
    "id": 6,
    "name": "Galaxy J7",
    "oemId": 2,
    "rank": null,
    "oem": null,
    "active": true
  },
  {
    "id": 7,
    "name": "iPhone 7\r\n Plus",
    "oemId": 1,
    "rank": null,
    "oem": null,
    "active": true
  },
  {
    "id": 8,
    "name": "iPhone 8\r\n",
    "oemId": 1,
    "rank": null,
    "oem": null,
    "active": true
  },

  {
    "id": 10,
    "name": "Galaxy S5 Active\r\n",
    "oemId": 2,
    "rank": null,
    "oem": null,
    "active": true
  },
  {
    "id": 11,
    "name": "Galaxy S6\r\n",
    "oemId": 2,
    "rank": null,
    "oem": null,
    "active": true
  },
  {
    "id": 12,
    "name": "Galaxy S6 Edge\r\n",
    "oemId": 2,
    "rank": null,
    "oem": null,
    "active": true
  },
  {
    "id": 13,
    "name": "Galaxy S6 Active\r\n",
    "oemId": 2,
    "rank": null,
    "oem": null,
    "active": true
  },
  {
    "id": 14,
    "name": "LG G4\r\n",
    "oemId": 8,
    "rank": null,
    "oem": null,
    "active": true
  },
  {
    "id": 15,
    "name": "LG G5\r\n",
    "oemId": 8,
    "rank": null,
    "oem": null,
    "active": true
  }
]

Open in new window


Does anybody know how I'd go about this using JavaScript to build the select? Thanks so much for looking.

John
John S.Web DeveloperAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

John S.Web DeveloperAuthor Commented:
I just noticed I left out the OEM Name. It will be in there though ( in the JSON )
Julian HansenCommented:
Somewhere you need to get a mapping for OEM ID so you can link that to the manufacture display name. I have created an array to hold this data.
Assuming your <select> looks like this
<select id="phones" class="form-control">
  <option>Select</option>
</select>

Open in new window

We can create the following jQuery / JavaScript to reformat your JSON data into a structure more conducive to creating the output you want. Essentially what we are doing is grouping all like records under a common parent as the first pass through the data - we then take our new structure and use that to render out the list.

I have created a function that takes a jQuery reference to the <select> to populate and the parsed JSON data.
function populate(select, phones)
{
  var options = {};
  // FIRST BUILD OUR GROUPED STRUCTURE
  for(var i = 0 ; i < phones.length;i++) {
    var idx = phones[i]['oemId'];

    var oem = oemList[idx] || 'Another OEM Provider Here';
    if (!options[oem]) {
      options[oem] = []
    }
    options[oem].push(phones[i]['name']);
  }
  
  // NOW RENDER IT
  // THIS ALLOWS FOR THE DATA TO BE IN ANY ORDER AND STILL
  // BE GROUPED CORRECTLY ACCORDING TO OEM
  for(var o in options) {
    var optgroup = $('<optgroup>', {label: o});
    for(var i = 0; i < options[o].length; i++) {
      optgroup.append($('<option>').text(options[o][i]));
    }
    select.append(optgroup);
  }
}

Open in new window


You can view this working here

EDIT
I left out the Array I use to map OEM ID to the name
var oemList = {
  '1' : 'Apple',
  '2' : 'Samsung'
}

Open in new window

The code assumes if the ID is not in that list it must use the label 'Another OEM Provider Here'

If your JSON contains the OEM name you can simply remove the Array look up and put the name in directly.
Julian HansenCommented:
Function that assumes OEM name is in the JSON return as oemName
function populate(select, phones)
{
  var options = {};
  // FIRST BUILD OUR GROUPED STRUCTURE
  for(var i = 0 ; i < phones.length;i++) {
    var idx = phones[i]['oemId'];

    // THIS IS THE ONLY LINE YOU CHANGE
    var oem = phones[i]['oemName'];
    if (!options[oem]) {
      options[oem] = []
    }
    options[oem].push(phones[i]['name']);
  }
  
  // NOW RENDER IT
  // THIS ALLOWS FOR THE DATA TO BE IN ANY ORDER AND STILL
  // BE GROUPED CORRECTLY ACCORDING TO OEM
  for(var o in options) {
    var optgroup = $('<optgroup>', {label: o});
    for(var i = 0; i < options[o].length; i++) {
      optgroup.append($('<option>').text(options[o][i]));
    }
    select.append(optgroup);
  }
}

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
John S.Web DeveloperAuthor Commented:
Thank you very much, Julian.  That is exactly what I needed. I wish I could give you a million points!
Julian HansenCommented:
You are most welcome.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.