JSF Problem with selectInputDate overriding a set value - jsf

I have a problem with selectInputDate:
I have a backing bean which I am binding to the selectInputDate. I have a menu which, when the menu changes, I set the date to now to the same property the selectInputDate is bound to.
For some reason, the date changes correctly, but the selectInputDate then calls a set and overrides the value with the old value...
Any idea why selectInputDate would call the setter?
<ice:selectInputDate popupDateFormat="dd-MMM-yyyy" renderAsPopup="true" value="#{dateContoller.date}"/>
<ice:selectOneMenu value="#{dateContoller.dateRange}" valueChangeListener="#{dateRangeDateContoller.dateRangeChanged}" >
....
</ice:selectOneMenu>
(dateRangeChanged sets the current date to now)

The valueChangeListener is intend to run some code logic whenever the newly submitted value differs from the original value. But you're apparently actually not interested in the change of the value, you're actually interested in resetting the submitted value.
Just get rid of the valueChangeListener and do your thing in the bean's action method.
If that is not an option for some reason, then you need to elaborate more about the problem for which you thought that using a valueChangeListener is the right solution. There may be workarounds to keep the valueChangeListener anyway, such as calling FacesContext#renderResponse(), so that JSF won't run the update model values (and invoke action!) phases anymore, or using ValueChangeEvent#queue() to let it re-execute itself during invoke action phase.
To learn a bit more about the JSF lifecycle and when/why/how the one and other get called/invoked, you may find this practical article useful.

Related

Can JSF be configured to not invoke Entity setter unless the field actually changed?

When a JSF form field is wired into an entity bean field (which is mapped to a DB field), each setter in the entity bean is called regardless of whether the user changed the form field value in the front end, i.e. the setters on unchanged fields are invoked the same as those that have changed but their new value is the same as the old value.
My question is simple: Is there a way to configure JSF to only call the setters mapped to the fields that have changed in the front end? The reason for this is that I have a requirement by which I have to detect deltas on every persist and log them, more about which can be read in this question.
Maybe I didn't understand you clearly, but why are you mapping directly your entity beans to a JSF view ?! IMHO it would be better if you add managed beans between your JSF pages and the entities in order to better separate your business logic from data access.
Any way, I think the easiest solution to impelement for that case is by making use of Value Change Events which are invoked "normally" after the Process Validations phase (unless you make use of the immediate attribute).
The good news about Value Change Events (regarding your example) is they are invoked ONLY after you force form submit using JavaScript or Command components AND the new value is different from the old value.
So, as an example on how to use value change listeners, you can add valueChangeListner attribute to each of your JSF tags like following:
<h:inputText id="input" value="#{someBean.someValue}"
valueChangeListener="#{someBean.valueChanged} />
Then, implement your valueChanged() method to look something like:
public void valueChanged(ValueChangeEvent event) {
// You can use event.getOldValue() and event.getNewValue() to get the old or the new value
}
Using the above implementation, may help you to separate your logging code (it will be included in the listeners) from your managed properties setters.
NB: Value Change Listeners may also be implemetend otherwise using the f:valueChangeListener Tag, but this is not the best choice for your example (you can find some examples in the section below, just in case)
See also:
Valuechangelistener Doubt in JSF
JSF 2 valueChangeListener example
When to use valueChangeListener or f:ajax listener?

EL function not found in validator attribute

El function cannot be found using within validator attribute, which is dependent on dynamic or repeated values?
Function 'el:min' not found
#{el:min(a + b, c)}
<f:validateLongRange maximum="#{el:min(foo.bar, 10)}"/>
Just printing out the value is working where it is not working in the validator.
The error message Function 'el:min' not found was so misleading.
The problem was never the construct but it was an underlying NullPointerException on the nested property.
Since in one case the value was depending on a different component selection it was updated via ajax and the default value was null. Since the default value was null this misleading exception was thrown.
The value was a nested property, so it was not catched within the el function
Solution: disable the validator on default
<o:validator validatorId="javax.faces.LongRange" maximum="#{el:min(foo.bar, 10)}"
disabled="#{foo eq null}"/>
This construct should work just fine. The problem is most likely the scope of the variables which you've there and the timing (i.e. when do you need them? when are they "behind the scenes" changed?).
You need to understand that taghandlers like <f:xxx> run during view build time (like JSTL <c:xxx>). So their attribtues are resolved during view build time and would be filled with bean's default values. Perhaps you're performing some business logic on them while submitting the form and expecting that they would be reflected into the taghandler attribute. But this is not true. They were already evaluated during view build time and won't re-evaluate the values during processing the form submit.
If this is indeed the case, then you've basically the same problem which is already outlined and answered with various possible solutions in this answer: How to set converter properties for each row of a datatable? Apart form homegrowing a Validator for this, you could use OmniFaces <o:validator> for this:
<o:validator validatorId="javax.faces.LongRange" maximum="#{el:min(a + b, c)}" />

Jsf always remove last element from ArrayList

I have an ArrayList in a backing bean and his rendering in JSF page with c:forEach. When iI remove the ArrayList element by index, jsf, no matter what index is, always removes the last element. Why happening this?
Remove button in JSF is :
<a4j:commandButton immediate="true" action="#{bean.removeEntry}" ...
So i use immediate attribute. I think problem is because immediate skips Apply request phase in JSF Life Cycle. Is possible?
If yes, than how run Apply request phase in this case ?
Are you using Facelets (.xhtml pages)? If so, you may be running into some common misconceptions about JSTL tags like <c:foreach>. Here's a good article on it:
https://rogerkeays.com/jsf-c-foreach-vs-ui-repeat
Basically, <c:foreach> is processed only when the view is initially built; it does not become part of the component tree, and can have some behavior you don't expect when the backing collection is changed. You may be better off using <ui:repeat> instead.
little more code would have helped, but immediate on command button is basically used for navigating away from current page as actionlistener or action will execute in apply request phase, typical case cancel button. This means you will not get updated value there.
If your logic depends on some other uiinput make that immediate and you can hook things in valuechangelistener.
But I doubt what you are trying to achieve can be done in better way, have a look at this link # SO
I was having the similar issue. I was using 'tr:iterator' to iterate over ArrayList'<'Customer'>'(); 'ui:repeat' solved my problem.
Thanks.

How to call an action method of a UICommand Component which was rendered conditionally?

action method is not called Please refer to this question - , One of my UICommand Component is rendered conditionally , it was said in the answer of the linked question - point 5 - that if the Component's or any of its parents rendered or disabled attributes are false - then the action method will not be called ? If thats the case- How do i achieve the same functionality? Is there a work around ? or a trick ? or any other approach ?
Thanks!
To the point, you'd like to retain the property responsible for the rendered condition in the subsequent request. There are several solutions for this problem:
Put bean in session scope. It's easy, but it hurts. It's bad for user experience since changes will be reflected in all tabs/windows the user has open in the same session.
Use <h:inputHidden> to transfer the property. In theory easy, but in practice it hurts as well. The value will namely get lost whenever a validation/conversion error has occurred in any of other inputs in the same form. This is an odditity in how JSF handles hidden input elements. A workaround is to use <h:inputHidden binding="#{bean.hidden}"> and do a hidden.getValue() and hidden.setValue() in bean.
If you're using <h:commandLink> instead of <h:commandButton>, then you can use <f:param> to transfer the property. It will be available as request parameter, you can check for it in bean's (post)constructor.
Use Tomahawk's <t:saveState>. The perfect solution as far. This will retain the value (or even a complete bean) in the subsequent request.
If you're already on JSF 2.0, the #ViewScoped would have solved this all. It behaves like the <t:saveState>.
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated
The trick is to have 'rendered' evaluate to true when it is time to run the action and then change the condition to false in the action method.
Let's say you have a link rendering based on a boolean in your bean called 'editing'. Then your action would look something like this:
public String myAction() {
// whatever you want your action to do
editing = false;
}
Edit: this assumes that the bean is either session scoped or the boolean get propagated between requests.
In my case, Javascript came for rescue, Which means, whatever was to be displayed conditionally , put them in a HTML Portion and don't display them display: none until the desired event occurs.
HTML Portion can have any JSF Tags(including CommandButtons) as you wish and would work (invoking the action methods and the stuff )perfectly okay.

Between a jsf page and a managed bean, why the getter method is called twice

I have a jsf page with a form has an outputtext in it. The value of outputtext component is called from a backing bean (or managed bean). I know when I code it as #{MyBean.myString}
Jsf rename it and calls getMyString() method. However the wierd thing is, when I put a breakpoint to the getter method of this component, I see it is called twice during the page is being rendered.
The outputtext is in a h:form, and it is the only component wich is bind to a backingbean. I mean, it is so wierd that jsf should get the value when it first come to the getter method, however it needs to go to the getter method twice.
Can you explain what is the reason of this behaviour in jsf?
Any help would be appreciated,
Best wishes,
Baris
The getter, as its name already self-describes, is just there with the pure purpose to retrieve the data. JSF doesn't cache this data. It will call it whenever needed. The cost of calling a getter is in practice nihil --unless you do something more than returning the data, e.g. hitting the DB everytime, this logic should then be moved out of the getter or be turned into lazy loading.
In case of a form submit, the first get call is usually fired during validations phase to check if there is any initial value so that JSF can handle the value change event. The second call is usually fired during render response phase to display the model value in the view.
You may find this article useful as well to learn more about the JSF lifecycle. You may find this answer useful to learn more about ways to do preprocessing/initialization in a backing bean.

Resources