minValue attribute in inputNumber not working in JSF primefaces? - web

The inputNumber declaration below will not accept any input, however when I removed the minValue attribute, it accept input.
What am not doing wrong here?
code xhtml:
<a:column>
<p:inputNumber id="year"
value="#{consomationControleur.myYear}"
maxValue="#{now.year + 1900}"
minValue="2000"
>
<p:ajax event="blur" process="#this"/>
</p:inputNumber>
</a:column>
java CDI bean
#Getter
#Setter
#Named("consomationControleur")
#ViewScoped
public class ConsomationControleur implements Serializable {
private int myYear;
//...
}
jsf version 2.2 primefaces version 11
I tried to remove the maximum value.
I tried to set minValue to a negative value, it works, but I need the years 1990-2022. So I only need positive values.

I would like to make a note
minValue="1980" maxValue="#{now.year + 1900}" it works but because of JS
but because of JS When you write a value, you selected the input and you type a number (like 2), the JS triter this value, and as the minimum condition is 1980, automate re update the input and put the field to minimum value 1980.
to work you have to select only the 3rd number (8) and change it, change a number by one, it's bad, but it works like this .
or you using <f:validateLongRange minimum = "" maximum = "" />
<p:inputNumber value="#{consomationControleur.anneeActuel}" >
<f:validateLongRange minimum = "1900" maximum = "#{now.year + 1900}" />
<p:ajax event="blur" update="display2" process="#this"/> </p:inputNumber>

Related

PrimeFaces datatable fails sorting with active filter

PrimeFaces Version: 6.0
In my data table I can sort and filter columns but not both at the same time.
Following scenario:
Column1 Column2
http://someurl.com 1
http://anotherurl.com 5
When I enter a value into the Column1 filter. Only the filtered rows are visible. Now when I click on sort of Column1 I get the following result:
Column1 Column2
0
0
Column2 is mapped to a primitive value, that explains the zero value.
As a workaround I have added:
<p:ajax event="sort" onstart="PF('mytableWidget').filter();"/>
But I can still see the above empty result for some milliseconds, before the filter() function is executed.
<p:dataTable id="mytable" widgetVar="mytableWidget" value="#{bean.data}" var="item">
<p:column headerText="Column1" sortBy="#{item.column1}" filterBy="#{item.column1}" filterMatchMode="contains">
#{item.column1}
</p:column>
<p:column headerText="Column2" sortBy="#{item.column2}">
#{item.column2}
</p:column>
bean.data is mapped to an ArrayList<MyDataHolder>.
import lombok.Data;
import lombok.EqualsAndHashCode;
#Data
#EqualsAndHashCode(of = "column1")
public class MyDataHolder {
String column1;
int column2;
}
It seems to me you must make MyDataHolder serializable;
public class MyDataHolder implements Serializable
My best bet for an elaboration is the same as here (the same applies to ViewScoped beans). ViewScoped (and broader scoped) beans must be serializable, and therefore all their attributes must be the same.

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

Can't we give two values for one lable in JSF?

I have one label field which is license and I want give two license numbers for this..how to give two values here. I have one properties file (manageprofile) and one java class (manageprofiledatabean) which contains the license values
<h:outputLabel value="#('label.manageprofile.license')"/>
<h:outputText value="#{manageProfileDataBean.license}" />
<h:outputText escape="false" value=" "></h:outputText>
Concat both values in one string variable of manageProfileDataBean and then set it in
public class ManageProfileDataBean{
private String license = "";
private String val1 = "val1":
private String val2 = "val2";
public ManageProfileDataBean(){
license = val1+val2;
}
//setter getter
}
firstly, h:outputLabel is meant to be used for labelling input controls - it renders as the html <label> tag(e.g.)
<h:outputLabel for="myname" value="#{bean.labelValue}" />
<h:inputText id="myname" value="#{bean.name} />
If you need to specify multiple values in expression language you can do so like this:
<h:outputText value="#{bean.property1 bean.property2}"/>
so I guess in your case you would write it as
<h:outputText value="#{'label.manageprofile.license' manageProfileDataBean.license}" />
Finally, you don't need to use an h:outputText if you're not referenceing any propery so the last pair of nbsp characters don;t need to be in in outputText tag at all.

How to save h:inputText values of a h:dataTable? My attempt only saves the value of last row

I'm having trouble making a dataTable where each row has a inputText and a commandLink. When the link is clicked, only it's row's inputText's data is submitted.
Something like this?
<h:dataTable value="#{bean.items}" var="item">
<h:column>
<h:inputText value="#{bean.value}"/>
</h:column>
<h:column>
<h:commandLink action="#{bean.save}" value="save">
<f:setPropertyActionListener target="#{bean.item}" value="#{item}" />
</h:commandLink>
</h:column>
</h:dataTable>
Bean:
#RequestScoped
public class Bean {
private Item item;
private String value;
Right now, as it is, it's using the last row's inputText to fill the value. I wrapped another h:form, but it broke other things and I've learned that nested h:form is not the right way to do it hehe
What's the correct way to do this?
Thanks.
You're binding the value of all HTML input elements to one and same bean property. This is of course not going to work if all those HTML input elements are inside the same form. All values are subsequently set on the very same property in the order as the inputs appeared in the form. That's why you end up with the last value. You'd like to move that form to inside the <h:column> (move; thus don't add/nest another one).
The usual approach, however, would be to just bind the input field to the iterated object.
<h:inputText value="#{item.value}"/>
An alternative, if you really need to have your form around the table, is to have a Map<K, V> as bean property where K represents the type of the unique identifier of the object behind #{item} and V represents the type of value. Let's assume that it's Long and String:
private Map<Long, String> transferredValues = new HashMap<Long, String>();
// +getter (no setter necessary)
with
<h:inputText ... value="#{bean.values[item.id]}" />
This way you can get it in the action method as follows:
String value = values.get(item.getId());
By the way, if you happen to target Servlet 3.0 containers which supports EL 2.2 (Tomcat 7, Glassfish 3, etc), then you can also just pass the #{req} as a method argument without the need for a <f:setPropertyActionListener>.
<h:commandLink ... action="#{bean.save(item)}" />
See also:
How and when should I load the model from database for h:dataTable
How can I pass selected row to commandLink inside dataTable?
How to dynamically add JSF components

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