Let us learn JQuery - Part 3 of 9 (JQuery Traversal)

Niladri.Biswas
Posted by in jQuery category on for Beginner level | Points: 250 | Views : 13254 red flag
Rating: 4 out of 5  
 5 vote(s)

In this part we will learn about JQuery Traversal methods


 Download source code for Let us learn JQuery - Part 3 of 9 (JQuery Traversal)

Table of Content

  1. Introduction
  2. What is JQuery Traversal and why we need it?
  3. Common JQuery Traversal methods
    1. find()
    2. each()
    3. not()
    4. filter()
    5. first()
    6. last()
    7. prev()
    8. next()
    9. parent()
    10. closest()
    11. children()
    12. siblings()
    13. nextUntil()
    14. eq()
    15. nth-child()
  4. References
  5. Conclusion

Introduction

This is the third part of the "Let us learn JQuery" series and in this part we will learn about the JQuery Traversal for traversing the DOM trees.

This whole series is comprise of nine sections which are as under

  1. JQuery - A formal introduction using "Hello World"
  2. JQuery Selectors
  3. JQuery Traversal
  4. CSS with JQuery
  5. DOM with JQuery
  6. JQuery and Events
  7. Animated effects using JQuery
  8. JQuery and Ajax
  9. Custom JQuery Plugins

What is JQuery Traversal and why we need it?

DOM traversal is the process of visiting each node in a DOM data structure exactly once in a proper way.Traversing through grid is a very common requirement in the projects.In this section we will look into some of the traversing techniques that JQuery offers us.It is needed for modifications to each element in the DOM tree.

Common JQuery Traversal methods

In this section we will encounter some of the commonly use JQuery Traversal methods which are listed under

  1. find()
  2. each()
  3. not()
  4. filter()
  5. first()
  6. last()
  7. prev()
  8. next()
  9. parent()
  10. closest()
  11. children()
  12. siblings()
  13. nextUntil()
  14. eq()
  15. nth-child()

So before going to do play anything with these functions, let us first set up the environment.We will have a GridView control in our page and we will populate it with some records in the below way.

using System;

using System.Collections.Generic;

 

public partial class JQueryTraversalExample : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

if (!IsPostBack)

{

grdView.DataSource = LoadEmployeeRecord();

grdView.DataBind();

}

}

private List<Employee> LoadEmployeeRecord()

{

var lstEmpRecords = new List<Employee>();

int recordsToGenerate = 10;

for (int i = 1; i <= recordsToGenerate; i++)

{

lstEmpRecords.Add

(new Employee

{

EmpId = 1000 + i,

EmpName = "EmpName# " + i.ToString(),

EmpDOJ = DateTime.Now.AddYears(-10).AddYears(i),

EmpSalary = 10000 + (i * 10)

});

}

return lstEmpRecords;

}

}

class Employee

{

public int EmpId { get; set; }

public string EmpName { get; set; }

public DateTime EmpDOJ { get; set; }

public decimal EmpSalary { get; set; }

}

The code is pretty simple to understand henceforth skipping the part of explanation.So the initial look of the grid with records will be as under

Upon rendering, the Html code for the grid comes out as under

<table cellspacing="0" rules="all" border="1" id="grdView" style="border-collapse:collapse;">

<tr>

<th scope="col">EmpId</th>

<th scope="col">EmpName</th>

<th scope="col">EmpDOJ</th>

<th scope="col">EmpSalary</th>

</tr>

<tr>

<td>1001</td>

<td>EmpName# 1</td>

<td>6/4/2003 7:58:27 AM</td>

<td>10010</td>

</tr>

<tr>

<td>1002</td>

<td>EmpName# 2</td>

<td>6/4/2004 7:58:27 AM</td>

<td>10020</td>

</tr>

<tr>

<td>1003</td>

<td>EmpName# 3</td>

<td>6/4/2005 7:58:27 AM</td>

<td>10030</td>

</tr>

<tr>

<td>1004</td>

<td>EmpName# 4</td>

<td>6/4/2006 7:58:27 AM</td>

<td>10040</td>

</tr>

<tr>

<td>1005</td>

<td>EmpName# 5</td>

<td>6/4/2007 7:58:27 AM</td>

<td>10050</td>

</tr>

<tr>

<td>1006</td>

<td>EmpName# 6</td>

<td>6/4/2008 7:58:27 AM</td>

<td>10060</td>

</tr>

<tr>

<td>1007</td>

<td>EmpName# 7</td>

<td>6/4/2009 7:58:27 AM</td>

<td>10070</td>

</tr>

<tr>

<td>1008</td>

<td>EmpName# 8</td>

<td>6/4/2010 7:58:27 AM</td>

<td>10080</td>

</tr>

<tr>

<td>1009</td>

<td>EmpName# 9</td>

<td>6/4/2011 7:58:27 AM</td>

<td>10090</td>

</tr>

<tr>

<td>1010</td>

<td>EmpName# 10</td>

<td>6/4/2012 7:58:27 AM</td>

<td>10100</td>

</tr>

</table>

1.find()

Purpose:Once a match for a specified selector is made, this function searches for descendent elements.

Objective:We want to set the background color of the Table Headings (th) to "Green" while the Table Definitions(td) to "Orange"

Code:

$(document).ready(function () {

$("table tr").find("th").css('background-color', 'green');

$("table tr").find("td").css('background-color', 'orange');

});

Output:

Explanation:"tr" is a child of "table" element.Once this evaluates to true,we are trying to find the "th" or "td" elements by using the "find" method and once found, we are setting the background color.

Though this is a way of achieving the target, we do have other ways of doing so which are as under

Alternative 1:

$("table").find("th").css('background-color', 'green');

$("table").find("td").css('background-color', 'orange');

Alternative 2:

$("table th").css('background-color', 'green');

$("table td").css('background-color', 'orange');

Alternative 3:

$("table > tbody > tr > th").css('background-color', 'green');

$("table > tbody > tr > td").css('background-color', 'orange');

It gives a hierarchical structure using the > (greater than) symbol that helps to drill down through the hierarchy

Alternative 4:

$("table").children("tbody").children("tr").children("th").css('background-color', 'green');

$("table").children("tbody").children("tr").children("td").css('background-color', 'orange');

Alternative 5:Well there can be many table objects and our requirement may be specific to one table.In that case it is better to do the operation using the "Element Id" approach

var tableObject = $('#grdView');

$(tableObject).find("th").css('background-color', 'green');

$(tableObject).find("td").css('background-color', 'orange');

2.each()

Purpose:For every matched element, this function will traverse over the matched JQuery object

Objective 1:We want to set the alternate color of the Table Rows(tr) to "Green" for even rows and "Yellow" for odd rows

Code:

<style type="text/css">

tr.even { background-color: green; }

tr.odd { background-color: yellow; }

</style>

<script type="text/javascript">

$(document).ready(function () {

$('table').each(function () {

$('tr:even', this).addClass('even').removeClass('odd');

$('tr:odd', this).addClass('odd').removeClass('even');

});

});

</script>

Output:

But if we look closely, we can make out that the alternate color has been applied to the table heading also which was not the intension. One way to avoid this is to exclude the table heading ("th") as under

$('table').each(function () {

$('tr:even', this).not(':first').addClass('even').removeClass('odd');

$('tr:odd', this).addClass('odd').removeClass('even');

});

Output:

Explanation: "not() " function removes elements from the set of matched elements. So, if we look at the generated html, there is only one "th" element embeded under the "tr" element and it appears at teh first place.Henceforth,we used the syntax "not(':first')" for removing the "th" elements from teh collection and then applied the modifications

Other alternatives are listed as under

Alternative 1:

$('table tr').not(':first').each(function (i) {

$(this).addClass(i % 2 ? 'even' : 'odd');

});

In this case, for every row, we are checking the even/odd position and then applying the CSS style

Alternative 2:

$('table > tbody').each(function () {

$('tr:odd', this).addClass('odd').removeClass('even');

$('tr:even', this).addClass('even').removeClass('odd');

});

$('table tr:first-child').removeClass('even');

});

In this case first we are applying the styles to the table rows ("tr"). And then removing the "even" style from the first child (i.e. "th").

Alternative 3:Changing only the CSS style

<style type="text/css">

tr.even td{ background-color: green; }

tr.odd td{ background-color: yellow; }

</style>

<script type="text/javascript">

$(document).ready(function () {

$('table').each(function () {

$('tr:even', this).addClass('even').removeClass('odd');

$('tr:odd', this).addClass('odd').removeClass('even');

});

});

</script>

What we have do is that, we have changed the "tr.even" to "tr.even td" which implies that the CSS will get apply only for the "td" elements.

Alternative 4: Without using the each() function

$("tr:even").not(':first').addClass('even');

$("tr:odd").addClass('odd');

Objective 2:We want to set the alternate color of the Table Definitions(td) to "Green" for even rows and "Yellow" for odd rows

Code:

<style type="text/css">

td.even { background-color: green; }

td.odd { background-color: yellow; }

</style>

<script type="text/javascript">

$(document).ready(function () {

$('table').each(function () {

$('td:even', this).addClass('even').removeClass('odd');

$('td:odd', this).addClass('odd').removeClass('even');

});

});

</script>

Output:

Objective 3:We want to set the color to "Green" for only the last column.

Code:

var initialValue = 3;

$('table tr td').each(function (i) {

if (i == initialValue) {

$(this).addClass('even');

initialValue = initialValue + 4;

}

});

Output:

Explanation:The first index value of the last column is 3. The next index value (next row) is 7. So the difference is 4. So whenever thereis a match, we are incrementing the next index value by 4 and if there is a match with the "td" index, then the column color is set.

Objective 4:We want to set the color to "Green" for only those employees whose DOJ is after Year 2009 column.

Code:

var initialValue = 2; //initial value for 3rd column

$('table tr td').each(function (i, element) {

if (i == initialValue) {

var dt = new Date($(element).text()); // creates the date object

var fullYear = dt.getFullYear(); //get the year

if (fullYear > 2009) {

$(this).addClass('even');

}

initialValue = initialValue + 4;

}

});

Output:

Explanation:We are obtaining the value for the DOJ column by using $(element).text() and after getting the year (by using getFullYear() function) we are filtering teh records

I hope that we have now enough information to work with each() function. So let us move on to the next function

3.not()

Purpose:It filteres the elements that are not needed from the set of matched JQuery objects.

Objective:We want to hide the odd rows in the table.

Code:

$(document).ready(function () {

$("table tr").not(':even').hide();

});

The code says that hide only the "odd" rows and display the even ones. not(':even') means negate the even rows i.e. "odd" rows and apply the hide functions on those rows.

4.filter()

Purpose:This function narrows down the search operation further and restricted the element sets to the extent that matches the selector initially.

Objective:We want to set the alternate color of the Table Rows(tr) to "Green" for even rows and "Yellow" for odd rows

Code:

<style type="text/css">

tr.even { background-color: green; }

tr.odd { background-color: yellow; }

</style>

<script type="text/javascript">

$(document).ready(function () {

$('table tr').not(':first')

.filter(':even').addClass('even').end()

.filter(':odd').addClass('odd');

});

</script>

Explanation:Well it is the same example that we say in the each() function example but this time with the filter() function.For every "even" rows we are adding the "even" CSS class and for every "odd" rows we are adding the "odd" CSS class.These we are doing after filtering the "table heading"(th) from the initial DOM object

5.first()

Purpose:This function returns the first element in the selected set of elements.

Objective:We want to set the color of the first Table Row(tr) to "Cyan".

Code:

$("table tr").first().css("background-color", "cyan");

Explanation:Now only the first row has its background color set to "Cyan".

6.last()

Purpose:This function returns the last element in the selected set of elements.

Objective:We want to set the color of the last Table Row(tr) to "Brown".

Code:

$("table tr").last().css("background-color", "brown");

Explanation:Now only the last row has its background color set to "Brown"

7.prev()

Purpose:This function returns the previous HTML element in the page (DOM).

Objective:We want to set the color of the penultimate last Table Row(tr) to "Orange".

Code:

$("table tr").last().prev().css("background-color", "orange");

Explanation:The example first selects all elements with "tr" in the DOM object. Then it applies the last() function to it to get the last row from the DOM object.Finally, it asks for the previous element in the DOM tree and once the target is achieved we applied the background color to it.

8.next()

Purpose:This function returns the next HTML element in the page (DOM).

Objective:We want to set the color of the second Table Row(tr) to "Yellow".

Code:

$("table tr").first().next().css("background-color", "yellow");

Explanation:The example first selects all elements with "tr" in the DOM object. Then it applies the first() function to it to get the first row from the DOM object.Finally, it asks for the next element in the DOM tree and once the target is achieved we applied the background color to it.

9.parent()

Purpose:This function returns the parent element of a selected HTML element .

Objective:We want to set the background color of the entire div content given the child "GridView" id.

Code:

<html>

<head id="Head1" runat="server">

<title></title>

<script type="text/javascript" src="Scripts/jquery-1.7.2.js" temp_src="Scripts/jquery-1.7.2.js"></script>

<script type="text/javascript">

$(document).ready(function () {

$("#grdView").parent().parent().css("backgroundColor", "#ffaaaa");

});

</script>

</head>

<body>

<form id="form1" runat="server">

<div id="parentDiv">

<span>I am the first child</span>

<p> I am the second child

<asp:GridView ID="grdView" runat="server">

</asp:GridView>

</p>

<span>I am the third child</span>

</div>

</form>

</body>

</html>

Output:

Explanation:The first parent of the GridView is a paragraph tag(p). The parent of that "P" tag is the div tag (id="parentDiv"). That means, the GridView is nested under two parents.And hence $("#grdView").parent().parent(). So at this stage, we have the object for the parent div tag.Now we apply the CSS backgound color to the Div tag and the entire effect happens for it's childrens.

10.closest()

Purpose:This function works by initially looking at the current element to figure out if that matches the given expression and if so it returns the element itself otherwise it continues to traverse up the DOM parent by parent until an element matching the specified expression is found. If no match is found at all then nothing will be returned.

Objective:We want to set the background color of the selected childs(only SPANS) of the parent(i.e. DIV) given the child "GridView" id.

Code:

<html>

<head id="Head1" runat="server">

<title></title>

<script type="text/javascript" src="Scripts/jquery-1.7.2.js" temp_src="Scripts/jquery-1.7.2.js"></script>

<script type="text/javascript">

$(document).ready(function () {

var parentElement = $("#grdView").closest("#parentDiv"); //find the parent reference

var selectedChildElement = parentElement.children("span"); //only span childs

selectedChildElement.css("backgroundColor", "#ffaaaa"); //set the background colors of the selected childs

});

</script>

</head>

<body>

<form id="form1" runat="server">

<div id="parentDiv">

<span>I am the first child</span>

<p> I am the second child

<asp:GridView ID="grdView" runat="server">

</asp:GridView>

</p>

<span>I am the third child</span>

</div>

</form>

</body>

</html>

Output:

Explanation:In the line $("#grdView").closest("#parentDiv") we are finding the parent reference.Then finding the "Span" child's of the parent and finally setting their background color.

11.children()

Purpose:This function returns all child HTML elements of a given HTML element.

Objective:We want to set different background color of the childs of the parent(i.e. DIV) given the child "GridView" id.

Code:

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

<title></title>

<script type="text/javascript" src="Scripts/jquery-1.7.2.js" temp_src="Scripts/jquery-1.7.2.js"></script>

<script type="text/javascript">

$(document).ready(function () {

var parentElement = $("#grdView").closest("#parentDiv"); //find the parent reference

var selectedChildElement = parentElement.children(); //find only childs

selectedChildElement.first().css("backgroundColor", "orange"); //set the background color to Orange of the first child

selectedChildElement.first().next().css("backgroundColor", "cyan"); //set the background color to cyan of the second child

selectedChildElement.last().css("backgroundColor", "yellow"); //set the background color to Yellow of the last child

});

</script>

</head>

<body>

<form id="form1" runat="server">

<div id="parentDiv">

<span>I am the first child</span>

<p> I am the second child

<asp:GridView ID="grdView" runat="server">

</asp:GridView>

</p>

<span>I am the third child</span>

</div>

</form>

</body>

</html>

Output:

Explanation:

After finding the childrens of the parent by using parentElement.children();, we are setting different background colors to the childs

12.siblings()

Purpose:This function returns all siblings of a given HTML elements.

Objective:We want to find the siblings of type "Input" from the below Html.

<div id="parentDiv">

<input type="text" id="txt1"/>

<input type="text" id="txt2"/>

<input type="button" id="btn" value="I am a button"/>

<a href="#" temp_href="#" id="aLink">GetSiblings</a>

</div>

Siblings are all elements of similar type (except itself) inside the same parent.For a better understanding please refer jQuery – Child and Sibling Selectors example

Code:

$(document).ready(function () {

$("#aLink").click(function () {

var result = "";

var inputSiblings = $(this).siblings("input");

var inputSiblingsCount = inputSiblings.length;

result += "Siblings found = " + inputSiblingsCount + "\n";

for (var i = 0; i < inputSiblingsCount; i++) {

result += inputSiblings[i].outerHTML + "\n";

}

alert(result);

})

});

Output:

Explanation:

The textboxes and button all belongs to the category "input" type and under the same parent ("parentDiv").Henceforth, the result count is 3.

13.nextUntil()

Purpose:This function finds all the siblings of each element up to but not including the element matched by the selector.

Objective:We want to find the siblings of only Parent1 from the below Html.

<ul>

<li class="parent"> Parent - 1 </li>

<li> Sibling1 of Parent - 1</li>

<li> Sibling2 of Parent - 1 </li>

<li> Sibling3 of Parent - 1 </li>

<li> Sibling4 of Parent - 1 </li>

<li class="parent"> Parent - 2 </li>

<li> Sibling1 of Parent - 2</li>

<li> Sibling2 of Parent - 2 </li>

</ul>

Code:

$(document).ready(function () {

$("#btnnextUntilDemo").click(function () {

var result = $(".parent:first").nextUntil(".parent");

alert(result.text());

});

});

Output:

Explanation:

The code started by taking the first of the CSS "parent" class and continues until it finds a similar next match and returns all the siblings inside the first "parent" class

14.eq()

Purpose:This function narrows the set of matched elements to the one at the specified index.

Objective:We want to find the third child of the first parent from the below Html.

<ul class="parent">

<li>Child 1 of Parent1</li>

<li>Child 2 of Parent1</li>

<li>Child 3 of Parent1</li>

<li>Child 4 of Parent1</li>

</ul>

<ul class="parent">

<li>Child 1 of Parent2</li>

<li>Child 2 of Parent2</li>

<li>Child 3 of Parent2</li>

<li>Child 4 of Parent2</li>

</ul>

Code:

$(document).ready(function () {

$("#btnNChild").click(function () {

var whichChildToFind = 3;

var result = $('ul li').eq(whichChildToFind - 1);

alert(result[0].outerHTML);

});

});

Explanation:eq(X) is a Zero("0") based index function.It matches the selector and gets the result back.

Alternative 1:

$('ul li:eq(3)');

15.nth-child()

Purpose:This function is similar to "eq" function but matches more than one.

Objective:We want to find the third child of all the parents from the below Html.

<ul class="parent">

<li>Child 1 of Parent1</li>

<li>Child 2 of Parent1</li>

<li>Child 3 of Parent1</li>

<li>Child 4 of Parent1</li>

</ul>

<ul class="parent">

<li>Child 1 of Parent2</li>

<li>Child 2 of Parent2</li>

<li>Child 3 of Parent2</li>

<li>Child 4 of Parent2</li>

</ul>

Code:

$(document).ready(function () {

$("#btnNChild").click(function () {

var result = "";

var childs = $('ul li:nth-child(3)');

var childsCount = childs.length;

result += "Childs found = " + childsCount + "\n";

for (var i = 0; i < childsCount; i++) {

result += childs[i].outerHTML + "\n";

}

alert(result);

});

});

Explanation:$('ul li:nth-child(3)') fetches us individual 3rd matched list element of each <ul>in the DOM model.

References

For a complete list of traversal functions please visit Traversing

Conclusion

Hope that we have a fair idea by now about JQuery Traversal methods and their usage.If not, we will revisit it again and will go through it properly.We will proceed to the next section once we are through with the current one.Thanks for reading.The attached zip file contains all the examples being demonstrated here.

Page copy protected against web site content infringement by Copyscape

About the Author

Niladri.Biswas
Full Name: Niladri Biswas
Member Level: Platinum
Member Status: Member
Member Since: 10/25/2010 11:04:24 AM
Country: India
Best Regards, Niladri Biswas
http://www.dotnetfunda.com
Technical Lead at HCL Technologies

Login to vote for this post.

Comments or Responses

Posted by: Sheonarayan on: 7/12/2012 | Points: 25
Awesome series of the jQuery articles, keep it up!
Regards

Login to post response

Comment using Facebook(Author doesn't get notification)