How append a json data in select box with optgroup - javascript

I am a newbie in jquery. I want to display JSON data to my select box. My JSON Data is
{
"Color":[
{
"Id":"1",
"Attrib_name":"Color",
"Attrib_value":"Red"
},
{
"Id":"2",
"Attrib_name":"Color",
"Attrib_value":"Blue"
}
],
"Size":[
{
"Id":"3",
"Attrib_name":"Size",
"Attrib_value":"5.6"
},
{
"Id":"4",
"Attrib_name":"Size",
"Attrib_value":"5.1"
}
]
}
I want to create optgroup with option based on the above json. i.e
<optgroup label="color">
<option>Red</option>
<option>Blue</option>
</optgroup>
<optgroup label="size">
<option>5.6</option>
<option>5.1</option>
</optgroup>
I am stuck on how to start. Please help me to get rid of this.

Just take the result of this code and paste it as HTML
What it does is iterate over your json object and create the elements.
var json = {
"Color":[
{
"Id":"1",
"Attrib_name":"Color",
"Attrib_value":"Red"
},
{
"Id":"2",
"Attrib_name":"Color",
"Attrib_value":"Blue"
}
],
"Size":[
{
"Id":"3",
"Attrib_name":"Size",
"Attrib_value":"5.6"
},
{
"Id":"4",
"Attrib_name":"Size",
"Attrib_value":"5.1"
}
]
}
console.log(
Object.keys(json).map(a=>`<optgroup label="${a}">${json[a].map(b=>`<option>${b.Attrib_value}</option>`).join``}</optgroup>`)
)

Here is a full example of how you can do this. You just have to build your HTML and use a jQuery function to add it in the html file. Check my codepen. Code is also bellow
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"
type="text/javascript"></script>
<select id="mySelect"></select>
<script type="text/javascript">
var data = {
"Color":[
{
"Id":"1",
"Attrib_name":"Color",
"Attrib_value":"Red"
},
{
"Id":"2",
"Attrib_name":"Color",
"Attrib_value":"Blue"
}
],
"Size":[
{
"Id":"3",
"Attrib_name":"Size",
"Attrib_value":"5.6"
},
{
"Id":"4",
"Attrib_name":"Size",
"Attrib_value":"5.1"
}
]
};
var html = "";
for(var option in data){
html += `<optgroup label="`+ option +`">`;
data[option].forEach(function(item){
html += `<option value="` + item["Attrib_value"] + `" >`+
item["Attrib_value"] +`</option>`
});
html += `</optgroup>`;
}
console.log('html',html);
$('#mySelect').html(html);
</script>

Since jQuery allows a nice api to create dom elements so I would use the following approach but other answer will work:
var data = {
"Color":[
{
"Id":"1",
"Attrib_name":"Color",
"Attrib_value":"Red"
},
{
"Id":"2",
"Attrib_name":"Color",
"Attrib_value":"Blue"
}
],
"Size":[
{
"Id":"3",
"Attrib_name":"Size",
"Attrib_value":"5.6"
},
{
"Id":"4",
"Attrib_name":"Size",
"Attrib_value":"5.1"
}
]
};
var select = $('<select/>');
$.each(data, function(g, colors) {
var group = $('<optgroup/>', {label:g});
$.each(colors, function(i, color) {
var option = $('<option/>', {
value: color.Attrib_value,
text: color.Attrib_value
});
select.append(group.append(option));
});
});
$('#dropdown').append(select);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='dropdown'></div>

Related

Convert a list of objects with paths to a nested hierarchy structure

This is my input:
[
{
"id":360006927051,
"name":"KBVSA::Agent",
"raw_name":"KBVSA::Agent",
"value":"kbvsa__agent",
"default":false
},
{
"id":360006927071,
"name":"KBVSA::Agent Procedure",
"raw_name":"VSA::Agent Procedure",
"value":"vsa__agent_procedure",
"default":false
},
{
"id":360006927091,
"name":"KBVSA::Anti-Malware",
"raw_name":"KBVSA::Anti-Malware",
"value":"kbvsa__anti-malware",
"default":false
},
{
"id":360006927111,
"name":"KMTraverse::Devices",
"raw_name":"KMTraverse::Devices",
"value":"kmtraverse__devices",
"default":false
},
{
"id":360006927131,
"name":"KMTraverse::Signatures",
"raw_name":"KMTraverse::Signatures",
"value":"kmtraverse_signatures",
"default":false
},
{
"id":360006927151,
"name":"MCBMS::HR",
"raw_name":"MCBMS::HR",
"value":"mcbms__hr",
"default":false
},
{
"id":360006927171,
"name":"MCBMS::Finance",
"raw_name":"MCBMS::Finance",
"value":"mcbms__finance",
"default":false
},
{
"id":360006927191,
"name":"TMONAuthAnvil::On-Demand::2FA",
"raw_name":"TMONAuthAnvil::On-Demand::2FA",
"value":"tmonauthanvil__on-demand__2fa",
"default":false
},
{
"id":360006927211,
"name":"TMONAuthAnvil::On-Premise::2fa",
"raw_name":"TMONAuthAnvil::On-Premise::2fa",
"value":"tmonauthanvil__on-premise__2fa",
"default":false
},
{
"id":360006927231,
"name":"KYUnigma::Monitor",
"raw_name":"kyUnigma::Monitor",
"value":"kyunigma__monitor",
"default":false
},
{
"id":360006927251,
"name":"KYUnigma::Report",
"raw_name":"kyUnigma::Report",
"value":"kyunigma__report",
"default":false
},
{
"id":360006927271,
"name":"2365 Command::Monitor",
"raw_name":"365 Command::Monitor",
"value":"365_command__monitor",
"default":false
},
{
"id":360006927291,
"name":"2365 Command::Report",
"raw_name":"2365 Command::Report",
"value":"2365_command__report",
"default":false
}
]
This is the output I am trying to get from it:
[
{
"label":"-",
"value":""
},
{
"label":"KBVSA",
"options":[
{
"label":"Agent",
"value":"kbvsa__agent"
},
{
"label":"Agent Procedure",
"value":"vsa__agent_procedure"
},
{
"label":"Anti-Malware",
"value":"vsa__anti-malware"
}
]
},
{
"label":"KMTraverse",
"options":[
{
"label":"Devices",
"value":"kmtraverse__devices"
},
{
"label":"Signatures",
"value":"kmtraverse_signatures"
}
]
},
{
"label":"MCBMS",
"options":[
{
"label":"HR",
"value":"mcbms__hr"
},
{
"label":"Finance",
"value":"mcbms__finance"
}
]
},
{
"label":"TMONAuthAnvil",
"options":[
{
"label":"On-Demand",
"options":[
{
"label":"2FA",
"value":"tmonauthanvil__on-demand__2fa"
}
]
},
{
"label":"On-Premise",
"options":[
{
"label":"2fa",
"value":"tmonauthanvil__on-premise__2fa"
}
]
}
]
},
{
"label":"KYUnigma",
"options":[
{
"label":"Monitor",
"value":"kyunigma__monitor"
},
{
"label":"Report",
"value":"kyunigma__report"
}
]
},
{
"label":"23365 Command",
"options":[
{
"label":"Monitor",
"value":"365_command__monitor"
},
{
"label":"Report",
"value":"365_command__report"
}
]
}
]
I'm trying to create a new array and push it to data like this. But I'm not able to make the exact output Array Name split ("::"), and distinguish between the first name(s), that is/are common, and the new label's value as sub arrays.
I'm trying to make a select option design where a single select will show multiple related values.
You could create a Map keyed by "path" (i.e. a "::"-delimited string), and map each key to a target node you have created for that key.
As you iterate the labels that make up a path, look up the corresponding partial path in that map, and if it doesn't exist yet, create the target object for it (with a label property), and include it in the parent's options property. That parent is the node that was retrieved/created in the previous iteration of this path traversal.
When the iteration of a path is complete, attach the value property to the last node that was created in that traversal.
As the entry { label: "-", value: "" } has no backing source in your input data, I just hard-coded it as an initialisation step. I didn't get clarification when I asked about it.
Here is an implementation:
function convert(data) {
const map = new Map;
const root = { options: [{ label: "-", value: "" }] };
for (const {name, value} of data) {
let path = "";
let parent = root;
for (const label of name.split("::")) {
path += "::" + label;
let node = map.get(path);
if (!node) {
map.set(path, node = { label });
(parent.options ??= []).push(node);
}
parent = node;
}
parent.value = value;
}
return root.options;
}
const data = [{"id":360006927051,"name":"KBVSA::Agent","raw_name":"KBVSA::Agent","value":"kbvsa__agent","default":false},{"id":360006927071,"name":"KBVSA::Agent Procedure","raw_name":"VSA::Agent Procedure","value":"vsa__agent_procedure","default":false},{"id":360006927091,"name":"KBVSA::Anti-Malware","raw_name":"KBVSA::Anti-Malware","value":"kbvsa__anti-malware","default":false},{"id":360006927111,"name":"KMTraverse::Devices","raw_name":"KMTraverse::Devices","value":"kmtraverse__devices","default":false},{"id":360006927131,"name":"KMTraverse::Signatures","raw_name":"KMTraverse::Signatures","value":"kmtraverse_signatures","default":false},{"id":360006927151,"name":"MCBMS::HR","raw_name":"MCBMS::HR","value":"mcbms__hr","default":false},{"id":360006927171,"name":"MCBMS::Finance","raw_name":"MCBMS::Finance","value":"mcbms__finance","default":false},{"id":360006927191,"name":"TMONAuthAnvil::On-Demand::2FA","raw_name":"TMONAuthAnvil::On-Demand::2FA","value":"tmonauthanvil__on-demand__2fa","default":false},{"id":360006927211,"name":"TMONAuthAnvil::On-Premise::2fa","raw_name":"TMONAuthAnvil::On-Premise::2fa","value":"tmonauthanvil__on-premise__2fa","default":false},{"id":360006927231,"name":"KYUnigma::Monitor","raw_name":"kyUnigma::Monitor","value":"kyunigma__monitor","default":false},{"id":360006927251,"name":"KYUnigma::Report","raw_name":"kyUnigma::Report","value":"kyunigma__report","default":false},{"id":360006927271,"name":"2365 Command::Monitor","raw_name":"365 Command::Monitor","value":"365_command__monitor","default":false},{"id":360006927291,"name":"2365 Command::Report","raw_name":"2365 Command::Report","value":"2365_command__report","default":false}];
const result = convert(data);
console.log(result);

Filter nested JSON with jQuery for empty values

I have a nested JSON which looks like this:
var unfilteredJSON = {
"payload":{
"oldKeys":[
"125262"
],
"keyData":[
{
"key":"123456",
"products":[
{
"prodId":"H1",
"qty":"1"
},
{
"prodId":"H2",
"qty":""
}
],
"rushFee":"true"
},
{
"key":"234234",
"products":[
{
"prodId":"H1",
"qty":"1"
},
{
"prodId":"H2",
"qty":""
}
],
"rushFee":"false"
}
],
"submit":"false"
}
}
The qty key can have empty values in the object. I want to filter the data with jQuery method and remove the object with blank qty so the JSON can look like this -
{
"payload":{
"oldKeys":[
"125262"
],
"keyData":[
{
"key":"123456",
"products":[
{
"prodId":"H1",
"qty":"1"
},
],
"rushFee":"true"
},
{
"key":"234234",
"products":[
{
"prodId":"H1",
"qty":"1"
},
],
"rushFee":"false"
}
],
"submit":"false"
}
}
Please help.
Here's a filter approach which mutates the object in-place:
var unfilteredJSON = {"payload":{"oldKeys":["125262"],"keyData":[{"key":"123456","products":[{"prodId":"H1","qty":"1"},{"prodId":"H2","qty":""}],"rushFee":"true"},{"key":"234234","products":[{"prodId":"H1","qty":"1"},{"prodId":"H2","qty":""}],"rushFee":"false"}],"submit":"false"}};
unfilteredJSON.payload.keyData.forEach(e =>
e.products = e.products.filter(p => p.qty)
);
console.log(unfilteredJSON);

I want to get my value from json data

i have json like this
{
"id":"1",
"name":"Kitchen Set",
"parent_id":"0",
},
{
"id":"2",
"name":"Bedroom",
"parent_id":"0"
},
{
"id":"3",
"name":"Living Room",
"parent_id":"0"
},
{
"id":"4",
"name":"Kitchen Set",
"parent_id":"1",
"price":"1000"
},
{
"id":"5",
"name":"Meja Bar",
"parent_id":"1",
"price":"2000"
},
and i want to add price: to my javascript
here is my question i want to get the price from my json to my javascript how can i do that??
i try this but it doesnt work
load_json_data('Price');
function load_json_data(price)
{
var html_code = '';
$.getJSON('int_fur_fin.json', function(data)
}
and this is my javascript
<script>
$(document).ready(function(){
load_json_data('Interior');
function load_json_data(id, parent_id)
{
var html_code = '';
$.getJSON('int_fur_fin.json', function(data){
html_code += '<option value="">Select '+id+'</option>';
$.each(data, function(key, value){
if(id == 'Interior')
{
if(value.parent_id == '0')
{
html_code += '<option value="'+value.id+'">'+value.name+'</option>';
}
}
else
{
if(value.parent_id == parent_id)
{
html_code += '<option value="'+value.id+'">'+value.name+'</option>';
}
}
});
$('#'+id).html(html_code);
});
}
$(document).on('change', '#Interior', function(){
var Interior_id = $(this).val();
if(Interior_id != '')
{
load_json_data('Furniture', Interior_id);
}
else
{
$('#Furniture').html('<option value="">Select Furniture</option>');
}
});
});
</script>
i use this javascript code to populate my dropdown
<form>
<select name="Interior Details" id="Interior" class="form-control input-lg">
<option value="">Select Interior Details</option>
</select>
<br />
<select name="Furniture" id="Furniture" class="form-control input-lg" required >
<option value="">Select Furniture</option>
</select>
</form>
You can use array.find() method to find the matching element. Also i have modified your JSON as a array.
items.find(t=>t.parent_id ==='1');
DEMO
var items = [{
"id":"1",
"name":"Kitchen Set",
"parent_id":"0",
},
{
"id":"2",
"name":"Bedroom",
"parent_id":"0"
},
{
"id":"3",
"name":"Living Room",
"parent_id":"0"
},
{
"id":"4",
"name":"Kitchen Set",
"parent_id":"1",
"price":"1000"
},
{
"id":"5",
"name":"Meja Bar",
"parent_id":"1",
"price":"2000"
}];
var result = items.find(t=>t.parent_id ==='1');
console.log(result);
EDIT
If you want multiple elements with matching id use array.filter.
var items = [{
"id":"1",
"name":"Kitchen Set",
"parent_id":"0",
},
{
"id":"2",
"name":"Bedroom",
"parent_id":"0"
},
{
"id":"3",
"name":"Living Room",
"parent_id":"0"
},
{
"id":"4",
"name":"Kitchen Set",
"parent_id":"1",
"price":"1000"
},
{
"id":"5",
"name":"Meja Bar",
"parent_id":"1",
"price":"2000"
}];
var result = items.filter(t=>t.parent_id ==='1');
console.log(result);

Displaying key and label from JSON data using JQUERY

Below is my json data which is stored in Checklistdata.json, i want to display the key and the labels as check boxes using jquery,my jquery will only display the label with check box.Any help, i will be grateful.
[
{
"Beginning": [
{
"label": "Enter basic information"
},
{
"label": "Enter name of Vendor "
}
]
}
]
Below is my jquery!!
$.getJSON('Checklistdata.json', function (data) {
$.each(data, function (i, entity) {
$('#Checklist').append($('<input />', { 'type': 'checkbox','label': entity.label, 'value': entity.is_correct })).append(entity.answer + '<br />');
});
$("#checkboxes").on('change', '[type=checkbox]', function () {
console.log($(this).val());
});
});
The way you are iterating around the data is the problem. After you change data to:
var data= [
{
"Beginning": [
{ "label": "Enter basic information","id":1 },
{ "label": "Enter name of Vendor ","id":2 }
]
}
];
Change your line of code:
$.each(data, function(key, val) {
to
$.each(data[0].Beginning, function(key, val) {
That is because data is an array of object. After you make this change you will see it moving a step closer to what you want to achieve! That should give you idea to modify your code further to do what you want it to do.
Here is a FIDDLE that will probably get you started.
The arrays would be the equivalent of your json data.
You'd need to style it and change the format to suit your needs.
It's not very elegant, but seems to work.
JS
var myarray1 = ['y', 'n', 'y', 'y', 'y'];
var myarray2 = ['A', 'B', 'C', 'D', 'E'];
$('#mybutton').click(function(){
$.each(myarray2, function(key, value){
$('#holderdiv').append(value + "<input type='checkbox' />" + '<br />');
});
$('input[type=checkbox]').each(function(index){
if(myarray1[index] == 'y')
{
$(this).prop('checked', true);
}
});
});
EDIT:
Ok, here's the new FIDDLE that works with your array.
It's a good idea to use jsonlint.com to check the validity of your json array.
New JS
var mydata = {
"Beginning": [
{ "label": "Enter basic information", "id": 1 },
{ "label": "Enter name of Vendor ", "id": 2 }
]
};
var firstvar = mydata.Beginning[0].id;
$('#mybutton').click(function(){
$.each(mydata.Beginning, function(key, value){
$('#holderdiv').append(mydata.Beginning[key].label + "<input type='checkbox' />" + '<br />');
});
$('input[type=checkbox]').each(function(index){
if( mydata.Beginning[index].id == 1)
{
$(this).prop('checked', true);
}
});
});
I have got my answer. have to made some changes to JSON data storing, but it satisfies my requirement. So below is the answer with fiddle. http://jsfiddle.net/Suma_MD/fWLgD/2/
var data = getData(),
$checklist = $('#checklist');
data.forEach(function (v) {
var Description = v.Description;
$checklist.append('<br>' + Description);
var Array1=v.Checklist;
var Array2;
Array1.forEach(function(d){
Array2 = d.label;
$checklist.append('<br>' +"<input type='checkbox' />" + Array2 );
});
});
function getData() {
return [
{
"Description": "Beginning1",
"Checklist": [
{
"label": "Enter basic information",
},
{
"label": "Enter basic information",
},
{
"label": "Enter basic information",
},
{
"label": "Enter basic information",
}
]
},
{
"Description": "Beginning2",
"Checklist": [
{
"label": "Enter basic ",
},
{
"label": "Enter basic ",
},
{
"label": "Enter basic ",
},
{
"label": "Enter basic ",
}
]
}
];
}
HTML : <div id="checklist"></div>

How to change the current value of a select list bound with ng-options?

I have a select list created like this:
<div class="actionList" ng-repeat="selectedAction in outputDevice.selectedActions">
<select class="outputAction" ng-model="selectedAction.value" ng-options="action as action.name for action in outputDevice.userDevice.baseDevice.outputs">
<option value="">
Select Action
</option>
</select>
</div>
It is contained within a create/edit page. When the page is in edit mode, I want to chose which item in the list is selected, based on some values retrieved from the server. Currently the select list will populate with the correct options, but I can't make the select list start on the correct value. Here is the code where I populate the values on the page:
for(var i =1; i<result.length; i++){
var appyDevice = result[i];
var userDevice = appyDevice.device;
var selectedActions;
if(appyDevice.outputs){
selectedActions = appyDevice.outputs;
for(var j =0; j<selectedActions.length; j++){
selectedActions[j].value = {
name: selectedActions[j].name,
id: selectedActions[j].id
};
}
$ctrlScope.outputDevices.push({
userDevice: userDevice,
selectedActions: selectedActions
});
}
}
$ctrlScope.$apply();
I set selectedActions[j].value, which the select list is bound to, however it does not update. Any ideas why this isn't working? Or other ways to do this?
EDIT:
Here is a sample of the results JSON (ignore the redundant information and stuff, we're working on the serialization still):
[
{
"user":{
"id":1,
"username":"asdf",
"email":"asdf"
},
"id":1,
"name":"SuperAppy",
"description":"some super duper descriptioon "
},
{
"appy":{
"user":{
"id":1,
"username":"asdf",
"email":"asdf"
},
"id":1,
"name":"SuperAppy",
"description":"some super duper descriptioon "
},
"inputs":[
{
"id":1,
"name":"Shake"
}
],
"outputs":[
{
"id":1,
"name":"TurnOn"
}
],
"device":{
"user":{
"id":1,
"username":"asdf",
"email":"asdfm995#gmail.com"
},
"baseDevice":{
"inputs":[
{
"id":1,
"name":"Shake"
},
{
"id":2,
"name":"Slide"
}
],
"outputs":[
{
"id":1,
"name":"TurnOn"
},
{
"id":2,
"name":"TurnOf"
}
],
"id":1,
"name":"iPhone5",
"osVersion":5.0,
"appVersion":0.0
},
"id":1
},
"id":1
},
{
"appy":{
"user":{
"id":1,
"username":"asdf",
"email":"asdfm995#gmail.com"
},
"id":1,
"name":"SuperAppy",
"description":"some super duper descriptioon "
},
"inputs":[
{
"id":1,
"name":"Shake"
},
{
"id":2,
"name":"Slide"
}
],
"outputs":[
{
"id":2,
"name":"TurnOf"
}
],
"device":{
"user":{
"id":1,
"username":"asdf",
"email":"asdfm995#gmail.com"
},
"baseDevice":{
"inputs":[
{
"id":1,
"name":"Shake"
},
{
"id":2,
"name":"Slide"
}
],
"outputs":[
{
"id":1,
"name":"TurnOn"
},
{
"id":2,
"name":"TurnOf"
}
],
"id":3,
"name":"GalaxyS3",
"osVersion":5.0,
"appVersion":0.0
},
"id":3
},
"id":2
}
]
Edit 2:
As per the possible duplicate linked in the comments, I attempted to add an ng-init to no avail:
<select class="inputAction" ng-model="selectedAction.value" ng-options="action as action.name for action in inputDevice.userDevice.baseDevice.inputs" ng-init="selectedAction.value=selectedAction.name">
I think this is irrelevant anyways, as I am effectively doing this initialization in the following lines of my code:
selectedActions[j].value = {
name: selectedActions[j].name,
id: selectedActions[j].id
};
I've modified mb21's fiddle to get your code working and demonstrate initializing the values.
http://jsfiddle.net/GCrU3/
The issue is, when you use ng-model on the select and ng-options for the options, you must set the ng-model variable to the exact reference of the object that is being used to generate that option:
for(var j =0; j<selectedActions.length; j++){
selectedActions[j].value = userDevice.baseDevice.outputs[0]; // change index to select different initial value
}

Categories