Cannot pass model attribute in thymeleaf th:each - thymeleaf

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.

Related

Thymeleaf - getting locale and comparing

The below should set h1 to HOWDY as the locale is showing en_GB, but it doesn't fall into the case?
Am I doing something wrong here? Thanks
<h1 th:text="${#locale}"></h1>
<div th:switch="${#locale}">
<h1 th:case="'en_GB'">HOWDY</h1>
</div>
When you use Thymeleaf's #locale, you are using a reference to a Java Locale object.
What Works?
The following works the way you expect, because it has already evaluated the Java locale object to its string representation, before evaluating each case statement:
<div th:switch="${#locale.toString()}">
<h1 th:case="'en_GB'">HOWDY</h1>
</div>
The following also works:
<div th:switch="__${#locale}__">
<h1 th:case="'en_GB'">HOWDY</h1>
</div>
In this case, it works because you are using the Thymeleaf preprocessor syntax __${...}__ to force Thymeleaf to evaluate #locale (to its string representation) before it evaluates the remainder of the switch statement.
Additional Explanation
Because Thymeleaf's #locale represents a Java Locale object, you can use any of Locales suitable fields and methods, such as :
<div th:text="${#locale.country}"></div> <!-- a field -->
<div th:text="${#locale.toLanguageTag()}"></div> <!-- a method -->
This is why only using ${#locale} in the Thymeleaf switch statement does not match the 'en_GB' string literal that you are expecting it to match: Thymeleaf is comparing an object to a string.
When you use this...
<div th:text="${#locale}"></div>
...you are again accessing the object itself. But in this case the object will use its toString() method when being rendered by Thymeleaf, before it is displayed - giving you your en_GB displayed value.
However, when you use this...
<div th:switch="${#locale}">
<h1 th:case="'en_GB'">HOWDY</h1>
</div>
...Thymeleaf is using the locale object in the switch statement, not its string representation.

Capybara - usage of applying has_xpath? on an apath with variable

There is the structure like:
<div class="parent">
<div>
<div class="fieldRow">...</div>
</div>
<div>
<div class="fieldRow">
<div class="CheckBox">
</div>
</div>
<div>
<div class="fieldRow">...</div>
</div>
<div>
<div class="fieldRow">...</div>
</div>
</div>
In my script I am writing a loop for each of the 4 div's under div[#class='parent'] and aiming to click the checkbox if there is, i.e.
members = page.all(:xpath, '//div[#class='parent'])
members.each do |a|
if **page.has_xpath?(a).find(:xpath, "div[#class='fieldRow']/div[#class='CheckBox']")**
a.find(:xpath, "div[#class='fieldRow']/div[#class='CheckBox']").click
end
end
However I can't look for the correct usage of has_xpath? with xpath including variable.
Please advice? Thank you!
has_xpath? takes an XPath expression (not an element) and returns a boolean (true/false) based on whether there are any elements that match that expression within the current scope - http://www.rubydoc.info/gems/capybara/Capybara/Node/Matchers#has_xpath%3F-instance_method. Since it returns true/false you can't then call find on it. For the example you posted there's no need for XPath or checking for the existence of the elements, just find all the matching elements and call click on them. Something like
page.all('div.parent div.fieldRow div.Checkbox').each { |cb| cb.click }
or
page.all('div.parent div.Checkbox').each { |cb| cb.click }
if the fieldRow class isn't something you really need to check.
Note: this assumes clicking the elements doesn't invalidate any of the other matched elements/change the page.
If you REALLY need to do it with the whole members and looping on them , using XPath, and checking for presence then it would be something like
members = page.all(:xpath, './/div[#class='parent'])
members.each do |a|
if a.has_xpath?(:xpath, ".//div[#class='fieldRow']/div[#class='CheckBox']")
a.find(:xpath, ".//div[#class='fieldRow']/div[#class='CheckBox']").click
end
end
Note: the .// at the beginning of the XPath expressions is needed for scoping to work correctly - see https://github.com/teamcapybara/capybara#beware-the-xpath--trap - which is an issue using CSS selectors doesn't have, so you should really prefer CSS selectors whenever possible.

<g:set> variable's value is not being rendered properly

I've used <g:set> tag like this:
<g:set var="extraStyle" value="style='min-width:120px;'"/>
and used the extraStyle variable like this:
<div class="myClass" ${extraStyle}> ${myValue}</div>
And it should be rendered as:
<div class="myClass" style="min-width:120px;"> XYZ </div>
But, I am getting this instead:
<div class="myClass" style="'min-width:120px;'"> XYZ </div>
Due to which, min-width style is not being applied. What am I doing wrong here?
Grails version: 3.1.6
You could try just setting the style value e.g.
<g:set var="extraStyle" value="min-width:120px;"/>
<div class="myClass" style="${extraStyle}"> ${myValue}</div>
I think Mike's answer is correct, and although I do not know the context of your project I think it might in the long run be better to add a class dynamically to the element.
Something like
<div class="myClass ${extraClass}">...</div>

Angular 2 Dart: Template syntax - how to concatenate strings?

Feels like a dumb question but I do not get it. How can I do fast string concatenation in Angular 2 Dart templates?
I have a seperate html file for my component lets say my_component.html:
Works:
....
<div id="abc">
{{order.pickupPlace.email}}
</div>
...
Works:
....
<div id="abc">
{{ ((order.pickupPlace.state) ? order.pickupPlace.state+" ":'')}}
</div>
...
Does not work:
....
<div id="abc">
{{"<br/>"+order.pickupPlace.email}}
</div>
...
Does not work:
....
<div id="abc">
{{order.pickupPlace.name+" "+order.pickupPlace.email}}
</div>
...
Have tried to find an answer in the docs here (https://webdev.dartlang.org/angular/guide/template-syntax#!#expression-operators) but no luck.
Of course I could use *ngIf on every element which I output conditionally but is there a way for simple string concatenation?
The best way is to declare a getter inside your Component controller that does the concatenation for you, you will get dart syntax support and the html template will looks cleaner.
String get myConcatenation => "${order.pickupPlace.name}${order.pickupPlace.email}";
<div id="abc">
{{myConcatenation}}
</div>
The last two examples can be made to work easily:
<div id="abc">
<br/>{{order.pickupPlace.email}}
</div>
And:
<div id="abc">
{{order.pickupPlace.name}} {{order.pickupPlace.email}}
</div>
Angular handles this pretty well. If you need some more complicated logic you can move it to the Dart code (but you cannot use HTML there easily).
If you find creating lot of weird logic consider creating more smaller components that can handle this for you.

How do I make dynamic ids in Haml?

#item
creates a div with id="item"
.box#item
creates a div with class="box" and id="item"
.box#="item "+x
creates a div with class="box" and a comment '#="item"+x'
.box#
="item"+x
throws "Illegal element: classes and ids must have values."
How do I get set the id to a variable?
There are two ways:
The long form way (define the id as if it were a regular attribute):
.box{:id => "item_#{x}"}
produces this (x is what ever x.to_s evaluates to):
<div class="box" id="item_x">
The short form way:
.box[x]
produces the following assuming x is an instance of item:
<div class="box item" id="item_45">
See the HAML reference for more information.
You can set the id and class in HAML the following ways
The normal way
.box.item#item
<div id="item" class="box item"></div>
If you need to interpolation you can use this format
.box{id: "item_#{123}", class: "item_#{123}"}
<div id="item_123" class="box item_123"></div>
This format generates the class and id using the object reference
# app/controllers/items_controller.rb
#item = Item.find(123)
.box[#item]
<div id="item_123" class="box item"></div>
If you need to prefix something
.box[#item, :custom]
<div id="custom_item_123" class="box custom_item"></div>
If you need a custom class and id generation you need to add the following method to model.
class CrazyUser < ActiveRecord::Base
def haml_object_ref
"customized_item"
end
end
And then you will get the customized class
.box[#item]
<div id="customized_item_123" class="box customized_item"></div>
Refer:
http://haml.info/docs/yardoc/file.REFERENCE.html#object-reference-
http://haml.info/docs/yardoc/file.REFERENCE.html

Resources