Alexis Garcia
Alexis Garcia

Reputation: 472

Loop for each data-attribute on an element and create variables out of it

im trying to loop every data-attributes my element has and store it as variable because it has 17 attr and i dont want 'spam' it.

HTML 
<tr data-a="1" data-b="2" data-c="3" data-d="4"..........>

JS that i dont want
$('.trData').click(function (){
    var a = $(this).attr('data-a');
    var b = $(this).attr('data-b');
    var c = $(this).attr('data-c');
    var d = $(this).attr('data-d');
    var e = $(this).attr('data-e');
..........................

what i have is this but its not working:

$('.trData').click(function () {
    var data = $(this).data();
    for (var i in data) {
        var i = data[i];
    }
});
Desire output
   var a = 1;
    var b = 2;
    var c = 3;

Upvotes: 0

Views: 1368

Answers (3)

Alexis Garcia
Alexis Garcia

Reputation: 472

Thanks to @charlietfl i got it working.

$("tr[data-a]").click(function () {
    $.each($(this).data(), function (key, value) {
        var key = value;
});

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1075795

You'll be glad to hear the DOM has basically done this work for you, and along the way it's removed the data prefix and converted kebab-case to camelCase, etc. It's done that via the dataset property, which is a DOMStringMap:

$(".trData").click(function () {
    for (const [name, value] of Object.entries(this.dataset)) {
        // Here, `name` will be `"a"`, `"b"`, `"c"`, etc., and value will be `"1"`, `"2"`, `"3"`, etc.
        // Note that the values have been magically converted to numbers for you
        console.log(`${name} = ${value}`);
    }
});

Live Example:

$(".trData").click(function () {
    for (const [name, value] of Object.entries(this.dataset)) {
        // Here, `name` will be `"a"`, `"b"`, `"c"`, etc., and value will be `1`, `2`, `3`, etc.
        // Note that the values have been magically converted to numbers for you
        console.log(`${name} = ${value}`);
    }
});
<div class="trData" data-a="1" data-b="2" data-c="3" data-d="4">click me</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

If you don't want the automatic conversion that dataset does, you can use attributes and filter out the non-data-* attributes:

$(".trData").click(function () {
    const dataAttrs = Array.from(this.attributes)
        .filter(attr => attr.name.startsWith("data-"))
        .map(attr => [attr.name.substring(5), attr.value]);
    for (const [name, value] of dataAttrs) {
        // Here, `name` will be `"data-a"`, `"data-b"`, `"data-c"`, etc., and value will be `"1"`, `"2"`, `"3"`, etc.
        // Note that the values are *strings*
        console.log(`${name} = ${value}`);
    }
});

Live Example:

$(".trData").click(function () {
    const dataAttrs = Array.from(this.attributes)
        .filter(attr => attr.name.startsWith("data-"))
        .map(attr => [attr.name.substring(5), attr.value]);
    for (const [name, value] of dataAttrs) {
        // Here, `name` will be `"data-a"`, `"data-b"`, `"data-c"`, etc., and value will be `"1"`, `"2"`, `"3"`, etc.
        // Note that the values are *strings*
        console.log(`${name} = ${value}`);
    }
});
<div class="trData" data-a="1" data-b="2" data-c="3" data-d="4">click me</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Upvotes: 0

charlietfl
charlietfl

Reputation: 171698

Use selector tr[data-a] then you can get all the data- values in a single object with data() and no arguments

$('tr[data-a]').click(function(){       
   console.log($(this).data());
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr data-a="1" data-b="2" data-c="3" data-d="4">
    <td>Item 1</td>
</table>

Upvotes: 1

Related Questions