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

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>

Related

Unable to define siteprism element from a given label text

I'm using a cucumber/ruby/capybara/siteprism framework and I'm having problems identifying elements as either we're missing the ids, names, etc or they create them with a in real time.
I was mainly trying to define some of those elements in a siteprism page object model. For example, I was trying to enter some data in the 'input' field for 'First Name' below:
<div class="control-group">
<label class="control-label" for="input_field_dec_<random_number>">
First Name
<span class="required"></span>
</label>
<div class="controls">
<input id="input_field_dec_<random_number>" class=" span5" type="text" value="" scripttofire="SetUserFirstName('input_field_dec_<random_number>')" required="required" name="input_field_dec_<random_number>" data-val-required="First Name is required" data-val-regex-pattern="^[a-zA-Z0-9_ \-\']*$" data-val-regex="Only alphabetic and numeric characters allowed" data-val="true">
<span class="field-validation-valid help-inline" data-valmsg-for="input_field_dec_<random_number>" data-valmsg-replace="true"></span>
</div>
</div>
Is there a way to pass the label text (eg: 'First Name' - ignoring the spaces around, something like - contains='First Name') and then find the input element inside to set it up?
I was thinking something along the lines of:
element :first_name_field, :xpath, "//label[contains(text()='Continue'])/<and here something to find the input field?>" but cannot figure it out...
Capybara provides a bunch of built-in "selectors" that can be used for this, and you can add your own if you find it necessary. You can see the provided selectors by either building the Capybara docs yourself (rubydocs doesn't run the custom yard code used to generate that part of the docs) or by browsing the file where they are implemented - https://github.com/teamcapybara/capybara/blob/master/lib/capybara/selector.rb#L47
For your original example you can use the :field selector
element :first_name_field, :field, 'First Name'
which will match on the inputs associated label text. For you second example (from the comments) where the input and label have no connection (wrapped or for attribute) you should be able to do something like
element :some_field, :xpath, ".//label[contains(normalize-space(string(.)), 'label text')]/following-sibling::*[1]/self::input"
If you wanted to make that reusable you could add your own "selector" like
Capybara.add_selector(:sibling_input) do
label "Label adjacent sibling input"
xpath do |locator|
XPath.descendant(:label)[XPath.string.n.is(locator)].next_sibling(:input)
end
end
which could then be used as
element :some_field, :sibling_input, 'label text'

Grails: Removing Unwanted Brackets when Displaying Variable

I have a .gsp page where a student can select a course that they are in. That selection is then stored in an array list. I have another .gsp page that shows student details and within those details it shows which course they selected from the other page. However, when it displays the course it displays like this: "[courseName]", but I would like it to display without the brackets: "courseName".
This is my code for displaying the selection:
<g:if test="${studentDetails?.course}">
<li class="fieldcontain">
<span id="course-label" class="property-label">
<g:message code="student.course.label" default="Course(s)" /></span>
<span class="property-value" aria-labelledby="course-label">
<g:set var="course" value="${studentDetails?.course.courseName}" />
<g:message message="${course}" /></span>
</li>
</g:if>
So far I've tried displaying the variable with g:fieldValue, g:message, and just the variable itself without a tag. All methods display with the brackets. Any suggestions on how to remove the brackets are appreciated. If any other code is needed I can provide it. Thanks.
If your studentDetails?.course.courseName contains a List of courses and your want to display all of them, you need to convert it to a String. But default implementation of List.toString() uses brackets. Your could use .join(',') instead.
Like:
<g:if test="${studentDetails?.course}">
<li class="fieldcontain">
<span id="course-label" class="property-label">
<g:message code="student.course.label" default="Course(s)" /></span>
<span class="property-value" aria-labelledby="course-label">
${studentDetails.course.courseName.join(', ')}
</span>
</li>
</g:if>
Also I suggest to add .encodeAsHTML() if you got this data (course name) from a user, to escape any HTML content inside variables (avoid XSS, etc). Like:
${studentDetails.course.courseName.join(', ').encodeAsHTML()}

ASP.NET MVC Razor conditional rendering an element

How does one conditionally render an HTML element in Razor 2?
For instance, suppose I had the tag
<div class="someclass">
<p>#somevalue</p>
</div>
And I wanted to suppress the <-div-> tag from rendering if the value of #somevalue was equal to 1. Is there a simple way to do this in Razor similar to how I might "hide" the <-div-> tag with Knockout.js in a browser, where I might :
<div class="someclass" data-bind="showWhenTrue: someValue != 1">
<p data-bind="text: someValue"></p>
</div>
At the moment, the best Razor alternative I have is to do this:
#if (someValue != 1) {
<div class="someclass">
<p>#somevalue</p>
</div>
}
There are many ways to do this. First, it should be noted that your knockout code doesn't actually remove the html from output, it just sets its display to hidden.
The razor code you have actually removes the code from the rendered HTML, so that's a very different thing.
To answer your question, we need to know what it is you're trying to achieve. If you just want to hide the display, you can simply do something like this:
<div class="someclass" style="display: #{ somevalue == 1 ? #:"none" : #:"block" };">
<p>#somevalue</p>
</div>
You could also do it with a class:
<div class="someclass #{ somevalue == 1 ? #:"HideMe" : #:"ShowMe" }">
<p>#somevalue</p>
</div>
If you want to remove the code from the output, then you can just do what you've done.. i'm mot sure what you find so objectionable about it... but if you want other alternatives, you could create an Html helper, you could use a razor helper, you could use a Display or EditorTemplate....
The list is actually quite long and i'm just scratching the surface...
An elegant (and re-usable) solution is to write an extension method for Html to do conditional rendering of text ( a bit like IF() in Excel) - e.g.
public static MvcHtmlString ConditionalRender(this HtmlHelper helper, bool condition, string trueString, string falseString = "")
{
return MvcHtmlString.Create((condition) ? trueString : falseString);
}
You can then use it in your code as such:
<div class="someclass" style="display: #Html.ConditionalRender(somevalue == 1, "none","block")">
<p>#somevalue</p>
</div>

Choosing a radio button from its labels with Capybara

I have a dynamically generated form that looks like this:
Do you like Pizza?
[ ] Yes [ ] No
The HTML looks like this:
<form>
<div class="field">
<label>Do you like Pizza?</label>
<input
type="radio" value="true"
id="reply_set_replies_attrs_0_pizza_true"
name="reply_set[replies_attrs][0][pizza]">
</input>
<label for="reply_set_replies_attrs_0_pizza_true">Yes<label>
<input
type="radio" value="false"
id="reply_set_replies_attrs_0_pizza_false"
name="reply_set[replies_attrs][0][pizza]">
</input>
<label for="reply_set_replies_attrs_0_pizza_false">No<label>
</div>
</form>
I'd like to get check those radio buttons with Capybara. How can I do this? I don't always know the ids of the radio buttons, because there's a few of them and when I also ask about Popcorn and Chicken I don't want to depend on knowing their order.
Is there a way to do something like...
field = find_label("Do you like pizza?").parent('field')
yes = field.find_label('Yes')
yes.click
?
Note that when using find, the :text option does a partial text match. Therefore, you could find the div directly:
find('div.field', :text => 'Do you like Pizza?').choose('Yes')
(Also using choose makes radio button selection easier.)
not bad!
label = find('label', :text => "Do you like Pizza?")
parent = label.find(:xpath, '..')
parent.find_field("Yes").click

Grails RadioGroup, how to bind labels to radio name

I'm struggling arround with the g:radioGroup tag -- I want to create some radios and some labels correspondig to the radios:
<g:radioGroup name="stateOfHealth" value="${review.stateOfHealth}" id="stammp"
labels="['1','2','3','4','5']"
values="['bad','suboptimal','well','veryWell','excellent']">
<span class="radioSpan"> ${it.radio}</span>
<label for="${ ???? }">${it.label}</label>
</g:radioGroup>
What do I need to do to insert in the label's "for" attribute to match the right radio?
You don't need to set the for attribute, just wrap the radio with the label, like this:
<g:radioGroup name="stateOfHealth" value="${review.stateOfHealth}" id="stammp"
labels="['1','2','3','4','5']"
values="['bad','suboptimal','well','veryWell','excellent']">
<label>
<span class="radioSpan">${it.radio}</span>
${it.label}
</label>
</g:radioGroup>

Resources