Null value submitted for a conditionally disabled field in a reusable JSF popup - jsf

I have a popup dialog developed in IceFaces 1.8.x (JSF 1.2).
The dialog is reusable (used for account creation as well as modification) and has a cancel button with immediate = true (to avoid validations). This dialog suffered a problem in the past ,where old values were rendered on re-opening the dialog, but that problem is now fixed as directed here (by setting submittedValue to null etc.).
The problem that I am facing now is specific to a conditionally disabled input field (<ice:inputText>) and here is what happens:
The popup is first opened (say for account creation) and this field
is NOT disabled.
User then cancels this dialog and, as we have incorporated the fix mentioned above (setSubmittedValue(null)), the submittedValue for this field is set to null (along with other fields).
Now the user opens "modify account" dialog, where in this field IS disabled. Everything seems to be rendered fine until user makes any changes to the form.
When user changes some field (say name) in the form, a partial submit happens for the name field as expected, but along with it null value is submitted for this disabled field.
This problem can be worked around by adding a null check in the setter method for the field in question, but this is not the desired solution for the project - as there are multiple places where this could be needed and doesn't seem like a very intuitive thing to do.
So I need to understand:
Why is the setter for this disabled field getting called in the
first place? and that too with a null value. The setter is not
called for any other enabled fields.
More importantly, is there any way to fix this (other than adding null check in the setter)?

You must be using rendered attribute to show/hide the dialog
<ice:panelPopup modal="true" rendered="#{bean.enabled}">
When dialog is reopened, it is coming up with some residual values from previous instance
The solution (or workaround) is to use <c:if> instead of rendered attribute, this way the DOM is completely destroyed when dialog closes and created from scratch when dialog opens
<c:if test="#{bean.enabled}">
<ice:panelPopup modal="true">
...
</ice:panelPopup>
</c:if>
This way you even would not need the fix to set submittedValue to null

Related

Incorrect view update after validation error

View looks like this:
form (can have only one checkbox selected)
----------------------------------------
checkbox_1 (on value change clears checkbox_1 and checkbox_2 values in the backing bean and updates form**. new checkbox_1value is set after all checkbox values are cleared)row_checkbox_1(rendered only ifcheckbox_1` is checked)
checkbox_2 (on value change clears checkbox_1 and checkbox_2 values in the backing bean and updates form**. new checkbox_2value is set after all checkbox values are cleared)row_checkbox_2(rendered only ifcheckbox_2` is checked)
saveButton (on click updates formand a separate messages component)
---------------------------------
Lets state checkbox_1 is selected meaning that row_checkbox_1 components is also visible. Also there are errors in row_checkbox_1 fields.
After saveButtonis pressed the errors are displayed.
Problem: pressing/checking checkbox_2 updates backing bean - checkbox_1 value field in the backing bean gets set to false (debugged and verified by looking at getter) and checkbox_2 value field is set to true. However view does not update correctly since checkbox_1 is rendered as checked while row_checkbox_1 is not rendered at all. Remember row_checkbox_1 is rendered only if checkbox_1 is true. checkbox_2 is rendered and checked as it should be and row_checkbox_2 fields are visible as it should be.
I'm doing all this in PrimeFaces 6.0
ajax attribute restValues="true" helped. Maybe someone could do an explanation why this situation occurs? Would gladly give answer point to them!

h:inputText and h:outputText show different values for same (EL) field

I've got a very strange problem here. I have a rich:popupModal which is used to edit an entity. Some of the input fields on that modal use a validator. There is also some ajax going on which is used to update other fields on that modal. There is e.g. a 'Number of packages' field, a weight per package field and a total weight field. If you change the number of packages it will update the total weight field, etc.
Now when e.g. the user entered a value that is too high, the validation fails, an error message is shown. The user can either correct the values on the modal or press cancel.
When he cancels the entity is reset to the values it had before the edit (there were some ajax changes so I need to reset those). The modal closes and a table is showing the correct (reset) values for that entity.
Now the strange thing happens. When I edit another entity the modal is suddenly showing the old values for the previous entity (the ones that did not pass validation).
To debug this I was checking whether the correct instance of the commodity is used so I added h:outputText fields for some of the values and I am also showing the System hash of the entity on the modal.
I've got e.g.
<h:outputText value="#{backingBean.entity.description}"/> which prints 'Stuff 1'
and then
<h:inputText value="#{backingBean.entity.description}"/> which prints 'Stuff 3' (the first entity I've edited). WTH?
I've added getter and a dummy setter on the entity to return the System.identityHashCode. And h:outputText and h:inputText use indeed a different entity but how is that possible when the EL is #{backingBean.entity.hashId} in both cases?
I've used the richfaces a:log to see whether that shows any errors but it all looks okay.
I have tried to clear the modal on cancel (rerender it with no components in) but that didn't fix the problem either. I've tried it on both Chrome and Firefox. Both have the same problem.
What could be going on here?
My environment: JSF 2, Seam 2.3, RichFaces 4.3.3, JBoss EAP 6.1

Set current displayed tab programmatically in p:wizard

Is it possible to set current displayed tab programmatically in <p:wizard>?
For example, I want that for two different request to the same page which contains a wizard, to have a different tab selected.
What I am currently trying to do, is to have a wizard with many tabs, in the second tab I have a redirection to another page, so when I come back I want to come to the last step which caused the redirection.
Can you please help me ? Thank you a lot !
According to primefaces documentation there's a step attribute for p:wizard tag, which specifies the step of the wizard you're currently in.
attribute: step
default value: 0
type: String
description: Id of the current step in flow
You must bind this attribute to a value of your backing bean and maintain it during redirection and coming back. If your wizard's bean is #ViewScoped you'll loose that info during redirection step, so you have to pass it using a view param or flash scope.
My answer would most probably not meet your complete requirements, but, nonetheless, it may point you towards solution to your problem.
As far as I know, the PrimeFaces Wizard UIComponent is designed for a workflow of one page. That effectively means that inputs will be handled by a backing beans that is in a view scope.
This way, making a redirection on a certain step will clear all data inputs, because your view changes and the old one is destroyed.
Anyway, a means of setting a current tab for display is step attribute of Wizard component. So,
<p:wizard step="#{wizardBean.currentStep}" >...</p:wizard>
will force the wizard to show you step which you specified in your bean. You may be able to get it by using, for example, a view parameter, like in
<f:viewParam name="step" value="#{wizardBean.currentStep}" />
But it will make sense if lifetime of your bean is more that for a view, for example, the bean could be put in session scope.
That said, maybe it is a better idea to do login beforehand. Or, if it is absolutely necessary to do it in step 2 of your wizard, provide for a built-in login functionality in a page itself, or in a popular window?
Also, programmatically the setting you speak of can be achieved via a binding of component to your backing bean and setting the step value in the backing bean, for example, in a preRenderView event.

what happens to jsf components after render attribute is updated

Given the following scenario : A jsf component's (e.g a CommandButton) render attribute depends on an application scoped managed property. Since the property is shared across all sessions, the following might easily happen : User A loads a jsf page and the button's render attribute is true, so it is rendered. Now user B also loads the page and the render attribute is still true. Now user A clicks the button which causes the property to change its value and the button is not rendered anymore. User B still has the old view and although the render attribute is false now, he can click the button because he didn't update his view in the meantime. What happens now if user B clicks the button?
I thought the button's action is fired anyway because the render attribute is just used for rendering the button and has no influence anymore, once the page is rendered. But after doing some tests it seems to me that the render attribute is also checked again after clicking the button and if the attribute is false then, the action is not performed. Can someone confirm this ?
Disclaimer: I'll ignore the strange design for now.
But after doing some tests it seems to me that the render attribute is also checked again after clicking the button and if the attribute is false then, the action is not performed. Can someone confirm this ?
Yes, that's correct. This is part of safeguard against possibly tampered requests wherein the hacker is trying to simulate the invocation of an action component which is actually not rendered by the server side (such as an admin-only command button which is only rendered when the current user has the admin role). The rendered (and disabled and readonly) attributes are always re-checked during processing the form submit.
In your particular case, you'd like to have a copy of the condition responsible for the rendered attribute in the view scope so that only this copy will be used as long as you're interacting with the same view. This can be achieved by just injecting the application scoped property as a managed property of a view scoped managed bean and then referencing it in the rendered attribute instead.
#ManagedBean
#ViewScoped
public class ViewBean {
#ManagedProperty("#{appBean.rendered}")
private boolean rendered;
// ...
}
with
<h:commandButton ... rendered="#{viewBean.rendered}" />

Using `immediate` for a cancel button but saving only some fields

I have a JSF 1.2 Form which is composed of several parts.
I have validation with required tag turned on.
I want to be able to clear a certain part of the form which has required fields so on the 'clear' button i used the immediate tag.
Now the challenge - When pressing the 'clear' button all the values that were filled since the last submission are restored to the last submitted state while I would like only the certain part of the form to be affected. (Meaning, all the values that are not in that part of the form should be sumbitted although the button pressed is immediate)
Is there a way to do this?
EDIT - Can I submit a value after every time it was filled? This might be a solution.
Thanks!
If you want to take some fields along with the cancel button with immediate="true", then you should also put immediate="true" on those fields.
If you want to skip validation on those fields as well, then you need to change required="true" to required="#{empty param['formId:cancelButtonId']}" so that it is only required when the cancel button is not been used to submit the form.
As to submitting the values on change, that's best to be achieved with ajax in combination with a value change listener. To achieve that you would need to upgrade to JSF 2.0 or to introduce an ajaxified JSF component library.

Resources