Array data wont display in a table - javascript

I have an ajax function which sends a get request to an api and returns data in the following format-
{
"firstname": "John",
"lastname": "Doe",
"email": "doej#gmail.com",
"subjects": [
{
"id": 1,
"name": "maths"
},
{
"id": 2,
"name": "chemistry"
}
]
},
I need to display this data in a table but am having trouble getting the subjects array to display correctly, ie as a list in one table cell. I have tried to put the array data into another table inside the main one but it's not working out. I presume I'm going very wrong somewhere in my iteration loops.
function getPeople() {
$.ajax({
type: "GET",
url: "http://example.com",
contentType: "application/json; charset=utf-8",
crossDomain: true,
dataType: "json",
success: function (data, status, jqXHR) {
// fill a table with the JSON
$("table.mytable").html("<tr><th></th><th>First Name</th><th>Last Name</th><th>Subjects</th></tr>" );
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data[i].subjects.length; j++) {
var subjects = data[i].subjects[j];
$("table.insidetable").append('<tr><td>' + subjects + 'tr><td>')
}
$("table.mytable").append('<tr><td><input type = "checkbox" id = '+data[i].id+'>' + "</td><td>" + data[i].firstname + "</td><td>" + data[i].lastname + "</td><td>" + "table.insidetable" + "</td></tr>");
}
},
error: function (jqXHR, status) {
// error handler
console.log(jqXHR);
alert('fail' + status.code);
}
});
}

Below is the working (tested) code.
var data = [{
"firstname": "John",
"lastname": "Doe",
"email": "doej#gmail.com",
"subjects": [
{
"id": 1,
"name": "maths"
},
{
"id": 2,
"name": "chemistry"
}
]
},
{
"firstname": "Steve",
"lastname": "Gentile",
"email": "steve#gmail.com",
"subjects": [
{
"id": 1,
"name": "history"
},
{
"id": 2,
"name": "geography"
}
]
}];
$("table.mytable").html("<tr><th></th><th>First Name</th><th>Last Name</th><th>Subjects</th></tr>");
for (var i = 0; i < data.length; i++) {
var subjectList = '';
for (var j = 0; j < data[i].subjects.length; j++) {
subjectList += '<li>' + data[i].subjects[j].name + '</li>';
}
$("table.mytable").append('<tr><td><input type="checkbox" id=' + i +'/></td><td>' + data[i].firstname + '</td><td>' + data[i].lastname + '</td><td><ul>' + subjectList + '</ul></td></tr>');
}
It seems there are many problems in below statement like,
Tags are not closed properly
Properties that do not exist are being used (data[i].id)
Single and Double quotes don't match
...
$("table.mytable").append('<tr><td><input type = "checkbox" id = '+data[i].id+'>' + "</td><td>" +data[i].firstname + "</td><td>" + data[i].lastname + "</td><td>" + "table.insidetable"+ "</td></tr>");

As a guess are you missing a '<'?
In the line:
$("table.insidetable").append('<tr><td>' + subjects + 'tr><td>')
Also
$("table.mytable").append('<tr><td><input type = "checkbox" id = '+data[i].id+'>' + "</td><td>" + data[i].firstname + "</td><td>" + data[i].lastname + "</td><td>" + "table.insidetable" + "</td></tr>");
I don't think you should be appending "table.insidetable"? This will be seen rendered as the value "table.insidetable" and not the contents of the table. I think this should rather be something like $("table.insidetable").val()

Related

Select filter hides all the items in the list

I am trying to create a select dropdown filter which dynamically gets its values and data from rest api.
Here is my code
HTML
<div class="container">
<select data-filter="season" class="filter_category_name filter form-control"></select>
<div class="listContent" id="listitem"></div>
</div>
JS
var data = [{
"category_name": "1",
"title": "One One",
"more": [{
"details": "some details"
}]
},
{
"category_name": "1",
"title": "One Two",
"more": [{
"details": "some details"
}]
},
{
"category_name": "2",
"title": "Two One",
"more": [{
"details": "some details"
}]
},
{
"category_name": "3",
"title": "Three One",
"more": [{
"details": "some details"
}]
}];
let listItems = "",
categoryAll = "";
for(var i = 0;i < data.length; i++) {
var title = data[i].title,
category_name = data[i].category_name;
listItems += "<a onclick='createAVideoContainer(" + i + ")'><div class='listItem'><p>" + title + "</p></div></div></a>";
if (categoryAll.indexOf("<option value='" + category_name + "'>" + category_name + "</option>") == -1) {
categoryAll += "<option value='" + category_name + "'>" + category_name + "</option>";
}
}
$("#listitem").html(listItems);
$(".filter_category_name").append(categoryAll);
var filtersObject = {};
$(".filter").on("change",function() {
var filterName = $(this).data("filter"),
filterVal = $(this).val();
if (filterVal == "") {
delete filtersObject[filterName];
} else {
filtersObject[filterName] = filterVal;
}
var filters = "";
for (var key in filtersObject) {
if (filtersObject.hasOwnProperty(key)) {
filters += "[data-"+key+"='"+filtersObject[key]+"']";
}
}
if (filters == "") {
$(".listItem").show();
} else {
$(".listItem").hide();
$(".listItem").hide().filter(filters).show();
}
});
But for some reason it hides all the items and nothing change after changing the options
I want to initially load all the items and then filter based on the option
I want the select element to dynamically create the options with the values of the category names like the first option should have the value of cars1 and display all the other objects with the same category_name.
Note: The entire code is wrapped inside an async function which renders on page load.
Here is a proper working js fiddle with the above problem
Based on your fiddle code, it would be better to filter the <a> items within the listItem area based on season, as that is the filter that is built, instead of trying to show/hide the entire listItem area.
The two minor code changes to achieve the desired result, is at these two code points:
Add a data-season reference here, to the <a> tags, with the category_name value:
listItems += '<a data-season="' + category_name + '" '
+ "onclick='createAVideoContainer(" + i + ")'><div class='listItem'><p>"
+ title + "</p></div></a>";
Change the filtering to filter on the <a> tags for the data-season that you build:
if (filters == "") {
$("a").show();
} else {
$("a").hide();
$("a").filter(filters).show();
}
Integrating those two changes into your fiddle example code, try the runnable example below:
var data = [
{
"category_name": "1",
"title": "One One",
"more": [
{
"details": "some details"
}
]
},
{
"category_name": "1",
"title": "One Two",
"more": [
{
"details": "some details"
}
]
},
{
"category_name": "2",
"title": "Two One",
"more": [
{
"details": "some details"
}
]
},
{
"category_name": "3",
"title": "Three One",
"more": [
{
"details": "some details"
}
]
},
];
let listItems = "",
categoryAll = "";
for(var i = 0; i < data.length; i++) {
var title = data[i].title,
category_name = data[i].category_name;
listItems += '<a data-season="' + category_name + '"'
+ "onclick='createAVideoContainer(" + i + ")'><div class='listItem'><p>"
+ title + "</p></div></a>";
if (categoryAll.indexOf("<option value='" + category_name + "'>" + category_name + "</option>") == -1) {
categoryAll += "<option value='" + category_name + "'>" + category_name + "</option>";
}
}
$("#listitem").html(listItems);
$(".filter_category_name").append(categoryAll);
var filtersObject = {};
//on filter change
$(".filter").on("change",function() {
var filterName = $(this).data("filter"),
filterVal = $(this).val();
if (filterVal == "") {
delete filtersObject[filterName];
} else {
filtersObject[filterName] = filterVal;
}
var filters = "";
for (var key in filtersObject) {
if (filtersObject.hasOwnProperty(key)) {
filters += "[data-"+key+"='"+filtersObject[key]+"']";
}
}
if (filters == "") {
$("a").show();
} else {
$("a").hide();
$("a").filter(filters).show();
}
});
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<div class="container">
<select data-filter="season" class="filter_category_name filter form-control"></select>
<div class="listContent" id="listitem">
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/#popperjs/core#2.9.3/dist/umd/popper.min.js" integrity="sha384-eMNCOe7tC1doHpGoWe/6oMVemdAVTMs2xqW4mwXrXsW0L84Iytr2wi5v2QjrP/xp" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/js/bootstrap.min.js" integrity="sha384-cn7l7gDp0eyniUwwAZgrzD06kc/tftFf19TOAs2zVinnD/C7E91j9yyk5//jjpt/" crossorigin="anonymous"></script>
Here's the updated fiddle with the same change applied.

How to get the values inside a nested JSON array

Can someone let me know how can I access the values inside the option_value array? It's an array within another array.
I get the below error with my code:
TypeError: json.option[i].option_value[j] is undefined
My code
$(document).on("click", "[name^='option']", function () {
var value = $(this).val();
var parent_id = $(this)
.attr("name")
.replace(/[^\d.]/g, "");
$.ajax({
url:
"index.php?route=controlller/get_options&parent_id=" +
parent_id +
"&value=" +
value +
"&product_id=<?php echo $product_id; ?>",
type: "get",
dataType: "json",
success: function (json) {
if (json["option"]) {
for (i = 0; i < json["option"].length; i++) {
if (
json["option"][i]["type"] == "radio" ||
json["option"][i]["type"] == "checkbox"
) {
$("#ioption" + json["option"][i]["product_option_id"])
.find("input")
.prop("checked", false);
for (j = 0; j <= json["option"][i]["option_value"].length; j++) {
$("#ioption" + json["option"][i]["product_option_id"])
.find(
"input[value='" +
json["option"][i]["option_value"][j][
"product_option_value_id"
] +
"']"
)
.parent()
.show();
}
}
}
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
},
});
});
Below is my JSON result:
{
"option": [
{
"product_option_id": "975",
"option_id": "76",
"name": "Stage",
"type": "image",
"option_value": [
{
"product_option_value_id": "2490",
"option_value_id": "389",
"name": "Level 1",
"price": "\u20ac 2,00"
},
{
"product_option_value_id": "2491",
"option_value_id": "390",
"name": "Level 2",
"price": "\u20ac 3,00"
}
],
"required": "1"
}
]
}
Thanks
I don't have an exact structure of your html, but atleast i can provide a clean solution with some Array.map usage.
You can loop through each object and then you can target HTML element you want to.
Example
result.option.map(opt => {
if (opt.type === 'radio' || opt.type === 'checkbox') {
let optionElement = '#ioption' + opt.option_id;
$(optionElement).find('input').prop('checked', false);
opt.option_value.map(optVal => {
let inputElement = 'input[value=\'' + optVal.product_option_value_id + '\']';
$(optionIdElement).find(inputElement).parent().show();
});
}
});
P.S: Snippet won't run as i've not included result json in the answer!
Hope this will help!
Get value of option_value use this option[0]["option_value"][0]
I just give answer according to display the top json.
And 0 replace using any loop(for / foreach) accoding to your requirment.

JSON add value on click

I'm trying to make a site of restaurant and now doing some table reservation. So far have one problem:
I have a JSON of tables and want to add date (day/time) to it, when table was clicked.
The problem's next - when I click on some table, the date adds to all JSON elements. And I wand to add it only to the element I clicked.
Here is link to codepen:
https://codepen.io/wilchilly/pen/qBEvegW
(To see the result click on some table and open console)
My HTML:
<p class="href-to italic" id="showMore">Show tables</p>
<div class="wrapper" id="wrapper">
<div class="tables-wrapper" id="tables-wrapper"></div>
</div>
JS:
fetch('tables.json')
.then(response => response.json())
.then(json => {
const myJson = json;
let showTables = document.getElementById('showMore');
//show elements on page
function loadGoods(data) {
let out = '';
for (let key in data) {
if (data[key].isAvailable == false) {
out += '<div class="single-table not-available" data-name="' + data[key]['name'] + '" data-art="' + data[key]['id'] + '">';
out += '<h4>' + data[key]['name'] + '</h4>';
out += '<p>' + data[key]['location'] + '</p>';
out += '</div>';
} else {
out += '<div class="single-table" data-name="' + data[key]['name'] + '" data-art="' + data[key]['id'] + '">';
out += '<h4>' + data[key]['name'] + '</h4>';
out += '<p>' + data[key]['location'] + '</p>';
out += '</div>';
}
}
$('#tables-wrapper').html(out);
}
//set Date (day/time)
function setDate() {
for (let key in myJson) {
myJson[key]['date']['day'] = '10/02';
myJson[key]['date']['time'] = '20:00';
}
console.log(myJson);
}
showTables.addEventListener('click', function () {
loadGoods(myJson);
let singleTable = document.getElementsByClassName('single-table');
Array.from(singleTable).forEach(function (element) {
element.addEventListener('click', setDate);
});
});
})
JSON:
[
{
"id": 0,
"index": 0,
"name": "Table 1",
"capacity": 5,
"isAvailable": true,
"location": "Bar",
"date": {
"day": " ",
"time": ""
}
},
{
"id": 1,
"index": 1,
"name": "Table 2",
"capacity": 5,
"isAvailable": true,
"location": "Patio",
"date": {
"day": " ",
"time": " "
}
},
{
"id": 2,
"index": 2,
"name": "Table 3",
"capacity": 5,
"isAvailable": true,
"location": "Bar",
"date": {
"day": " ",
"time": " "
}
},
{
"id": 3,
"name": "Table 4",
"capacity": 6,
"isAvailable": true,
"location": "Inside",
"date": {
"day": " ",
"time": " "
}
}
]
I found a solution. This might be helpful for someone with a similar question.
function setDate() {
let inputDay = document.getElementById('form-data').value;
let inputTime = document.getElementById('form-time').value;
for (let i = 0; i < myJson.length; i++) {
if (this.getAttribute('data-art') == myJson[i].id) {
myJson[i]['date']['day'] = inputDay;
myJson[i]['date']['time'] = inputTime;
}
}
}
Just use the index from the iteration on table creation as id (or any attr you like) for example (you will probably need a classic for or a foreach) and then, in the event you attached pass the click event as param. Finally you just use the event.target to get the id (or the attr you choose) of the element and use it in the setDate func.

How to iterate JSON Array in Jquery

I have this below type of array. I want to iterate this array in JavaScript. How is this possible?
{
"result": true,
"data": [
{
"ID": 1,
"stage_ID": 1,
"badge_type_ID": 1,
"name": "Despertar da Força",
"description": "Fazer a primeira SuperAtividade",
"type": "",
"image_static": "url123.jpg",
"image_animated": "",
"SQL": "",
"published": 1
},
{
"ID": 2,
"stage_ID": 1,
"badge_type_ID": 1,
"name": "Super 3",
"description": "Fazer 3 SuperAtividades",
"type": "",
"image_static": "urlimage123.png",
"image_animated": "",
"SQL": "",
"published": 1
}
etc
I tried the following script and it is returning "undefined", "undefined".
$.getJSON('https://www.legiaodossuperpoderes.com.br/chronus/api/adm/badges', function(data) {
var output= "<ol>";
for (var i in data) {
output += "<li>" + data[i].ID + "</li>"
}
output+="</ol>";
document.getElementById("placeholder").innerHTML=output;
});
Any solutions ? Thanks!
You can try converting to Json Object
$.getJSON('https://www.legiaodossuperpoderes.com.br/chronus/api/adm/badges', function(data) {
var output= "<ol>";
var jsondata = $.JSON.parse(data); // Json object Convertion
for (var i in data) {
output += "<li>" + data[i].ID + "</li>"
}
output+="</ol>";
document.getElementById("placeholder").innerHTML=output;
});
You are trying to access an undefined property using data[i].ID .
When you are getting response from your getJSON() function then you need to call the response with a name and then you can access any inner property using this name .
Now if you want to iterate using data key/value on myResponse variable then you need to do this.
$.getJSON('https://www.legiaodossuperpoderes.com.br/chronus/api/adm/badges', function(myResponse) {
var output= "<ol>";
var dataCount = myResponse.data.length;
for (var i = 0; i < dataCount; i++) {
output += "<li>" + myResponse.data[i].ID + "</li>";
}
output+="</ol>";
document.getElementById("placeholder").innerHTML=output;
});

jsTree JSON issue [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I am working on some project module where i am using jstree.js plugin.
I am getting following JSON via web service call:
[
{
"name":"Folder1",
"attributes": {
"SubFolder1-1":"value1-1",
"SubFolder1-2":"value1-2",
...
"SubFolder1.7":"value1-7",
"SubFolder1.8":"value1-8"
}
}, {
"name":"Folder2",
"attributes": {
"SubFolder2-1":"value2-1"
}
}, {
"name":"Folder3",
"attributes": {
"SubFolder3-1":"value2-1"
}
}
]
But jsTree.js is not accepting the JSON format, It accept following format:
{
"data" : "node_title",
"attr" : {
"id" : "node_identificator",
"some-other-attribute" : "attribute_value"
},
"children" : [ /* an array of child nodes objects */ ]
}
Our approach:
var new_avatar = new Array();
new_avatar = data.attributeSets;
// Hardcoded data for JSTree
var dirn = {};
var final_child = {};
dirn = "[";
final_child = "[";
for (var info in new_avatar) {
for (var detailInfo in new_avatar[info].attributes) {
ckey = detailInfo; // Key
cval = new_avatar[info].attributes[detailInfo]; // Key => Value
final_child += '{ "data": "' + ckey + '",';
final_child += ' "attr": { "rel":"directory" },';
final_child += ' "children": [ "' + cval + '" ] },';
}
}
final_child = final_child.substring(0, final_child.length - 1); //removing last comma so it would be a valid JSON
final_child += " ] "; //final close to this JSON
for (var info in new_avatar) {
dirn += '{ "data": "' + new_avatar[info].name + '" ,';
dirn += ' "attr": { "rel":"directory" }, ';
dirn += ' "children": ' + final_child + " }, ";
// Putting final_child in so it will build level 2 + level 3 (level 3 child is just value declared in final_child children above)
}
dirn = dirn.substring(0, dirn.length - 2); // removing whitespace + comma
dirn += " ] "; // this is main tree data var end box
dirn = $.parseJSON(dirn); // parse the whole dirn variable so it would be an array and ready to feed to jstree.
$("#tree2").jstree({
plugins: ['themes', 'json_data', "ui"],
json_data: {
"data": dirn,
},
themes: {
theme: 'default'
},
checkbox: {
real_checkboxes: true,
two_state: true
},
"types": {
"types": {
"disabled": {
"check_node": false,
"uncheck_node": false
},
"directory": {
"check_node": false,
"uncheck_node": false
}
}
}
});
Current Output:
Showing error that json is not valid string.
Expected Output:
I got the solution and is working fine now. Thanks you all for showing interest.
var new_avatar = new Array();
new_avatar = data.attributeSets;
var dirn = {};
var final_child = {};
var nodeChildren = {};
//Collect children for each node
for (var info in new_avatar) {
final_child = "[";
for (var detailInfo in new_avatar[info].attributes) {
ckey = detailInfo; // Key
cval = new_avatar[info].attributes[detailInfo]; // Key => Value
final_child += '{ "data": "' + ckey + '",';
final_child += ' "attr": { "rel":"directory" },';
final_child += ' "children": [ "' + cval + '" ] },';
}
final_child = final_child.substring(0, final_child.length - 1); //removing last comma so it would be a valid JSON
final_child += " ] "; //final close to this JSON
nodeChildren[info] = final_child;
}
// Attached collected nodes to respective parents
dirn = "[";
for (var info in new_avatar) {
dirn += '{ "data": "' + new_avatar[info].name + '" ,';
dirn += ' "attr": { "rel":"directory" }, ';
dirn += ' "children": ' + nodeChildren[info] + " }, "; //putting final_child in so it will buld level 2 + level 3 (level 3 child is just value declared in final_child children above)
}
dirn = dirn.substring(0, dirn.length - 2);
dirn += " ] ";
dirn = $.parseJSON(dirn);
$("#tree2").jstree({
plugins: ['themes', 'json_data', "ui", "dnd"],
json_data: {
"data": dirn,
},
themes: {
theme: 'default'
},
checkbox: {
real_checkboxes: true,
two_state: true
},
"types": {
"types": {
"disabled": {
"check_node": false,
"uncheck_node": false
},
"directory": {
"check_node": false,
"uncheck_node": false
}
}
}
});

Categories