h:selectOneMenu required="true" reverts to bean value on validation failure - jsf

I have something like this on a create/edit form:
<h:selectOneMenu value="#{bean.value}" required="true" ... >
<f:selectItem itemLabel="-- Select --" itemValue=""/>
<f:selectItems .../>
</h:selectOneMenu>
In the create new object case, the required validation works as expected.
In the edit object case, if I change a valid value to the placeholder "-- Select --", I get the validation failure w/expected requiredMessage because itemValue is blank (""); however, the HTML <select> reverts to whatever option was already selected from the bean, rather than retaining the invalid user input from form submission.
To reiterate, the required=true on the h:selectOneMenu itself works fine, generating the expected message - the only thing that's wrong is the value reverting to the bean value, instead of retaining the blank submitted value. (I confirmed with Chrome developer toolbar that an empty string is indeed being POSTed for the <select>.)
Why is this happening? More precisely, why is h:selectOneMenu not behaving like h:inputText, where the UIInput displays the invalid user input from the form, and does not refresh its value from the bean? Both of these controls extend the same UIInput base class and implement EditableValueHolder, so I expect their lifecycle would behave the same.
Also, to clarify, I do not have the INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL context param anywhere in web.xml.
This is a JSF application on Mojarra 2.1.3 / Glassfish 3.1.1.

Related

Primefaces: Keep value of input text inside a dialog after calling initPosition

I have a dialog which need to be rerender after a certain selectOneMenu ist chosen.
To accomplish that, the following code is used inside the selectOneMenu:
<p:ajax event="valueChange" oncomplete="PF('dialog').initPosition();" update="panelGrid" />
However, after the dialog is rerendered, all user inputs in my p:inputTextare lost (reset to value from java bean).
How can I make the inputText keep the new value without persisting it to backend?
provide the XHTML page where your inputText component is situated. My best guess to solve your problem is by adding the p:ajax component inside the inputText component. p:ajax as defined below triggers on the default event which is change and processes #this which is the inputText component. this way it saves your input on the backing bean as soon as you exit the field.
<p:inputText value="#{bean.value}" >
<p:ajax />
</p:inputText>

JSF h:selectOneMenu wont call relevant setter method

Hi I've got a question
<h:selectOneMenu id="cmbFileStatus1" disabled="#{!schedulerController.oldFile}"
value="#{schedulerController.test}">
<f:selectItem itemValue="#{null}" itemLabel="--Show All--" noSelectionOption="true"/>
<f:selectItems value="#{schedulerController.statusList}"/>
<f:ajax execute="#this" render="dataTable"/>
</h:selectOneMenu>
The above code the ajax executes(I checked through firebug). But the thing is the selected value wont be set to h:selectOneMenu value parameter.
There is a h:form tag that is wrapping this element, plus there are two other elements similarly using ajax as shown here. But they are positioned before this element in the DOM, they call the relevant setter methods and the updates the bean variables.
But this element it doesn't set necessary selected value.
Also another detail, the list that is populated for selection, it is a list created from enum values.
One instance I moved the problematic code to the top of the DOM (before the other two elements that ajax is applied) and then it hit the setter method when ran in debug mode.
I cannot understand whats wrong, it doesn't show any javascript errors and such. The JSF version is 2.0, this is an old project.
Any ideas guys?

JSF 1.2/Seam 2.2 - validator is skipped when input it empty

I am trying to call validateLength in JSF (xhtml file of seam)
<f:validateLength minimum="2" maximum="512"/>
It works for values such as text length 513 and 1 (i.e. it shows a warning, but not for 0)
The input text filed for which it is being used is set to required=false (so that it can use a4j support for empty fields, I have to show a preview based on the input)
The problem that I see is that there a validator method in a helper class but it gets ignored when the length of input is 0 (ie I put nothing , it works for non-empty values).
I also have a NullableStringConverter here but what I have noticed that as soon as that converter sets the value of null of empty string, the validator gets skipped. Here is the complete snippet of in the inputText
<h:inputText id="linkNameInput"
value="#{someHelper.name}"
validator="#{someHelper.validateMethod}"
required="false">
<f:validateLength minimum="2" maximum="512"/>
<f:converter converterId="NullableStringConverter" />
</h:inputText>
I would just like the ability to validate an empty string in a validator.
I would just like the ability to validate an empty string in a validator.
That's not possible in JSF 1.x. That's only possible since JSF 2.0 (in favour of JSR303 Bean Validation support).
I'm not sure why you'd like to validate the empty string in the custom validator. There you normally use the required="true" attribute for this. If the sole goal is to change the required message, then just use requiredMessage attribute.
<h:inputText ... required="true" requiredMessage="Please enter name" />
As mentioned already, validating an empty input String in a JSF 1.2 component is not supported. However, you can check for this null/empty model value in your backing bean on form submit and add a FacesMessage that is mapped to that specific input field. This would allow integration with server-side component-specific error message display (<h:message for="componentId" />).
FacesContext.getCurrentInstance().addMessage("componentId",
facesMessageForComponent);

JSF/Richfaces/A4j ==> component/field conversion and reRendering problem

I have an input field in a JSF Page like the following (maps to BigDecimal on backing bean)
<h:inputText disabled="#{volumeBean.grossVolumeDisabled}" id="grossVolume" size="10" validateOnExit="true" value="#{volumeBean.enteredGrossVolume}" >
<a4j:support ajaxSingle="true" event="onblur" ignoreDupResponses="true" oncomplete="checkFieldValidation(this)" onsubmit="updateDirty()"/>
</h:inputText>
And an a4j:commandButton to "refresh" all the data from the database on the page:
<a4j:commandButton accesskey="T" action="#{volumeBean.revert}" button-type="ajax" disabled="#{volumeBean.revertDisabled}" id="volumeBean_reset" immediate="true" reRender="volumesTable" value="#{msg.button_RESET}"/>
Here are the steps to reproduce my problem:
And please note that the error occurs regardless of whether there is a reRender attribute set on the a4j:support
Here are the steps to reproduce - just to clarify further:
navigate to the screen where the BigDecimal input field exists
type aa into the field (should be a number but put non-numeric characters purposely)
tab off the field
notice that an error is reported 'aa' is not a valid netVolume
click on the RESET button
all of the changed fields have their original values EXCEPT those that have non-numeric data entered
unless the user manually deletes the non-numeric data in the fields or refreshes the entire screen, the "bad data" sticks
When you do a reset, you fire an Ajax request, the entire form is submitted and you get validation error again. So the field still has the old (incorrect) value.
Try adding the parameter ajaxSingle="true" to the button. I've found that immediate="true" is not adequate for bypassing validation on ajax components.

JSF selectOneMenu is refreshing and going back to its previous state rather than showing the new value

I have a datatable where a lot of selectOneMenu items are available , for example, for 10 items each having one selectOneMenu combo. now if i click on any of the combos, they are supposed to save the value in the database and they do it. but after saving the changed value the selectOneMenu is returning back to its previous state. I want the selectOneMenu to keep its current state. also, the method is being invoked for every single combo in the datatable. i really wonder why!! i have been banging my head for the last 2 weeks. any help would be really appreciated. thanks in advance.
this is my first post here. this is my jsf datatable:
<h:dataTable value="#{careNeedBean.controlledCareNeedsList}" var="careNeed"
id="careneed_table" binding="#{careNeedBean.dataTable}">
<h:column>
<f:facet name="header">
<h:outputText value="NeedsLevel"/>
</f:facet>
<h:selectOneMenu id="needs_level_combo" style="width:200px;font-size:9px;"
onchange="submit()"
valueChangeListener="#{careNeedBean.saveTaskAsessment}"
binding="#{careNeedBean.selectOneMenu}">
<f:selectItem itemValue="not_assessed" itemLabel="----Not assessed----"/>
<f:selectItems value="#{careNeed.humanReadableNeedsList}" />
</h:selectOneMenu>
</h:column>
This is my bean code:
public String saveTaskAsessment(ValueChangeEvent event) {
//does some things
return "Success";
}
The valueChangeListener doesn't run on the recently changed component only. In fact, you're using JavaScript submit() function to submit the entire form. The valueChangeListener will always be executed whenever the new selected value differs from the old value as is been declared in the value attribute.
You don't have declared a value attribute, so its default value is effectively null. If the default selected item of the list is not null, then the valueChangeListener will be invoked.
To fix this, you need to assign a value attribute to the component
<h:selectOneMenu value="#{careNeed.needsLevel}">
and you need to prefill it with the same value as the default value of the dropdown list.
this.needsLevel = "not_assessed";
Alternatively, you can also make the default value null.
<f:selectItem itemValue="${null}" itemLabel="----Not assessed----"/>
Unrelated to the problem, since you're already on JSF 2.0, I'd suggest to use <f:ajax> to submit only the recently changed dropdown by ajaxical powers instead of using onchange="submit()" to submit the entire form. That's after all better for user experience.
<h:selectOneMenu>
<f:ajax />
</h:selectOneMenu>
Also, the valueChangeListener method doesn't need to return anything. It will be ignored anyway. Just declare it void.
You can use AjaxSingle="true" and onsubmit="form.refresh();" on your ajax request.
So that it will process only the current component.
form.refresh(); will remove the old cache value.
You will get the refreshed bean value.

Resources