Validation error in h:selectOneMenu with converter - jsf

The following code:
<h:selectOneMenu id="discountCode" value="#{customerMBean.details.discountcode}"
title="DiscountCode" required="true" requiredMessage="The DiscountCode field is required."
converter="#{customerMBean.discountCodeConverter}">
<f:selectItems value="#{customerMBean.allDiscountCodes}"/>
</h:selectOneMenu>
<h:commandButton id="back" value="Back" action="#{customerMBean.list}"/>
<h:commandButton id="update" value="Update" action="#{customerMBean.update}"/>
Shows the following error, regardless of the clicked button:
j_idt6:discountCode : validation error .
public Converter getDiscountCodeConverter() {
return discountCodeConverter;
}
private Converter discountCodeConverter = new Converter() {
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return new ConverterException("On verra la conversion String->Objet plus tard...");
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
DiscountCode dc = (DiscountCode) value;
return dc.getDiscountcode()+" : "+dc.getRate()+"%";
}
};
How is this caused and how can I solve it?

When using a custom converter in h:selectOneMenu, you should always override the equals() method of the object involved.
See also
JSF Validation Error While Using Custom Converter

Use <h:message/> tag it will show you validation error and update it on clicking of button or you can use auto update.
According to me :-
why your button is not working ?? because every time when you click on submit button it will show you validation error but you are not using that's why it is not visible on your screen.
And on back button use immediate=true it will skip the validation phase.

Related

ColorPicker validation and required not working

At first I tried with just the 'required' attribute, but as it never seems to be checked, I added an extremely simple validator which checks the length of the 'color' property... but nothing seems to work. In the same form I have other inputText required components which are correctly checked when I press the commandButton.
I have the following code:
<p:colorPicker id="color" value="#{backBean.color}" required="true" requiredMessage="Required!" validator="ColorValidator" validatorMessage="Required!"/>
<p:commandButton id="createOrUpdateButton"
actionListener="{backBean.createOrUpdate}"
process="#form"
update="#all"
value="Save"
style="width: 95%;" />
Validator:
#FacesValidator("ColorValidator")
public class ColorValidator implements Validator{
public ColorValidator(){
}
#Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if (value==null || value.toString().trim().isEmpty()) {
FacesMessage msg = new FacesMessage("Color validation failed.","Please select a color.");
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
throw new ValidatorException(msg);
}
}
}
The answer is: It was simply not supported!
Issue #5887 and issue #5892 addressing this and offer fixes which should be included in PrimeFaces version 9.0.

Custom validation for p:selectOneMenu

I have the following element:
<p:selectOneListbox id="requirementsUrl"
value="#{data.selectedURL}">
<f:selectItems value="#{data.requirementsDocuments}" />
<f:validator validatorId="conf.ListValidator" />
</p:selectOneListbox>
inside my validator how I can check whether the size of the list requirementsDocuments is bigger than 0. data actually is a specific class generated by the framework that i am using and i cant directly access it through plain java code
In your validator you can access the value of the EL expression "#{data.requirementsDocuments}" via the FacesContext.
example:
public void validate(FacesContext context, UIComponent component,
Object value) throws ValidatorException {
List requireDocuments = context.getApplication()
.evaluateExpressionGet(context, "#{data.requirementsDocuments}", List.class);
if(requireDocuments.size() == 0) {
throw new ValidatorException("List is empty!");
}
}

p:autoComplete shows entity Id after submit

I'm using Primefaces version 5.3 autocomplete in a web project, I have written the search method and converter for the java entities i am searching for. These all work well the selected entity from the autocomplete is set correctly in the backing bean using a p:ajax tab and initially the entity name, which i specify in the itemValue, is set in the text input.
When i then submit the form that includes this autocomplete the variable in the backing bean which i set from the autocomplete stays as it is which is intended but the text input on the autocomplete will display the entities id instead of the name as i'd specified on the itemValue. This is because it is calling the toString method in my converter but I want it still to display the name yet i need the converter..
Has anyone come across this issue that may be able to help?
I have found a thread else where that describe this behaviour but it is a couple years old now and doesn't have an answer.
This thread is:
http://forum.primefaces.org/viewtopic.php?f=8&t=37918
As it may explain it better than i have...
Any help is appreciated.
UPDATE: code added
Here is my autocomplete tag, complete method returns a java List of entity type.
<h:form>
<p:autoComplete id="autocomplete" value="#{bean.selectedEntity}"
completeMethod="#{bean.listOfPossibleEntities}"
itemValue="#{_e}" itemLabel="#{_e.name}" autocomplete="off"
minQueryLength="3" var="_e"
placeholder="Enter Entity Name Here"
converter="EntityConverter" forceSelection="true">
<p:ajax event="itemSelect" update="enclosingForm"/>
<p:column>
<h:outputText value="#{_e.name}" />
</p:column>
</p:autoComplete>
<p:commandButton update="#form" >
</h:form>
FacesConverter looks like as below, i use a DAO call to our database find the object for each id
private EntityDAO entityDAO = (EntityDAO)Component.getInstance("entityDAO");
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
Integer id = Integer.valueOf(value);
return entityDAO.findById(id,false);
}
#Override
public String getAsString(FacesContext fc, UIComponent uic, Object object) {
String result = "";
if(object != null) {
if(object instanceof Entity){
result = ""+ String.valueOf(((Entity) object).getEntityId());
}
}
return result;
}
So yes on update of the h:form after the entity on the autocomplete is selected and the submitting with the p:commandButton the value display or the entity will change from the entity name to the entity id.
Hope this helps further thanks.

s:selectItems on List of String?

I am using seam 2.2.2.Final on JBoss AS 5. I am working on a multi-page wizard.On my first page, user will be able to enter several business names separated by a new line on a textarea.
<s:decorate id="businessNameTextAreaField" template="layout/edit.xhtml">
<ui:define name="label">Business Names</ui:define>
<h:inputTextarea id="businessNameTextArea"
cols="80"
rows="3"
required="true"
value="#{businessNameHome.instance.businessNameTextArea}"/>
</s:decorate>
Upon submission of the page, the system parses the inputed value and splits it into a list of strings
public String checkBusinessNames(){
String businessNameTextArea = this.getInstance().getbusinessNameTextArea();
String[] businessNameTextAreaArray = businessNameTextArea.split("\\n");
List<SelectItem> businessNameChoices = new ArrayList<SelectItem>();
for(String businessNameText: businessNameTextAreaArray){
businessNameChoices.add(new SelectItem(businessNameText));
}
this.getInstance().setBusinessNameChoices(businessNameChoices);
return "valid";
}
The user is then asked to select from the list of valid business names to register
<s:decorate id="businessNameRegisterListField" template="layout/edit.xhtml">
<ui:define name="label">Business Name</ui:define>
<h:selectManyCheckbox value="#{businessNameHome.instance.selectedbusinessName}" layout="pageDirection" immediate="true" >
<s:selectItems value="#{businessNameHome.instance.businessNameChoices}" var="bn" label="#{bn.label}" /> </h:selectManyCheckbox>
</s:decorate>
selectedbusinessName is of type String while businessNameChoices is of List
Upon submission of the page, what is submitted as business names is something like this:
javax.faces.model.SelectItem#135aa7c
I have tried putting an itemValue on the s:selectItems but I get another error which is "Value is not valid"
Tried to use <s:convertEntity> but gets a NumberFormatException
I have also tried to create my own converter
public class BusinessNameBeanConverter implements javax.faces.convert.Converter {
#Override
public Object getAsObject(FacesContext context, UIComponent cmp, String value) {
// TODO Auto-generated method stub
System.out.println("getAsObject "+value);
return value;
}
#Override
public String getAsString(FacesContext context, UIComponent cmp, Object value) {
// TODO Auto-generated method stub
System.out.println("getAsString "+((SelectItem)value).getValue());
return ((SelectItem)value).getValue();
}
}
but I still get the same "Value is not valid" error.
I don't know what to do anymore. Please help.
Thanks,
Nicholas
Change
<s:selectItems value="#{businessNameHome.instance.businessNameChoices}" var="bn" label="#{bn.label}" />
to
<f:selectItems value="#{businessNameHome.instance.businessNameChoices}" />
You've namely already a List<SelectItem>, not a List<SomeObject> for which <s:selectItems> is useful.
Don't forget to remove the converter, it makes no sense.

JSF 2.0 selctOneMenu with SelectItems

Iam new to JSF technology, currently in our project we are using JSF 2.0 with spring and hibernate integration.I have one doubt regarding h:selectOneMenu and f:selectItems.
From the Database i'm getting a list of UserBeans.I'm using like
<h:selectOneMenu id="users" value="#{MyBean.user}">
<f:selectItems value="#{MyBean.userList}" var="user" itemLabel="#{user.userName}" itemValue="#{user.userId}" />
</h:selectOneMenu>
Here user is of type UserBean and userList is the list of UserBeans.
In the view page it is showing correctly but in the backing bean when i select one item and click on submit button, it showing the selected user as NULL.
My doubt is i can only pass List of SelectItem objects for the f:selectItems or any other beans list ..??
Is there any other way to populate the list of UserBeans otherthan SelectItem for selectItems.
Thank you All,
Anil
You have set the user ID as value of the select items, but you seem to be trying to bind the value to a fullworthy User property in the bean. You need to bind it as an user ID.
<h:selectOneMenu id="users" value="#{MyBean.userId}">
<f:selectItems value="#{MyBean.userList}" var="user" itemLabel="#{user.userName}" itemValue="#{user.userId}" />
</h:selectOneMenu>
If your sole intent is to be able to select and set User instead of only the ID, then you need a Converter to convert between User and String. That's because HTTP/HTML doesn't understand Java objects. It only understands strings. Here's a kickoff example:
<h:selectOneMenu id="users" value="#{MyBean.user}">
<f:selectItems value="#{MyBean.userList}" var="user" itemLabel="#{user.userName}" itemValue="#{user}" />
</h:selectOneMenu>
with
#FacesConverter(forClass=User.class)
public class UserConverter implements Converter {
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
try {
return userService.findById(Long.valueOf(value));
} catch (SomeException e) {
throw new ConverterException(new FacesMessage(String.format("Cannot convert %s to User", value)), e);
}
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return String.valueOf(((User) value).getId());
}
}
However, this is a pretty expensive job. I'd suggest to stick to passing ID around and obtain the real user in the bean's action method just once instead of letting the converter do it for every single item.

Resources