Why does rich:inputNumberSlider does not update backing bean (#Managed Bean) - jsf-2

The inputNumberSlider of Richfaces fails in my case to immediately update the backing bean. The setter method is never invoked. I'm right in saying, that backing bean field should should be updated on change?
<rich:inputNumberSlider
id="severityLevel"
value="#{pubController.severityLevel}"
minValue="1"
maxValue="3"
maxlength="1" />
I did set a breakpoint in the setter method, but it never rises. I must say, it works properly for all the h:inputText tags.

The setSecurityLevel setter will never be invoked till you submit the form where your rich:inputNumberSlider is contained.
Alternatively, you can set the value whenever the inputNumberSlider is changed, adding an ajax per event processing, which will execute your component (I don't use richfaces, but that would be the desired format):
<h:form>
<rich:inputNumberSlider id="severityLevel" value="#{pubController.severityLevel}"
minValue="1" maxValue="3" maxlength="1" >
<a4j:ajax event="change" execute="#this" />
</rich:inputNumberSlider>
</h:form>
Generally, that kind of behaviour is unrequired unless you want to perform some kind of validation while user is changing the input value (it also could be useful to render dependent components). In most of the cases the validation is performed over all the components once you post the whole form.

Related

What are the downsides of using binding in order to update a JSF component?

Consider this xhtml piece.
<p:dialog id="consumerDialog"
widgetVar="dealerDialog" modal="true">
<h:panelGroup binding="#{cdContent}">
</h:panelGroup>
</p:dialog>
<p:dialog id="dealerDialog"
widgetVar="dealerDialog" modal="true">
<h:form>
<p:commandButton value="Close"
onclick="PF('dealerDialog').hide()"
update=":#{cdContent.clientId}"/>
</h:form>
</p:dialog>
In the dealerDialog component is a p:commandButton which updates the h:panelGroup component inside the consumerDialog where the id of the updated component is obtained through binding. I sometimes do this to save pains figuring out the actual id of the target component (especially for complex views).
Are there any downsides or risks if I do it this way?
Are there any downsides or risks if I do it this way?
Only if the EL variable represented in binding, which is in your case #{cdContent}, is shared by multiple components in the same view. E.g. when the given code snippet is included multiple times in the same template via <ui:include>, tagfile or composite. Or even when there's a managed bean on that name. It doesn't apply in your case, but it would for sure fail if the binding attribtue references a session scoped bean property.
There are no risks if you make absolutely sure that #{cdContent} is exclusively used by only one component in the entire view.
See also:
How does the 'binding' attribute work in JSF? When and how should it be used?

Performing logic with state with a JSF ui:repeat loop

I'm pretty new to JSF / Facelets and trying to understand where best placed to put logic when deciding whether to render content within a ui:repeat component.
In my backing bean I have a list of messages each one containing a date. I want to print all messages but only render the date when it changes.
Currently I have something like below where the backing bean getter method determines whether or not to render the message date based on logic and setting state within the backing bean.
<ui:repeat value="#{bean.orderedMessages}" var="message" varStatus="messageLoop">
<h:panelGroup rendered="#{bean.isDateRendered(messageLoop.index)}">
#{message.formattedDate}
</h:panelGroup>
// some other stuff for each message
</ui:repeat>
This is buggy and horrible since JSF calls the getter method many times before actually rendering which adds further complexity to the getter method, the code has nothing to do with the anything other than whether something should be rendered or not which should really be in the UI and the getter method has a whole bunch of nasty logic in it whereas I would prefer a simple property to be returned.
I believe the UI has to somehow store the state of the last rendered date and compare that against the one it is about to render but I'm not sure whether that's correct.
I don't believe this is an uncommon problem. Does anyone know if there is a more elegant solution to solving this?
From the thoughts raised by BalusC in the comments of the question, I have implemented the following solution.
My Message object from the entity/domain layer is returned to the backing bean when the instance is created #PostConstuct, I have created another model in the UI layer called UIAugmentedMessage which takes the Message in the constructor as well as a boolean property for isRendered and a String for the formatted date.
The backing bean builds the list of UIAugmentedMessage objects when the Message list is returned from the server just after the bean is constructed and this contains the correct state for the isRendered and formattedDate fields.
The UI layer is now simplified as follows
<ui:repeat value="#{bean.orderedMessages}" var="message">
<h:panelGroup rendered="#{message.rendered}">
#{message.formattedDate}
</h:panelGroup>
</ui:repeat>

How do you pass a Managed Bean of different type to a composite for reuse?

I'm creating an inline text editor. I've written the code to edit one single h:ouputText field (h:inputHidden). Works. Thus, I thought I create a composite (widget), that I can call for every field I want to update. Of course, those fields refer to a managed bean in my case, that is the PubController MB.
<composite:interface name="inlineEditor">
<composite:attribute name="attrOfMb" required="true"
type="java.lang.String" />
<composite:attribute name="pubController" required="true" type="com.playground.webapp.controller.PubController"/>
</composite:interface>
Now, I have the following tasks to accomplish:
pass the MB to the composite (done).
in the composite, create the div and the hidden input field with id of the MB attribute.
Challenge where I struggle:
How do I "bind" an attribute of the passed PubController to the hidden input field? #{cc.attrs.pubController.title}? Well, it should not always be the same attribute. The attribute should be chosen by what has been passed in the interface attribute attrOfMb.
In other cases, its not necessariley PubController. Might be another MB. My initial thought was to define the interface type to javax.faces.bean.ManagedBean. On the other hand, how could you then "bind" the passed MB to the input hidden field (respectively vice-versa).
Is there a JSF-Pattern on how you accomplish these things?
You're going in the wrong path as to designing the composite. You should bind a bean property, not a whole bean.
I.e. you should not have
<my:composite bean="#{bean}" />
but you should have
<my:composite value="#{bean.value}" title="#{bean.title}" />
Once you fix that problem, then you can easily reuse it on any backing bean. Please note that this is also the way how standard JSF <h:xxx> components work. If you worry about about "too many" attributes for some unclear reason, then just create a reusable model class which in turn can be a property of the backing bean.
<my:composite data="#{bean.data}" />
This way you can use it further in the composite as #{cc.attrs.data.value}, #{cc.attrs.data.title}, etc.
If you really, really need to bind a whole bean, then I'd question if a tag file or maybe an include file isn't a better solution for whatever functional requirement you've had in mind. A composite component should really represent a component with a single responsibility and a single point of model value binding.
See also:
When to use <ui:include>, tag files, composite components and/or custom components?

OmniFaces o:validateAllOrNone in ui:repeat or h:dataTable

Is it possible to use OmniFaces <o:validateAllOrNone> (which is pretty cool ;)) within an <ui:repeat> or <h:dataTable>?
I need a table with each row having an input field column. You could either fill in none of these values or all of them.
If I put the <o:validateAllOrNone> within the <ui:repeat> or <h:dataTable> and use the id of the input field in components attribute, then the validator also gets triggered, if all fields are empty.
No, that's not possible. The components attribute must refer physically multiple components, not a single component which is rendered multiple times. It can however be used on physically multiple components which are rendered during same iteration round. The <o:validateXxx> multi field validator is not designed to reference a single component which is rendered multiple times. The only OmniFaces validator which does that is <o:validateUniqueColumn>.
If you want to use the <o:validateXxx> multi field validator on dynamic inputs based on a collection, then your best bet is to use JSTL <c:forEach>. It will build physically multiple components.
E.g.
<c:forEach items="#{bean.items}" var="item" varStatus="loop">
<h:inputText id="input_#{loop.index}" value="#{item.value}" />
</c:forEach>
Assuming that there are 3 items, this will dynamically create JSF components with IDs of input_0, input_1 and input_2. Then you can just use <o:validateXxx> as follows (put it outside the loop!)
<o:validateAllOrNone components="input_0 input_1 input_2" />
You can replace the hardcoded string in the above example by an EL expression which returns the desired space separated string of component IDs from a backing bean.
<o:validateAllOrNone components="#{bean.inputIds}" />
An alternative would be to create a <x:validateAllOrNoneColumn> yourself or to post an enhancement request at OmniFaces issue tracker. It would be not exactly trivial to alter the existing <o:validateAllOrNone> that a completely separate component is desired.

JSF 2.0 - how to get the property path of a jsf component?

is there a way to get from a JSF component the property path which is obviously used for updating the model?
I am asking cause we have a concept where the backend validates the whole stuff. Don't ask why but I am not allowed to use JSF build-in validation.
The backend provides ValidationException if for example a property is null but should not be null and the ValidationException contains a list of ValidationInfos containing the full property path for the property the validation info belongs to.
My task is to find a way to map back this info to the corresponding JSF component to be able to show the message for the correct JSF component.
It is allowed for me to register/attach some kind of little helpers to the component to make it easier for mapping back the infos.
My first approach was to write a tag handler and in the tag handler to find out the property path and the root bean. But I am lost there cause we are also using JSF 2.0 components with deferred value expression so I see at the moment a value expression like vor example #{cc.attrs.value} but I am interested in the "caller" expression like for example #{aBean.street} which is obiously the property path for updating the model.
<composite:interface>
<composite:attribute name="value" required="true"/>
</composite:interface>
<composite:implementation>
<h:inputText value="#{cc.attrs.value}" styleClass="#{!component.valid ? 'col2 error' : 'col2'}">
<my-components:registerTagHandler value="#{cc.attrs.value}"/>
</h:inputText>
</composite:implementation>
Maybe there are other approaches or other ideas out there. It would be helpful for me to get some hints/ideas.
Best Regards,
Walter
PS: sorry for my crude english cause I am not a native english speaker.

Resources