Store JSON object in data attribute in HTML jQuery

JqueryHtmlJson

Jquery Problem Overview


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?

Jquery Solutions


Solution 1 - Jquery

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).

Solution 2 - Jquery

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;

Solution 3 - Jquery

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));

Solution 4 - Jquery

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.

Solution 5 - Jquery

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);

Solution 6 - Jquery

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

Solution 7 - Jquery

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"] 
}

Solution 8 - Jquery

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:

  1. "{test: 1}" (test does not have double quotes around it).
  2. "{'test': 1}" ('test' is using single quotes instead of double quotes).
  3. "'test'" ('test' is using single quotes instead of double quotes).
  4. ".1" (a number must start with a digit; "0.1" would be valid).
  5. "undefined" (undefined cannot be represented in a JSON string; null, however, can be).
  6. "NaN" (NaN cannot be represented in a JSON string; direct representation of Infinity is also n

Solution 9 - Jquery

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" }

Solution 10 - Jquery

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.

Solution 11 - Jquery

.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>

Solution 12 - Jquery

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);

Solution 13 - Jquery

!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...

Solution 14 - Jquery

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);

Solution 15 - Jquery

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionzumzumView Question on Stackoverflow
Solution 1 - JqueryNicolas Le Thierry d'EnnequinView Answer on Stackoverflow
Solution 2 - Jquerynathan gonzalezView Answer on Stackoverflow
Solution 3 - JquerySathvik reddy GaddamView Answer on Stackoverflow
Solution 4 - JqueryDanView Answer on Stackoverflow
Solution 5 - JqueryArtur BarseghyanView Answer on Stackoverflow
Solution 6 - JquerymolokolocoView Answer on Stackoverflow
Solution 7 - JqueryWayneView Answer on Stackoverflow
Solution 8 - JqueryGeorge DonevView Answer on Stackoverflow
Solution 9 - Jqueryuser2069751View Answer on Stackoverflow
Solution 10 - JqueryShane E.View Answer on Stackoverflow
Solution 11 - JquerySajjan SarkarView Answer on Stackoverflow
Solution 12 - JqueryBazleyView Answer on Stackoverflow
Solution 13 - JqueryVishal PatelView Answer on Stackoverflow
Solution 14 - JqueryHp SharmaView Answer on Stackoverflow
Solution 15 - JqueryChris PanayotoffView Answer on Stackoverflow