Thymeleaf expression parse exception - spring

I've 2 lists; allkontrols (2 element), risk.kontrols (1 element)
I'm listing all kontrols as checkbox and trying to 'select' them if risk.kontrols list contains it.
The one element in risk.kontrols is also in allkontrols.
So, when I tried to print the results of this:
<div th:each="kontrol : ${allkontrols}" th:text="${#lists.contains(risk.kontrols, kontrol)}"/>
I got results as
true
false
Everything is ok till here. Now, when I tried to populate them with data, I got errors. Here is the code:
<div th:each="kontrol : ${allkontrols}" class="items form-control-lg">
<label>
<input th:value="${kontrol.id}" th:selected="{#lists.contains(risk.kontrols, kontrol)}" type="checkbox" class="flat">
<div style="display: inline-block;" th:utext=" ${kontrol.name}"></div>
</label>
</div>
Error part:
th:selected="{#lists.contains(risk.kontrols, kontrol)}"
Stacktrace:
2018-07-27 20:36:55 ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "view/riskkontrol.html")] with root cause
org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: "{#lists.contains(risk.kontrols, kontrol)}" (template: "riskkontrol" - line 44, col 140)

It looks like you're missing a $ before the { in your th:selected, try changing it to: th:selected="${#lists.contains(risk.kontrols, kontrol)}"

Related

Exception evaluating SpringEL expression for String array

While at spring boot <= 2.4.3 the below snippet worked fine.
<div class="link-red ddmenu" th:with="urls=${new String[]{'/'}}"
th:classappend="${#arrays.contains(urls, #httpServletRequest.getRequestURI()) ? 'selected' : ''}">
<a href="/" th:href="#{/}"> <i class="fa fas fa-home"></i>Home
</a>
</div>
But after upgrading to 2.7.0, I am getting this parsing exception. What should I do to fix it?
Exception evaluating SpringEL expression: "new String[]{'/'}"
Or any related information for this break, available on any Thymeleaf's official site?
Interestingly enough, if you keep looking down the stack track you find this error at the bottom:
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1005E: Type cannot be found 'String'
If I change the expression to:
th:with="urls=${new java.lang.String[]{'/'}}"
Everything works again for me (tested with Spring Boot starter 2.6.7).

insert quotes into expression thymeleaf

I have a fragment of thymeleaf code with form. I want to validate this form.
<form>
<th:block th:fragment="input (label, name, type)">
<div class="col-md-3 form-group" th:class="${#fields.hasErrors(*{__${name}__})}
? 'col-md-3 form-group has-error' : 'col-md-3 form-group'">
Here I got exception:
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "#fields.hasErrors(name)" (template: "fragments/inputFieldWithType" - line 5, col 42)
Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'user' available as request attribute
As I seen in Baeldung, i have to bring field name in quotes like this:
${#fields.hasErrors('name')}
So how can I put name param into quotes?
You can use th:class="${#fields.hasErrors('__${fieldName}__')}"

codeigniter dom-pdf - No block-level parent found. Not good

Fatal error: Uncaught exception 'DOMPDF_Exception' with message 'No block-level parent found. Not good.' system/library/dompdf/include/inline_positioner.cls.php:37
Remove <thead> and <tbody> tags
and remove space between <html><head> , </head><body> and </body></html>
It will works fine.!

Spring Thyme Leaf checking for global errors results in NPE

To display global errors created with Spring MVC with Thyme Leaf, I tried the example given at http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#global-errors:
That, is:
<div th:if="${#fields.hasGlobalErrors()}">
and
<ul th:if="${#fields.hasErrors('global')}">
and
<div th:if="${#fields.hasGlobalErrors()}">
When I add them to my HTML, the page won't even render, nevermind about submitting the form. All the examples result in:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "#fields.hasErrors('global')"
I tried this with v2.1.4 and v.2.1.3 and got the same error. Bug or am I doing something wrong?
Yes, the tags are all closed and properly formed. Yes, this code was within a form. Yes, all the other aspects of the form work without the global error check.
Here is a short version of broken HTML:
<form action="search.html" th:action="#{/auto/search}">
<p th:if="${#fields.hasErrors('global')}" th:errors="*{global}">
Incorrect date
</p>
<input type="text" th:field="${command.stockNumber}" />
<select th:field="*{command.startYear}">
<option value="" th:each="year : ${modelYears}" th:value="${year}"
th:text="${year}"></option>
</select>
</form>
And the controller..
#RequestMapping(value = "/auto/search", method = RequestMethod.POST)
public String search(#Validated
#ModelAttribute("command")
AutoSearchCommand autoSearchCommand
BindingResult result, Model model) {
return "search";
}
Solved:
th:object is needed in a tag preceding to the global error check. Unfortunately, this isn't mentioned in the Spring Thyme Leaf tutorial. Presumably, there's a default form name somewhere which I've overridden in my controller.
Adding the tag in results in this working html:
<form action="search.html" th:action="#{/auto/search}">
<div th:object="${command}" th:remove="tag">
<p th:if="${#fields.hasErrors('global')}" th:errors="*{global}">
Incorrect date
</p>
</div>
<input type="text" th:field="${command.stockNumber}" />
<select th:field="*{command.startYear}">
<option value="" th:each="year : ${modelYears}" th:value="${year}"
th:text="${year}"></option>
</select>
</form>
.. Where "command" is the name of the form bean in the controller.
This thread helped me figure it out.

Thymeleaf with recursive fragment for menus

I am trying to create a recursive fragment in Thymeleaf to produce a left-side menu. Core architecture is Spring Boot, and I am passing in a populated Menu object that has children and such. Code for the Menu looks like:
public class MenuItem {
private String displayLabel;
private String actionUri;
private List<MenuItem> children;
// ...getters/setters/etc...
}
And a Thymeleaf fragment defined like:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Menu</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div th:fragment="submenu (menu)" th:remove="tag">
<ul th:if="${not #lists.isEmpty(menu.children)}" th:class="${#objects.nullSafe(depth, 1) > 1}? 'children'">
<li th:each="child : ${menu.children}">
<span th:if="${#strings.isEmpty(child.actionUri)}" th:text="${child.displayLabel}">Addons</span>
<a th:if="${not #strings.isEmpty(child.actionUri)}" th:href="${child.actionUri}" th:text="${child.displayLabel}">Link Item</a>
<div th:replace="fragments/submenu :: submenu(menu=${child}, depth=depth+1)" th:remove="tag" />
</li>
</ul>
</div>
</body>
</html>
If I take the depth code out, everything seems to work fine. But with it I get:
2014-07-30 11:13:00.832 ERROR 45869 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "#objects.nullSafe(depth, 1) > 1" (fragments/submenu:9)] with root cause
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
The purpose of the depth code is so I can optionally put in a class to track when menu items are children of the parent. Is it possible to either fix the depth counter or to do something else to test if the fragment was ran already? Ultimately I just want a recursive menu with the top ul having no class and the child uls having a class of children.
Try these changes
1.Use two parameters in fragment as
<div th:fragment="submenu (menu, depth)" >
2.Pass the depth as
<div th:replace="fragments/submenu :: submenu(menu=${child}, depth=${depth+1})" />

Resources