1

I have a table with a directive on it. When I sort the table then my directive is triggered which gives me a property called $elem.

This property holds the table DOM elment. Is there a way to iterate through this object and read all the <td> innerHTML of each <tr> row?

For example in this example: http://plnkr.co/edit/eodM0kMxZukG8y9DIh00?p=preview

How can I get all the TD values or each row and store that in a JS array using AngularJS only? So the result is something like:

var arr = {['1', 'User 1', '<a href="#">link 1</a>'],
           ['2', 'User 2', '<a href="#">link 2</a>']};
1
  • Have you checked the docs for angular.element? Commented Aug 12, 2014 at 15:41

5 Answers 5

2

This is how you can collection this information:

 var rows = $elem[0].tBodies[0].rows,
     cells,
     result = [];

 for (var i = 0; i < rows.length; i++) {
     cells = rows[i].cells;
     result.push([]);
     for (var j = 0; j < cells.length; j++) {
         result[i].push(angular.element(cells[j]).html());
     }
 }

Demo: http://plnkr.co/edit/ZMOurGJccz6sjFME2EUr?p=preview

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

Comments

1

OK, I literally hate myself for saying this (grin) because this type of question is almost always the lead-in to using the wrong pattern to do something more sophisticated in AngularJS. BUT, since it does get asked a lot, this does totally work:

http://plnkr.co/edit/XnT5tGjeDUVGHJ3pzFpc?p=preview

var entries = [];
angular.forEach($elem.children()[1].children, function(tr) {
  var entry = [];
  angular.forEach(tr.children, function(td) {
    entry.push(td.innerHTML);
  });

  entries.push(entry);
});
console.log(entries);

There's nothing really Angular-ish about this. $elem is just a lightweight wrapper around the HTML element for the table. It's HTML5 so there's a <thead> element followed by a <tbody>, which the first forEach follows down the chain to get each <tr> - the children of the <thead>. The inner

Comments

1

In this case $elem is just a jQuery (or jqLite) object. See the link that @Yoshi posted above. Traversing it to get child nodes is less of an angular question and really just a jQuery question. You might try something like:

$elem.find('td').each(function(index) {
    $(this).... // do something with $(this)
});

Comments

1

The $elem parameter is just a jqLite object. In the end that makes this a jQuery question. I would like to note that this is a bit backwards from the AngularJs way. Typically, you should be generating the table from data somewhere else in your model. In that way you would never have to read in the data from the DOM.

However, here's one way to generate the output you want:

var row, rows;
var item, data = [];

// find all of the table rows that are below $elem
rows = $elem.find('tr');

for(var i = 0; i < rows.length; i++) {
    item = [];

    // get a jqLite reference to this row
    row = $elem.find(rows[i]);

    // get all of its child cells, and iterate over each element
    row.find('td').each(function(i, e) {
        // push the element's inner html in to our item array
        item.push(e.innerHTML);
    });

    // only add the item if it has data
    if (item.length) {
        data.push(item);
    }
}

Comments

0

Use the following query to get all the td.

     link: function($scope, $elem) {
  var arr = ($($elem[0]).find('tbody tr'));
  var coll = [];
  for(var i=0; i < arr.length; i++){
    var tr = arr[i];
    var tdColl = $(tr).find('td');
    var obj = [];
    for(var y = 0; y < tdColl.length; y++ ){

      obj.push(tdColl[y].innerText);
    }
    coll.push(obj)
  }
 console.log(coll);
}

You can then loop and get all array of objects

Plunkr : http://plnkr.co/edit/Z5XNp4q4F7sbN5SvjCll?p=preview

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.