jsf - Using a "Please select" f:selectItem with null/empty value inside a p:selectOneMenu -


i'm populating <p:selectonemenu/> database follows.

<p:selectonemenu id="cmbcountry"                   value="#{bean.country}"                  required="true"                  converter="#{countryconverter}">      <f:selectitem itemlabel="select" itemvalue="#{null}"/>      <f:selectitems var="country"                    value="#{bean.countries}"                    itemlabel="#{country.countryname}"                    itemvalue="#{country}"/>      <p:ajax update="anothermenu" listener=/> </p:selectonemenu>  <p:message for="cmbcountry"/> 

the default selected option, when page loaded is,

<f:selectitem itemlabel="select" itemvalue="#{null}"/> 

the converter:

@managedbean @applicationscoped public final class countryconverter implements converter {      @ejb     private final service service = null;      @override     public object getasobject(facescontext context, uicomponent component, string value) {         try {             //returns item label of <f:selectitem>             system.out.println("value = " + value);              if (!stringutils.isnotblank(value)) {                 return null;             } // makes no difference, if removed.              long parsedvalue = long.parselong(value);              if (parsedvalue <= 0) {                 throw new converterexception(new facesmessage(facesmessage.severity_error, "", "message"));             }              country entity = service.findcountrybyid(parsedvalue);              if (entity == null) {                 throw new converterexception(new facesmessage(facesmessage.severity_warn, "", "message"));             }              return entity;         } catch (numberformatexception e) {             throw new converterexception(new facesmessage(facesmessage.severity_error, "", "message"), e);         }     }      @override     public string getasstring(facescontext context, uicomponent component, object value) {         return value instanceof country ? ((country) value).getcountryid().tostring() : null;     } } 

when first item menu represented <f:selectitem> selected , form submitted then, value obtained in getasobject() method select label of <f:selectitem> - first item in list intuitively not expected @ all.

when itemvalue attribute of <f:selectitem> set empty string then, throws java.lang.numberformatexception: input string: "" in getasobject() method though exception precisely caught , registered converterexception.

this somehow seems work, when return statement of getasstring() changed from

return value instanceof country?((country)value).getcountryid().tostring():null; 

to

return value instanceof country?((country)value).getcountryid().tostring():""; 

null replaced empty string returning empty string when object in question null, in turn incurs problem demonstrated here.

how make such converters work properly?

also tried org.omnifaces.converter.selectitemsconverter made no difference.

when select item value null, jsf won't render <option value>, <option>. consequence, browsers submit option's label instead. specified in html specification (emphasis mine):

value = cdata [cs]

this attribute specifies initial value of control. if attribute not set, initial value set contents of option element.

you can confirm looking @ http traffic monitor. should see option label being submitted.

you need set select item value empty string instead. jsf render <option value="">. if you're using converter, should returning empty string "" converter when value null. specified in converter#getasstring() javadoc (emphasis mine):

getasstring

...

returns: zero-length string if value null, otherwise result of conversion

so if use <f:selectitem itemvalue="#{null}"> in combination such converter, <option value=""> rendered , browser submit empty string instead of option label.

as dealing empty string submitted value (or null), should let converter delegate responsibility required="true" attribute. so, when incoming value null or empty string, should return null immediately. basically entity converter should implemented follows:

@override public string getasstring(facescontext context, uicomponent component, object value) {     if (value == null) {         return ""; // required spec.     }      if (!(value instanceof someentity)) {         throw new converterexception("value not valid instance of someentity.");     }      long id = ((someentity) value).getid();     return (id != null) ? id.tostring() : ""; }  @override public object getasobject(facescontext context, uicomponent component, string value) {     if (value == null || value.isempty()) {         return null; // let required="true" job on this.     }      if (!utils.isnumber(value)) {         throw new converterexception("value not valid id of someentity.");     }      long id = long.valueof(value);     return someservice.find(id); } 

as particular problem this,

but returning empty string when object in question null, in turn incurs problem demonstrated here.

as answered on there, bug in mojarra , bypassed in <o:viewparam> since omnifaces 1.8. if upgrade @ least omnifaces 1.8.3 , use <o:viewparam> instead of <f:viewparam>, shouldn't affected anymore bug.

the omnifaces selectitemsconverter should work in circumstance. returns empty string null.


Comments

Popular posts from this blog

php - Wordpress website dashboard page or post editor content is not showing but front end data is showing properly -

javascript - Get parameter of GET request -

javascript - Twitter Bootstrap - how to add some more margin between tooltip popup and element -