Catch data from JSON without a key - javascript

My problem is that i cant print what i recieve from a server with out having a key at the start of the JSON file, here is my current code...
$.getJSON("http://10.21.26.251:8080/Transport/getMessage?user=1", function(data) {
var output = "<tr>";
for ( var i in data.item) {
output += "<td>"
+ "-- "
+ data.item[i].messageId
+ " --<br>-- "
+ data.item[i].userId
+ " --<br>"
+ data.item[i].messageContent
+ "<br></br></td>";
}
output += "</tr>";
document.getElementById("placeholder").innerHTML = output;
});
But this is reliant on the code being recieved having a name of items, the current JSON is recieved like this... I have no control over what is recieved
{
"messageId": "d1e5afa5-5153-49b7-ae73-3501fbed1b68",
"userTo": {
"userId": 1,
"userName": "COE",
"userLastCheckedDate": 1362994638139
},
"userFrom": {
"userId": 2,
"userName": "Man",
"userLastCheckedDate": 1362994638139
}
etc...

Its difficult to get an idea of the json schema with such a small sample, but assuming it is a list of emails i would try this:
$.getJSON("http://10.21.26.251:8080/Transport/getMessage?user=1", function(data) {
var output = "<tr>";
for ( var i = 0; i < data.length;i++) {
output += "<td>"
+ "-- "
+ data[i].messageId
+ " --<br>-- "
+ data[i].userFrom.userId
+ " --<br>"
+ data[i].messageContent
+ "<br></br></td>";
}
output += "</tr>";
document.getElementById("placeholder").innerHTML = output;
});

If I understood what you're trying to do, you basically want to loop through the JSON object properties without knowing their names. Also (correct me if I'm wrong), your object seems to be an array of objects.
You could do something like this:
var output = "<tr>";
for (var i=0; i<data.length; i++) { // Loop through the main array of objects
output += "<td>";
$.each(data[i], function(key, val) { // Loop through the properties of the current object
output += "-- "
+ val
+ " --<br>";
});
output += "</br></td>";
}
output += "</tr>";
document.getElementById("placeholder").innerHTML = output;

Related

Dynamically populate <td> from return of a function

I want to dynamically update the contents of cells but only if data for those cells exists in the database.
What I have tried is to add a call to the addDataIfPres function, from the appropriate each time it is dynamically generated, in the hope that it would be populated with the returning data from the function: either some data if it exists for that student, or 'blank' if it does not.
But, this is not working. How can I call the addDataIfPres function, each time an HTML cell is created, and populate it with the returning value?
function makeEditTableHTML(studentArray, groupID) {
return populateDB(groupID, function(data) {
// Data from AJAX POST
console.log(data);
function addDataIfPres(col, student, data) {
for(var j=0; j < data.length; j++) {
if ((student == data[j][0]) && (col == 1)) {
res = data[j][1];
}
else {
res = "";
}
}
return res;
}
var result = "<table id='dataEditTableid' class='stripe' border=1><thead><tr><td><b>ID</b></td><td><b>Student Email</b></td><td><b>Group ID</b></td><td><b>Target</b></td><td><b>SEN</b></td><td><b>Disadvantaged</b></td></tr></thead>";
result += "<tbody>";
for(var i=0; i < studentArray.length; i++) {
result += "<tr>";
result += "<td>"+studentArray[i][1]+"</td>";
result += "<td>"+studentArray[i][0]+"</td>";
result += "<td>"+groupID+"</td>";
result += "<td id=" + studentArray[i][1] + " contenteditable='true' onBlur='saveToDB(1, this.id, this.innerHTML, "+groupID+")'>+ addDataIfPres(1, this.id, data) +</td>";
result += "<td id=" + studentArray[i][1] + " contenteditable='true' onBlur='saveToDB(2, this.id, this.innerHTML, "+groupID+")'></td>";
result += "<td id=" + studentArray[i][1] + " contenteditable='true' onBlur='saveToDB(3, this.id, this.innerHTML, "+groupID+")'></td>";
result += "</tr>";
}
result += "</tbody></table>";
dataTable.innerHTML = result;
$(document).ready(function() {
$('#dataEditTableid').DataTable({
});
});
return result;
});
}
You don't actually call the function because the code is still part of the string (missing quotation marks to denote the end of the string).
Try this:
result += "<td id=" + studentArray[i][1] + " contenteditable='true' onBlur='saveToDB(1, this.id, this.innerHTML, "+groupID+")'>" + addDataIfPres(1, this.id, data) + "</td>";

Dynamic option list from an array

I have the following code which works perfectly, but can I make the drop menu dynamic using quantityAllowed as the maximum the drop menu goes to. at the moment I have added 10 options for every print, but what i would prefer is the drop menus only have the correct quantity in. I think the loop I need would go where the options begin using the value of the loop, but when i have tried, i just get an error, so I know I have done something wrong.
function arrayData() {
var index;
var text = "<ul>";
var htmlTable = '';
var calcTable = [];
calcTable = [
{ printName:"Name1", printPrice:8000000, quantityAllowed:6},
{ printName:"Name2", printPrice:12000000, quantityAllowed:5},
{ printName:"Name3", printPrice:20000000, quantityAllowed:4},
{ printName:"Name4", printPrice:2000000, quantityAllowed:3},
];//end of array
for (index = 0; index < calcTable.length; index++) {
var myclass = 'class="printwant"';
$("#tbNames tr:last").after("<tr>" +
"<td style='padding:0px 0px 0px 36px;'>" + calcTable[index].printName + "</td>" +
"<td class='printpoints'>" + calcTable[index].printPrice + "</td>" +
"<td>" + calcTable[index].quantityAllowed + "</td>" +
"<td><select " + myclass + "><option value=0>0</option><option value=1>1</option><option value=2>2</option><option value=3>3</option><option value=4>4</option><option value=5>5</option><option value=6>6</option><option value=7>7</option><option value=8>8</option><option value=9>9</option><option value=10>10</option></select></td><td></td> </tr>");
}//end of loop
$("#tbNames tr:last").after("<tr>" + "<td colspan = '5' height=40 > </tr>");
}
You can separate out your HTML generation code from the jQuery DOM assignment. This makes it a little easier to read and manipulate. When you come to your select/option area, drop it into a for... loop to generate the appropriate number of options.
function arrayData() {
var index;
var text = "<ul>";
var htmlTable = '';
var calcTable = [];
calcTable = [
{ printName:"Name1", printPrice:8000000, quantityAllowed:6},
{ printName:"Name2", printPrice:12000000, quantityAllowed:5},
{ printName:"Name3", printPrice:20000000, quantityAllowed:4},
{ printName:"Name4", printPrice:2000000, quantityAllowed:3},
];//end of array
for (index = 0; index < calcTable.length; index++) {
var myclass = 'class="printwant"';
var output = '';
output += "<tr>";
output += "<td style='padding:0px 0px 0px 36px;'>" + calcTable[index].printName + "</td>";
output += "<td class='printpoints'>" + calcTable[index].printPrice + "</td>";
output += "<td>" + calcTable[index].quantityAllowed + "</td>";
output += "<td><select " + myclass + ">";
for( var i=0, x=calcTable[index].quantityAllowed; i<x; i++ ){
output += '<option value="' + i + '">' + i + '</option>';
}
output += "</select></td><td></td> </tr>";
$("#tbNames tr:last").after(output);
}//end of loop
$("#tbNames tr:last").after("<tr>" + "<td colspan = '5' height=40 > </tr>");
}
arrayData();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tbNames">
<tr></tr>
<tr></tr>
</table>

Building and resorting a multidimensional array with AJAX/Javascript/jQuery

I have a multidimensional array that is built in a jQuery AJAX call when my page loads, called sumArr.
$( document ).ready( function() {
...
$.ajax({
type: 'GET',
url: 'models/table.php',
mimeType: 'json',
success: function(data) {
var sumCount = 0;
var sumArr = [];
$( "#sum-body" ).empty();
$.each(data, function(i, data) {
sumArr.push([
data[0],
data[1],
data[2],
data[3],
data[4],
data[5],
data[6],
data[7],
data[8],
data[9]
]);
var body = "<tr class='clickable-row'>";
body += "<td>" + data[0] + "</td>";
body += "<td>" + data[1] + "</td>";
body += "<td>" + data[2] + "</td>";
body += "<td>" + data[3] + "</td>";
body += "<td>" + data[4] + "</td>";
body += "<td>" + data[5] + "</td>";
body += "<td>" + data[6] + "</td>";
body += "<td>" + data[7] + "</td>";
body += "<td>" + data[8] + "</td>";
body += "<td>" + data[9] + "</td>";
body += "</tr>";
$( body ).appendTo( $( "#sum-body" ) );
sumCount = sumCount + 1;
});
console.log(sumArr);
});
...
});
I have another function that then tries to re-sort the array. I will eventually display the array on my HTML page.
function compareCols(arr, cols) {
arr.sort(function (a, b) {
console.log("comparing " + a[cols] + ", " + b[cols]);
if (a[cols] > b[cols]) {
return 1;
}
if (a[cols] < b[cols]) {
return -1;
}
return 0;
});
}
compareCols('sumArr', 0);
console.log(sumArr);
When my page loads, I get the following error:
Uncaught TypeError: arr.sort is not a function
This is baffling, because I have a much simpler version of this code as an example that works fine. See below:
var items = [
['Edward', 21],
['Sharpe', 37 ],
['And', 45 ],
['The', -12 ],
['Magnetic', 0 ],
['Zeros', 37 ]
];
function compareCols(arr, cols) {
arr.sort(function (a, b) {
console.log("comparing " + a[cols] + ", " + b[cols]);
if (a[cols] > b[cols]) {
return 1;
}
if (a[cols] < b[cols]) {
return -1;
}
return 0;
});
}
compareCols(items, 0);
console.log(items);
I can't seem to find where this code is going wrong. Can anyone spot where the error is? I've combed through the code and can't find anything. I'm guessing it has something to do with AJAX, but don't know for sure. I originally had my array as an object, but changed it to an array or arrays.
Two issues here:
When calling compareCols('sumArr', 0); should remove the quotes as suggest by kurt in the comments.
But the bigger problem is that the sumArr may not be defined as your global variable.
You need to call the compareCols only after a successful ajax call.
Make sure you remove the var in the ajax section so the sumArr = [] refers to the global variable.

Removing objects from an array onclick

I have a an array of items which holds item objects. I want to create a function that when I click on a certain item it is removed from the array. I know I need to use something like splice and I have implemented the following solution but it does the seem to work.
Can anyone tell me what am I doing wrong.
function updateView() {
for (var i = 0; i < storeItems.length; i++) {
output += "<a href='#' id='itemTitle' onclick='removeRecord(" + i + ");'>"
+ storeItems[i].title + " " + "\n" + "</a>";
}
function removeRecord(i) {
storeItems.splice(i, 1);
var newItem = "";
// re-display the records from storeItems.
for (var i = 0; i < storeItems.length; i++) {
newItem += "<a href='#' onclick='removeRecord(" + i + ");'>X</a> "
+ storeItems[i] + " <br>";
};
document.getElementById('foods').innerHTML = newItem;
}
I think this the error is in the line below:
output += "<a href='#' id='itemTitle' onclick='removeRecord(" + i + ");'>" + storeItems[i].title + " " + "\n" + "</a>";
Because it does not recognise the "onclick" event even when I try to do a test with a simple alert.
Can anyone tell me what am I doing wrong. Also if you think you need more information to answer this question please let me know.
Thank you in advance.
Try ...
storeItems = storeItems.splice(i, 1);
WRONG: Basically, you have to assign the spliced array to something.
UODATE:
Here's the way I would do it ... tested in jsFiddle:
var storeItems = [{
title: "Dog"
}, {
title: "Cat"
}, {
title: "Bird"
}];
var foods = document.getElementById('foods');
foods.addEventListener('click', function(e) {
var index = e.target.getAttribute('value');
storeItems.splice(index, 1);
// re-display the records from storeItems.
updateView();
});
function updateView() {
var output = "";
for (var i = 0; i < storeItems.length; i++) {
output += "<a href='#' class='item' value='" + i + "'>" + storeItems[i].title + " " + "\n" + "</a>";
}
document.getElementById('foods').innerHTML = output;
}
updateView();
HTML:
<div id='foods'></div>
This effectively takes the onclick event off of the anchor tag (you could have them on any type of tag at this point) and I also reused your updateView code in the Listener so that it only needs maintained in one location.

Target Specific Javascript Object Literal fields and array with jquery

I cant seem to get this to work. Im trying to do two things
A). Get the following code to show up correctly. The first element is show 'undefined
<ul>
<li>Button
<ul>
<li>x:1</li>
<li>y:2</li>
<li>width:3</li>
<li>height:4</li>
</ul>
</ul>
Here is my code:
$(document).ready(function() {
var data = {
"Controls": [{
"Button":[{ "x": "1","y": "2","width": "3","height": "4" }],
"Image":[{"x": "5","y": "6","width": "7","height": "8"}],
"TextField":[{"x": "9","y": "10","width": "11","height": "12"}]
}]
}
var str = '<ul>';
$.each(data.Controls, function(k, v) {
str += '<li>' + k[0] + '</li><ul>';
for(var kk in v.Button[0]){
str += '<li>' + kk + ':' + v.Button[0][kk] + '</li>';
}
str += '</ul>';
});
str += '</ul>';
$('div').append(str);
})
And
B). trying to display a list(separate list from above) of just the fields. like this:
<li>Button</li>
<li>Image</li>
<li>TextField</li>
I think that the answer to the second lies in the first, but I cannot seem to get the targeting right.
Any help is appreciated
Demo
To get the first list:
var str = '<ul>';
var target = "Button";
str += '<li>' + target + '<ul>';
$.each(data.Controls[0][target][0], function(kk, vv){
str += '<li>' + kk + ':' + vv + '</li>';
});
str += '</ul></li>';
str += '</ul>';
To get the second list:
var str = '<ul>';
$.each(data.Controls[0], function(k,v) {
str += '<li>' + k + '</li>';
});
str += '</ul>';
To target them by index, so Button is 0:
var str = '<ul>';
var target = 0;
var count = 0;
$.each(data.Controls[0], function(k,v) {
if(count == target)
{
str += '<li>' + k + '<ul>';
$.each(v[0], function(kk, vv){
str += '<li>' + kk + ':' + vv + '</li>';
});
str += '</ul></li>';
return false; // <-- break because we got what we wanted
}
count++;
});
str += '</ul>';
First of all, this has nothing to do with JSON. JSON is a string-serialization format. What you have here is an object literal.
Second, I have no idea why you are wrapping all your object definitions inside Controls, with arrays, seems like a lot of extra hassle. You are also doing things in a very non-jQuery way.
You could try something like this:
var data = {
"Controls": {
"Button":{ "x": "1","y": "2","width": "3","height": "4" },
"Image":{"x": "5","y": "6","width": "7","height": "8"},
"TextField":{"x": "9","y": "10","width": "11","height": "12"}
}
}
$('div').append('<ul id="outer_ul">');
$.each(data.Controls, function(key, value) {
$('#outer_ul').append('<li>' + key + '</li>', '<ul id="' + key +'">');
$('#field_list').append('<li>' + key + '</li>');
$.each(value, function(key2, value2) {
$('#' + key).append('<li>' + key2 + ':' + value2 + '</li>');
}
}
This code populates both you div as well as a ul with the id of field_list which would represent the container into which you want to put the second list (so adjust this code according the the proper jQuery selector you want to use.

Categories

Resources