0

I have a ul tag with few li elements. Each li have some data attributes.

<ul id="elements">
<li id="mtq" data-id="1" data-name="abc">test 1</li>
<li data-id="2">test 2</li>
<li data-id="3" data-name="xyz">test 3</li>
<li data-id="4" data-name="pqr">test 4</li>
<li data-id="5" data-type="text">test 5</li>
<li data-id="7">test 6</li>
</ul>

I need to get all data attributes (without date- string) & value of each li like key:value like below one.

{"id":1,"name":"abc"}

I tried the below javascript code, but I got an error that says Array.prototype.forEach called on null or undefined.

function getDataAttributes(el) {
    var data = {};
    [].forEach.call(el.attributes, function(attr) {
        if (/^data-/.test(attr.name)) {
            var camelCaseName = attr.name.substr(5).replace(/-(.)/g, function ($0, $1) {
                return $1.toUpperCase();
            });
            data[camelCaseName] = attr.value;
        }
    });
    return data;
}

$("#hello").click( function (e) {

    $("ul#elements li").each(function() {
    var data = getDataAttributes($(this));
    console.log(data);
    //var json = JSON.stringify(data, null, 2);
    //el.appendChild(document.createTextNode(json));
    });

});

Here is my jsfiddle. https://jsfiddle.net/a4vya9m4/26/

When I select one li by ID, it give answer. What is wrong in my script?

Sarathlal N
  • 839
  • 5
  • 13
  • 3
    `el.attributes` - you are trying to access a DOM element property here, but `el` is a jQuery object. Just pass the DOM element into the function to begin with, `getDataAttributes(this)` – CBroe Feb 24 '18 at 14:09
  • Duplicate of https://stackoverflow.com/questions/23703044/converting-data-attributes-to-an-object – Boris Lobanov Feb 24 '18 at 14:15
  • @CBroe , Seriously I don't know the difference between `$(this)` & `this`. But after reading your comment, I have searched & just updated my code. `var data = getDataAttributes(this);` & got the result. Now I understood what you are saying. – Sarathlal N Feb 24 '18 at 14:47
  • 1
    Check out [Difference between $(this) and this in jquery](https://stackoverflow.com/questions/3633270/difference-between-this-and-this-in-jquery) – CBroe Feb 24 '18 at 14:52

4 Answers4

2

You're overthinking the getDataAttributes, you can take the dataset in your el, that already have what you need.

function getDataAttributes(el) {
    if(el[0] && el[0].dataset) {
        return Object.assign({}, el[0].dataset);
    }
    return {};
}

the el[0].datasetwill return you a DOMStringMap, that's why I use the Object.assing to convert it into a normal Object.

Hope this help you.

Miguel Angel
  • 944
  • 8
  • 20
2

Use the below code

$("#hello").click( function (e) {

    $("ul#elements li").each(function() {
        var data = $(this).data()
        console.log(data);
    }); 
});

I hope this helps!

Farhan Haque
  • 991
  • 1
  • 9
  • 21
1

You can just use dataset

The HTMLElement.dataset property allows access, both in reading and writing mode, to all the custom data attributes (data-*) set on the element, either in HTML or in the DOM.

Check snippet:

$(function() {

  let result = $("#elements>li").map(function() {
    let o = this;
    return Object.keys(o.dataset).reduce(function(c, v) { c[v] = o.dataset[v]; return c;}, {})
  }).get();

  console.log(result);

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="elements">
  <li id="mtq" data-id="1" data-name="abc">test 1</li>
  <li data-id="2">test 2</li>
  <li data-id="3" data-name="xyz">test 3</li>
  <li data-id="4" data-name="pqr">test 4</li>
  <li data-id="5" data-type="text">test 5</li>
  <li data-id="7">test 6</li>
</ul>

For more info: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset

Eddie
  • 26,593
  • 6
  • 36
  • 58
1

you can use $(elem).data() to get all data attribute and key

$(function(){
  var result = [];
  $('#elements li').each(function(i,e){
   var data = $(this).data();
   if(Object.keys(data).length){//is obj (data) empty or not
    var temp = {};
    for (var key in data) {
     temp[key] = data[key];
    }
    result.push(temp);
   }
  });
  console.log(result);
 });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="elements">
<li id="mtq" data-id="1" data-name="abc">test 1</li>
<li data-id="2">test 2</li>
<li data-id="3" data-name="xyz">test 3</li>
<li data-id="4" data-name="pqr">test 4</li>
<li data-id="5" data-type="text">test 5</li>
<li data-id="7">test 6</li>
<li>no data example</li>
</ul>
plonknimbuzz
  • 2,594
  • 2
  • 19
  • 31