Process data-attributes: how to seralize - javascript

I'm trying to create and HTML chart with a jquery plugin and I'm using HTML5 data attributes to pass data from my rails app to jquery function.
My html, after the ruby hash conversion, is something like this:
<div class="chart" data-contents-01="0" data-contents-02="1" data-contents-03="3" data-contents-04="0" data-contents-05="0" data-contents-06="0" data-contents-07="0" data-contents-08="0" data-contents-09="0" data-contents-10="0" data-contents-11="0" data-contents-12="0" data-contents-13="0" data-contents-14="0" data-contents-15="0" data-contents-16="0" data-contents-17="0" data-contents-18="0" data-contents-19="0" data-contents-20="0" data-contents-21="0" data-contents-22="0" data-contents-23="2" data-contents-24="1" data-contents-25="4" data-contents-26="0" data-contents-27="0" data-contents-28="0" data-contents-29="2" data-contents-30="2" data-contents-31="0" id="chart_2" style="padding: 0px; position: relative;">
I have a lot if data-contents-xx and I must convert this data to an array of array.
My function take data as:
var contents = [
[x, y],
[x,y]
];
so I must process my data attributes to have an array of array, where each sub-array is a couple of data-contents-x
How can i serialize my data attribute?

The JQuery method .data() will pull all data objects into an array of key: value pairs. With your element names:
$('.chart').data();
For example, given:
<div class="chart" data-foo="1" data-bar="2"></div>
Use:
var data = $('.chart').data();
for(var i in data){
console.log("data attribute - " + i + ":" + data[i]);
}
Here's the fiddle: http://jsfiddle.net/WVfSg/260/
When playing with your code in the fiddle, it doesn't work. However, when I get rid of the second hyphen, it works as expected.

Related

How do I add a value from a callback into a new element with setAttribute?

I need to add the value of a callback into my setAttribute. How do I do that?
This value is necessary to get data out of a table at a later moment.
This is the code:
row.forEach(function(row) {
var subchapname = document.createElement("div");
subchapname.setAttribute("id", "subchaptertitle");
subchapname.setAttribute("subid", '"+row+"');
subchapname.setAttribute("onclick","{ alert('You are not going to believe this!') } ");
subchapname.textContent = row.subname;
rows.appendChild(subchapname);
Basically, this means:
callback = row
This callback needs to be added to subchapname.setAttribute("subid", '"+row+"');
Is this possible?
This is the actual result:
<div id="subchaptertitle" subid=""+row+"" onclick="{ alert('You are not going to believe this!') } ">bos in brand</div>```
subid is not attribute to store data in it, so you can not add a attribute like this to a html-tag and fill it with a value (Of course writing a string into it, would work, but is this what you need?). But you can add datasets if you use html5. So use this solution to store your rows-value in the dataset-property of subid.
If row is a object and you want to see the the stringified value of the Object use JSON.stringify before storing it in the dataset
row.forEach(function(row) {
var subchapname = document.createElement("div");
subchapname.setAttribute("id", "subchaptertitle");
subchapname.dataset.subid = row;
// subchapname.dataset.subid = JSON.stringify(row);
subchapname.setAttribute("onclick","{ alert('You are not going to believe this!') } ");
subchapname.textContent = row.subname;
rows.appendChild(subchapname);
});
Your Element should now look like this:
<div id="subchaptertitle" onclick="{ alert('You are not going to believe this!') } " data-subid="[object Object]"></div>
Or if you used JSON.stringify:
<div id="subchaptertitle" onclick="{ alert('You are not going to believe this!') } " data-subid="what ever row is as a string"></div>
To log the value to the console, (after you added the tag to the DOM) do something like this:
console.log(document.getElementById('subchaptertitle').dataset.subid);
In case you used JSON.stringify, now use something like this:
console.log(JSON.parse(document.getElementById('subchaptertitle').dataset.subid));

HTML data attributes values. How to change?

I have a div, which I can't edit. Is it possible to multiply the values of the data attribute?
Code:
<div class="reviews" data-page-opts="
{
showform:1,
showsupport:0,
postid:241,
perpage:5,
paginate:1,
classes:reviews_in_content, wrapper:1,
morelink:,
on_postid:0,
num:9999,
hidecustom:0,
snippet:0,
hidereviews:0,
hideresponse:0,
ajax:0,
thispage:1
}
">
</div>
Example:
I want to multiply thispage: 1 by 5 or just to replace 1 with 5. Can I do this with JavaScript/jQuery? Thanks in advance.
Use can use jQuery to get value of data first, and then use JSON.parse(), and then modify, after you modify, you can use JSON.stringify();
Here is example code:
var data = $('div.reviews').attr('data-page-opts');
var dataObj = JSON.parse(data);
dataObj.ajax = 1;
data = JSON.stringify(dataObj);
$('div.reviews').attr('data-page-opts', data);

Retrieving escaped JSON string from PHP webservice in javascript

I'm trying to retrieve some HTML to be inserted into a web page from a web service, I have a database of HTML which relates to different applications so i'm selecting the ID of the application and returning them in JSON to the javascript front end, the problem i'm getting is the first two numeric values get parsed fine, but the CSS/JS/HTML elements don't - i'm guessing its to do with the way the string is escaped but i'm not sure how to handle it?
[{"id":"1","machine_id":"1","CSS":"<link rel=\"stylesheet\" type=\"text\/css\" href=\"newcss.css\">","JavaScript":"<script src=\"js\/SlotMachine.js\" type=\"text\/javascript\"><\/script>,<script src=\"js\/jquery-1.11.1.min.js\" type=\"text\/javascript\"><\/script>","HTML":"<div class=\"outer_container\">\n <div class=\"reelcasing\">\n <canvas id=\"reel1\" width=\"150\" height=\"400\"><\/canvas>\n <\/div>\n <div class=\"reelcasing\"> \n <canvas id=\"reel2\" width=\"150\" height=\"400\"><\/canvas>\n <\/div>\n <div class=\"reelcasing\">\n <canvas id=\"reel3\" width=\"150\" height=\"400\"><\/canvas>\n <\/div>\n <input type=\"button\" id=\"start\" class=\"start_button\" value=\"Press Start\">\n <\/div>","rollSpeed":"25","rollIncrement":"20"}]
Then i'm doing:
$http({
method: 'GET',
url: 'http://localhost/api/machine/get/' + machineId
}).success(function(data){
$scope.machineDetails = data;
// Debugging
for(machine in data){
alert(machine.id);
}
}).error(function(){
alert("Unable to retrieve slot machine information.");
});
};
UPDATE
To clarify the values from the JSON get read in except where they've got the complex html, for example that example returns:
machineDetails: [
0: {
id: 1
machine_id: 1
CSS:
JavaScript: ,
HTML:
Edit:
Ok well its odd if I step through the data using...
angular.forEach(data, function(data, key){
console.log(data.CSS);
});
It gives the correct values however if I do:
$scope.machineDetails = data;
It fills in the ID and machineID but doesn't put any of the HTML stuff in, its not a massive issue but i'd like to know why it won't store it in scope?

too much HTML in an ajax script?

I read from this page that appending a lot of elements is bad practice and I should build up a string during each iteration of the loop and then set the HTML of the DOM element to that string. Does the same go for using too much HTML in the loop?
I have an AJAX script that parses JSON data. It requires adding data to different existing elements, like this:
$.ajax({
url: "url",
success: function (data) {
$(data.query.results.json.json).each(function (index, item) {
var title = item.title, // A,B,C or D
age = item.age,
background = item.background,
ingredient = item.Ingredient;
$('.'+ title+'_ingredient').html(''+ingredient+'')
$('.'+ title+'_age').html(''+age+'')
$('.'+ title+'_background').html(''+background+'')
});
},
error: function () {}
});
HTML:
<div class="A_ingredient"></div>
<div class="B_ingredient"></div>
<div class="C_ingredient"></div>
<div class="D_ingredient"></div>
<div class="A_age"></div>
<div class="B_age"></div>
<div class="C_age"></div>
<div class="D_age"></div>
<div class="A_background"></div>
<div class="B_background"></div>
<div class="C_background"></div>
<div class="D_background"></div>
Is it necessary to build up a string first? If so, can you show me how to do that?
It is purely about the time it takes to process calls to html() so they simply recommend you reduce the number of calls. In this case you could build them once in a loop then sets the div html once for each.
Update:
Based on your update, aside from all the extra trailing quotes you don't need to add (a string is a string is a string), your code is fine as is. You only hit each item once.
e.g.
$.ajax({
url: "url",
success: function (data) {
$(data.query.results.json.json).each(function (index, item) {
var title = item.title, // A,B,C or D
age = item.age,
background = item.background,
ingredient = item.Ingredient;
$('.'+ title+'_ingredient').html(ingredient);
$('.'+ title+'_age').html(age);
$('.'+ title+'_background').html(background);
});
},
error: function () {}
});
Note: If your item properties (Age, Background, Ingredient) are simple values (not objects or arrays), yo do not need the leading ''+s either.
Previous
Assuming you actually want to concatenate the results (you are only keeping the last ingredient at the moment), you could do something like this:
e.g.
$.ajax({
url: "url",
success: function (data) {
var ingredients = '';
$(data.query.results.json.json).each(function (index, item) {
var title = item.title;
var ingredient = item.Ingredient;
ingredients += ingredient;
});
$('.aclass').html(ingredients);
$('.bclass').html(ingredients);
$('.cclass').html(ingredients);
$('.dclass').html(ingredients);
},
error: function () {}
});
Which can be reduced to:
$('.aclass,.bclass,.cclass,.dclass').html(ingredients);
The contents of each div are identical in your example, so you only need a single string.
In this instance you would probably need some form of delimiter between ingredients, but your example is too vague.
e.g.
ingredients += ingredient + '<br/>';
In your example, you're setting the HTML on many different document elements.
If they're grouped in some way, for example all in a Div with ID #Container, you could build a string of the HTML and set the content of the whole Div at the end of it, something like this:
$.ajax({
url: "url",
success: function (data) {
var sHTML="";
$(data.query.results.json.json).each(function (index, item) {
var title = item.title,
background = item.background,
ingredient = item.Ingredient;
// not sure what your actual HTML is (div/span/td etc) but somethign like this?
sHTML+="<div>"; // an opening container for this item
sHTML+='<div class="'+title+'_ingredient">'+ingredient+'</div>')
sHTML+='<div class="'+title+'_age">'+title+'</div>')
sHTML+='<div class="'+title+'_background">'+background+'</div>')
sHTML+="</div>";
});
$("#Container").html(sHTML);
},
error: function () {}
});
Note I haven't tested this code, but you see the principal hopefully.
That is, build a string of the HTML then set one element at the end with the content.
I have done this a lot in a recent project and haven't seen any speed issues (maybe 50 'items' to set in my case).
HTML will initially look like this :
<div id="container">
</div>
Then end up like this (2 x items in this example) :
<div id="container">
<div>
<div class="<sometitle1>_ingredient">ingredient 1</div>
<div class="<sometitle1>_age">age 1</div>
<div class="<sometitle1>_background">background 1</div>
</div>
<div>
<div class="<sometitle2>_ingredient">ingredient 2</div>
<div class="<sometitle2>_age">age 2</div>
<div class="<sometitle2>_background">background 2</div>
</div>
</div>
subsequent calls will replace the element's content with new values, replacing the old items.
Building a string is, I would imagine, less processor-heavy than setting the html() on lots of elements individually. Each time you use html() I'm guessing that the browser has to go some way towards working out any knock-on effects like expanding the width of an element to accomodate it or whether events will still work as they did, etc - even if actual rendering is only run at the end of the process. This way you use html() once, although what you're setting is more complex.
Hope this helps.

Create an horizontal description list from a json object

The structure I plan to have is an horizontal description list like
key key2 ...
value value2 ...
My code is:
html:
<dl class="horizonal_list">
<dt>Key</dt>
<dd>Value</dd>
</dl>
<dl class="horizonal_list">
<dt>Another key</dt>
<dd>Another value</dd>
</dl>
...
css:
dt, dd {
margin-left: 15px;
margin-right: 15px;
text-align:center;
}
.horizonal_list {
float: left;
}
Basically, I'd like to show into the above horizontal list some information retrieved from the server and then sent to a JSON object, like the following:
var current_status = {"REFERENCE":"1000006",
"NUMBER":108,
"DESCRIPTION":"SC1B",
"CONFIRMATION":"155248",
"CREATION_DATE":15584,
"YEAR":2013,
"NDOQ":161,
"NEZC":"161",
"STATUS":"LI"};
But, I'm very new to web dev and I'd like some tips. Thanks.
You can loop through each property in your object, and then add a new <dl> element for each key/value pair.
NOTE that this example JQuery for appending the html to the DOM.
function addItem(key, value) {
$("div").append('<dl class="horizonal_list"><dt>' + key + '</dt><dd>' + value + '</dd></dl>');
}
for (var key in current_status) {
addItem(key, current_status[key]);
}
Here is a working example
In the example above, <div> has been used to represent an empty container that each <dl> element will be added to. This may be different from what you current have so you will need to change that accordingly.
If you are going to be calling this function more than once you will want to clear the <div> element each time before you populate it:
$("div").empty();
Here is a more realistic example, which shows how to update the data on demand

Categories