Quantcast
Channel: Baeldung
Viewing all articles
Browse latest Browse all 3680

Get the Index Values From forEach Loop in JSTL

$
0
0

1. Overview

When working with JavaServer Pages (JSP), we often simplify our code using the JavaServer Pages Standard Tag Library (JSTL).

One of the most commonly used JSTL tags is <c:forEach>, which allows us to iterate over collections such as arrays, lists, or maps. While iterating, we frequently need to access the index of each element.

In this quick tutorial, we’ll explore getting the elements’ index values while iterating using the JSTL <c:forEach> tag.

2. Creating a Simple Example

As an example, we’ll create a simple Spring-MVC JSTL web application to list some predefined movies. For simplicity, we’ll skip Spring configurations such as Spring ViewResolver.

First, let’s look at the Movie POJO:

public class Movie {
    private String title;
    private int year;
    public Movie(String title, int year) {
        this.title = title;
        this.year = year;
    }
    //... getter and setter methods are omitted
}

Then, we need a Spring Controller class to process HTTP requests. So, let’s create one:

@Controller
public class JSTLForEachDemoController {
 
    @RequestMapping(value = "/foreach-demo", method = RequestMethod.GET)
    public ModelAndView forEachDemo(final Model model) {
        ModelAndView mv = new ModelAndView("jstlForEachDemo");
  
        List<Movie> movies = List.of(
          new Movie("The Hurt Locker", 2008),
          new Movie("A Beautiful Mind", 2001),
          new Movie("The Silence of the Lambs", 1991),
          new Movie("A Man for All Seasons", 1966),
          new Movie("No Country for Old Men", 2007)
        );
        mv.addObject("movieList", movies);
        return mv;
    }
}

As we can see, the JSTLForEachDemoController class has only one method to handle the “/foreach-demo” GET request. For simplicity, we prepared a List of hard-coded Movie objects and added it to the ModelAndView object named “movieList“. Further, we defined jstlForEachDemo as the view to present the Movie data.

Finally, let’s create a JSP file as the view at webapp/WEB-INF/views/jstlForEachDemo.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<style>
    table, th, td {
        border: 1px solid black;
        border-collapse: collapse;
    }
</style>
<head>
    <title>JSTL ForEach Example</title>
</head>
<body>
<h1>Movie List</h1>
<div>
    <table style="width: 50%">
        <tr>
            <th>Year</th>
            <th>Title</th>
        </tr>
        <c:forEach var="movie" items="${movieList}">
            <tr>
                <td>${movie.year}</td>
                <td>${movie.title}</td>
            </tr>
        </c:forEach>
    </table>
</div>
</body>
</html>

As the code example shows, we used JSTL’s <c:forEach> tag to loop through the movieList object and generate the rows in the HTML table.

If we deploy our web application to a servlet container, such as Apache Tomcat, we can see the movies’ data by accessing the URL in a web browser:

Movie List

Next, let’s figure out how to obtain each Movie element’s index during the forEach iteration.

3. Using varStatus to Access Index and Count

Fortunately, JSTL provides a built-in mechanism for getting the indexes of elements in a forEach loop. The varStatus attribute allows us to define a loop status variable that provides useful metadata about the iteration. 

Next, let’s add the varStatus attribute to the <c:forEach> tag and show the element indexes in the HTML table:

...
<h1>Movie List</h1>
<div>
    <table style="width: 50%">
        <tr>
            <th>varStatus.index</th>
            <th>Year</th>
            <th>Title</th>
        </tr>
        <c:forEach var="movie" items="${movieList}" varStatus="theLoop">
            <tr>
                <td>${theLoop.index}</td>
                <td>${movie.year}</td>
                <td>${movie.title}</td>
            </tr>
        </c:forEach>
    </table>
</div>
...

In this example, we named varStatus in the forEach loop “theLoop” and obtained an element’s index by accessing varStatus‘s index property: theLoop.index.

Now, if we access the same URL, we can see the new column containing the indexes of the elements in movieList:

Movie List with varStatus.index

As the screenshot shows, varStatus‘s index is zero-based. However, sometimes, we want to have one-based indexes in our view. Of course, we can quickly achieve it by adding one to varStatus‘s index, for example, ${theLoop.index + 1}. In fact, varStatus offers the count property, which provides one-based indexes.

Next, let’s add another one-based index column next to the zero-based one, using varStatus.count:

...
<h1>Movie List</h1>
<div>
    <table style="width: 50%">
        <tr>
            <th>varStatus.index</th>
            <th>varStatus.count</th>
            <th>Year</th>
            <th>Title</th>
        </tr>
        <c:forEach var="movie" items="${movieList}" varStatus="theLoop">
            <tr>
                <td>${theLoop.index}</td>
                <td>${theLoop.count}</td>
                <td>${movie.year}</td>
                <td>${movie.title}</td>
            </tr>
        </c:forEach>
    </table>
</div>
...

Let’s redeploy our application and check the result in the browser:

Movie List with varStatus.index and varStatus.count

The table includes one-based indexes, as expected.

4. Other Useful Properties of varStatus

Using the built-in varStatus attribute in the JSTL’s <c:forEach> tag, we’ve successfully obtained element indexes. Apart from index and count, varStatus offers other valuable properties.

Sometimes, in a loop, we need to detect whether the current element is the first or the last. For example, we want to set different background colors for the first and last movie in our HTML table.

varStatus provides two boolean properties, first and last, which allow us to easily detect if we’re in the first or the last iteration, respectively.

Next, let’s set different background colors on the first and last movie rows by checking varStatus’s first and last properties:

...
<style>
...
    .first { background-color: lightgreen }
    .last { background-color: orange }
</style>
...
<h1>Movie List</h1>
<div>
    <table style="width: 50%">
        <tr>
            <th>varStatus.index</th>
            <th>varStatus.count</th>
            <th>Year</th>
            <th>Title</th>
        </tr>
        <c:forEach var="movie" items="${movieList}" varStatus="theLoop">
            <tr ${ theLoop.first ? 'class="first"' : '' } ${ theLoop.last ? 'class="last"' : '' }>
                <td>${theLoop.index}</td>
                <td>${theLoop.count}</td>
                <td>${movie.year}</td>
                <td>${movie.title}</td>
            </tr>
        </c:forEach>
    </table>
</div>
...

We defined two CSS classes for the background colors. Then, in the <tr> tagwe set the corresponding class name by checking varStatus‘s first and last properties.

With this change, let’s see the result in the browser:

Movie List with the first and the last entry highlighted

Now, the first row has a light green background, and the last row’s background is orange.

5. Conclusion

In this article, we’ve explored how to access an index within a <c:forEach> loop in JSP with JSTL. Whether we need zero-based indexing for logic or one-based counting for display purposes, JSTL provides an easy-to-use solution for handling loops effectively.

In addition, we demonstrated detecting the first and the last iteration in a <c:forEach> loop using varStatus‘s first and last properties.

As always, the complete source code for the examples is available over on GitHub.

The post Get the Index Values From forEach Loop in JSTL first appeared on Baeldung.
       

Viewing all articles
Browse latest Browse all 3680

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>