31

I'm trying these HTML

<div data-params="{a: 1, b: '2'}" id="TEST1"></div>
<div data-params='{"a": 1, "b": "2"}' id="TEST2"></div>

Then I use data() method in the jQuery

$('#TEST1').data('params'); //return a string
$('#TEST2').data('params'); //return a object

But TEST1 it's not a return object, but a string, it can only return object TEST2. But I want to get a object by TEST1, How do I do it?

=============

Finally, I choose to write a function to achieve their own needs

$.fn.data2 = function(key, value)
{
    if (value === undefined) 
    {
        var data = $(this).data(key);
        if (typeof(data) === 'string') 
        {
            var _data = data.replace(/^[\s\r\n]*/g, '').replace(/[\s\r\n]*$/g, '');
            if (_data.match(/\{.*\}/) || _data.match(/\[.*\]/)) {
                try {
                    _data = (new Function( 'return ' + data ))();
                    if (typeof(_data) == 'object') {
                        $(this).data(key, _data);
                        data = _data;
                    }
                } catch(ex) {}
            }
        }
        return data;
    }
    return $(this).data(key, value);
};
2
  • But why I try to use jquery.metadata plugin is to working? Commented Sep 14, 2011 at 1:46
  • Is there a way to get jQuery to parse the same as the first HTML jquery.metadata plugin? Commented Sep 14, 2011 at 2:05

3 Answers 3

36

In order to be parsed as an object, the data attribute must be a well formed JSON object.

In your case you just need to quote the object keys (as you do in the second object). Try:

<div data-params='{"a": 1, "b": "2"}' id="TEST1"></div>

For more info see the data method docs, the relevant part is this one (emphasis mine):

Every attempt is made to convert the string to a JavaScript value (this includes booleans, numbers, objects, arrays, and null) otherwise it is left as a string... ...When the data attribute is an object (starts with '{') or array (starts with '[') then jQuery.parseJSON is used to parse the string; it must follow valid JSON syntax including quoted property names.

Sign up to request clarification or add additional context in comments.

6 Comments

For what it's worth, I think JSON is so strict that even using single quotes instead of double quotes is invalid.
@joe perhaps that plugin parser is not as strict as jQuery's. I'd use the keys with quotes just to be sure.
Is there a way to get jQuery to parse the same as the first HTML jquery.metadata plugin?
No, I guess you could try older versions of jQuery that weren't so strict... butI don't know if they support the HTML5 custom data attribs.
Whell... Doing parameter like this i even don`t nead to pass throguht jQuery.parseJSON() function :D (at least for $ 1.9.1 and above).
|
7

You can escape the inner quotes:

<div data-params="{&quot;a&quot;: 1, &quot;b&quot;: &quot;2&quot;}" id="TEST2"></div>

But there is nothing wrong with your second method:

<div data-params='{"a": 1, "b": "2"}' id="TEST2"></div>

I would use that.

1 Comment

Is there a way to get jQuery to parse the same as the first HTML jquery.metadata plugin?
0

Try this one. It's how Uikit parse data attribute json. Hope this will helpful

function str2json(str, notevil) {
  try {
    if (notevil) {
      return JSON.parse(str
                        .replace(/([\$\w]+)\s*:/g, function(_, $1){return '"'+$1+'":';})
                        .replace(/'([^']+)'/g, function(_, $1){return '"'+$1+'"';})
                       );
    } else {
      return (new Function("", "var json = " + str + "; return JSON.parse(JSON.stringify(json));"))();
    }
  } catch(e) { return false; }
}

function options(string) {
  if (typeof string !='string') return string;

  if (string.indexOf(':') != -1 && string.trim().substr(-1) != '}') {
    string = '{'+string+'}';
  }

  var start = (string ? string.indexOf("{") : -1), options = {};

  if (start != -1) {
    try {
      options = str2json(string.substr(start));
    } catch (e) {}
  }

  return options;
}

var paramsData = document.querySelectorAll('[data-params]')[0].dataset.params;

var optionsParsed = options(paramsData);

console.log(optionsParsed);
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>
<body>
  <div data-params="{hello: 'world'}"></div>
</body>
</html>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.