How to loop through all json items with jquery? - javascript

This is the json file I am working with
?(
{
"title":"1",
"description":"description",
"site":"site",
"image_s":"/Becki.jpg",
"image_l":"aurel"
},
{
"title":"2",
"description":"2",
"site":"1",
"image_s":"8.jpg",
"image_l":"aurel"
})
The question mark is replaced with a dynamic number in order to over come cross-domain restrictions. And I think this is why I am having trouble
I am trying to get both image_s but I can only read the data of the first item (if that's the right word):
$.getJSON(surl, function(data) {
$.each(data, function(tete, i){
$.each(data, function(tete, i){
$("<div>").addClass("box").append(
$("<img/>").attr("src", [this]))
).appendTo("#showdata");
});
})
});
I know there is something wrong with $("<img/>").attr("src", [this])) but that is not the problem. The problem is that the above loop only get the content of the first item (title:1 to the end not title:2)
I think if the name of the question mark wasn't dynamic I could have done the loop from there and got its children, but I dont know how to do that in this case
And in case you need to know, I can not use server-side programing for this particular project
Can you help in any way?

You have to put your items (called objects in JavaScript) into array:
[
{
"title":"1",
"description":"description",
"site":"site",
"image_s":"/Becki.jpg",
"image_l":"aurel"
},
{
"title":"2",
"description":"2",
"site":"1",
"image_s":"8.jpg",
"image_l":"aurel"
}
]
And also change your JS:
$.each(data, function(index, item){
$("<div>").addClass("box")
.append($("<img/>").attr("src", [item.image_s]))
.appendTo("#showdata");
});
Running example is shown in this JSFiddle.

If you're passing data through another domain, you're probably using JSONP. JSONP requires the server to return the values wrapped in a function; in your case, the function is a random string of numbers.
If your post is accurate, you'll have to update the server to return the JSON object properly:
Currently it is returning multiple objects wrapped by a function: 235235({one object}, {two object})
When it should be returning one JSON object, wrapped by a function: 235235([{first object in array}, {second object in array}])

Related

Parse JSON data, and then pass all its values to another function

I'm building this website: http://collections.design
The way it works is by reading all tools data from a JSON, using jQuery (I don't know much javascript). Then, you can click on an item and a side panels opens with further information. But there's a lot of repeated code, so I'm trying to optimise it a bit.
First I parse the JSON:
// The data source
var data_source = "../data/tools/tools.json";
// Parsing the JSON
$.getJSON(data_source, function(data) {
$.each(data, function(key,val) {
// And I'm storing all of its values in variables, to make them easier to read:
var name = val.availability.name;
var linux = val.os.linux;
// Then I'm using all that to render each item on screen
…
});
});
Each of the items has a button that calls another function to create and open the side panel. The side panel reuses that item's data from the JSON. This function to create the side panel is using the name variable as parameter, but then inside is parsing the JSON again to get the rest of the values it needs.
My question is:
How can I "encapsulate" all variables when I do the JSON parsing, then pass it as a parameter to the other function; and finally, individually read each of those values in the other function?
I tried working with arrays. But didn't manage it to work, also keeping in mind that I'm trying to simplify things, not repeat myself, and keep short names…
Maybe I'm asking too much, but any pointers or links to doc will be appreciated.
I see two ways of doing this.
1) Save the JSON data outside the scope so you can reuse it and pass the index of the data you want.
Something like this
// The data source
var data_source = "../data/tools/tools.json";
var all_data;
// Parsing the JSON
$.getJSON(data_source, function(data) {
all_data = data;
$.each(data, function(key,val) {
$('.button').on('click', function() { callToOtherFunction(key) })
});
});
function callToOtherFunction(key) {
console.log(all_data[key]);
}
2) As Sam Axe said, pass the data directly to the function
// The data source
var data_source = "../data/tools/tools.json";
// Parsing the JSON
$.getJSON(data_source, function(data) {
$.each(data, function(key,val) {
$('.button').on('click', function() { callToOtherFunction(key) })
});
});
function callToOtherFunction(val) {
console.log(val);
}
Here's a working fiddle.
The data is already "encapsulated" in the data object. Pass that object to the function that you want to use the data in.
You could always construct a new object - but what's the point - it's already in the data object.

d3. Calling a csv url from an array javascript

I'm new at this. Im trying to make a simple interactive chart using jaavascript. The idea is that when I change the values in the selector, the chart change the data is using.
However, I´m having troubles with the data switching. The data come´s frome different urls. Those urls are in a CSV file. My code extracts the urls from th CSV file and makes an array. Then it proceed to call the CSV file from the adequate element of the array. Simplifying the code:
functionThatReturnsArray(){
d3.csv("http//URL.COM", function(){
SomeMoreCode;
return ArrayOfStrings
};)
}
A = functionThatReturnsArray();
MoreCode;
//For example, the first value from A is selected
d3.csv(A[0], function(error, data) {
MoreCode;
})
The problem is that it seems that this isn´t a valid input to d3.csv, because it doesn´t work. I don´t know if i´m missing something or it just can´t be done this way.
I searched and it might be from the fact that d3.csv is an asynchronous method, but I´m not sure if that´s the problem.
Any suggestion will be apreciated
Your first CSV data is loading asynchronously, so this function will not return anything
functionThatReturnsArray(){
d3.csv("http//URL.COM", function(){
SomeMoreCode;
return ArrayOfStrings
};)
}
You can put following code in function
function processArray(A){
MoreCode;
//For example, the first value from A is selected
d3.csv(A[0], function(error, data) {
MoreCode;
})
}
and invoke this function in first csv loading callback
functionThatReturnsArray(){
d3.csv("http//URL.COM", function(){
SomeMoreCode;
processArray(ArrayOfStrings) //add this
};)
}

Json data from table in an onclick function show in seperate div

I'm trying to get data used in my table to be used in a div when I click on the table. The thing is, there are multiple tables in my script according to the data of my JSON. So my JSON consists of object that consists of object. For example:
My table(s) are rendered like this:
data.forEach(function(somedata){
return '<table><tr><td>'+somedata.something+'</td></tr></table>';
});
Now I've tried to get the onclick to work in this case but I cant seem to figure out how. I'd like to not use specific ID's rendered in the foreach like:
var i=0;
data.forEach(function(somedata){
i++;
return '<table id="'.id.'"><tr><td>'+somedata.something+'</td></tr></table>';
});
the variable somedata consists of an object so I cant just make an onclick in the html code of the table either and send the data in it.
So somedata would look something like this but json encoded:
somedata{
[0]=>array(
'something'=>'test',
'theobject'=>array(...)
),
[1]=>array(etc...)
}
Now what I want is to get the data from theobject in a seperate div as soon as I click on the table that belongs to the right somedata.
I've been thinking of making a jquery on click for this but then I would need specific ID's in the table(if that's the only possible solution then I'd take it). Cant I do something with this or something? Or send the data at the same time it's being rendered cause in my code I can at the moment of course reach to somedata.theobject
I think I'm thinking a bit too difficult about this. Am I?
You can pass this in onclick function like
return '<table onclick=makeObject(this)><tr><td>'+somedata.something+'</td></tr></table>';
And then use the function to get the data
function makeObject(that){
var tbl = $(that).find('tr').map(function() {
return $(this).find('td').map(function() {
return $(this).html();
}).get();
}).get();
}
There are a few ways to go about this. Rather than using the forEach function we can use the jQuery.map function, since you've indicated that you're open to using jQuery :-)
var $els = $.map(data, function(somedata, i){
var $el = $('<table><tr><td>'+somedata.something+'</td></tr></table>')
.click(function(e) {
populateDivWithData(somedata.theobject);
});
return $el;
});
The call to .click inside each will create a separate click handler for each item in data; each click handler then has access to the relevant theobject value.
EDIT: Thanks #Loko for the reminder about the .forEach built-in

d3 csv readin to objects in array

I am currently trying to use the d3 framework for a university visualisation approach.
For testing purpose I want to read a csv-file and parse the rows to objects inside an array.
My csv looks like:
ID, Referred To, TimeStamp, Votes, Comment
So I want to read it with the following lines:
d3.csv("test_comments.csv", function(data) {
commentlist = data.map(function(d) {
return[+d["ID"],
+d["Referred To"],
+d["TimeStamp"],
+d["Votes"],
+d["Comment"]
]
});
});
But if I want to readout the values afterwards I am just getting "undefined"
I also tried the way mbostock described in this thread:
csv to array in d3.js
but working with a global variable is not working either.
var commentlist;
d3.csv("test_comments.csv", function(data) {
commentlist = data.map(function(d) {
return[+d["ID"],
+d["Referred To"],
+d["TimeStamp"],
+d["Votes"],
+d["Comment"]
]
});
});
console.log(commentlist);
Am I understanding something wrong?
Maybe you have a solution for me.
var commentlist=[];
d3.csv("test_comments.csv", function(data) {
commentlist=data;
});
console.log(commentlist);
What I know is, In the call back data object will contain array of JSON objects of csv file's all rows of data, that each row data is pushed as a JSON format into the data array.
As below
[{"ID": valueFromtheRow, "Referred To": value, "TimeStamp": value, "Votes":value, "Comment":value}]
The call back function is called by passing the array of JSONs.
So data object will look like
data=[{"ID": valueFromtheRow, "Referred To": value, "TimeStamp": value, "Votes":value, "Comment":value}];
Hope you understood...If not ask me.
I think the reason you got { console.log(commentlist) } undefined is that inside d3.csv the callback function is parsed and called last by browser, and { console.log(commentlist) } is called earlier even though it appears at the bottom of your code. So the moment when { console.log(commentlist) } is called, { commentlist } is actually undefined (only declared).
That being said, just try putting { console.log(commentlist) } inside the callback and it should do the job.

Sorting Dynamic Data with Isotope

I am trying to use Isotope.js to sort data by type. There seem to be a few ways to do this however they all require that you know the sort variables before hand.
One of the best examples of what I'm talking about is found in this question.
In the example they are trying to sort by class for example group all elements with class .milk like so:
milk: function( $elem ) {
var isMilk = $elem.hasClass('milk');
return (!isMilk?' ':'');
},
A jsfiddle is provided here: http://jsfiddle.net/Yvk9q/9/
My problem:
I am pulling the categories (classes or data-type) from a user generated database. For this reason I cannot simply add all the sorting variables to the code before hand.
I played with the fiddle and got a semi working sort here: http://jsfiddle.net/BandonRandon/erfXH/1/ by using data-category instead of class. However,this just sorts all data alphabetically not by actual category.
Some possible solutions:
Use JSON to return an array of all categories and then use this to loop through classes
Use inline javascript and run a PHP loop inside a <script> tag
Write an external PHP file with a javascript header
What I'm looking for
The simplest best approach here, being if it's one of the solutions above or something different. This doesn't seem like it should need to be this complicated. So I may be over complicating this.
EDIT:
I now have a json array of my data but I can't figure out how to pass the data into the isotope settings when i try something like this
var $container = $('.sort-container');
var opts = {
itemSelector: '.member-item',
layoutMode: 'straightDown',
getSortData : {
$.getJSON( 'member-cat-json.php', function(data) {
$.each(data, function(i, item) {
var slug = data[i].slug;
slug : function( $elem ) {
var is+slug = $elem.hasClass(slug);
return (!is+slug?' ':'');
}
}
});
});
}
}
var $container = $('.sort-container');
$container.isotope(opts);
It fails because I can't use a loop inside of the plugin settings. Not sure what can be done about this though.
EDIT 2:
I found this question which seems about what I'm trying to do but unfortunately the most recent jsfiddle fails with isotope
Here is a sample of my JSON output:
{term_id:9, name:Milk, slug:milk, term_group:0, term_taxonomy_id:17...}
{term_id:9, name:Eggs, slug:eggs, term_group:0, term_taxonomy_id:17...}
I am using the slug as the class name and in my loop.
I'm not sure I entirely understand your question, but I'll state my assumptions and work from there:
You have data in a format as described above:
{term_id:9, name:Milk, slug:milk, term_group:0, term_taxonomy_id:17...}
You want to sort on the slug names, even though we do not know what the slugs will be named ahead of time.
Assuming these two things, the fiddle you've linked to is close, but has a problem due to closures which I have fixed.
As expected, your situation is similar to the one listed, except that you need to obtain the JSON data first, as you have.
var $container = $('.sort-container'),
createSortFunction = function(slug) {
return function($elem) {
return $elem.hasClass(slug) ? ' ' : '';
};
},
getSortData = function(data) {
var sortMethods = {};
for (var index in data) {
var slug = data[index].slug;
// immediately create the function to avoid
// closure problems
sortMethods[slug] = createSortFunction(slug);
}
return sortMethods;
}
$.getJSON('member-cat-json.php', function (data) {
// I'm wrapping the isotop creation inside the `getJSON`
// call, just to ensure that we have `data`
$container.isotope({
itemSelector: '.member-item',
layoutMode: 'straightDown',
getSortData: getSortData(data);
});
});

Categories