Thursday, May 17, 2012

jQuery find function

I've recently been using Tilava Table on a few different projects. At one point I ran into a situation where I wanted to change all of the visible rows as well as the template, but the row template was no longer found when using a traditional jQuery selection. The solution to my problem was a combination of holding on to the template as well and using jQuery find to select the td elements I was interested in altering.

In Tilava Table you create a template, but that template row isn't displayed within the table. We could use that as an example, but it seems easier to simplify the example to the following code:
<script src="http://code.jquery.com/jquery-1.7.2.min.js">
</script>
<label><input type="checkbox" id="hideMoreData"/>hide more data</label>
<table id="myTable" style="border:1px solid black">
  <tr class="template">
    <td>row data</td><td class="additional-field">more data</td>
  </tr>
</table>
<button id="addButton">Add</button>
<script>
$(document).ready(function () {
  function addRow(template) {
    $('#myTable').append(template.clone().removeClass('template'));
  }
  var template = $(".template");
  $('#myTable').html("");
  $("#addButton").click(function () {
    addRow(template);
  });
  $("#hideMoreData").click(function () {
    $(".additional-field").toggle(!$('#hideMoreData').is(':checked'));
  });
  addRow(template);
  addRow(template);
});
</script>
The executing version of that code can be found below.

row datamore data


In the above example we have a table in which we can dynamically add rows by clicking the 'Add' button. We also have a checkbox that determines whether or not the additional data is displayed in our table. Click the add button a few times and show and hide the additional data, just to make sure everything is working as you'd expect.

You may have noticed (either by reading the code, or by playing with the example) that when you hide the additional data it hides what is already in the table; however, if you add additional rows the additional data for the new rows will be shown. This is due to the fact that when you select all td elements with the class 'additional-field' the template is not included in the results. Even though the template is not returned in our 'additional-field' selection, it does still exist and is accessible as the var 'template'. When we clone the template var the cloned row will contain the additional-field td, but it will not be 'correctly' toggled.

One solution would be to append the row and rerun the toggle code, but that wouldn't be as efficient - and, jQuery gives us a better solution anyway: find
find: Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.
The simple solution is to add the following line in the #hideMoreData click handler.
template.find(".additional-field").toggle(!$('#hideMoreData').is(':checked'));
The finished code is below in it's entirety, and the working version of the code can also be found at the bottom.
<label><input type="checkbox" id="hideMoreData2"/>hide more data</label>
<table id="myTable2" style="border:1px solid black">
  <tr class="template2">
    <td>row data</td><td class="additional-field2">more data</td>
  </tr>
</table>
<button id="addButton2">Add</button>
<script>
$(document).ready(function () {
  function addRow(template) {
    $('#myTable2').append(template.clone().removeClass('template2'));
  }
  var template = $(".template2");
  $('#myTable2').html("");
  $("#addButton2").click(function () {
    addRow(template);
  });
  $("#hideMoreData2").click(function () {
    $(".additional-field2").toggle(!$('#hideMoreData2').is(':checked'));
    template.find(".additional-field2").toggle(!$('#hideMoreData2').is(':checked'));
  });
  addRow(template);
  addRow(template);
});
</script>
row datamore data

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.