Home » Java » Enterprise Java » Thymeleaf – fragments and angularjs router partial views

About Biju Kunjummen

Thymeleaf – fragments and angularjs router partial views

One more of the many cool features of thymeleaf is the ability to render fragments of templates – I have found this to be an especially useful feature to use with AngularJs.

AngularJS $routeProvider or AngularUI router can be configured to return partial views for different “paths”, using thymeleaf to return these partial views works really well.

Consider a simple CRUD flow, with the AngularUI router views defined this way:
 
 
 

app.config(function ($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise("list");

    $stateProvider
        .state('list', {
            url:'/list',
            templateUrl: URLS.partialsList,
            controller: 'HotelCtrl'
        })
        .state('edit', {
            url:'/edit/:hotelId',
            templateUrl: URLS.partialsEdit,
            controller: 'HotelEditCtrl'
        })
        .state('create', {
            url:'/create',
            templateUrl: URLS.partialsCreate,
            controller: 'HotelCtrl'
        });
});

The templateUrl above is the partial view rendered when the appropriate state is activated, here these are defined using javascript variables and set using thymeleaf templates this way (to cleanly resolve the context path of the deployed application as the root path):

<script th:inline="javascript">
    /*<![CDATA[*/
    var URLS = {};
    URLS.partialsList = /*[[@{/hotels/partialsList}]]*/ '/hotels/partialsList';
    URLS.partialsEdit = /*[[@{/hotels/partialsEdit}]]*/ '/hotels/partialsEdit';
    URLS.partialsCreate = /*[[@{/hotels/partialsCreate}]]*/ '/hotels/partialsCreate';
    /*]]>*/
</script>

Now, consider one of the fragment definitions, say the one handling the list:

file: templates/hotels/partialList.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" layout:decorator="layout/sitelayout">
<head>
    <title th:text="#{app.name}">List of Hotels</title>
    <link rel="stylesheet" th:href="@{/webjars/bootstrap/3.1.1/css/bootstrap.min.css}"
          href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"/>
    <link rel="stylesheet" th:href="@{/webjars/bootstrap/3.1.1/css/bootstrap-theme.css}"
          href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.css"/>
    <link rel="stylesheet" th:href="@{/css/application.css}" href="../../static/css/application.css"/>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-xs-12">
            <h1 class="well well-small">Hotels</h1>
        </div>
    </div>
    <div th:fragment="content">
        <div class="row">
            <div class="col-xs-12">
                <table class="table table-bordered table-striped">
                    <thead>
                    <tr>
                        <th>ID</th>
                        <th>Name</th>
                        <th>Address</th>
                        <th>Zip</th>
                        <th>Action</th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr ng-repeat="hotel in hotels">
                        <td>{{hotel.id}}</td>
                        <td>{{hotel.name}}</td>
                        <td>{{hotel.address}}</td>
                        <td>{{hotel.zip}}</td>
                        <td><a ui-sref="edit({ hotelId: hotel.id })">Edit</a> | <a
                                ng-click="deleteHotel(hotel)">Delete</a></td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </div>
        <div class="row">
            <div class="col-xs-12">
                <a ui-sref="create" class="btn btn-default">New Hotel</a>
            </div>
        </div>
    </div>
</div>
</body>
</html>

The great thing about thymeleaf here is that this view can be opened up in a browser and previewed. To return the part of the view, which in this case is the section which starts with “th:fragment=”content””, all I have to do is to return the name of the view as “hotels/partialList::content”!

The same approach can be followed for the update and the create views.

One part which I have left open is about how the uri in the UI which is “/hotels/partialsList” maps to “hotels/partialList::content”, with Spring MVC this can be easily done through a View Controller, which is essentially a way to return a view name without needing to go through a Controller and can be configured this way:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

 @Override
 public void addViewControllers(ViewControllerRegistry registry) {
  registry.addViewController("/hotels/partialsList").setViewName("hotels/partialsList::content");
  registry.addViewController("/hotels/partialsCreate").setViewName("hotels/partialsCreate::content");
  registry.addViewController("/hotels/partialsEdit").setViewName("hotels/partialsEdit::content");
 }

}

So to summarize, you create a full html view using thymeleaf templates which can be previewed and any rendering issues fixed by opening the view in a browser during development time and then return the fragment of the view at runtime purely by referring to the relevant section of the html page.

  • A sample which follows this pattern is available at this github location – https://github.com/bijukunjummen/spring-boot-mvc-test

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

and many more ....

 

Leave a Reply

Your email address will not be published. Required fields are marked *

*


× five = 20

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Want to take your Java Skills to the next level?
Grab our programming books for FREE!
  • Save time by leveraging our field-tested solutions to common problems.
  • The books cover a wide range of topics, from JPA and JUnit, to JMeter and Android.
  • Each book comes as a standalone guide (with source code provided), so that you use it as reference.
Last Step ...

Where should we send the free eBooks?

Good Work!
To download the books, please verify your email address by following the instructions found on the email we just sent you.