2

My question basically is exactly like this question. I am just wondering, if there is a way to achieve this without jQuery.

The following code does not work. I have also tried it with an array, but just like the object it is stored as a string. Is there something I am doing wrong, or is it just not possible in plain javascript?

var div = document.getElementById("testDiv");
var obj = {name: "Test1", value: 100};
div.setAttribute("data-obj", obj);

var arr = [59, 40, 3, 2, 1, 0];
div.setAttribute("data-arr", arr);

console.log("Object-Value: "+div.dataset.obj+"; Type: "+(typeof div.dataset.obj)+"; Name: "+div.dataset.obj.name);
console.log("Array-Value: "+div.dataset.arr+"; Type: "+(typeof div.dataset.arr)+"; Third Value: "+div.dataset.arr[2]);
<div id="testDiv">This is a test.</div>
Fay Boisam
  • 127
  • 4
  • 10
  • 1
    Why are you adding data to a DOM element? I don't think it's a good idea. – Satish Kumar Jun 03 '19 at 18:57
  • 1
    You should consider creating an object with the id (or unique selector of some kind) of the element as the key and the data itself as a property. Then you can easily get the data and you don't have to worry about serialization. – Heretic Monkey Jun 03 '19 at 19:01
  • @SatishKumar the DOM element visualisies an entry of a database. The user can select certain settings so that the displayed data changes accordingly. Since there are multiple of such entries, I wanted to save the entry-objects for each DOM element. Do you think there is a more efficient way to approach this? – Fay Boisam Jun 03 '19 at 19:02
  • Most modern development centers around making the UI dependent on the data Witness frameworks like Angular, React, etc.., where the data are transformed into the UI. You change the data and the UI changes, rather than the other way around. – Heretic Monkey Jun 03 '19 at 19:09
  • I wasn't talking about an efficient way. 1. It's good to separate data from view. 2. Whatever you add to dom is directly visible/accessible, by anyone, this might expose some sensitive information. 3. Also, don't save a lot of data to dom – Satish Kumar Jun 03 '19 at 19:16
  • @HereticMonkey but how could you implement what I have described in the way you explained? – Fay Boisam Jun 03 '19 at 19:49
  • 1
    There are a number of ways, but the easiest to grasp is `var elementData = { "testDiv": { "obj": { name: "Test1", value: 100 }, "arr": [59,40,3,2,1,0] };` Then to get the data out, `var obj = elementData.testDiv.obj` (or `elementData["testDiv"].obj` if you have the id as a string). – Heretic Monkey Jun 03 '19 at 19:52

2 Answers2

3

Use JSON.stringify() before storing the data in the attribute. It is basically serializing the data into a string.

var div = document.getElementById("testDiv");
var obj = JSON.stringify({name: "Test1", value: 100});
div.setAttribute("data-obj", obj);

var arrayAsJSON = JSON.stringify([59, 40, 3, 2, 1, 0]);
div.setAttribute("data-arr", arrayAsJSON);

Then use JSON.parse() after you fetch the attribute value and before presenting it. This will deserialize it back to a javascript object, array or simple value, depending on your case.

zhulien
  • 5,145
  • 3
  • 22
  • 36
  • @FayBoisam Yes, it will. It is even stated in the example. Check out 'arrayAsJSON' . It will work for every javascript structure(object, array or simple value type). – zhulien Jun 03 '19 at 19:04
  • 1
    You need to watch out for circular references, which JSON doesn't handle without some help. – Heretic Monkey Jun 03 '19 at 19:07
0

You need to change your object/array into json (string) using JSON.stringify (and parse for read)

var obj = {name: "Test1", value: 100};
var arr = [59, 40, 3, 2, 1, 0];

testDiv.dataset.obj = JSON.stringify(obj);
testDiv.dataset.arr = JSON.stringify(arr);

console.log( JSON.parse(testDiv.dataset.obj).name );
console.log( JSON.parse(testDiv.dataset.arr)[2] );
<div id="testDiv"></div>
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345