Get value from specific JSON object based on first selection - javascript

I have a set of dropdowns which I will be populating with JSON. What I would like to do is populate the first dropdown with the name of each object. Then when someone selects an option from the first dropdown, the second dropdown is populated with other data pertaining to their first selection. What I have right now is populating the first select box with the name of a product and assigning the value to the ID For the second dropdown I want the options to be based on the options associated with the product that was selected in the first dropdown, based on ID.
Here's what I have so far, I am not sure how to only get the data from the selected product based on the products ID:
$(function() {
var products = [{
"id": 0,
"name": "First Product",
"sizes": [{
"size": "small"
},{
"size": "medium"
}]
},
{
"id": 1,
"name": "Second Product",
"sizes": [{
"size": "small"
},{
"size": "medium"
}]
}
]
$.each(products, function(key, val) {
$('.first').append('<option value="' + val.id + '">' + val.name + '</option>');
});
$('.first').change(function() {
var selectedProduct = $(this).val();
$.each(products['id'][selectedProduct], function(key, val) {
$('second').append('<option id="' + val.sizes.size + '">' + val.sizes.size + '</option>');
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="first">
</select>
<select class="second">
</select>

$(function() {
var products = [{
"id": 0,
"name": "First Product",
"sizes": [{
"size": "small"
},{
"size": "medium"
}]
}, {
"id": 1,
"name": "Second Product",
"sizes": [{
"size": "small"
},{
"size": "medium"
}]
}]
$.each(products, function(key, val) {
$('.first').append('<option value="' + val.id + '">' + val.name + '</option>');
});
$('.first').change(function() {
var selectedProduct = $(this).val();
var getProduct = products.filter(function( obj ) {
return obj.id == selectedProduct;
});
$('.second').find('option').remove();
$.each(getProduct[0].sizes, function(key, val) {
$('.second').append('<option id="' + val.size + '">' + val.size + '</option>');
});
});
});

You just need to iterate over products again to find the one with the currently selected ID. Then, iterate over its sizes and fill the second just like you did with the first.
Clear the options each time.
And, trigger a 'change' at the start to get the second's filled to begin with.
$(function() {
var products = [{
"id": 0,
"name": "First Product",
"sizes": [{
"size": "small"
},{
"size": "medium"
}]
},
{
"id": 1,
"name": "Second Product",
"sizes": [{
"size": "med"
},{
"size": "large"
}]
}
]
$.each(products, function(key, val) {
$('.first').append('<option value="' + val.id + '">' + val.name + '</option>');
});
$('.first').change(function() {
var selectedProduct = $(this).val();
$.each(products, function(key, val) {
if (val.id==selectedProduct) {
$('.second').find('option').remove();
$.each(val.sizes, function(key2, val2) {
$('.second').append('<option value="' + val2.size + '">' + val2.size + '</option>');
});
}
});
});
$('.first').trigger('change');
});

You could stick the object on the option as a data field for reference.
$(function() {
var products = [{
"id": 0,
"name": "First Product",
"sizes": [{
"size": "small"
},{
"size": "medium"
}]
},
{
"id": 1,
"name": "Second Product",
"sizes": [{
"size": "small"
},{
"size": "medium"
}]
}
]
$.each(products, function(key, val) {
var $option = $('<option>').val(val.id).text(val.name).data('object-reference', val);
$('.first').append($option);
});
$('.first').change(function() {
var selectedProduct = $(this).find('option:selected');
$.each(selectedProduct.data('object-reference').sizes, function(key, val) {
$('.second').append('<option id="' + val.size + '">' + val.size + '</option>');
});
});
setTimeout(function(){
products[1].sizes = [ { 'size': 'changed1' }, { 'size': 'changed2' } ];
}, 2000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="first">
</select>
<select class="second">
</select>

Related

Avoid Iterating Outer Loop

I've a scenario where I've to iterate two list or arrays to get required values. So I am doing something like this:
var html = "";
$.each(list, function (i, set1) { //set1 is a list or array
$.each(set1.Tabs, function (i, set2) { //set1.Tabs is another one
html += "<li><a href='#" + set2.TabName + "'>" + set2.Details + "</a> <span class='ui-icon ui-icon-close' role='presentation'>Remove Tab</span></li>";
})
})
The above works fine, it returns me the required data. But the problem is, say the outer loop has 10 values and the inner loop has four values. So the inner loop gets iterated ten times with the four values. This is natural and it should do. I was trying to get distinct values using the following (For the outer loop specifically):
list = list.filter((x, i, a) => a.indexOf(x) === i);
Though the above should work, my expected output is as follows:
Input: [1, 2, 3, 3, 4, 5, 6, 6]
Output: [1, 2, 3, 4, 5, 6]
N.B: My concern is with the inner loop, not with the outer one. But to iterate the inner loop, I've to go through the outer loop. Is there any way I can get the inner loop work directly?
Update 1: Sample Code
$(document).ready(function() {
var html = "";
var data = [{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" }
]
},
{
"id": "0002",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" }
]
}
]
$.each(data, function(i, set1) { //set1 is a list or array
$.each(set1.topping, function(i, set2) { //set1.Tabs is another one
html += "<li><a href='#" + set2.id + "'>" + set2.type + "</a> <span class='ui-icon ui-icon-close' role='presentation'>Remove Tab</span></li>";
})
})
$('#add').append(html);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="add"></div>
You can create unique toppings based on the id and then render the list using unique toppings. To create unique toppings, you can use flatMap() Object.values() and array#reduce.
$(document).ready(function() {
var html = "";
var data = [{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"topping": [{
"id": "5001",
"type": "None"
},
{
"id": "5002",
"type": "Glazed"
},
{
"id": "5005",
"type": "Sugar"
},
{
"id": "5007",
"type": "Powdered Sugar"
}
]
},
{
"id": "0002",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"topping": [{
"id": "5001",
"type": "None"
},
{
"id": "5002",
"type": "Glazed"
},
{
"id": "5005",
"type": "Sugar"
},
{
"id": "5007",
"type": "Powdered Sugar"
}
]
}
]
const uniqueToppings = Object.values(data
.flatMap(o => o.topping)
.reduce((r, {id, type}) => {
r[id] = r[id] || {id, type};
return r;
},{}));;
$.each(uniqueToppings, function(i, set) {
html += "<li><a href='#" + set.id + "'>" + set.type + "</a> <span class='ui-icon ui-icon-close' role='presentation'>Remove Tab</span></li>";
});
$('#add').append(html);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="add"></div>

How to get array value in seperate combobox

I want to get the array value in separate comboboxes using JavaScript and PHP. Suppose i have array like
0:{"id":"none","name":"none"},1:{"id":"none","name":"none"},2:{"id":"write","name":"write"}
I want that 0 index array will show in first combo box, 1 index array will show in 2nd combo box and so on, all combo boxes having same name. But when I done it is showing all arrays in one combo box .Here is my code
var data = [{
"id": "none",
"name": "none"
}, {
"id": "none",
"name": "none"
}, {
"id": "write",
"name": "write"
}]
$.each(data, function(i, item) {
$('#modules').append('<option value="' + data[i].id + '">' + data[i].name + '</option>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="modules"></select>
You want 3 dropdowns?
var data = {
"one": [{ "id": "none", "name": "none 1" }, { "id": "none", "name": "none 1" }, { "id": "write", "name": "write 1" }],
"two": [{ "id": "none", "name": "none 2" }, { "id": "none", "name": "none 2" }, { "id": "write", "name": "write 2" }],
"three": [{ "id": "none", "name": "none 3" }, { "id": "none", "name": "none 3" }, { "id": "write", "name": "write 3" }]
}
$.each(data, function(i, item) {
var $sel = $("<select/>", {
"name": "data"
});
$.each(item, function(i, selItem) {
$sel.append('<option value="' + selItem.id + '">' + selItem.name + '</option>')
});
$('#modules').append($sel);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="modules"></div>
If you wanted to achieve this using plain JavaScript, please see below snippet with desired output - select dropdown with text from objects in array populating the options.
var data = [{
"id": "none",
"name": "none"
}, {
"id": "none",
"name": "none"
}, {
"id": "write",
"name": "write"
}]
function comboBox(data) {
const select = document.getElementById('modules')
data.map(object => {
let option = document.createElement("option");
option.value = object.id;
option.text = object.id;
select.appendChild(option);
})
}
comboBox(data);
<select id="modules"></select>
i think you want to show data in dropdown
just make sure your array is in correct format.
var data = [{"id":"none","name":"none"},
{"id":"none","name":"none"},
{"id":"write","name":"write"}];
$.each(data,function(i,item){
$('#modules').append('<option value="'+data[i].id+'">'+data[i].name+'</option>'); });
$('.modules').eq(i).append('<option value="' + data[i].id + '">' + data[i].name + '</option>');

Jquery multiply input number value and Json data

I have a time calculation tool which you can find in the following fiddle link. Once someone has selected a platform, task type, component and number of units, the number of units entered should be multiplied with selected component value and show it on the below table. I have managed to get the all populated values but can't do the math. I have tried several attempts but it wasn't working.
var myJson = {
"platforms": [
{
"name": "Sitecore",
"id": "sitecore",
"tasktype": [
{
"name": "Promobox",
"id": "promobox",
"components": [
{
"name": "Accordion",
"id": "accordion",
"time": "20"
},
{
"name": "Box 1",
"id": "box1",
"time": "30"
}
]
},
{
"name": "Video",
"id": "video",
"components": [
{
"name": "Box 2",
"id": "box2",
"time": "25"
},
{
"name": "Box 3",
"id": "box3",
"time": "30"
}
]
}
]
},
{
"name": "Siab",
"id": "siab",
"tasktype": [
{
"name": "Newswire",
"id": "newswire",
"components": [
{
"name": "Box 4",
"id": "box5",
"time": "50"
},
{
"name": "Box 5",
"id": "box5",
"time": "40"
}
]
},
{
"name": "Task Type New",
"id": "tasktypenew",
"components": [
{
"name": "Box 6",
"id": "box6",
"time": "20"
},
{
"name": "Box 7",
"id": "box7",
"time": "100"
}
]
}
]
}
]
};
$.each(myJson.platforms, function (index, value) {
var platform_id;
var tasktype_id;
var component_id;
$("#platform").append('<option rel="' + index + '" value="' + value.id + '">' + value.name + '</option>');
$("#platform").change(function () {
$("#tasktype, #component").find("option:gt(0)").remove();
$("#tasktype").find("option:first").text("Loading...");
platform_id = $(this).find('option:selected').attr('rel');
$.each(myJson.platforms[platform_id].tasktype, function (index1, value1) {
$("#tasktype").find("option:first").text("Select Task Type");
$("#tasktype").append('<option rel="' + index1 + '" value="' + value1.id + '">' + value1.name + '</option>');
});
});
$("#tasktype").change(function () {
$("#component").find("option:gt(0)").remove();
$("#component").find("option:first").text("Loading...");
tasktype_id = $(this).find('option:selected').attr('rel');
$.each(myJson.platforms[platform_id].tasktype[tasktype_id].components, function (index2, value2) {
$("#component").find("option:first").text("Select Component");
$("#component").append('<option rel="' + index2 + '" value="' + value2.time + '">' + value2.name + '</option>');
});
});
});
$(document).ready(function () {
$('#calculate').click(function () {
$('#calc input, #calc select').each(
function (index) {
var input = $(this);
$('#data tbody').append('<tr><td>' + input.val() + '</td></tr>');
});
});
});
JS Fiddle
Ok this took a lot of debugging. You were building your table wrong and not storing data properly. The whole fishing for data was problematic. Here is the debugged calculator:
$(document).ready(function () {
$('#calculate').click(function () {
let tr = $("<tr/>").appendTo("#data tbody");
console.log(tr);
$('#calc input, #calc select').each( function (index) {
console.log($(this));
var input = $(this);
$(tr).append('<td class=row-'+ $(input).attr("id") + '>' + input.val() + '</td>');
});
const componentFactor = $(tr).children(".row-component").text();
const units = $(tr).children(".row-units").text();
const total = componentFactor*units;
$(tr).append('<td>' + total + '</td>');
});
});
notice:
Change of table structure format.
Now appending td's to single tr each time in order to sustain table-row consistency.
Fishing data from row with the help of adding class tag identifier to each td
Showing result.
update fiddle link:
https://jsfiddle.net/x4rLuf88/1/

cant print the json content in table form in jquery

guys i know its dummy question but i have spent alot of hours in this and still cant reach .. i want print the json content in table form .. here is my code
[{
"id": 1,
"name": "name1",
"age": 67,
"feedback": "feedback1"
}, {
"id": 2,
"name": "name2",
"age": 30,
"feedback": "feedback2"
}, {
"id": 3,
"name": "name3",
"age": 59,
"feedback": "feedback3"
}, {
"id": 4,
"name": "name4",
"age": 17,
"feedback": "feedback4"
}]
in javascript
$(document).ready(function() {
$.ajax({
url : 'data.json',
error : function(that, e) {
console.log(e);
},
success : function(data) {
$.each(data, function(index1, MyList) {
$.each(MyList, function(index2, item) {
$('body').append('<div id="div'+ index2+'" />');
$('#div' + index2).append(MyList[index2]);
});
});
}
});
});
here is my output
1234
name1name2name3name4
67305917
feedback1feedback2feedback3feedback4
and i want to make it in table form like this
1 name1 67 feedback1
2 name2 39 feedback2
3 name3 59 feedback3
4 name4 17 feedback4
try this snippet.you dont need two loops. just loop on items and build the bale row markup with data in each item.
data = [{
"id": 1,
"name": "name1",
"age": 67,
"feedback": "feedback1"
}, {
"id": 2,
"name": "name2",
"age": 30,
"feedback": "feedback2"
}, {
"id": 3,
"name": "name3",
"age": 59,
"feedback": "feedback3"
}, {
"id": 4,
"name": "name4",
"age": 17,
"feedback": "feedback4"
}]
var table_markyp = "<table>";
$.each(data, function(i, v) {
table_markyp += '<tr><td>' + v.id + '</td><td>' + v.name + '</td><td>' + v.age + '</td><td>' + v.feedback + '</td><tr>';
})
table_markyp += '</table>';
$('body').append(table_markyp)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
what you can do is , you have to create and HTML structure,
so that all the result will be displayed with a line by line and for that you can follow the table structure,.
check this code.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
</head>
<body>
</body>
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
url: "data.json",
error : function(that, e) {
console.log(e);
},
success : function(data) {
var Mytable = "<table>";
$.each(data, function(temp, res) {
Mytable +=
'<tr>\n\
<td>' + res.id + '</td>\n\
<td>' + res.name + '</td>\n\
<td>' + res.age + '</td>\n\
<td>' + res.feedback + '</td>\n\
<tr>';
});
Mytable += '</table>';
$('body').append(Mytable);
}
});
});
</script>
</html>
create a container with an id e.g <div id="tablecontainer"> and this below will generate a table with the results
if you want headers you can take one object from data e.g data[0], perform Object.keys(data[0]) and attached them to a <tr/> <th/> object like the row method below
success: function(data) {
var container = $('#tablecontainer');
var table = $('<table></table>');
data.forEach(function(datarow) {
var row = $("<tr />");
for (var item in datarow) {
row.append($("<td>" + datarow[item] + "</td>"));
}
table.append(row);
});
container.append(table);
}
example output with headers:
var data = [{
"id": 1,
"name": "name1",
"age": 67,
"feedback": "feedback1"
}, {
"id": 2,
"name": "name2",
"age": 30,
"feedback": "feedback2"
}, {
"id": 3,
"name": "name3",
"age": 59,
"feedback": "feedback3"
}, {
"id": 4,
"name": "name4",
"age": 17,
"feedback": "feedback4"
}];
var container = $('body');
var table = $('<table></table>');
var head = $("<tr />");
var keys = Object.keys(data[0]);
keys.forEach(function(key){
head.append($("<th>" + key + "</th>"))
})
table.append(head);
data.forEach(function(datarow) {
var row = $("<tr />");
for (var item in datarow) {
row.append($("<td>" + datarow[item] + "</td>"));
}
table.append(row);
});
container.append(table);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

How to access nested value from JSON Instagram API with Javascript

Im trying to modify script from https://github.com/bigflannel/bigflannel-Instafeed to access Instagram Photos in Website. But it doesn't include feature to display photo comments. So, im trying to modify but it returns undefined value. The script uses javascript to access data from API.
Example:
[
{
"attribution": null,
"tags": [
],
"type": "image",
"location": null,
"comments": {
"count": 2,
"data": [
{
"created_time": "1389168592",
"text": "Beautiful bridge!",
"from": {
"username": "realwahyuputra",
"profile_picture": "http:\/\/images.ak.instagram.com\/profiles\/profile_180213154_75sq_1359089013.jpg",
"id": "180213154",
"full_name": "realwahyuputra"
},
"id": "628714182443349004"
},
{
"created_time": "1389168601",
"text": "also good views",
"from": {
"username": "realwahyuputra",
"profile_picture": "http:\/\/images.ak.instagram.com\/profiles\/profile_180213154_75sq_1359089013.jpg",
"id": "180213154",
"full_name": "realwahyuputra"
},
"id": "628714254652486672"
}
]
},
"filter": "Hefe",
"created_time": "1350749506",
"link": "http:\/\/instagram.com\/p\/RAqdlGyTSc\/",
"likes": {
"count": 0,
"data": [
]
},
"images": {
"low_resolution": {
"url": "http:\/\/distilleryimage0.s3.amazonaws.com\/d87203101ad011e297b922000a1fa527_6.jpg",
"width": 306,
"height": 306
},
"thumbnail": {
"url": "http:\/\/distilleryimage0.s3.amazonaws.com\/d87203101ad011e297b922000a1fa527_5.jpg",
"width": 150,
"height": 150
},
"standard_resolution": {
"url": "http:\/\/distilleryimage0.s3.amazonaws.com\/d87203101ad011e297b922000a1fa527_7.jpg",
"width": 612,
"height": 612
}
},
"users_in_photo": [
],
"caption": {
"created_time": "1350749545",
"text": "From the office",
"from": {
"username": "bigflannel",
"profile_picture": "http:\/\/images.ak.instagram.com\/profiles\/anonymousUser.jpg",
"id": "240129684",
"full_name": "Mike Hartley"
},
"id": "306431853609956969"
},
"user_has_liked": false,
"id": "306431525321782428_240129684",
"user": {
"username": "bigflannel",
"website": "",
"profile_picture": "http:\/\/images.ak.instagram.com\/profiles\/anonymousUser.jpg",
"full_name": "Mike Hartley",
"bio": "",
"id": "240129684"
}
}];
Here's one of function to access data from that JSON:
function imageCaptionText(timestamp) {
var text = 'Filter: ' + imageData[imageCount].filter + '<br />'
if (imageData[imageCount].caption != null) {
text = text + 'Caption: ' + imageData[imageCount].caption.text + '<br />';
}
if (imageData[imageCount].likes.count > 0) {
text = text + 'Likes: ' + imageData[imageCount].likes.count + '<br />';
}
if (imageData[imageCount].comments.count > 0) {
text = text + 'Comments: ' + imageData[imageCount].comments.count + '<br />';
}
if (imageData[imageCount].comments.data != null) {
text = text + 'Comments Data: ' + imageData[imageCount].comments.data.text + '<br />';
}
if (imageData[imageCount].location != null) {
text = text + 'Location: ' + imageData[imageCount].location + '<br />';
}
var date = new Date(1000*timestamp);
text = text + 'Date: ' + date.toLocaleString() + '<br />';
text = text + 'On Instagram<br />';
return text; }
Everything goes fine except this code returns undefined value (I'm trying to create this to access comments data)
if (imageData[imageCount].comments.data != null) {
text = text + 'Comments Data: ' + imageData[imageCount].comments.data.text + '<br />';
}
How to make it works? Any help would be appreciated. Thanks :)
comments.data is an array, the actual text will be at imageData[imageCount].comments.data[commentCount].text so you have to do something like this:
if (imageData[imageCount].comments.data != null) {
text = 'Comments Data:<br />';
imageData[imageCount].comments.data.forEach(function(comment){
text += comment.from.username + ': ' + comment.text + '<br />';
});
}

Categories

Resources