I am stuck in a concept of html5 data attributes. That attributes allows nesting like:
<div data-user--name="John" data-user--surname="Doe"></div>
I have seen plugins in the past (like select2 ) and some of them use the following similar syntax to make an AJAX call:
<div data-ajax--url="my/url" data-ajax--method="POST">
This code in background converts to a dataset in javascript and it returns something like this:
data = {
ajax: {
url: "my/url",
method: "POST"
}
}
But in the practice, vanilla javascript's dataset
and jQuery data()
methods return different object content.
var el = document.getElementsByTagName("div")[0]; el.innerHTML = "<pre>"+JSON.stringify(el.dataset)+"</pre>";
<div data-ajax--url="my/url" data-ajax--method="POST"></div>
$('div').html("<pre>"+JSON.stringify($('div').data())+"</pre>");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div data-ajax--url="my/url" data-ajax--method="POST"></div>
$('div').html("<pre>"+JSON.stringify($('div').data())+"</pre>");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div data-ajax--url="my/url" data-ajax--method="POST"></div>
The code in error seems to be the jQuery 1.x versions, because in 2.x versions jQuery returns the same as vanilla Javascript. I found a related bug so it's confirmed: https://github.com/select2/select2/issues/2969
But I can't find where to construct a nested javascript object with the nested html syntax, like the following example:
{
ajax: {
url: "my/url"
method: "POST"
}
}
Is there any Javascript method, or a polyfill, that makes this kind of objects reading the data-*
HTML attributes? Is it possible to parse the data javascript strings (ie ajax-Method
) and return a nested object ( ajax.method
) ?
Ran into exact same need, but @artofcode's answer parses only 2 levels. So I had to figure out how to parse unlimited number of levels. Here's my solution without limiting levels, based on original answer.
function parseNestedDataSet(data_set) {
var keys = Object.keys(data_set);
var data = {};
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var value = data_set[key];
var splat = key.split('-');
data = parseNestedDataSetKey(splat, value, data);
}
return data;
}
function parseNestedDataSetKey(keys, value, data) {
data = data || {};
var key = keys[0].toLowerCase();
// Not tested, but should convert to camel case
// var key = keys[0].replace(/-([a-z])/g, function (g) {
// return g[1].toUpperCase();
// });
if (!data[key]) {
data[key] = {};
}
if (keys.length > 1) {
keys.splice(0, 1);
data[key] = parseNestedDataSetKey(keys, value, data[key]);
} else {
data[key] = value;
}
return data;
}
Didn't test it thoroughly, but it works in my case, like:
data-buttons--btn1--title
; data-buttons--btn1--icon
; data-buttons--btn2--title
. function parseDataset(dataset) {
data = {};
for(var i = 0; i < Object.keys(dataset).length; i++) {
var key = Object.keys(dataset)[i];
var value = dataset[key];
var splat = key.split("-");
console.log(key, data, splat);
if(!data[splat[0]]) {
data[splat[0]] = {};
}
data[splat[0]][splat[1]] = value;
}
return data;
}
Untested, but should work. Pass el.dataset
into the method, get a data
object out like:
data = {
'ajax': {
'Method': 'POST',
'Url': 'my/url'
}
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.