inputHidden binding to a long id field in backing bean - jsf-2

Just wondering how to set a hidden field value so that when I submit my form, JSF sets it as the id in an object in my CDI-managed bean.
My bean is called "discussionManager" and it has an object in it called 'discussion', which is an entity and therefore has an ID of type Long.
I need the ID so I can look it up and do stuff with it. But, JSF doesn't seem to like numeric hidden fields. It is fine with string fields though. Sure it has something to do with converters or the binding attribute, but can't get the syntax. This is what I'm trying in it's simplest form.
<h:inputHidden id="discussionId" value="#{viewDiscussionBean.discussion.id}"/>
I've tried lots of variations. Can anyone point me in the right direction please?
Thanks

You indeed need to explicitly specify a converter. The JSF builtin LongConverter is suitable.
<h:inputHidden id="discussionId" value="#{viewDiscussionBean.discussion.id}" converter="javax.faces.Long" />

Related

Thymeleaf th:field model evaluation

I'm including dynamic content to a view using a custom Thymeleaf attribute processor that simply adds additional nodes while processing the attribute itself.
The code I use is very similar to the one below:
final Template template = arguments.getTemplateRepository().getTemplate(
new TemplateProcessingParameters(arguments.getConfiguration(), "name-of-a-view", arguments.getContext()));
final List<Node> children = template.getDocument().getChildren();
// Add to the tree.
for (final Node node : children) {
element.addChild(node);
}
This works fine, but breaks when the included nodes contains forms that use th:object and th:field.
I put the model I need inside the node variable map and in fact th:object does find and retrieves the object, but th:field does not seems to care and breaks with a
Neither BindingResult nor plain target object for bean name 'model' available as request attribute
From my understanding (step-by-step debugging), it seems to me that th:field only search for the model in the request context.
Am I missing something here?
Thank you in advance.
No, you're spot on. I'm still not sure why the binding is different for th:field than other th: attributes, but it definitely works differently. Essentially, you can't use th:field unless your th:object is on the model. The workaround is to stop using th:field and just specify your input attributes manually, like:
<form action="#" th:action="#{/process}" th:object="${objectFromList}" method="post">
<input type="text" id="fieldName" name="fieldName" th:value="*{fieldName}" />
</form>
I realize this post is old. Hopefully, this will help someone who is running into this quirk.

Dynamically added option in SelectOneMenu control on a JSF form submits as null

I have a standard JSF h:form which contains an h:SelectOneMenu control. As long as I am selecting an item from the list which is populated when the page is rendered it works perfectly. I don't think it is important, but to put it in context, the value from the select is used to build a query which returns a list of matching records.
I've implemented the JQuery autocomplete box on the control and it still works just fine as long as I'm selecting one of the original values.
The problem comes when I enter a value not in the select control when the page is rendered. Using JQuery, I've set it up so that when a value not on the list entered, the value is added to the select as a new option.
I can verify that the option is added to the underlying select control, and selected through the javascript. However when the setter is invoked in the backing bean immediately after that, the value passed in to the setter is null, and the function to run the query is never reached. The following error is returned in the AJAX response, but I have yet to be able to find a place where the value is validated. It isn't a required field either.
Validation Error: Value is not valid
Here is my front end code:
<h:selectOneMenu id="make" styleClass="combobox" value="#{listBean.make}"
effect="fade" label="#{listBean.makeLabel}" >
<f:selectItems value="#{listBean.makeList}" />
</h:selectOneMenu>
And the setter in the bean:
public void setMake(String make) {
this.make = make;
}
I'm guessing I just need to find a way to include the new option in the makeList List on the backing bean, but I'm not sure how to do that. Any help or suggestions would be appreciated.
Java EE 6, GlassFish 3.1, Eclipse 3.7 - problem observed on both FireFox and Chrome
You need to provide the dynamically added item through <f:selectItems>, not through JavaScript. If the item is not present in <f:selectItems>, then you will get exactly this validation error. This is done so as part of safeguard against tampered/hacked requests in an attempt to get illegal/unprovided values into the server side.
Easier is to use a JSF component library. PrimeFaces for example has a <p:autoComplete> for the exact purpose.

How do I break the tyranny of the clientID?

My least favorite part of coding JSF 2.0 forms has to do with the handing of the id attributes of the various input elements. I am forever having trouble coding the clientID of the target component from within the backing bean, particularly since PrimeFaces tabView now includes the id of the p:tab element as part of the clientID. I waste tons of time coding, testing, then re-coding those clientIDs.
It is reminiscent of older-style assembly language programming where you have to generate tons of label names for your branches and loops. I've done of enough of that for a lifetime.
One approach I am trying is to use only auto-generated id attributes. For example one line of my form might look like this.
<h:outputLabel value="Full Name:" />
<p:inputText value="#{editUser.user.fullName}"
binding="#{editUser.compFullName}"/>
<p:message for="#{editUser.compFullName.clientId}" />
Note that I do not have an explicit id attribute. Then in the backing bean:
String clientID = getCompFullName().getClientId();
msg = new FacesMessage(FacesMessage.SEVERITY_INFO,
"Summary Message For Full Name", "Detail Message Full Name");
FacesContext.getCurrentInstance().addMessage(clientID, msg);
This always works, even if the component has a complex clientID, such as when PrimeFaces inserts the p:tab id into the clientID. (Which it does starting v 3). Rearranging the form never breaks anything.
It is, however, laborious, since I have to create UIComponent properties, getters and setters, and bind them in the form with binding attributes. Can anyone suggest a better way of doing this?
since I have to create UIComponent properties, getters and setters, and bind them in the form with binding attributes. Can anyone suggest a better way of doing this?
It's not required to bind the component to some backing bean if you don't use it in there at all. Just bind it to the view instead:
<p:inputText value="#{editUser.user.fullName}"
binding="#{compFullName}"/>
<p:message for="#{compFullName.clientId}" />
To make the code more self-documenting, I suggest to put a HashMap in the request scope by faces-config.xml:
<managed-bean>
<description>Holder of all component bindings.</description>
<managed-bean-name>components</managed-bean-name>
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
with
<p:inputText value="#{editUser.user.fullName}"
binding="#{components.fullName}"/>
<p:message for="#{components.fullName.clientId}" />
Adding messages is supposed to be done by a Converter or a Validator which is trowing it as a ConverterException or ValidatorException respectively. It will automatically end up in the right message holder. Or if it are informal messages, just add it on the client ID of the UIComponent which is already available as method argument.
See also:
JSF component binding without bean property

How to persist JSF view parameters through validation

I am using JSF 2.0/CDI and PrimeFaces 2.2.1 for a number of CRUD forms that let the user view or update the attributes of an existing entity by clicking on a link in a datatable, where the identifier of the entity is passed to the CRUD form as a View Parameter. I display the entity's ID (often just an integer) on the CRUD form in a PrimeFaces InputText field with the readonly attribute set to true (since I can't let them change it), so the user knows which entity they're editing. The backing bean of the CRUD form is RequestScoped, which works fine except when validation fails. In that case, the value of the View Parameter is lost, so a 0 is displayed in the entity ID field on validation failure.
I am able to maintain the actual entity ID in a hidden field so it's available to update the database once validation succeeds, but it's rather maddening that I've not been able to find a way to maintain the value in a visible field of some sort after a validation failure. Ideally the InputText field would retain its functionality as an inputted and validated field even with its readonly (or disabled) attribute set to true, which would let me forgo the hidden field entirely. But it doesn't appear that I can make it work that way. Any suggestions besides making the backing bean ConversationScoped, which I'd prefer to avoid?
Actually, after stating what I'm looking for a little differently in a Google search I found a novel suggestion at the link below that seems to work cleanly. Instead of making the entity ID field readonly or disabled, I leave it enabled but blur it as soon as it receives focus. I'm able to get rid of the hidden field, the user can't change the value and it survives a validation failure.
<p:inputText id="entid" value="#{RequestBean.entityID}" onfocus="blur();" />
http://www.codingforums.com/archive/index.php/t-1738.html

grails list.gsp / g:sortableColumn: being able to sort on associated domain objects

Lets say I have an Issues domain class and it has as a field assignedTo:
String title
String priority
User assignedTo
...
I need to be able to sort on assignedTo. Neither the list.gsp default scaffolding nor the tag it uses, g:sortableColumn, support this. It seems like the g:sortableColumn needs to have both a property field, and a propertyOfProperty field.
Do you know a good way to solve this?
Ok, so this appears possible, just missing clarity in the documentation, and searching the web didn't help.
So, one can do property="assignedTo.lastName", i.e.
<g:sortableColumn property="assignedTo.lastName" title="${message(code: 'issue.assignedTo.label', default: 'Assigned To')}" />
Ray's solution will work but if assignedTo is a nullable field, any results with assignedTo set as null won't show up in your result list
This grail's solution is a workaround:
http://www.grails.org/version/GSP+Tag+-+sortableColumn/2
Of course if it is a required field, or you don't care about not showing results without the assignedTo variable then use property="assignedTo.lastName"

Resources