Thymeleaf - Add attribute without value - thymeleaf

In Thymeleaf I would like to generate following HTML
<span data-my-attr>
</span>
I would like to display data-my-attr conditionally, but there seems to be no way how to display or NOT to display an empty attribute conditionally.
In case of required attribute there is th:required but for custom attributes there is nothing.
I tried to use th:attr="'data-my-attr'=${value}" and value is true or false, but it does not work.

Let's assume condition is true when your attribute should be shown and false when it shouldn't. You can have following:
<span data-my-attr th:attr="${condition} ? 'meaningless' : 'data-my-attr'=''"></span>
Explanation:
According to this thread when you specify the empty value for an attribute within th:attr then Thymeleaf will delete this attribute. So in above snippet:
data-my-attr is added by default.
The empty value is assigned to an attribute using th:attr.
The name of the attribute overriden with empty value is selected accordingly to ${condition}.
When ${condition} is true then data-my-attr should stay so any meaningless name (not present within the tag) should be picked.
Otherwise data-my-attr should be deleted so this name is picked.
Feels hacky but such a way of attribute removal seems working since 2012. Therefore I'd consider it stable.

Related

difference between Html.HiddenFor & HiddenInput attribute

HiddenFor description is:
Returns an HTML hidden input element for each property in the object that is represented by the specified expression.
I read that it is useful for fields in your Model/ViewModel that you need to persist on the page and have passed back when another call is made but shouldn't be seen by the user.
HiddenInput description is:
Represents an attribute that is used to indicate whether a property or field value should be rendered as a hidden input element.
Can you please tell me when is HiddenInput useful? and when to use it instead of Html.HiddenFor?
Thanks!
HiddenFor is determined by the view - the view creates a Hidden input value from any element of the viewmodel or data.
HiddenInput is an attribute on a field in the (view)model - which means that it can be used across multiple views and indicates that this field should be hidden wherever it is rendered by an EditorFor helper

asp.net mvc disabled text box updated by javascript does not post new value

I am using a strongly typed model for my view. I have a disabled text box whose value I update using javascript. The textbox is rendered using this
<%: Html.TextBoxFor(model => model.TotalAmount, new { disabled = "disabled"})%>
This renders a textbox with NAME and ID as 'TotalAmount'. TotalAmount is also a property on my model that binds to this view.
The javascript to update its value in the view is like this within its function:
document.getElementById('TotalAmount').value = {assigning new value here};
The function does get called and I can see the value in the disabled textbox when I change some value in another editable textbox. However, when I post this form to my action method as below :
[HttpPost]
public ActionResult Process (ProcessVM FormPostVM)
{
}
the disabled textbox property [TotalAmount] still has the old value but the editable textbox which I modified contains the new value I entered. Why does the disabled textbox not contain the javascript updated value?
I tried using
ModelState.Remove("TotalAmount");
in the action method above, but as I already figured it didn't work.
Any clues, tips?
Thanks for your time....
HTML input elements such as textboxes that have the disabled="disabled" attribute will never send their values to the server when the form is submitted. If you want to send the value to the server while still disabling the user from changing it you could make the textbox readonly:
<%= Html.TextBoxFor(model => model.TotalAmount, new { #readonly = "readonly" }) %>
Disabled inputs are never sent in a form submit, try using readonly attribute instead or hidden inputs
Disabled fields don't get posted. Try having a hidden form field that will send the value to the server, and set both TotalAmount and the hidden form field. On the server, use the value for the hidden field instead.
On a side note, since this looks like the order total, this is something I would recalcuate on the server rather than opening up the possibility of someone hacking the html and getting a discount on their product.
EDIT:
To the other's points, I'd forgotten about the readonly attribute. That will work too.
If you change it to use readonly rather than disabled, then this should give you the same functionality, but post the value.
Browsers don't post values back in disabled input controls, as you've discovered. Probably the easiest way to work around this is to hook onto form submission, and re-enable the input as the form is being submitted; the user won't have a chance to edit the value, and it should get posted with the rest of the request.
i think the last issue described it : please check it out :
Retrieving the value of a asp:TextBox

GSP- Select tag. How to achive selected="selected"

I have a select tag in my GSP file as
<g:select name="clientId" id="clientId" size = "4" from="${com.springcommunity.fleet.partymodel.roles.ClientRole.list()}" class = "filter_combo" optionKey="id" />
i want client with id 2 is selected initially (in simple html it is achived by using selected="selected")
how can i do it?
You need to specify the value attribute in this tag. http://grails.org/doc/2.0.x/ref/Tags/select.html
So in your example,
<g:select ... value="${com.springcommunity.fleet.partymodel.roles.ClientRole.get(2)}" />
One thing to be aware of here is that the value that you're selecting must be an object equal to the item in the list, and not just an id - this is where a lot of people get tripped up. So you can't just say value='2', you need to specify the object in the list that you have in your from attribute.
From the docs -
value (optional) - The current selected value that evaluates equals()
to true for one of the elements in the from list.

How to mimic MVC's checkbox -> bool model binding?

I've got an editor template which renders out a checkbox:
#Html.CheckBoxFor(model => model.Follow)
Which renders something like this:
<input checked="checked" data-val="true" data-val-required="The Follow field is required." id="Follow" name="Follow" type="checkbox" value="true" />
<input name="Follow" type="hidden" value="false" />
AFAIK the hidden field is something to do with catering when an unchecked box isn't sent to the server or something.
Anyway, if i take a look at the Request.Form["Follow"] when the checkbox is checked, i see a value of "true,false".
How do i coerce a bool from this value? Do i simply ignore the second field? (e.g the hidden field).
I'm doing this is a base controller (protected method, invoked from child controller), so i don't have a strongly-typed view model, only the raw Request object.
Can anyone help? Or alternatively, if someone could point me to where in the MVC source code this happens, i could take a look myself, but not sure where to start looking.
You are correct the hidden field is just so the form will be submitted to the server. Because if the form had just checkboxes that are not checked then nothing will be submitted and the server would not know to set them to false.
You only require 1 hidden field per form, you do not need one per checkbox. But if your making your own control it is hard to tell if a hidden textbox is already on the field or not. If you know you are always going to have a textbox or select list etc somewhere else on your forms you do not need a hidden textbox at all
You can rename your hidden textbox to anything name it "dummy" or something different to the checkbox name so Request.Form["Follow"]; will only return the value of the check box not need to split. You never need to check the value of the "hidden textbox".
On a side note you shouldn't be using Request.Form["Follow"] you Action method should have a parameter like this instead "bool? follow"
MVC helper renders checkbox input control with two input fields, the checkbox and the hidden, because the browser do not send a value for checkbox input field if the checkbox is not selected. If you do not use auto mapping, you need to parse the input value that you receve from your form.
Use this simple rule to detect the checkbox:
var rawFollow = Request.Form["Follow"];
if (rawFollow.Contains("true"))
{
// do something
}
As far as i know, the extra hidden field is because if the checkbox is NOT checked, that input will not be submitted with the form and therefore we need the hidden field with the value of false.
So the only solution is can think of is this:
var rawFollow = Request.Form["Follow"];
var rawFollows = rawFollow.Split(',');
if (rawFollows.Count() > 1)
{
rawFollow = rawFollows[0];
}
But this seems hacky (and what about the order of the elements on the page, what if for some reason the hidden field was FIRST, then it would always evaluate to false), which is why i'm wondering how the MVC source does this.

Grails hasErrors method with ternary operator?

I'm developing application using Grails framework and I'm having problems with hasErrors when invoked as a method from a gsp view.
I have a form that get's populated by values from a database (default values). Those values are stored in a session object. Users can edit values in form fields and send results back to the database. Before data gets persisted I have a command object that validates data. If there are errors command objects renders view with the same form and errors highlighted.
What I'm trying to do is to have form fields populated by values stored in a session object unless there are errors from command object. In that case field(s) should be populated by the wrong values entered by the user.
Here's the code snippet:
<g:textField name="somename" id="someid" value="${hasErrors(bean: commandobject, field: 'somename') ? fieldValue(bean: commandobject, field: 'somename') : session.somevalue}" />
Problem with above code is that no matter the value entered in the field, whether be right or wrong, field always ends up with the value from the session object. Is there a solution to this or am I doing something wrong in the first place?
When you call hasErrors like that you're invoking the <g:hasErrors/> tag which doesn't return a boolean value - it looks at the condition and conditionally invokes the tag body. Under that description, it makes sense why it's behaving the way it is.
What I'd recommend is to create your own TagLib and use commandobject.errors.hasFieldErrors('somename') [docs] in your condition (to get the boolean value you're looking for).
The hasErrors as a method call in GSP works a bit differently than as a tag <g:hasErrors>. The former is intended to set CSS class in divs or spans etc...
e.g. <div class="prop ${hasErrors(bean:parent, field:'child.name', 'errors')}">
where errors is the CSS class name. So if you don't specify the output string, it seems to return false by default, so to workaround your case, return '1'. So your code should look like:
<g:textField name="somename" id="someid" value="${hasErrors(bean: commandobject, field: 'somename', '1') ? fieldValue(bean: commandobject, field: 'somename') : session.somevalue}" />
This will also work with logical operations in <g:if>

Resources