Prevent primefaces datatable select new row when validation fails - jsf-2

I have a master detail ui showing some items in a dataTable. If a item is selected the details are shown in a form.
If there is invalid data in the form I want to prevent that the user is able to select a new item from the dataTable. A validation already error is shown on the details side and the form is not updated when a validation error is existing (seems to be a bulit-in behaviour).
Unfortunately I wasn't able to prevent that the user can select another row in the dataTable. I tried:
<p:dataTable ...>
<p:ajax event="rowSelect" update="someId" />
<p:ajax event="rowUnselect" update="someId" oncomplete="if (args && args.validationFailed) return false;" process=":detialsFormId" />
...
</p:dataTable>
But this doesn't work. As I know only in oncomplete there is the args variable available. I think in both rowSelect and rowUnselect it is too late.
Maybe there is another approach? Thought about a remote command which sets the t-1 selection when validation failed. But maybe there's another fancier solution?
Regards
Oliver

Related

Display Item Label for drop down list, radio button, many check box and boolean check box instead of item value

I am working on a customer profile page that has various elements viz. h:selectOneMenu, h:selectOneRadio, h:selectBooleanCheckbox, h:selectManyCheckbox which are populated using master values from the database using List<MasterDTO>. The elements display perfectly when the page is in edit mode. However when the page is changed to view mode, instead of the selected item label being displayed, the selected item value is displayed. E.g. Need to display Single as Marital Status in view mode, instead it displays 001.
Please refer sample code below. I do not want to change the List object to something like a Map<K,V> across all the code. I am using JSF 2.0 and Primefaces 3.4.2. Is there a solution for this?
Select One Menu
<h:selectOneMenu id="marital_status" style="width:178px;"
rendered="#{customerProfileBean.editMode}"
value="#{customerProfileBean.marital_status}">
<f:selectItem itemValue="-1" itemLabel="--- Select ---" />
<f:selectItems value="#{customerProfileBean.maritalStatusList}"
var="mst" itemLabel="#{mst.valueName}" itemValue="#{mst.valueCode}" />
</h:selectOneMenu>
<h:outputText rendered="#{not customerProfileBean.editMode}"
value="#{customerProfileBean.marital_status}" />
Select Many Check Box
<h:selectManyCheckbox id="loanTypes" styleClass="selectOptionSpace"
rendered="#{customerProfileBean.editMode}"
value="#{customerProfileBean.loanTypes}">
<f:selectItems value="#{customerProfileBean.creditFacList}"
var="mst" itemLabel="#{mst.valueName}" itemValue="#{mst.valueCode}" />
</h:selectManyCheckbox>
<h:outputText rendered="#{not customerProfileBean.editMode}"
value="#{customerProfileBean.custLoanType}" />
Replaced the jsf controls with the primefaces controls viz. p:selectOneMenu and p:selectManyCheckbox which fixed the problem of displaying value instead of code.

JSF tag for disabling a checkbox on selecting a dropdown without using JavaScript

I have a dropdown and checkbox in my page and if we select a dropdown then the checkbox has to be disabled. We should not use JavaScript for this. I am new to JSF. Is there a way by using JSF. Any ideas.
Just add a <f:ajax> which executes on change of the dropdown and updates the checkbox whereby its disabled attribute checks if the dropdown's value is not empty.
E.g.:
<h:selectOneMenu value="#{bean.selectedItem}">
<f:selectItems value="#{bean.availableItems}" />
<f:ajax render="checkbox" />
</h:selectOneMenu>
<h:selectBooleanCheckbox id="checkbox" disabled="#{not empty bean.selectedItem}" />
That's basically all.
Please note that this uses under the covers still JavaScript for the job! The only difference is that you don't need to manually write any line of JavaScript code, instead JSF autogenerates the necessary JS code for you.

Immediate="true" causes update="component" to fail

I have a command button (a Cancel button to be specific) that I want to bypass the validation of some components on my page. When I have immediate="true" set on my command button, the update attribute does not work. By "not work" I mean that the values on :centerForm:p_definition do not reset to what they should be. If I select an item from a dropdown or enter data into an input text, the information should disappear when clicking cancel. Setting immediate="false" or leaving it off completely does reset the fields as expected. Here is the definition of the commandbutton I am having trouble with.
<p:commandButton value="Cancel" style="float: right;"
immediate="true"
actionListener="#{manageBomPropHandler.doCancel()}"
update=":centerForm:p_definition"/>
Is that the expected behavior from immediate="true"? If so, how have you gotten around this for cancel buttons?
"Update" will be called/executed at Update Model Value phase. When you set "immediate" attribute to button command, this phase is ignored.See below images for more detail.
P1: Standard Lifecycle executes Update Model Values phase
P2: Immediate Lifecycle ignored Update Model Values phase
If may help, there's a already solution for clean input fields with primefaces:
<p:commandButton value="Reset Tag" update="panel" process="#this" style="margin-right:20px;" >
<p:resetInput target="panel" />
</p:commandButton>
OR
<h:commandButton value="Reset p:ajax" style="margin-right:20px;" >
<p:ajax update="panel" resetValues="true" />
</h:commandButton>
Source: http://www.primefaces.org/showcase/ui/misc/resetInput.xhtml
In my case, in order to update the fields, I have attached p:ajax against the required component.
That ensured that corresponding fields/variable in backing bean is updated as soon as user makes changes in any of those fields.
Another requirement I had is to refresh a data table after user clicks a immediate - true command button.
In order to do that, I have used code like:
RequestContext.getCurrentInstance().reset("Datatable ID");
Yup, displaying my ignorance of the JSF lifecycle. Found the answer here: JSF commandButton with immediate="true" and here: https://cwiki.apache.org/confluence/display/MYFACES/Clear+Input+Components

How do I get PrimeFaces <p:selectOneMenu> to call valueChangeListener?

Using PF 3.0-RC1 Snapshot (11/22/2011)
I have a in a composite component.
I want to call the valueChangeListener when a selection is made, but it does not appear to be calling the listener.
Here is the code for the component:
<p:selectOneMenu style="width: 220px;"
value="#{customerProfileSessionBean.selectedAccount}"
valueChangeListener="#{customerProfileSessionBean.accountValueChange}" >
<f:selectItems value="#{sessionBean1.custAccountList}"/>
</p:selectOneMenu>
The listener in the backing bean has a print statement that is not being called (at least I do not see it in the server log).
Is there something else that I need to do to get the valueChangeListener to be called when the value changes?
Do I need to use ?
Also, in the listener, is there a ValueChangeEvent that is passed?
Thanks.
You seem to be expecting that the valueChangeListener method in the server side is called immediately when a change event occurs on the client side. This is not correct. It will only be invoked when the form is submitted to the server and the new value does not equals() the old value.
There are at least two ways to achieve your functional requirement:
Add onchange="submit()" so that JavaScript will submit the form whenever you change the value:
<p:selectOneMenu style="width: 220px;"
value="#{customerProfileSessionBean.selectedAccount}"
valueChangeListener="#{customerProfileSessionBean.accountValueChange}"
onchange="submit()">
<f:selectItems value="#{sessionBean1.custAccountList}"/>
</p:selectOneMenu>
This is however very JSF-1.x-ish and poor for user experience. It will also submit (and convert/validate!) all other input fields which may not be what you want.
Make use of an ajax listener instead, for sure if you are not interested in the actual value change (i.e. the old value is not interesting for you), but you're actually interested in the change event itself. You can do this using <f:ajax> or in PrimeFaces components using <p:ajax>:
<p:selectOneMenu style="width: 220px;"
value="#{customerProfileSessionBean.selectedAccount}">
<p:ajax listener="#{customerProfileSessionBean.accountValueChange}" />
<f:selectItems value="#{sessionBean1.custAccountList}"/>
</p:selectOneMenu>
And replace the ValueChangeEvent argument by the AjaxBehaviorEvent argument.
Add f:ajax statement for p:selectOneMenu , it will create ajax call and your value will be submitted EX:
<p:selectOneMenu style="width: 220px;" value="#
{customerProfileSessionBean.selectedAccount}"
valueChangeListener="#{customerProfileSessionBean.accountValueChange}" >
<f:selectItems value="#{sessionBean1.custAccountList}"/>
<f:ajax render="#form"/>
</p:selectOneMenu>
Or you can provide panel id or datatable id ,if you dont want torender the whole form, like:
<f:ajax render=":formid:panelGroupId"/>

Ajax event never fires in <p:inptText> when required="true"

In PrimeFaces when I use:
<p:inputText required="true"
requiredMessage="message"
value="#{backingBean.value}">
<p:ajax event="focus"
update="infoText"
listener="#{backingBean.something()}" />
</p:inputText>
The Ajax-event is never fired.
However, if I remove the required="true" everything works fine and the event fires.
Can anyone tell me how to use p:inputText with p:ajax and required="true"?
This is probably occurring because when you gain focus to the text field an ajax event occurs that posts back the ViewState for the components on the page.
When it does this it is attempting to set the current value of the text field to #{backingBean.value} which is empty, causing a ValidatorException to be thrown. Because this validation error occurred the action event #{backingBean.something()} is never being fired.
Try adding the property immediate="true" to the <p:ajax> tag and see if that allows the event to fire before the validation phase.

Resources