Thursday, May 10, 2018

Thymeleaf: jQuery/JavaScript function call with or without parameters (Examples)

While developing our web application, it's very common use case to execute JavaScript functions on an account of any event like onblur, onchange, onclick, onkeydown, onmouseover etc [1]. These calls may be with or without parameters depending upon the business requirement.
             Today, we would see some examples to understand how to properly call JavaScript functions from Thymeleaf. But before that, we would also see used tech stack, Thymeleaf dependencies in the POM file and how we have added page fragments containing our CSS &  JS files in the target HTML page where we would be making the JavaScript function calls.



1. Tech Stack:


- Spring Boot 1.5.10.RELEASE
- Maven 3.3.9
- Thymeleaf 3.0.3.RELEASE

2. Thymeleaf Dependencies in Maven POM file

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
 <groupId>org.thymeleaf</groupId>
 <artifactId>thymeleaf</artifactId>
 <version>3.0.3.RELEASE</version>
</dependency>
<dependency>
 <groupId>org.thymeleaf</groupId>
 <artifactId>thymeleaf-spring4</artifactId>
 <version>3.0.3.RELEASE</version>
</dependency>
<dependency>
 <groupId>nz.net.ultraq.thymeleaf</groupId>
 <artifactId>thymeleaf-layout-dialect</artifactId>
 <version>2.1.2</version>
</dependency>

3. Add external JavaScript file to the HTML page


For cleanliness and better maintainability, I have kept almost all of my JavaScript functions in a separate JS file which is located at <project_name>/src/main/resources/public/js/main.js and then added the fragment containing CSS & JS in HTML file using th:replace attribute.

3.1 The Fragment 

## <project_name>/src/main/resources/templates/fragments/header.html
<head th:fragment="cssandjs">
 <title>Anshul's Blog</title>
 <link rel="stylesheet" type="text/css" th:href="@{/css/screen.css}"/>
 
 <script type="text/javascript" src="https://code.jquery.com/jquery-latest.min.js"></script>
 <script type="text/javascript" th:src="@{/js/main.js}" src="/js/main.js"></script>
</head>

3.2 The Target HTML page 


This is the file where we have added the cssandjs fragment using th:replace attribute and will be making JavaScript calls using Thymeleaf. For more details on th:replace attribute, have a look at this write-up.
## <project_name>/src/main/resources/templates/target.html
<head th:replace="fragments/header :: cssandjs">

4. jQuery / JavaScript Function Calls


Apart from function calls, we would also see situations where we may avoid writing JavaScript functions. One might confuse while making function calls as when to directly use events like onclick, onchange etc or use Thymeleaf's attributes like  th:onclick or th:onchange etc. Therefore, just follow the golden rule i.e. use Thymeleaf's attributes only when, we need to pass some dynamic values in the functions otherwise stick with normal HTML event attributes. Now we ready to fly, everything is in place.

4.1 Function call without parameter

<button onclick="addItemToKart()">Add Item</button>
<div class="close"><span id="x" onclick="closeItemDetailsInModelWindow()">&#9747;</span></div>
<select th:name="${#strings.listSplit(stream.key,',')[1]}" 
  th:onchange="${#strings.listSplit(stream.key,',')[1] == 'Science'} ? 'populateScienceOrCommerceDropdown()' : ''">

4.2  Function call with parameters

## ${item.id} is of type Integer
<input type="button" value="Select" th:onclick="|showItemDetailsInModelWindow(${item.id})|"/>

## ${author.id} is of type Integer & ${author.name} is of type String
<input type="button" value="Show books by author" th:onclick="|showBooksByAuthor(${author.id}, '${author.name}')|"/>

## ${titleModel.isbn} is of type String & ${book.bookId} is of type Integer
<a th:onclick="|bookDetails('${titleModel.isbn}',${book.bookId})|" style="cursor: pointer;">Book Details</a> 

4.3 Avoid writing JavaScript functions


In some situations, one could avoid writing JavaScript functions like when one have to simply call a particular controller's method or when one have to show the popup box [Alert box, Confirm box, and Prompt box] etc.
<button th:onclick="'javascript: document.location=\'/chapterdetails?isbn=' + ${bookModel.isbn} + '&amp;page=1\''"></button>  
<input type="submit" value="Approve" onclick="return ( prompt('You must type APPROVED to continue') == 'APPROVED' )" /> 

5. Conclusion 


Now we know how to make JavaScript function calls in Thymeleaf. We have also seen how to keep function calls in a separate file for better maintainability and then use th:replace attribute to add the fragments containing these CSS & JS files. Happy Learning!!

Appendix:
[1] : Some examples of event attribute and their corresponding event actions:
  • onclick Event:
    onclick of a button, invoke a controller method with or without parameter
    - onclick of a button, open a model window to either show some information to user or to take user's input
  • onchange Event:
    dynamically showing different select box on selecting different values from a select box 

3 comments: