0

I want to store some information in DOM elements (rows of table). I think I can do it using jQuery's data() function. I wrote some test code and found out that I can't get the stored data from elements using jQuery selectors. Is it possible? Maybe I'm doing something wrong?

Here is the simple code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JQuery data() test</title>
    <script src="https://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
</head>
<body>

<table id="myTable">
    <tbody>
    <tr id="rowPrototype" style="display:none;">
        <td class="td1"></td>
        <td class="td2"></td>
    </tr>
    </tbody>
</table>
<script>
    var table = $("#myTable");
    for (var i = 0; i < 5; i++) {
        var newRow = $("#rowPrototype").clone();
        newRow.removeAttr("style");
        newRow.removeAttr("id");

        $.data(newRow, "number", i);
        console.log("Data added to row: " + $.data(newRow, "number"));

        var tds = newRow.find("td");
        tds.text("test");
        table.append(newRow);
    }

    var trs = table.find("tr");
    trs.each(function () {
        var tr = $(this).text();
        var data = $.data(tr, "number");
        console.log("number: " + data);
    });
</script>

</body>
</html>

I expect the following output:

number: undefined (row prototype)
number: 0
number: 1
number: 2
number: 3
number: 4

But actual is:

number: undefined
number: undefined
number: undefined
number: undefined
number: undefined
number: undefined

So what's wrong with this code?

UPD You can test it here: https://jsfiddle.net/rfrz332o/3/

3
  • P.S. I know that using jquery-latest link is a bad practice. It's just for example. Commented Mar 27, 2016 at 6:39
  • It is advisable that you provide with a working jsFiddle Commented Mar 27, 2016 at 6:42
  • @Itay ok, I added the link Commented Mar 27, 2016 at 6:52

3 Answers 3

2

$.data() expects an actual DOM element as the first argument, not a jQuery object. You can $(selector).data() with jQuery objects. I'd suggest you change this:

$.data(newRow, "number", i);
console.log("Data added to row: " + $.data(newRow, "number"));

to this:

newRow.data("number", i);
console.log("Data added to row: " + newRow.data("number"));

And, then change this:

var trs = table.find("tr");
trs.each(function () {
    var tr = $(this).text();
    var data = $.data(tr, "number");
    console.log("number: " + data);
});

to this:

table.find("tr").each(function () {
    console.log("number: " + $(this).data("number"));
});
Sign up to request clarification or add additional context in comments.

2 Comments

About the first (logging data after storing it): it worked fine without this change, but I think it's better your way. And about second, now it works fine, thank you!
Fix: I understand now that my way to store data in element wasn't right too, so both of these changes are necessary
1

You messed with data method. You weren't applying data to dynamic created row. To see result, please check your console.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JQuery data() test</title>
    <script src="https://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
</head>
<body>

<table id="myTable">
    <tbody>
    <tr id="rowPrototype" style="display:none;">
        <td class="td1"></td>
        <td class="td2"></td>
    </tr>
    </tbody>
</table>
<script>
    var table = $("#myTable");
    for (var i = 0; i < 5; i++) {
        var newRow = $("#rowPrototype").clone();
        newRow.removeAttr("style");
        newRow.removeAttr("id");

        newRow.data("number", i);
        console.log("Data added to row: " + newRow.data("number"));

        var tds = newRow.find("td");
        tds.text("test");
        table.append(newRow);
    }

    var trs = table.find("tr");
    trs.each(function () {
        var tr = $(this).text();
        var data = $(this).data("number")
        console.log("number: " + data);
    });
</script>

</body>
</html>

Comments

1

$.data() expects DOM element, not jQuery object. Add [i] or use .get(i) at $.data(newRow[i], "number", i); and all js that follows where $.data() is used to reference DOM element.

There is also an issue with the for loop. If there is actually only one tr element and two td elements within #myTable, when i reaches 2 , if the selector included i the result would be undefined, as the maximum index of td elements would still be 1 within the cloned table ; whether $.data() or .data() is used. Similarly for the one tr element within #myTable; when i reaches 1

jQuery.data( element, key, value )

element

Type: Element

The DOM element to associate with the data.

1 Comment

@coolguy Are there actually only two td elements within #myTable ?

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.