default else statement for thymeleaf if case - thymeleaf

I know I can use th:if and th:unless for if-else condition on thymeleaf. But i am wondering if there are any other way to handle default else without using th:unless.
i have if condition like this
th:if="${not #lists.isEmpty(myList) and condition1 and condition2 and condition3}"
now i don't want to repeat same conditions on th:unless block. Is there is way to do this without using th:unless?

Nope, no way to do that with th:if -- it affects a single tag only. There are a couple of more verbose options though:
Use th:with for your conditions. For example:
<th:block th:with="condition=${not #lists.isEmpty(myList) and condition1 and condition2 and condition3}">
<div th:if="${condition}" />
<div th:unless="${condition}" />
</th:block>
Use th:switch. For example:
<th:block th:switch="${not #lists.isEmpty(myList) and condition1 and condition2 and condition3}">
<div th:case="true" />
<div th:case="*" />
</th:block>

Related

In a Thymeleaf `th:text` tag, how do I show different text on `if int == -1`?

I have this in a Thymeleaf web page ...
<span th:text="${account.balance}">balance</span>
When the account.balance == -1 that means unknown, so I want to display text "Unknown".
How do I do an if account.balance == -1 show 'Unknown' in Thymleaf?
There are a whole lot of ways to do this... I would just suggest reading through the Thymeleaf conditional evaluation documentation.
I'd probably do something like this, myself:
<th:block th:switch="${account.balance}">
<span th:case="-1">Unknown</span>
<span th:case="*" th:text="${account.balance}" />
</th:block>
You could also do some thing like this:
<span th:if="${account.balance == -1}">Unknown</span>
<span th:unless="${account.balance == -1}" th:text="${account.balance}" />
Or you could build a String:
<span th:text="${account.balance == -1 ? 'Unknown' : account.balance}" />
This should work: <span th:if="${account.balance == -1}">Unknown</span>
But this : page will be very much helpful for conditionals in general

Cannot pass model attribute in thymeleaf th:each

I'm trying to iterate over a list and pass the current iteration and another model variable to a fragment, but the "other" model variable is always null.
<div th:each="place : ${results.placeResults}" class="col-sm-6 col-xl-4 mb-5">
<div th:replace="fragments/placecard :: placecard" th:with="place=${place},res=${results}"/>
</div> <!-- end for each-->
In the fragment ${res} is always blank.
I figured it out, the th:replace basically makes the th:with have no effect. I changed the code to use th:include and things look better.

Thymeleaf - Always keep the HTML element but conditionally show a value

I need Thymeleaf to always include a label element but only conditionally show a value for it.
If message.type is equal to warning it should show the message.text. Otherwise, the HTML DOM should still contain the label element.
I've tried this but then the label element is missing from the HTML when the message.type is not equal to warning.
<label id="message" th:if="${message.type == 'warning'}"
th:value="${message.text}" th:text="${message.text}"></label>
I'm trying to accomplish something like this:
<label id="message" th:value="${message.type=='warning' ?
message.text: ''}" th:text="${message.type=='warning'?
message.text: ''"></label>
If the message.type is warning, I would expect HTML like this:
<label id="message">My warning message</label>
Otherwise, I would like to have HTML like this:
<label id="message"></label>
Many different ways to accomplish this. You already have one that I would expect to work. (why do you say it doesn't work?) Also, I'm not sure why you are including th:value in your tags (I'm including them to match your question).
<label
id="message"
th:value="${message.type == 'warning'? message.text : ''}"
th:text="${message.type == 'warning'? message.text : ''}"></label>
You could also do something like this:
<label th:if="${message.type == 'warning'}" id="message" th:value="${message.text}" th:text="${message.text}"></label>
<label th:unless="${message.type == 'warning'}" id="message"></label>
or like this (assuming an extra span wouldn't mess up the markup you are wanting):
<label id="message"><span th:if="${message.type == 'warning'}" th:text="${message.text}" /></label>

Thymeleaf - how to chose not null object in form

Trying to check if object is not null in form:
<form th:action="#{register}" th:object="${loginInfo != null ? loginInfo.account : account}" method="post">
<input th:field="*{phoneNumber}"/>
If loginInfo defined and not null I want to use loginInfo.account in form.
Otherwise I want to use account object.
How to do that?
In example above I get IllegalStateException: Neither BindingResult nor plain target object for bean name 'loginInfo!= null ? loginInfo' available as request attribute
Here is what I would do. Since we can't add a conditionals inside a th:object, then the only other way to achieve this, is using a th:block with a th:if. Of course, this will mean that you need your form's inputs in a template, otherwise you will have to duplicate code. I am assuming of course that loginInfo.account have the same fields as account.
First, let's create our template inside our layouts folder. For this example, this html file will be called form-inputs.
<th:block th:fragment="form-inputs">
<input th:field="*{phoneNumber}"/>
</th:block>
Now, the page will have the following code to decide which object to use. If loginInfo is not null, then we will use it's account information, otherwise, we will use account.
<th:block th:if="${loginInfo!=null}">
<form th:action="#{register}" th:object="${loginInfo.account}" method="post">
<section th:replace="layouts/form-inputs :: form-inputs" th:remove="tag">
</section>
</form>
</th:block>
<th:block th:if="${loginInfo == null}">
<form th:action="#{register}" th:object="${account}" method="post">
<section th:replace="layouts/form-inputs :: form-inputs" th:remove="tag">
</section>
</form>
</th:block>
Hope this helps you!

Grails filterPane plugin to fit page layout

I would like to have the filterPane to be inserted in my own div in order to fit my page layout. Basically I want to get rid of the default pop-up behavior and harmonize filterPane with the other elements of the application.
this is my gsp
<div class="filter">
<p>
<filterpane:isFiltered>
<filterpane:currentCriteria domainBean="demoracer.Pilot" />
</filterpane:isFiltered>
</p>
<g:formRemote method="post" name="form_search" url="${[action:'list']}" update="listContainer" >
<filterpane:filterPane customForm="true" formName="form_search" domainBean="demoracer.Pilot"
filterProperties="name," id="filterpaneContainer" />
<g:actionSubmit value="Apply Filter From Outside Filter Pane" action="list" />
</g:formRemote>
</div>
but the pane do not show up.
Thanks
Since the filterpane generates its own div, can't you just use the div it generates and restyle it to fit your layout? You can specify the id, class, and style attributes of the container div it generates. That should be more than enough to restyle it any way you'd like.
it doesn't seems possible since the html is statically created by the taglib
def output = """\
<div id="${containerId}"
class="filterPane ${containerClass ?: ''}"
style="display:none;${containerStyle}">
<h2>${title}</h2>
${openFormTag}
<input type="hidden" name="filterProperties" value="${propsStr}" />
<table cellspacing="0" cellpadding="0" class="filterTable">
"""

Resources