Comparing Strings in Grails GSP - grails

I'm stumped by this problem. I'm trying to display a class if a certain string is equals to the logged in username. However it doesn't seem to ever evaluate to true.
Here's the code in gsp
<g:if test="${it.from.username == sec.loggedInUserInfo(field: 'username')}">
<div class="direct-chat-msg right">
</g:if>
<g:else>
<div class="direct-chat-msg">
</g:else>
I also tried using this method
<div class="direct-chat-msg ${(it.from.username == sec.loggedInUserInfo(field: 'username')) ? 'right' : ''}">
However nothing I do can get the 'right' class to show up in the div.
Just for good measure, I printed out the values of both classes in my gsp in hidden fields.
<input type="hidden" value="${it.from.username}"/>
<input type="hidden" value="${sec.loggedInUserInfo(field: 'username')}"/>
And the values are exactly the same
<input type="hidden" value="u***#gmail.com">
<input type="hidden" value="u***#gmail.com">
I've tried several combinations of string comparison
.equals(), calling .toString() on both, also trying as String. however nothing seems to be working.
What could the issue be?
I have tried passing the logged in user object in the Model from the controller, and just calling loggedInUser.username and it works. So my question now is, what kind of object is returned by spring security?

The result of sec.loggedInUserInfo(field: 'username')} is an HTML encoded string. Spring security calls encodeAsHTML() before returning 'username' value. Visually they look the same but are they equal? Apparently not!

Related

Difference between th:text and th:value in Thymeleaf

I just recently started using Thymeleaf through one of my projects. I have seen few examples where th:text=${example} is being used in some places th:value=${example}.
I have gone through the Thymeleaf documentation but couldn't find anything explicitly citing the difference, nor did any question on SO.
Any help would be really appreciated! Thanks.
th:value is modification of html attribute value.
For button, input and option elements, the value attribute specifies the initial value of the element
th:text is used for tag body modification.
div{background-color: lightblue; padding: 2px} // to highlight empty div
<!--th code: <div th:value="${value}"/></div> -->
<br/>Result th:value div: <div value="sometext"/></div>
<!--th code: <form><input th:value="${value}"/></form>-->
<br/>Result th:value form: <form><input value="sometext"></form>
<!--th code: <div th:text="${value}"></div>
Same as: <div>[[${value}]]</div> -->
<br/>Result th:text div: <div>sometext</div>
Here is docs of different Thymeleaf attributes features
Lets see an example:
<input type="radio" name="gender" value="male"> Male<br>
if we want to use thymeleaf in value portion of this input tag, then we will use,
<input type="radio" name="gender" th:value="${someValue}"> Male<br>
if we want to see the text (here Male) sent from the controller dynamically, then we use,
<input type="radio" name="gender" th:text="${someText}""> <br>
th:name => This would be the name of the value that you will be passing to another page (Exemplar scenario).
th:value => This would be the actual value that you would be passing. It could be obtained from a model or straight from the database explicitly.
<form th:action="#{confirm-pass-details.html}">
<button type="submit" th:name="event-id" th:value="${event.get().getEventid()}">Buy Passes</button>
</form>

How to add specific attribute (like "multiple") to Thymeleaf templates?

I have this:
<input id="fileupload" type="file" name="files[]" data-url="rest/controller/upload" multiple>
and I need to make it work in a Thymeleaf template. I have the data-url part figured out but I keep getting an error on the word "multiple". This is needed to allow multiple selection in the file selection window.
I have looked everywhere and have not come across an answer.
EDIT:
If you are not familiar, here is the "multiple" attribute.
http://www.w3schools.com/tags/att_input_multiple.asp
The Standard Dialect of Thymeleaf includes attributes that allow you to set these attributes by evaluating a condition, so that if evaluated to true, the attribute will be set to its fixed value, and if evaluated to false, the attribute will not be set:
e.g for checkedattribute:
<input type="checkbox" name="active" th:checked="${user.active}" />
you have to use:
th:multiple
e.g
<input id="fileupload" type="file" name="files[]" th:multiple="{condition}">
see a tutorial here.

Why doesn't TextBoxFor include validation elements if called twice for the same model property?

Simple question... Here is an example of some razor code:
#Html.TextBoxFor(c => c.RevisedEstimate)
#Html.TextBoxFor(c => c.RevisedEstimate)
Here is how this renders:
<input data-val="true" data-val-number="The field Revised Estimate must be a number." id="RevisedEstimate" name="RevisedEstimate" type="text" value="0" />
<input id="RevisedEstimate" name="RevisedEstimate" type="text" value="0" />
The obvious question you ask is, "Why are you doing that?". The razor view is actually building client side detail-row templates that are used in KendoUI grids. There are two similar grids and we use the same viewmodel server side. We actually do provide the id element for the template so each field in each row ends up with a unique id.
Why does the second input element not have the data-val and data-val-number elements?
Off the top of my head knowing what the JS does in the background, it seems to do this to prevent conflicts. The JS looks for the elements with the data- attributes to do it's validation, along with other functions, so it could possibly pick the wrong one if there are multiple instances of it.
since we were generating HTML for use in a client side template what we did was just create a variable to hold the HTML generated by the helper, and then render out that code in the Views..
Something like:
#{
var revisedEstimateInput = Html.TextBoxFor(c => c.RevisedEstimate)
}
Then later in the view:
#(revisedEstimateInput)
...in as many places as needed. This way the validation and other metadata attributes were in place in our client templates and all the kenodUI validation worked correctly.

Why isn't Razor recognizing a variable without wrapping it in parenthesis in some cases?

I have a section of Razor code in one of my views that isn't behaving the way I expect. The code in question contains multiple locations where I need to append the value of a variable from the Model onto an html attribute. The code below is a slightly simplified version of the markup on my page (I've removed some of the markup 'noise' that wasn't important to this example and just made the code harder to read).
There are three instances where I use #topic.StandardTopicId. The 1st and 2nd instances get replaced as I expected, but the 3rd instance name="IsCovered_#topic.StandardTopicId" renders without replacing the variable.
Code in question:
#foreach(var topic in Model.Group) {
<div id="frame-#topic.StandardTopicId" class="topic-frame">
<label>
<input type="radio" name="IsCovered_#(topic.StandardTopicId)" />
No
</label>
<label>
<input type="radio" name="IsCovered_#topic.StandardTopicId" />
Yes
</label>
</div>
}
Sample of the output from the above code block:
...
<div id="frame-42" class="topic-frame">
<label>
<input type="radio" name="IsCovered_42" />
No
</label>
<label>
<input type="radio" name="IsCovered_#topic.StandardTopicId" value="No" />
Yes
</label>
</div>
...
Can anyone explain why the last instance of the variable is not being replaced and is instead being rendered as is?
Razor will not parse the "#" in the middle of a word. The underscore is treated as part of a word as opposed to the dash. Use #() to place Razor code within words. #(topic.StandardTopicId)
Here's a reference to Razor syntax: C# Razor Syntax Quick Reference
Most likely, Razor considers IsCovered_#topic.StandardTopicId a valid e-mail address format, and therefore leaves it as-is.

Html.Hidden builds wrong value data in MVC 2 app

I am using an id value that I pass in a hidden field. When the user submits the form I need the hidden field for my update. After the update, a new value is placed in the hidden field in the model and sent back to the view. What seems so strange is the helper always uses the first value, never updates. For example, look at the following from the View:
<%: Html.Hidden("MyId",Model.MyId) %>
<%: Model.MyId %>
First time in a look at the source in the browser yields:
<input type="hidden" id="MyId" name="MyId" value="1" />
1
** submit back to controller and model updates the MyId property to 2.
Back at the browser I now find:
<input type="hidden" id="MyId" name="MyId" value="1" />
2
The very same model property has different values! The helper method is somehow grabbing it from a prior model instance or something?
Any help greatly appreciated on what I am not understanding. BTW..get the same behavior with Html.TextBox and Html.TextBoxFor.
Thanks.
That's how HTML helpers work and it's by design. When binding they will first look at the value in the GET/POST request to see if the value is present and after that in the model. If a value is found in the request they will simply ignore the value you set in the model.
Normally you are not supposed to modify the data sent in the request inside your controller action. But if anyhow you decide to do it you will need to either roll your own helper or simply:
<input type="hidden" name="MyId" value="<%= Model.MyId %>" />

Resources