Applying locale to <h:inputText> for double value - jsf

How to apply locale to <h:inputText> for decimal values in Seam Application(JSF-richfaces)? If I add an <f:convertNumber/> to my <h:inputText> the correct decimal delimiter is shown (e.g. 6,28 instead of 6.20). But when I enter the input value & save, following error message is displayed, if converter="javax.faces.Double" attribute used in <h:inputText>, if not, an exception is thrown.
Scenario: If locale is to set to German(de), try to enter the input value in en-US format or vice-versa.
Error Message/Exception:
Can't set property 'xxx' on class 'xxx' to value '590'.:
java.lang.IllegalArgumentException:
java.lang.ClassCastException#11e51bd
Also let me know, if any alternate solution is available.
Below is the code snippet :
<h:inputText id="iEuroDollar" value="#{tempCurr.currencyRateEuroDollarValue}" rendered="#{tempCurr.editRates}" maxlength="6" converter="javax.faces.Double" converterMessage="#{msg['error.double.field']}" >
<f:convertNumber minFractionDigits="2" locale="#{rolePoolAction.requestLocale}"/>
<a4j:support event="onblur" action="#{conversionAction.checkInputValue(tempCurr)}" reRender="iDollarEuro"/>
</h:inputText>
Thanks in Advance....

Related

How to hide validatorMessage when field is empty

Please help how to hide validatorMessage when user clearing the field:
<div class="item">
<p:outputLabel for="firstName" value="#{msgs['customerForm.firstName']}"/>
<p:inputText id="firstName" value="#{customerBean.customer.firstName}"
requiredMessage="#{msgs['Error.firstName.mandatory']}"
validatorMessage="#{msgs['Error.firstName.wrongFormat']}"required="true">
<f:validateRegex pattern="^([a-zA-Z]+[a-zA-Z\s\-]*){1,255}$" />
</p:inputText>
<p:message id="m_firstName" for="firstName" display="text"/>
</div>
You defined your field having two validations:
* required value validator
* regular expression validator
Both validators have equivalent priority, and both are run against your field value. And both of these validators see empty value as a problem, and your framework, unable to determine which of these two equivalent-looking failures is the "actual" failure, displays both.
To "fix" it, you should allow empty values to pass your regex, like this:
<f:validateRegex pattern="^([a-zA-Z]+[a-zA-Z\s\-]*){0,255}$" />
Notice that I changed number qualifier to allow 0-255 characters instead of 1-255 characters like before.
That should allow two of your validators cover different cases of invalid values, like you intended.
You can update the error messages if you put this in the input element. It will validate the input on every keyup event though.
<f:ajax execute="#this" event="keyup" render="m_firstName" />

javax.el.PropertyNotWritableException when using EL conditional operator in value of UIInput

I get this error message:
javax.el.PropertyNotWritableException: /u/editProfile.xhtml #64,140 value="#{empty userProfile.cfg.gpu or userProfile.cfg.gpu == '' ? usernavmsg.EditMe: userProfile.cfg.gpu}": null
The problem is that when the value of a bean property is null the value of an inputText field switches from my ManagedBean property, to a resource string. So I cannot persist that value.
I request the profile of the user from my database in my managed bean. If a property of the said profile is null, the inplace text holder value is "Edit Me". If it's not null it's the value of that property. Which is working ! However when I submit the form and try to persist a new value or no value at all the error appears. The error only appears for the field that are null to begin with (when I requested them from the db). So the problem is that when the value is null it switch from my ManagedBean property, to a resource string.
I just have a form with this:
<h:outputLabel value="#{usernavmsg.GPU}: "/>
<p:inplace styleClass="lessDark">
<p:inputText value="#{empty userProfile.cfg.gpu ? usernavmsg.EditMe: userProfile.cfg.gpu}" />
</p:inplace>
when I submit the form I want to persist userProfile.cfg in the database which doesn't happen.
Can I work around this ? Is it even possible ?
Conditional statements in EL are indeed not writable. They are read-only. End of story. The same applies to method references in EL as in #{bean.property()}. It must really be a true value expression as in #{bean.property}.
Your approach of using a (HTML5) "placeholder" is actually wrong. For that you should be using the placeholder attribute, not the value attribute. In older versions of PrimeFaces that do not have a placeholder attribute you'll need passthrough.
<html ... xmlns:a="http://xmlns.jcp.org/jsf/passthrough">
...
<p:inputText value="#{userProfile.cfg.gpu}" a:placeholder="#{usernavmsg.EditMe}" ... />
Nowadays PrimeFaces offers a placeholder attribute.
<p:inputText value="#{userProfile.cfg.gpu}" placeholder="#{usernavmsg.EditMe}" ... />

JSF input processing order

Is there a way to specify the order in which the inputs should be set after a submit?
Here is my case:
<h:inputText id="fieldA" value=#{myBean.myObject.fieldA}" />
<h:inputText id="fieldB" value=#{myBean.myObject.fieldB}" />
<p:autoComplete id="myObject" value=#{myBean.myObject" converter="myObjectConverter" />
<h:inputText id="fieldC" value=#{myBean.myObject.fieldD}" />
<h:inputText id="fieldD" value=#{myBean.myObject.fieldC}" />
The issue I am encountering is that, as the inputs are processed in the ordered they are declared, fieldA and fieldB are set in the initial instance of myObject, then myObject is set (with a new instance thus filedA and fieldB values are lost), and finally fieldC and fieldD are set with no problem.
If I could manage to start by setting myObject first, that would solve my problem.
I will temporarily set the fields and myObject into two different attributes of my bean, and populate myObject after clicking a save button. But it looks more like a hack than a real solution.
Needless to say that declaring the autocomplete before the inputtexts is not an option.
Thanks in advance.
In shortcut:
You can use <p:inputText> tag from primefaces. Then, you can disable all inputs. Add ajax to your autoComplete, and update other inputs after processing autoComplete. Inputs disable attribute can be set to depend on whether the autoComplete is not null. This way you will make the user to enter the autoComplet first.
you can try to set immediate="true" to p:autocomplete, so that it will be processed in the APPLY_REQUEST_VALUES phase, before all other components.
The simple solution is to update h:inputTexts when p:autocomplete item is selected to reflect its values:
<p:autoComplete id="myObject" value="#{myBean.myObject}" ...>
<p:ajax event="itemSelect" process="#this" update="fieldA fieldB fieldC fieldD" />
</p:autoComplete>
but this reverts user inputs on h:inputTexts. And since you can't move p:autocomplete on top, probably this is not acceptable too.
In case you can't/don't want to use ajax, you can force an early model update:
<p:autoComplete id="myObject" value="#{myBean.myObject}" immediate="true"
valueChangeListener="#{component.updateModel(facesContext)}" ... />
but, in my opinion, this is not very user friendly...
P.S. this time it's tested :)
There's no pretty way to get around this; your situation is already less than ideal and is hacky (re: not being able to simply reorder the fields). One workaround is for you to set fieldA and fieldB as attributes of myObject. In the converter, you could then pull the values off the components. Observe
Set attributes thus
<h:inputText id="fieldA" binding=#{fieldA}" />
<h:inputText id="fieldB" binding=#{fieldB}" />
<p:autoComplete id="myObject" value=#{myBean.myObject" converter="myObjectConverter">
<f:attribute name="fieldA" value="#{fieldA}"/>
<f:attribute name="fieldB" value="#{fieldB}"/>
</p:autoComplete>
The binding attribute effectively turns those components into page-scoped variables, allowing you to then pass them as attributes on your p:autocomplete
Get the values of those variables in your converter
//Retrieve the fields and cast to UIInput, necessary
//to retrieve the submitted values
UIInput fieldA = (UIInput) component.getAttributes().get("fieldA");
UIInput fieldB = (UIInput) component.getAttributes().get("fieldB");
//Retrieve the submitted values and do whatever you need to do
String valueA = fieldA.getSubmittedValue().toString();
String valueB = fieldB.getSubmittedValue().toString();
More importantly, why can't you just reorder the fields/logical flow of your form? You can avoid all this nasty business if you did

validating and displaying decimal numbers in JSF 2.0

I wonder how to validate an inputText text field and see if it matchs a decimal format.
And also in the rendering time how to format that text field with a specific format
I've done this :
<rich:column id="soldes_comptables">
<f:facet name="header">
<h:outputText value="Solde Comptable" />
</f:facet>
<h:inputText id="inputTextSC" value="#{file.soldes_comptables}"
label="Montant"
style="border-color:#F2F3F7;"
validatorMessage="The number must be decimal eg: 000.00"
>
<f:convertNumber pattern="#,###,##0.00"/>
<f:validateRegex pattern="^[0-9]+(\.[0-9]{1,2})?$"></f:validateRegex>
<rich:validator />
</h:inputText>
<rich:message for="inputTextSC"/>
</rich:column>
but it's not working as i want :(. please help me
You're mixing validation and conversion. The <f:validateRegex> applies only on String values, not on Number values, however, the <f:convertNumber> has already converted it from String to Number beforehand, so the <f:validateRegex> is rather useless to you. You should remove it and specify the message as converterMessage instead.
<h:inputText ... converterMessage="The number must be decimal eg: 000.00">
<f:convertNumber pattern="#,###,##0.00"/>
</h:inputText>
An alternative would be to create a custom converter extending NumberConverter and throw a ConverterException on improper input format based on some regex pattern matching.
See also:
validating decimals inputs in JSF
How validate number fields with validateRegex in a JSF-Page?

JSF Number Validation

Is there any inbuilt number validator tag in JSF that checks whether an input entered in h:inputext field is a number?
The first question was answered. Edited to explain the next problem:
<h:inputText id="maxrecs" value="#{simpleBean.numRecords}" required="false" maxlength="4" >
<f:convertNumber longOnly="true"/>
</h:inputText>
Backing Bean
private long numRecords = null;
If I use String or Integer object in the backing bean , value is not being set. Now when I use primitive int, 0 is being printed on the screen. I would like the screen to be empty.
You can use f:convertNumber (use the integerOnly attribute).
You can get more information here.
You can use:
<f:validateLongRange minimum="20" maximum="1000" />
Where minimum is the smallest number allowed and maximum is the largest.
Look here for more details
JSF Number validation for inputtext
mention f:converterNumber component in between h inputText component and mention the attributes integerOnly and type.
<h:inputText id="textMobileId" label="Mobile" styleClass="controlfont" value="#{UserRegistrationBean.textMobile}">
<f:convertNumber integerOnly="true" type="number" />
</h:inputText>
If you enter abcd in Mobile textbox at the time when you click on commandbutton it automatically shows an error like
Mobile: 'abcd' is not a number.
i8taken solution converts number into long without validation message (at least in my case: JSF2 / global messages per page). For proper validation message you can
1. check value in action method in bean;
or
2. use converter attribute for inputText:
<h:inputText id="maxrecs" value="#{simpleBean.numRecords}" maxlength="4" converter="javax.faces.Integer" />
You can simply use the passthrough, so first add this library
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
and after use this
<h:inputText id="numberId" pt:type="number" />

Resources