Reputation: 20138
I am storing data using the data-
approach in a HTML tag like so:
<td><"button class='delete' data-imagename='"+results[i].name+"'>Delete"</button></td>
I am then retrieving the data in a callback like this:
$(this).data('imagename');
That works fine. What I am stuck on is trying to save the object instead of just one of the properties of it. I tried to do this:
<td><button class='delete' data-image='"+results[i]+"'>Delete</button></td>
Then I tried to access the name property like this:
var imageObj = $(this).data('image');
console.log('Image name: '+imageObj.name);
The log tells me undefined
. So it seems like I can store simple strings in the data-
attributes but I can't store JSON objects...
I've also tried to use this kid of syntax with no luck:
<div data-foobar='{"foo":"bar"}'></div>
Any idea on how to store an actual object in the HTML tag using the data-
approach?
Upvotes: 178
Views: 354792
Reputation: 1946
I found a better way in https://oblik.dev/utilities/config/ Basically what they do is have a parser from-to json-like objects without double quotes:
import { Parser } from 'oblik/utils/config'
let parser = new Parser()
let result = parser.parse('foo: bar, !baz')
console.log(result) // { foo: "bar", baz: false }
More examples:
<div ob-foo="text: Hello, num: 42">My Foo component</div>
I would like to see something like this format standartized
Upvotes: 0
Reputation: 14162
There's a better way of storing JSON in the HTML:
HTML
<script id="some-data" type="application/json">{"param_1": "Value 1", "param_2": "Value 2"}</script>
JavaScript
JSON.parse(document.getElementById('some-data').textContent);
Upvotes: 30
Reputation: 573
The trick for me was to add double quotes around keys and values. If you use a PHP function like json_encode
will give you a JSON encoded string and an idea how to properly encode yours.
jQuery('#elm-id').data('datakey')
will return an object of the string, if the string is properly encoded as json.
As per jQuery documentation: (http://api.jquery.com/jquery.parsejson/)
Passing in a malformed JSON string results in a JavaScript exception being thrown. For example, the following are all invalid JSON strings:
"{test: 1}"
(test
does not have double quotes around it)."{'test': 1}"
('test'
is using single quotes instead of double quotes)."'test'"
('test'
is using single quotes instead of double quotes).".1"
(a number must start with a digit; "0.1"
would be valid)."undefined"
(undefined
cannot be represented in a JSON string; null
, however, can be)."NaN"
(NaN
cannot be represented in a JSON string; direct representation of Infinity is also nUpvotes: 3
Reputation: 3519
Combine the use of window.btoa
and window.atob
together with
JSON.stringify
and JSON.parse
.
- This works for strings containing single quotes
Encoding the data:
var encodedObject = window.btoa(JSON.stringify(dataObject));
Decoding the data:
var dataObject = JSON.parse(window.atob(encodedObject));
Here is an example of how the data is constructed and decoded later with the click event.
Construct the html and encode the data:
var encodedObject = window.btoa(JSON.stringify(dataObject));
"<td>" + "<a class='eventClass' href='#' data-topic='" + encodedObject + "'>"
+ "Edit</a></td>"
Decode the data in the click event handler:
$("#someElementID").on('click', 'eventClass', function(e) {
event.preventDefault();
var encodedObject = e.target.attributes["data-topic"].value;
var dataObject = JSON.parse(window.atob(encodedObject));
// use the dataObject["keyName"]
}
Upvotes: 17
Reputation: 1162
A lot of problems with storing serialized data can be solved by converting the serialized string to base64.
A base64 string can be accepted just about anywhere with no fuss.
Take a look at:
The
WindowOrWorkerGlobalScope.btoa()
method creates a base-64 encoded ASCII string from a String object in which each character in the string is treated as a byte of binary data.
The
WindowOrWorkerGlobalScope.atob()
function decodes a string of data which has been encoded using base-64 encoding.
Convert to/from as needed.
Upvotes: 30
Reputation: 871
This is how it worked for me.
Object
var my_object ={"Super Hero":["Iron Man", "Super Man"]};
Set
Encode the stringified object with encodeURIComponent() and set as attribute:
var data_str = encodeURIComponent(JSON.stringify(my_object));
$("div#mydiv").attr("data-hero",data-str);
Get
To get the value as an object, parse the decoded, with decodeURIComponent(), attribute value:
var data_str = $("div#mydiv").attr("data-hero");
var my_object = JSON.parse(decodeURIComponent(data_str));
Upvotes: 87
Reputation: 379
This code is working fine for me.
Encode data with btoa
let data_str = btoa(JSON.stringify(jsonData));
$("#target_id").attr('data-json', data_str);
And then decode it with atob
let tourData = $(this).data("json");
tourData = atob(tourData);
Upvotes: 1
Reputation: 1
!DOCTYPE html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
$("#btn1").click(function()
{
person = new Object();
person.name = "vishal";
person.age =20;
$("div").data(person);
});
$("#btn2").click(function()
{
alert($("div").data("name"));
});
});
</script>
<body>
<button id="btn1">Attach data to div element</button><br>
<button id="btn2">Get data attached to div element</button>
<div></div>
</body>
</html>
Anser:-Attach data to selected elements using an object with name/value pairs.
GET value using object propetis like name,age etc...
Upvotes: 0
Reputation: 2847
For the record, I found the following code works. It enables you to retrieve the array from the data tag, push a new element on, and store it back in the data tag in the correct JSON format. The same code can therefore be used again to add further elements to the array if desired. I found that $('#my-data-div').attr('data-namesarray', names_string);
correctly stores the array, but $('#my-data-div').data('namesarray', names_string);
doesn't work.
<div id="my-data-div" data-namesarray='[]'></div>
var names_array = $('#my-data-div').data('namesarray');
names_array.push("Baz Smith");
var names_string = JSON.stringify(names_array);
$('#my-data-div').attr('data-namesarray', names_string);
Upvotes: 0
Reputation: 4198
.data()
works perfectly for most cases. The only time I had a problem was when the JSON string itself had a single quote. I could not find any easy way to get past this so resorted to this approach (am using Coldfusion as server language):
<!DOCTYPE html>
<html>
<head>
<title>
Special Chars in Data Attribute
</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script src="https://code.jquery.com/jquery-1.12.2.min.js"></script>
<script>
$(function(){
var o = $("##xxx");
/**
1. get the data attribute as a string using attr()
2. unescape
3. convert unescaped string back to object
4. set the original data attribute to future calls get it as JSON.
*/
o.data("xxx",jQuery.parseJSON(unescape(o.attr("data-xxx"))));
console.log(o.data("xxx")); // this is JSON object.
});
</script>
<title>
Title of the document
</title>
</head>
<body>
<cfset str = {name:"o'reilly's stuff",code:1}>
<!-- urlencode is a CF function to UTF8 the string, serializeJSON converts object to strin -->
<div id="xxx" data-xxx='#urlencodedformat(serializejson(str))#'>
</div>
</body>
</html>
Upvotes: 0
Reputation: 85
For some reason, the accepted answer worked for me only if being used once on the page, but in my case I was trying to save data on many elements on the page and the data was somehow lost on all except the first element.
As an alternative, I ended up writing the data out to the dom and parsing it back in when needed. Perhaps it's less efficient, but worked well for my purpose because I'm really prototyping data and not writing this for production.
To save the data I used:
$('#myElement').attr('data-key', JSON.stringify(jsonObject));
To then read the data back is the same as the accepted answer, namely:
var getBackMyJSON = $('#myElement').data('key');
Doing it this way also made the data appear in the dom if I were to inspect the element with Chrome's debugger.
Upvotes: 0
Reputation: 1
Using the documented jquery .data(obj) syntax allows you to store an object on the DOM element. Inspecting the element will not show the data-
attribute because there is no key specified for the value of the object. However, data within the object can be referenced by key with .data("foo")
or the entire object can be returned with .data()
.
So assuming you set up a loop and result[i] = { name: "image_name" }
:
$('.delete')[i].data(results[i]); // => <button class="delete">Delete</delete>
$('.delete')[i].data('name'); // => "image_name"
$('.delete')[i].data(); // => { name: "image_name" }
Upvotes: 0
Reputation: 11987
instead of embedding it in the text just use $('#myElement').data('key',jsonObject);
it won't actually be stored in the html, but if you're using jquery.data, all that is abstracted anyway.
To get the JSON back don't parse it, just call:
var getBackMyJSON = $('#myElement').data('key');
If you are getting [Object Object]
instead of direct JSON, just access your JSON by the data key:
var getBackMyJSON = $('#myElement').data('key').key;
Upvotes: 163
Reputation: 4602
For me it work like that, as I need to store it in template...
// Generate HTML
var gridHtml = '<div data-dataObj=\''+JSON.stringify(dataObj).replace(/'/g, "\\'");+'\'></div>';
// Later
var dataObj = $('div').data('dataObj'); // jQuery automatically unescape it
Upvotes: 13
Reputation: 6154
Actually, your last example:
<div data-foobar='{"foo":"bar"}'></div>
seems to be working well (see http://jsfiddle.net/GlauberRocha/Q6kKU/).
The nice thing is that the string in the data- attribute is automatically converted to a JavaScript object. I don't see any drawback in this approach, on the contrary! One attribute is sufficient to store a whole set of data, ready to use in JavaScript through object properties.
(Note: for the data- attributes to be automatically given the type Object rather than String, you must be careful to write valid JSON, in particular to enclose the key names in double quotes).
Upvotes: 189