Trouble build a table from json file under a div - json

I need to get rather complicate JSON data from (large) JSON file into a table at a specific part of a page. Somehow when I ran my code, nothing happens.
Snap shoot of purchase.json file -
{
"table": {
"purchases": [
{
"First Name": "Joe",
"Last Name": "Jenson",
"Product": "Netbook Computer",
"Price": "356",
"Purchase Date": "04/04/2011",
"Unit Count": "1",
"Type": "Computer",
"Return Date": "05/03/2011",
"Seq. No.": "0"
},
{
"First Name": "Christy",
"Last Name": "Davis",
"Product": "iPad",
"Price": "656",
"Purchase Date": "04/07/2011",
"Unit Count": "1",
"Type": "Computer",
"Return Date": "05/06/2011",
"Seq. No.": "10"
},
{
"First Name": "Justin",
"Last Name": "Gill",
"Product": "Laptop Computer sleeve",
"Price": "699",
"Purchase Date": "04/02/2011",
"Unit Count": "1",
"Type": "Computer Assesory",
"Return Date": "05/01/2011",
"Seq. No.": "20"
}
]
}
}
The html file -
JSON to table
get json file "purchase.json"
Parse the array into a table and load it in AJAXDiv
Table header has to be pulled from the key in the key:value pair found in the JSON.
The JavaScript code I have is -
$(document).ready(function() {
//Retrieve the JSON data from the server using AJAX
$('#AJAXButton').click(function() {
$.getJSON('data/purchase.json', function(data) {
processJSON(data);
});
});
//Process and display the JSON data
function processJSON(jsondata) {
var output = '<table cellpadding="0" cellspacing="0" border="0" class="display" id="example"><thead><tr>';
// retrieve the keys and place into an array
var keys = objKeys(jsonData.table.loans[0]).join("|");
var keyData = splitString(keys);
// print header
for (var i = 0; i < keyData.length; i++)
{
output += "<th>" + keyData[i] + "</th>";
}
output += "</thead></tr><tfoot>";
// print footer
for (var i = 0; i < keyData.length; i++)
{
output += "<th>" + keyData[i] + "</th>";
}
output += "</tfoot></tr><tbody>";
// print content of the json array in tbody
for(var j=0, jj = jsonData.table.loans.length; j < jj; j++)
{
for (var k = 0, kk = keyData.length; k < kk; k++)
{
var current = keyData[k];
output +="<td>" + jsonData.table.loans[j][current] + "</td>";
}
output += "</tr>";
}
output += "</tbody></tr></table>";
//Loop through the Languages
$('#AJAXDiv').html(output);
}
// get json keys
function objKeys(obj)
{
var keys = [];
var i = 0;
for (var z in obj)
{
if (obj.hasOwnProperty(z)) {
keys[i++] = z;
}
}
return keys;
}
// split string into array
function splitString(myString)
{
var mySplitResult = myString.split("|");
return mySplitResult;
}
});

It may be that you have a variable missing, there's
function processJSON(jsondata)
But you later use
jsonData.table.loans[0] //etc....
I suggest using a debugger like Firebug or DevTools, it makes problems like this much easier to catch.

You can also use this library: Json-To-Html-Table

I use this script that i coded my self, it really builds any json table from a mysql result
o whatever the MySQL is outputting, you can rename the column names with your own labels, by the output order. Also if you give none, the default names will be generated.
It used the $post Jquery plugin-in which you can add easly with 1 line of code.
all you need is the div with table_result:
function dyna_query(label){
$.post("your_mysql_query.php",{post_limit:15},function(e){
if(e=="fail"|| e=="" ||e=="[]"){return;}
var obj=JSON.parse(e);
//get default column names based on the associative object JSON
var column_n=Object.keys(obj[0]).length/2;
var c_names=Object.keys(obj[0]).splice(column_n,column_n);
//if there are labels, then these will replace others.
if( label){c_names=label.split(",");}
var table_row="";
//initialize table
var table_format="<table border=0><tr>";
for(var r=0; r<c_names.length;r++){
table_row+="<td class=table_h>"+c_names[r]+"</td>";}
table_row+="</tr>";
for(var i=0; i<obj.length;i++){table_row+="<tr>";
for(var c=0; c<c_names.length;c++){table_row+="<td class='table_bb'>"+obj[i][c]+" </td>";}table_row+="</tr>";}
//get all the other fields and rows
table_format+=table_row+"</table>";
//buld the html for the div with the id table_result
$("#table_result").html(table_format);
});
}
now simply call dyna_query("c1, c2, c3"); //renames default column names
or
dyna_query(); for full output with default labels

Related

Getting values from JSON using appscript

I'm creating two-dimentional array with google appscript using chrome devices users with the JSON response from a directory. I've been able to get values. However, when I try to get recentUsers represented as:
{
"kind": "directory#chromeosdevices",
"chromeosdevices": [
{
"kind": "directory#chromeosdevice",
"etag": "1234567890"
"deviceId": "def456",
"serialNumber": "234567",
"status": "ACTIVE",
"lastSync": "2013-03-05T17:30:04.325Z",
"supportEndDate": "2014-04-05T17:30:04.325Z",
"annotatedUser": "help desk",
"annotatedLocation": "Mountain View help desk Chromebook",
"annotatedAssetId": "1234567890",
"notes": "Loaned from support",
"orderNumber": "1234",
"willAutoRenew": true,
"osVersion": "Browser Version 18.0",
"platformVersion": "Platform Version 1415.2.0",
"firmwareVersion": "Firmware Version 1.2.3.4",
"bootMode": "validated",
"lastEnrollmentTime": "2012-04-05T17:30:04.325Z",
"orgUnitPath": "corp/engineering",
"recentUsers": [
{
"type": "USER_TYPE_MANAGED",
"email": "user#customer.com" //I'm trying to get the most recent user's email
}
],
"activeTimeRanges": [
{
"date": "2012-04-05",
"activeTime": "3600000"
}
],
}
],
"nextPageToken": "abcdefghijkl123"
}
I get an array but I can't get the value. I'm trying to get the most recent user's email. Anyone have experience with appscript? I've tried recentUsers[0].email and recentUser[0]['email']. This is the code I have to far: //I commented where I'm trying to push a value
enter code here
var chromeArgs = {
maxResults: 200,
orderBy: 'annotatedUser',
projection: "FULL"
};
var getChromes = (AdminDirectory.Chromeosdevices.list('XXXXXXXXX', chromeArgs));
var chromes = getChromes.chromeosdevices;
if (chromes && chromes.length > 0) {
Logger.log('Devices:');
//2d array
var wholeValues = [];
for (var i = 0; i < chromes.length; i++){
//create a 1D array first with pushing 0,1,2 elements with a for loop
var value = [];
for (var j = 0; j < 1; j++) {
var chrms = chromes[i];
var recentUser = chrms.recentUsers;
value.push(recentUser[0].email); // Here is where I need help
}
//pushing the value array with [0,1,2] to thw wholeValues array.
wholeValues.push(value);
} // the outer for loop runs five times , so five the 0,1,2 with be pushed in to thewholevalues array by creating wholeValues[0][0],wholeValues[0][1]...till..wholeValues[4][2]
Logger.log(wholeValues); '''
You are very close, the only thing you need to change is to replace the static recentUsers[0] with dynamic recentUsers[j] within the loop
Sample:
function getChromes(){
var chromeArgs = {
maxResults: 200,
orderBy: 'annotatedUser',
projection: "FULL"
};
var getChromes = (AdminDirectory.Chromeosdevices.list('XXXXXXXXX', chromeArgs));
var chromes = getChromes.chromeosdevices;
if (chromes && chromes.length > 0) {
Logger.log('Devices:');
var wholeValues = [];
for (var i = 0; i < chromes.length; i++){
var chrms = chromes[i];
var recentUser = chrms.recentUsers;
var value = [];
for (var j = 0; j < recentUser.length; j++) {
Logger.log(recentUser[j].email);
value.push(recentUser[j].email);
}
wholeValues.push(value);
}
Logger.log(wholeValues);
}
}
Note that you need to specify the iteration limit of the inner loop dynamically j < recentUser.length; instead of j < 1 to account for different quantity of recent users for each chrome device.

Delete token from SAPUI5 Multi Input Field with Data Binding

in my SAPUI5 app I am using a Multi Input Field with tokens which are bound to a JSON Model. Newly added entries are saved in the JSON Model. However, when deleting a token by pressing the "x" next to the token text, the token disappears from the multi input field. But when adding a new token the deleted one reappears.
How can I ensure that the deleted entry is also deleted from the JSON Model?
This is my current code for adding the token to the model:
multiInputField.addValidator(function(args){
MessageBox.confirm("Do you really want to add Token\"" + args.text + "\"?", {
onClose: function(oAction) {
if (oAction === MessageBox.Action.OK){
var oToken = new Token({key: args.text, text: args.text});
args.asyncCallback(oToken);
var aFields = sap.ui.getCore().getView().getModel("myModel").getProperty("/Tokens");
var oNewFields= {
Tokens: args.text
};
aFields .push(oNewFields);
sap.ui.getCore().getView().getModel("myModel").setProperty("/Tokens", aFields );
sap.ui.getCore().getView().getModel("myModel").refresh();
} else {
args.asyncCallback(null);
}
},
title: "Add Token"
});
return sap.m.MultiInput.WaitForAsyncValidation;
});
I guess we can use "tokenUpdate" event for this.
For example, given that I have this MultiInput in my view:
<MultiInput width="500px" id="multiInput" suggestionItems="{ path: 'dataModel>/data'}" showValueHelp="true" tokenUpdate="onTokenUpdate">
<core:Item key="{dataModel>key}" text="{dataModel>value}"/>
</MultiInput>
then in my controller I can handle this like :
onTokenUpdate: function(oEvent) {
var sType = oEvent.getParameter("type");
if (sType === "removed") {
var sKey = oEvent.getParameter("removedTokens")[0].getProperty("key");
var oModel = this.getView().getModel("dataModel");
var aData = this.getView().getModel("dataModel").getProperty("/data");
for (var i = 0, len = aData.length; i < len; i++) {
var idx;
console.log(sKey + "-" + aData[i].key);
if (aData[i].key === sKey) {
idx = i;
}
}
aData.splice(idx, 1);
oModel.setProperty("/data", aData);
console.log(oModel);
}
}
And this is my json:
{
"data": [
{
"key": "token1",
"value": "token1"
},
{
"key": "token2",
"value": "token2"
}
]
}

How do i parse JSON file into html table depending on dropdown selection using javascript?

I have a JSON File which contains some objects.
Would like to populate the object depending on dropdown selection .
The drop-down contains all the "Level" value and i need to display only the object which contains the "Level" value equal to the user selection .
Please see the following link
https://fiddle.jshell.net/agbpr021/
for (var i = 0; i < allData.length; i++) {
var x = document.getElementById("level").value;
if(x = allData.level)
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = allData[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("showData");
divContainer.innerHTML = "";
divContainer.appendChild(table);
This should get you the result you are looking for. Probably a more efficient way of doing this, esp how I create the html for the table, but it should give you the desired output.
function CreateTableFromJSON()
{
// only included this so snippet would work
allData = [
{ "Level": "a", "Country": "Unknown", "Currency": "USD" },
{ "Level": "a", "Country": "All", "Currency": "BRL" },
{ "Level": "b", "Country": "All", "Currency": "EUR" },
{ "Level": "c", "Country": "All", "Currency": "EUR" },
{ "Level": "d", "Country": "None", "Currency": "EUR" }
]
var x = document.getElementById("Levels").value;
var index = -1;
for (var i = 0; i < allData.length; i++) {
if (allData[i].Level == x)
index= i;
}
var html = "";
if (index != -1) {
// probably a better way to do this portion
html = "<table><thead><tr><th>Level</th><th>Country</th><th>Currency</th></tr></thead><tbody><tr>";
html += "<td>" + allData[index].Level + "</td>";
html += "<td>" + allData[index].Country + "</td>";
html += "<td>" + allData[index].Currency + "</td>";
html += "</tr></tbody></table>";
} else {
html = "Please make a selection";
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("showData");
divContainer.innerHTML = html;
}
<p>levels</p>
<select id="Levels">
<option value="Null" id="m">Choose level</option>
<option value="a" id="A">a</option>
<option value="b" id="B">b</option>
<option value="c" id="C">c</option>
<option value="d" id="D">d</option>
</select>
<br /><br />
<!--Button-->
<input type="button" onclick="CreateTableFromJSON()" value="Go" />
<div id="showData"></div>
<br>
EDIT: I wanted to mention real smart people have put together tools to handle this. React, Vue and Angular are a few examples that have tools for this type of stuff.
EDIT: Added check for bad index in allData

Access specified attributes of Json for search index in cloudant

I have a Json document as:
{
"_id": "3de00db35e6549604c711e7295a1982a",
"_rev": "1-ecba71644d341dfe5cb9abf6dd13b23a",
"dateCreated": "2014-01-29 00:00:00",
"attributeCollection": {
"attributeArray": [
{
"updateable": false,
"lookup": "issuetype",
"issueAttributeDefinitionId": 13,
"attributeType": 1,
"name": "Web Type",
"value": [
"Improper Limitation of Authentication"
]
},
{
"updateable": true,
"lookup": "status",
"issueAttributeDefinitionId": 1,
"attributeType": 4,
"name": "Status",
"value": [
"Access with Right Permission"
]
}
]
},
"hash": "287030d6efa085b5b92b7106c0edb6d7"
}
I want to create search index for document using "name" and "value" ("name" or "value" only). I accessed these attributes by this codes:
for (var i=0; i<doc.attributeCollection.attributeArray.length; i++) {
if (doc.attributeCollection.attributeArray[i].name) {
name = doc.attributeCollection.attributeArray[i].name;
}
if (doc.attributeCollection.attributeArray[i].value) {
value = doc.attributeCollection.attributeArray[i].value;
}
}
It works when i use contentindex = name + " "+ value; the content shows "Web Type Improper Limitation of Authentication". However, if i use value only contentindex = value, it doesn't work, it shows null.
I know that the structure of "value" likes array (array with 1 element) and it doesn't have any attribute name.
How can i access the value properly?
Update:
When i index some cases as:
1. It works
var content=name + " " + value;
index("default", content);
2. It works
index("default", name);
3. It doesn't work
index("default", value);
4.I fixed with by revised the code to get "value" as:
if (doc.attributeCollection.attributeArray[i].value) {
for (var j=0; j<doc.attributeCollection.attributeArray[i].value.length; j++){
value = doc.attributeCollection.attributeArray[i].value[j];
}
}
Or
if (doc.attributeCollection.attributeArray[i].value) {
value = doc.attributeCollection.attributeArray[i].value[0];
}
It works with index("default", value);
However, when i used permutation function as discussed in this post
5. It works
var content= permuteword(name);
for(var k=0; k<content.length; k++){
index("default", content[k], { store : true });
}
6. It doesn't work
var content= permuteword(value);
for(var k=0; k<content.length; k++){
index("default", content[k], { store : true });
}
7. It doesn't work
var content=name + " " +value;
var content1= permuteword(content);
for(var k=0; k<content1.length; k++){
index("default", content1[k], { store : true });
}
I'm not exactly sure I completely understand your question. It sounds like you are creating an index like this:
for (var i=0; i<doc.attributeCollection.attributeArray.length; i++) {
if (doc.attributeCollection.attributeArray[i].name) {
name = doc.attributeCollection.attributeArray[i].name;
}
if (doc.attributeCollection.attributeArray[i].value) {
value = doc.attributeCollection.attributeArray[i].value;
}
index("contentindex", name + " " + value);
}
If this is the case you could try indexing the name and value separately (Update: changed to access each element in the value array):
for (var i=0; i<doc.attributeCollection.attributeArray.length; i++) {
if (doc.attributeCollection.attributeArray[i].name) {
name = doc.attributeCollection.attributeArray[i].name;
index("contentindex", name);
}
if (doc.attributeCollection.attributeArray[i].value) {
for (var j=0; j<doc.attributeCollection.attributeArray[i].value.length; j++) {
value = doc.attributeCollection.attributeArray[i].value[j];
index("contentindex", value);
}
}
}
Then querying by either the name or the value should return the correct result.
Please let me know if I am misunderstanding you question.

Changing JSON array to get smaller messages?

When using JSON to send an array of objects from the same class the objects fields are repeated many times, often unnecessarily, and the message becomes very long for arrays with big length. To my knowledge, there is no way to remove the field's repetition using only JSON. So I'm looking for a solution that solves the encoding and decoding of arrays without repeating the fields names.
As an example, the array below:
A:
[
{id:1;name:Name 1;description:Description 1},
{id:2;name:Name 2;description:Description 2},
...,
{id:N;name:Name N;description:Description N}
]
can be represented by:
B:
{
fields:[id, name, description],
values:[
[1,Name 1,Description 1],
[2,Name 2,Description 2],
...,
[N,Name N,Description N]
]
}
spending lot less space in the case of arrays with big length.
But I need a solution that does this transformation (from A to B and B to A) automatically. It can use the B represantation, or a better, to reduce the message size by eliminating fields names.
Any solution?
You can do this by writing two simple javascript functions to encode and decode as you want. Some rules have to apply in order for this paterns to work:
There must be a valid JSON input data string, though you can use a
plain array with objects
All array elements must have the same object structure format
It does not wotk with child objects
Minify/Unminify object function:
function minifyObject(obj) {
var fields = Object.keys(obj[0]);
var values = [];
for(var record in obj) {
var value = [];
for(var field in fields) {
value.push(obj[record][fields[field]]);
}
values.push(value);
}
return {
fields: fields,
values: values
}
}
function unminifyObject(obj) {
var output = [];
for(var i = 0; i < obj.values.length; i++) {
var record = {};
for(var j = 0; j < obj.fields.length; j++) {
record[obj.fields[j]] = obj.values[i][j];
}
output.push(record);
}
return output;
}
var data = [
{"id":1, "name": "Name 1", "description": "Description 1"},
{"id":2, "name": "Name 2", "description": "Description 2"},
{"id":3, "name": "Name 3", "description": "Description 3"}
];
var minified = minifyObject(data);
console.log("Minified object\n", minified);
var unminified = unminifyObject(minified);
console.log("Unminified array\n", unminified);
This code can also be simplified using ES6.
You can also find my test JSON converter here: https://zikro.gr/dbg/so/20129724/