Disabling validation of selectOne when disabled - java

I am trying to figure out following problem. I have a simple rich:select
<rich:select listWidth="310" id="userSelect" value="#{departmentBacking.selectedUserId}"
disabled="#{departmentBacking.unassignCheckbox}"enableManualInput="true" defaultLabel="#{not departmentBacking.unassignCheckbox ? 'start typing a surname...' : 'Uncheck unassign departments first'}">
<f:selectItems value="#{departmentBacking.userList}" var="user" itemValue="#{user.id}" itemLabel="#{user.surname} #{user.name} - #{user.email}" />
</rich:select>
It selects a person who is later set as leader of some departments. Works well. However, if I only need to unassign departments, without choosing new one, problems start to occur. If the unnassignCHeckbox is selected, I don't want to use this value at all. However, I cannot make the jsf engine to do the postback, since I always get a validation error.
MyForm:userSelect: Validation Error: Value is not valid
I assume this is because the default value of #{user.id} is 0 and no user with this id is to be found in userList. The bean is view scoped. Is there a way to somehow either skip the validation or exclude the rich:select from the submitting form?.

Try adding a <f:selectItem> with the 0 value and a "SELECT" label (or whatever). That will solve your problem, and add a validation that when the unnassignCHeckbox is unselected, the selectedUserId value must be greater than 0 (this last only if its not yet implemented).
<rich:select listWidth="310" id="userSelect" value="#{departmentBacking.selectedUserId}"
disabled="#{departmentBacking.unassignCheckbox}"enableManualInput="true"
defaultLabel="#{not departmentBacking.unassignCheckbox ? 'start typing a surname...' : 'Uncheck unassign departments first'}">
<f:selectItem itemValue="0" itemLabel = "SELECT SURNAME" />
<f:selectItems value="#{departmentBacking.userList}" var="user"
itemValue="#{user.id}"
itemLabel="#{user.surname} #{user.name} - #{user.email}" />
</rich:select>

Related

How to render more JSF components by using a ui:repeat component?

I have a question concerning the jsf component . Here is a small code example:
<ui:repeat var="bean" value="myBean.myListToIterate">
<h:selectOneCheckbox value="#{myBean.specificField}" />
#{bean.car.name}
</ui:repeat>
Question 1: Why the expression #{bean.car.name} alone inside the ui:repeat element and why not for example in a
<h:outputLabel value="#{bean.car.name}" />"?
If i use this, nothing will be displayed.
Question 2: Why does this example doesn´t look very well, if i use a
<h:selectOneRadio value="#{myBean.specificField}"/> component
instead of a
<h:selectOneCheckbox value="#{myBean.specificField}"/> component?
Greetz
Marwief
Answer 1 :
EL JSF expressions are allowed in the last JSF versions. So it can be put without any wrapping tag (like <h:outputText />).
Using this <h:outputLabel value="#{bean.car.name}" /> did not give result, because you did not specify for attribute to point to, in order to be rendered as label of its client id, which means, it cannot be used alone.
Answer 2 :
First, this JSF tag <h:selectOneCheckbox /> doesn't exist, maybe you wanted to mean <h:selectBooleanCheckbox />. Replacing this by <h:selectOneRadio ... /> does not look very well, because this last one needs <f:selectItem /> or <f:selectItems /> to hold choices from where the end user will be able to choose between (i.e at least 2 choices), in the contrary of <h:selectBooleanCheckbox /> which can have no child select item(s) tag(s) in the case of one alone choice to (un)check.

Avoid validating/ submitting p:selectOneListbox's value completely

I'm fetching selectItems list for a p:selectOneListbox via ajax using a request scoped bean. Thus on submitting back the form I'm getting this error:
j_idt153:j_idt159:j_idt184:j_idt194: Validation Error: Value is not valid
I dont want to submit the value of p:selectOneListbox to any bean property that's why the value EL for that component was omitted but still JSF is validating the selected option & it is not there since my bean was request scoped. Now I want to completely skip validating this component since this p:selectOneListbox is just for presentation purposes & its value is not used after the submit form process. How do I avoid validating/ submitting p:selectOneListbox's value completely
<p:ajax event=".." listener="#{pim.retrieveProjects()}" update="usrProjctsList" />
<p:selectOneListbox id="usrProjctsList" onchange="jsfElmnt('#{cc.clientId}:selUsrProjct').val($(this).val());">
<f:selectItems value="#{pim.projects}" var="project" itemLabel="#{project.title}" itemValue="#{project.id}"/>
</p:selectOneListbox>
<h:inputHidden id="selUsrProjct" value="#{bean.underProject}"/>
I don't think that the error j_idt153:j_idt159:j_idt184:j_idt194: Validation Error: Value is not valid referring to <p:selectOneListbox id="usrProjctsList" cause its id not present in the j_idt153:j_idt159:j_idt184:j_idt194 id at all...
do view source in your browser and look for the j_idt153:j_idt159:j_idt184:j_idt194 id and try to find out to whom it belongs
also you can try to add immediate="true" to your <p:ajax to skip validation or try adding <p:ajax to that troublesome component j_idt153:j_idt159:j_idt184:j_idt194
As Daniel said, the id doesn't match either. But for skipping the validation you could also use the process=#this (and other stuff, except the listBox) on your ajax event. Since you are using primefaces this will just process the stuff written there and skip the rest.

How can I reset JSF UIInput components to their managed bean values

I want to reset JSF inputs to their original managed bean values after validation failed.
I have two forms inside the same page - the first form has a commandLink to initialize the second form. The second form is rendered as a dialog whose visibility is toggled through jQuery - for the purpose of this exercise, though, I can illustrate just with two forms on the same page. Also, while I'm using PrimeFaces 2.2.x in my app, the same behaviors appear with regular h:commandLink as well.
The issue I'm having is:
click link in first form to initialize second form
submit invalid values in second form
click link in first form again to initialize second form - invalid values still there and/or UIInput state is still invalid.
For example - take the following form
<h:form id="pageForm">
<h:commandLink actionListener="#{testBean.initialize}">Initialize, no execute
<f:ajax render=":dialogForm"/>
</h:commandLink>
<br/>
<h:commandLink actionListener="#{testBean.initialize}">Initialize, execute=#this
<f:ajax execute="#this" render=":dialogForm"/>
</h:commandLink>
</h:form>
<h:form id="dialogForm">
<h:messages/>
String property - Valid: <h:outputText value="#{property.valid}"/>
<br/>
<h:inputText id="property" binding="#{property}" value="#{testBean.property}">
<f:validateLength minimum="3"/>
</h:inputText>
<br />
Int property - Valid: <h:outputText value="#{intValue.valid}"/>
<h:inputText id="intValue" binding="#{intValue}" value="#{testBean.intValue}">
<f:validateLongRange maximum="50" />
</h:inputText>
<br/>
<h:commandLink actionListener="#{testBean.submit}">
Submit
<f:ajax render="#form" execute="#form"/>
</h:commandLink>
<h:commandLink actionListener="#{testBean.initialize}">Initialize, execute=#this
<f:ajax execute="#this" render="#form"/>
</h:commandLink>
</h:form>
Bean class:
#ManagedBean
#ViewScoped
public class TestBean {
private String property = "init";
private Integer intValue = 33;
// plus getters/setters
public void submit() { ... }
public void initialize() {
intValue = 33;
property = "init";
}
}
Behavior #1
click either "Initialize" link on the pageForm
inputs get initialized to "init", "33"
now submit something invalid for both fields like "aa", "99"
now click any of the "initialize" links again (they all seem to behave the same - makes no difference whether it's in the same form or different, or whether I have specified execute="#this" or not.)
Result => UIInput.isValid() = false, both values reset though ("init", "33").
Expected => valid = true (or is this not reasonable to expect?)
Behavior #2
click either "Initialize" link on the pageForm
inputs get initialized to "init", "33"
now submit something invalid for the text field but valid for the int field ("aa", "44")
now click any of the "initialize" links again
Result => "init", valid=false; 44, valid=true
Expected => "init", valid=true; 33, valid=true
I have also looked at:
JSF 2 - Bean Validation: validation failed -> empty values are replaced with last valid values from managed bean
and
How can I populate a text field using PrimeFaces AJAX after validation errors occur?
The suggestion to explicitly reset the state of UIInputs with resetValue does work, but I'm not happy with it.
Now, I sort of understand why the isValid is not resetting - my understanding of the JSF lifecycle is that once a value is submitted to a component, isValid is not reset until the component is successfully submitted and validated and the Update Model Values phase sets the bean value. So there may be no way around explicitly resetting the valid state in this case, since I want to use #{foo.valid} for conditional CSS styling.
What I don't understand, though, is why the components that successfully validated are not re-initializing from the bean. Perhaps my understanding of the JSF lifecycle is slightly off?
I understand the rules layed out in the answer to How can I populate a text field using PrimeFaces AJAX after validation errors occur? as they pertain to an individual component but not to the form as a whole - i.e., what happens if a component succeeds validation but the validation overall fails?
In fact, there may turn out to be no better way than explicitly calling resetValue on components. In my case, all of the dialogs are in the same big JSF view tree with the underlying page that opens them. So from JSF's perspective, the same view component state including invalid input values should be preserved until we navigate away from the view, as it has no visibility into how we're toggling display attributes client-side.
The only other thing that might work is if the components that make up the dialog are actually not rendered in the JSF view tree unless they're visible. In my case, they're always rendered, using CSS to toggle visibility.

JSF: Selecting value in one drop down enables another drop down

Lets say I have two selectOneMenu drop-downs:
Drop-down A:
<h:selectOneMenu value="valA"
immediate="false"
required="true"
valueChangeListener="#{JavaClass.someJavaMethod}"
id="caImplClassSelector"
rendered="#{JavaClass.someOtherMethod}">
Drop-down B:
<h:selectOneMenu value="valB"
immediate="false"
required="true"
valueChangeListener="#{JavaClass.someJavaMethod}"
id="caImplClassSelector"
disabled="what should I write here?"
rendered="#{JavaClass.someOtherMethod}">
How can I make sure that drop down B is disabled until a user selects a value in drop down A? I can make a method within the JavaClass that returns true or false depending on if a value in drop-down A has been selected or not, but is there any way to do the above wihout making that method?
Any help would be appreciated.
I have no idea what JSF/RF versions you are using, so here's just a generic answer.
Bind the value of the 1st dropdown to a bean property:
<h:selectOneMenu value="#{bean.firstMenu}">
Then let the disabled attribute of the 2nd dropdown intercept on that:
<h:selectOneMenu disabled="#{bean.firstMenu == null}">
Note that with JSF2/RF4 you don't need the valueChangeListener/immediate hacks which are been used in old ajaxless JSF 1.x versions.
Declare a boolean property in your managed bean and generate the getter and setter methods for it.
By default set it to true.
In <h:selectOneMenu value="valA"
immediate="false"
required="true"
valueChangeListener="#{JavaClass.someJavaMethod}"
id="caImplClassSelector"
rendered="#{JavaClass.someOtherMethod}">
In the first drop down based on application logic on the value change listener set the disabled property to false.
In the second drop down refer to the disabled property.
There could be some additional logic that you may have to handle.

How to specify the order in which a rich:extendedDataTable selection and h:selectOneMenu value are applied

I'm working on an application that's basically a customised database administration tool.
The page structure is basically the following:
<a4j:region>
<h:selectOneMenu value='#{bean.selectedTable}'>
...
<a4j:ajax event='change' render='tablePanel'/>
</h:selectOneMenu>
<a4j:outputPanel id='tablePanel'>
<rich:extendedDataTable id='table' selection='#{bean.selectedRows}' ...>
<f:facet name='header'>
[datascroller etc.]
<a4j:commandButton action='#{bean.deleteSelectedRows}' execute='#region' render='tablePanel'/>
</f:facet>
[columns]
</rich:extendedDataTable>
</a4j:outputPanel>
<a4j:region>
The selectOneMenu is used to choose which database table will be displayed. The backing bean is request scoped and set up to pick the first available table as a default when it's initialised. I'm using an ExtendedDataTable subclass to paginate data in the database.
When I click the commandButton to delete the rows, it seems that the extendedDataTable component determines the selected rows /before/ the value of bean.selectedTable is applied. This means that no matter what table is selected in the dropdown menu, RichFaces tells me the selected rows are some (more or less arbitrary) rows in the default database table.
I verified that this is an ordering problem, when deleteSelectedRows() is called the value of selectedTable is correct. I'm using Richfaces 4 M6, and a4j:keepAlive doesn't seem to be there anymore to preserve the bean state.
Is there a way to tell RichFaces / JSF in which order to do these things? I tried using immediate="true" on the h:selectOneMenu but that didn't help.
Also, after a delete, the tablePanel doesn't seem to be rerendered, while another a4j:commandButton that adds new records with the same execute and render attributes seems to work fine. Is there a way to debug the state of RichFaces ajax requests / hook into them via events?

Categories