How to check null and empty condition using Thymeleaf in one single operation?
In order to check null or empty string using thymeleaf expressions, Use this approach : ---
<div th:if= "${searchResults.results != null}">
OR, this :--
<div th:if= "${searchResults.results != ''}">
Furthermore, you can check the empty or null object on your controller itself and then send the response on your thymeleaf-html page accordingly, like this :--
1.) Your Controller :-
List ls = //some data from you DAO
if(ls.isEmpty()){
model.addAttribute("response","NoData");
}else{
model.addAttribute("response",ls);
}
2.) Then on your Thymleaf page :- - -
<th:block th:if="${response=='NoData'}"> No Data Found </th:block>
PS - I've answered the same question here which helps the questioner hope it helps you as well :--
ThymeLeaf: Not Equal expression in th:if
Thymeleaf - How to handle the null value and assign different value based on the condition?
It works when I use the Elvis Operator ?
in this way
The solution is attached at below:
<td>
<span th:text = "${question.objQuestion?.questionContent}"></span>
<span th:text = "${question.sbjQuestion?.questionContent}"></span>
</td>
Null fields in Thymeleaf form using Spring Boot, other fields fine
You have th:object="${user}"
in your Thymeleaf template, so I have to assume that you @GetMapping
method in your controller has added an instance of User
to the Model
using addAttribute
.
In your @PostMapping
, you should also use @ModelAttribute
:
@PostMapping("/register_attempt")
public String registerAttempt(@Valid @ModelAttribute("user") User newUser) {
...
You also need to have setters for each field. I see that User
has no setName(String name)
, no setDob(String dob)
, ...
Some other tips:
- Do not create
BCryptPasswordEncoder
instances in your controller method itself. When you use Spring Boot, this should be an application wide singleton (Called a bean in Spring lingo). Add a class to your application e.g.ReservationSystemApplicationConfiguration
which declares this:
@Configuration
public class ReservationSystemApplicationConfiguration {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Then in your controller, inject the password encoder:
@Controller
@RequestMapping("...")
public class MyController {
private final PasswordEncoder passwordEncoder;
public MyController(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
@PostMapping("/register_attempt")
public String registerAttempt(@Valid @ModelAttribute("user") User newUser) {
String encodedPassword = passwordEncoder.encode(newUser.getPassword());
newUser.setPassword(encodedPassword);
userRepository.save(newUser);
return "registered_successfully";
}
}
A Controller should not directly call the Repository, but use a Service in between.
It is better to use different objects for mapping the form data and for storing the data into the database. See Form Handling with Thymeleaf for more information on how to do that.
Thymeleaf form handling returning Null?
There are 2 problems with the thymleaf code you have posted:
- you are using th::object instead of th:object
- you are using th:object="${status}" instead of th:object="${stat}" => You have added stat in the model in the controller hence you should use stat instead of status.
thymeleaf th:if - Cannot index into a null value
For the th:each="row,rowStat : *{dataList}"
iterator, I would simplify that code to this:
th:each="row : ${dataList}"
You can think of this as being broadly equivalent to the following Java for-loop:
List<DataItem> dataList = ...; // assume this is populated with DataItems
for (DataItem dataItem : dataList) {
System.out.println(dataItem.getFolderName());
}
In the above for-loop, we do not need to access the list by index - and the same is also true for the Thymeleaf syntax.
Thymeleaf lets you access fields in an object without needing to refer to the getter method.
So, now that we have our row
variable from th:each="row : ${dataList}"
, we can do this:
<div class="mylist" th:each="row,rowStat : *{dataList}">
Folder: <span th:text="${row.folderName}" />
<div class="invalid-feedback"
th:if="${row.folderName == appFolderName}">
Folder already exists. Please choose different folder name.
</div>
</div>
In the above code, you can see ${row.folderName}
- which means Thymeleaf will invoke the getFolderName()
method on the row
object. This relies on your object using JavaBean naming standards for your getters.
You can enhance the Thymeleaf th:each
processor by adding a second variable - which is what you do in your question: rowStat
:
th:each="row,rowStat : ${dataList}"
This gives you access to extra information about the status of the Thymeleaf iterator - you can see a list of all these extra data values here.
These extra values are no needed in your case. But they can be useful in other situations - for example if you want to identify the first
or last
record in the list, or all even
records, and so on.
Your example in the question uses the __${...}__
preprocessing syntax - which is very powerful and can be extremely useful. But again, it is not needed for your basic functionality.
Your example uses both ${...}
and *{...}
syntaxes to create Thymeleaf variables. It's important to understand the basic differences between them.
The difference is covered in the documentation describing the asterisk syntax:
the asterisk syntax evaluates expressions on selected objects rather than on the whole context. That is, as long as there is no selected object, the dollar and the asterisk syntaxes do exactly the same. And what is a selected object? The result of an expression using the th:object attribute.
The documentation has examples.
Finally, because you are using Spring (as per the tag in your question), then you are actually using Spring's dialect of Thymeleaf and SpEL - the Spring Expression Language.
This is broadly similar to the standard (OGNL) expression language used by the standard (non-Spring) Thymeleaf dialect - but it has several very useful enhancements.
One such enhancement is the safe navigation operator I mentioned in my comment:
${row?.folderName}
Here, the ?
will immediately return null
if row
is null
. Without this, you would get a null pointer exception when Thymeleaf attempted to invoke the getFolderName()
method on a null row
object.
How to set values as NULL in thymeleaf
Just need to use the rest of the ternary expression :P
<td th:text = "${student.years != null ? student.years : 'NULL'}" />
Spring Boot Thymeleaf Method POST SELECT null
You should start with defining a form data object. For example:
public class AgeDifferenceFormData {
private long user1Id;
private long user2Id;
// getters and setters here
}
Create an empty such object in your @GetMapping
:
@GetMapping("/user-difference")
public String calculateDifferenceForm(Model model) {
model.addAttribute("formData", new AgeDifferenceFormData());
model.addAttribute("users", service.findAll());
return "user-difference";
}
Now update your HTML form to use the form data object:
<form method="post" action="/calculate_years" th:object="${formData}">
<select th:field="*{user1Id}"/>
<option th:each="user : ${users}" th:value="${user.id}" th:text="${user.firstName}">
</option>
</select>
<select th:field="*{user2Id}"/>
<option th:each="user : ${users}" th:value="${user.id}" th:text="${user.firstName}">
</option>
</select>
<button type="submit">Submit</button>
</form>
Note how you need to:
- Set a selected object for Thymeleaf via
th:object="${formData}"
- Set the dedicated field for each select via
th:field="*{user1Id}"
andth:field="*{user2Id}"
- Use the unique id of the user for the
th:value
.
Now in your @PostMapping
method do this:
@PostMapping("/calculate_years")
public String calculateDifferenceForm(@ModelAttribute("formData") AgeDifferenceFormData formData,
BindingResult bindingResult){
User user1 = service.getUser(formData.getUser1Id());
User user2 = service.getUser(formData.getUser2Id());
// calculate age difference here
return "redirect:/user-difference";
}
See also Using HTML select options with Thymeleaf for more info.
Related Topics
How to Embed a PDF Viewer in a Page
CSS Speech Bubble with Box Shadow
How to Add Button Inside Input
Rendering HTML Elements to <Canvas>
Svg Coordinates with Transform Matrix
Denoting a Preferred Place for a Line Break
How to Use Use Text as the Background with CSS
Html-Tooltip Position Relative to Mouse Pointer
Bootstrap 4 - Responsive Cards in Card-Columns
Input With Display:Block Is Not a Block, Why Not
Bootstrap: Add Margin/Padding Space Between Columns
How to Remove "Invisible Space" from HTML
How to Center an Iframe Horizontally