ajax call makes field empty - ajax

updated the code but not real change.
When I set the player I want to update the other select one menu with the current players club. But the menu will become completely empty. The bean will always return the correct value.
Navigating from the page and back will show the correct value. It will then always work as intended after the first time you navigate back.
<p:selectOneMenu value="#{player}"
converter="playerConverter" id="playerList">
<f:selectItem itemLabel="---" noSelectionOption="true" />
<f:selectItems value="#{servicePlayer.allPlayers}"
var="n"
itemValue="#{n}"
itemLabel="#{n.combinedName}"
itemLabelEscaped="true"/>
<p:ajax event="change" execute="#this" update="ClubMenu" actionListener="#{serviceHCP.getClubs(player)}"/>
<!-- p:ajax event="change" execute="#this" render="ClubMenu" /-->
</p:selectOneMenu>
<h:outputText value="Klubb"></h:outputText>
<p:selectOneMenu id="ClubMenu" value="#{serviceHCP.myClubList}" rendered="#{not empty serviceHCP.myClubList}">
<f:selectItems value="#{serviceHCP.getClubs(player)}" />
</p:selectOneMenu>
<h:outputText value="Serietyp"></h:outputText>
Backing bean function
public void getClubs(Player player) {
if (factory == null) {
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
}
EntityManager em = factory.createEntityManager();
//If we have a player just return that players club
Query q;
if (player == null || player.getClub() == null)
q = em.createQuery("select t from Club t");
else {
q = em.createQuery("select t from Club t where t.id = :playerID");
q.setParameter("playerID", player.getClub().getId());
}
myClubList = q.getResultList();
for (Club aClub : myClubList) {
System.out.println("Club list info: " + aClub);
}
System.out.println("Club Size: " + myClubList.size());
em.close();
}

You need to also process the playerList field:
<p:ajax process="#this" update="ClubMenu" />

Related

At least one/group of multiple fields required in JSF

I'm trying to do a search function of which I have multiple fields and need at least one of them required, or a group of them.
The only answer I found on StackOverflow is this one: How to validate if at least one of multiple input fields is entered?
And there are 2 solutions there: One uses Omnifaces (which I can't use due to project requirements), and the other is not elegant, because it grows a lot when the number of fields is big.
I have these fields for example:
<p:selectOneMenu value="#{backingBean.type}"id="type">
<f:selectItem itemLabel="#{constantsController.SELECT_TYPE_HEADER}"
itemDisabled="true" />
<f:selectItems
value="#{constantsController.getTypes().entrySet()}"
var="entry" itemValue="#{entry.key}" itemLabel="#{entry.value}" />
</p:selectOneMenu>
<p:inputText id="number" value="#{backingBean.number}"/>
<p:inputText id="year" value="#{backingBean.year}"/>
<p:inputText id="number2" value="#{backingBean.number2 }"/>
<p:selectOneMenu value="#{backingBean.state}"
id="state" filter="true" filterMatchMode="startsWith">
<f:selectItem itemLabel="Choose its state" disabled="true" />
<f:selectItems value="#{constantsController.getStates().entrySet()}"
var="entry" itemValue="#{entry.key}" itemLabel="#{entry.value}" />
</p:selectOneMenu>
<p:selectOneMenu id="entity"
value="#{backingBean.entity }">
<f:selectItem itemLabel="Select entity"
itemDisabled="true" />
<f:selectItem itemLabel="Entity1" itemValue="1"></f:selectItem>
<f:selectItem itemLabel="Entity2" itemValue="2"></f:selectItem>
</p:selectOneMenu>
<p:selectOneMenu id="documentType"
value="#{backingBean.documentType}">
<f:selectItems
value="#{constantsController.getDocumentTypes().entrySet()}"
var="entry" itemValue="#{entry.key}" itemLabel="#{entry.value}" />
</p:selectOneMenu>
<p:inputText id="documentNumber" value="#{backingBean.documentNumber}"/>
So as you can see, I have multiple fields. And the requirements dictate that I need one of the following required (I'll write the id's):
1- type + number + year
2- number2 + state
3- entity
4- documentType + documentNumber
So I when I click the commandButton, I need this to check if one of these groups (1, 2, 3 or 4) is filled.
Also, the groups in itself need to be required, i.e. let's say I already filled 'entity', and I also filled the 'year', it cannot let me advance since year needs to be accompanied by 'type' and 'number'.
I solved it by associating a boolean in the backing bean to each of the fields/group of fields. It's not an elegant solution, but I wasn't finding any other solution.
So what I did was define by group of fields in the backing bean a boolean initialized with true value:
private boolean typeNumberYear = true;
private boolean number2State = true;
private boolean entityRequired = true;
private boolean documentTypeDocumentName = true;
private boolean masterRequired = true;
then to validate them:
public void checkRequiredFields(){
if(!type.equals("") && number != 0 && year != 0)
typeNumberYear = false;
if(number2 != 0 && !state.equals(""))
number2State = false;
if(!entity.equals(""))
entityRequired= false;
if(!documentType.equals("") && documentNumber != 0)
documentTypeDocumentName = false;
if(!typeNumberYear || !number2State || !entityRequired || !documentTypeName)
masterRequired = false;
}
Since all this is in the backing bean, I can just put this function on the actionListener of the command button, while the action function is still in the controller.
<p:commandButton value="Search" icon="ui-icon-search"
actionListener="#{backingBean.checkRequiredFields}"
action="#{controller.searchButtonClicked}"/>
Now in the required parameter I just associated the respective boolean and the masterRequired on all of them. E.g. in the type, number and year inputs, I put the required as follows:
required = "backingBean.typeNumberYear and backingBean.masterRequired"
The only downside to this solution, is that in the interface, there will be appearing an asterisk on all the fields that are indicated above, but if you just input the entity for example, it will search as it is supposed to, and then it will update and remove the asterisks.

Change value of checkbox using ajax in JSF

I try to solve the following problem: i have a group of h:selectBooleanCheckbox that generates using ui:repeat:
<h:form>
<ui:repeat value="#{uiCheckboxList.list}" var="boxElement" varStatus="i">
<h:selectBooleanCheckbox id="a">
<f:attribute name="value" value="#{boxElement.enabled}"/>
</h:selectBooleanCheckbox>
<h:outputLabel value="#{boxElement.val}" for="a"/>
</ui:repeat>
</h:form>
Values and label's text stored in array list and controls by servlet:
#ManagedBean(name="uiCheckboxList")
#ApplicationScoped
public class CheckBoxListBean implements Serializable {
private ArrayList<BoxTuple> list;
// BoxTyple is class with 2 fields - val (double) and enabled (boolean)
public CheckBoxListBean() {
list = new ArrayList<>();
for(double i = -2.0; i <= 2.0; i += 0.5) {
list.add(new BoxTuple(i, false));
}
// Set first element to true
list.get(0).setEnabled(true);
}
public ArrayList<BoxTuple> getList() {
return list;
}
public void setList(ArrayList<BoxTuple> list) {
this.list = list;
}
And my problem is this: when you click on one of the h:selectBooleanCheckbox server asynchronously sent request with information about the changed box, and then change the values of the another boxes without reloading page. In other words, I need to get the behavior of radio boxes. Maybe it sounds silly, but I need to solve this problem. How can i implement this?
You can do something like this:
<h:form id="form">
<ui:repeat value="#{uiCheckboxList.list}" var="boxElement"
varStatus="i">
<h:selectBooleanCheckbox id="a">
<f:attribute name="value" value="#{boxElement.enabled}" />
<f:ajax render="form"
listener="#{uiCheckboxList.listen(boxElement)}" />
</h:selectBooleanCheckbox>
<h:outputLabel value="#{boxElement.val}" for="a" />
</ui:repeat>
</h:form>
(get rid of the varStatus if you don't use it)
public void listen(BoxTuple tuple) {
if (tuple.enabled)
for (BoxTuple t : list)
if (!t.equals(tuple))
t.setEnabled(false);
}

Table disappears after cell edit in primefaces (also data not saved)

I have an input field and a table on page. Whenever a number in a field changes (ajax listener to change event) - I want number of rows to change accordingly.
I pointed the table to an Arraylist in a Backing bean, and play with its size.
But then when I edit a value in the table - and press enter, the table disappears, and reappears only when I change field value again.
As a bonus, in debug mode, I see that backing arraylist always have empty values.
Here goes the Bean code:
#ManagedBean(name = "bean")
#ViewScoped
public class TestBean {
private List<String> hostnames = new ArrayList<String>();
private int copiesQuantityJustCopy;
public int getCopiesQuantityJustCopy() {
return copiesQuantityJustCopy;
}
public void setCopiesQuantityJustCopy(int copiesQuantityJustCopy) {
this.copiesQuantityJustCopy = copiesQuantityJustCopy;
}
public List<String> getHostnames() {
return hostnames;
}
public void setHostnames(List<String> hostnames) {
this.hostnames = hostnames;
}
public void onUpdateCount() {
int hostnamesCount = hostnames.size();
System.out.println("delta = " + hostnamesCount + " - " + copiesQuantityJustCopy);
int delta = hostnamesCount - copiesQuantityJustCopy;
if (delta > 0)
for (int i = 1; i < delta; i++)
hostnames.remove(delta);
if (delta < 0)
for (int i = 0; i < -delta; i++)
hostnames.add("");
}
}
and the view code:
<h:form id="form1">
<p:inputMask mask="9?99" maxlength="3" placeHolder=" " value="#{bean.copiesQuantityJustCopy}">
<p:ajax event="change" listener="#{bean.onUpdateCount()}" update=":form1:hostnamesTable" />
</p:inputMask>
<p:outputPanel id="hostnamesTable" rendered="true">
<p:dataTable value="#{bean.hostnames}" var="hostname"
id="hostnames" editable="true" editMode="cell">
<p:ajax event="cellEdit" update=":form1:hostnamesTable" process="#this" />
<p:column>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{hostname}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{hostname}" style="width:96%" />
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</p:outputPanel>
</h:form>
I think my answer won't help #Anton, but it may be helpful to another "stackers" facing same problem.
My problem is similar (dataTable dissapears when cellEdit event is completed). In my case the cause was the table update performed by ajax. Since I realy don't need table update after listener firied I simply removed update attribute and now everything works good to me.

Validate if new value of <h:inputText> is not higher than old value

I want to control the value in an <h:inputText> ..I want that once I leave the input fieldsif I have a higher value than the old value an error message is displayed and I can not validate fields after entering a value lower (the older value is loaded from the database)
I have done somthing like this :
<p:column headerText="Qte" >
<h:inputText value="#{ligne.qte}" styleClass="span12" required="true" valueChangeListener="#{myBean.changeQte}" >
<h:message id="message"></h:message>
<p:ajax event="keyup" listener="#{myBean.onQteChange}" update="message" />
</h:inputText>
</p:column>
in myBean I have this two methods :
public void onQteChange(){
String message =null;
int newqte = getQte();
if (newqte > previousQTE ){
message="invalid qte";
}
}
public void onQteChange(){
String message =null;
int newqte = getQte();
if (newqte > previousQTE ){
message="invalid qte";
}
}
Can someone tells me how can I do this because even if I try to make ajax call into my inputtext I have no result ?
You can use :
public void onQteChange(){
String message =null;
int newqte = getQte();
if (newqte > previousQTE ){
message="invalid qte";
FacesContext.getCurrentInstance().addMessage(
"message",new FacesMessage(FacesMessage.SEVERITY_ERROR, message,message));
}
}
<p:column headerText="Qte" >
<h:inputText value="#{ligne.qte}" id="x" styleClass="span12" required="true" valueChangeListener="#{myBean.changeQte}" >
<p:ajax event="keyup" listener="#{myBean.onQteChange}" update="message" />
</h:inputText>
<h:message id="message" for="x" />
</p:column>

Problems with ajax in jsf updating an output text field

I'm new to JSF and in class we should just set up a little "Pizza-Service" with logins etc. On the Page where i want to prepare my Order as a user I've a data table (primeface data table) with 4 columns. The last one is for the number of pizza of the type in the current cell.
What I want: If I am typing in a Number i want to set up a current Order (works fine so far with ajax) in the same moment i just want to show the user the current price. This is the little thing that is not working.
When I am using the tag there is just nothing happening and if I am taking the tag I'm getting this mistake:
<f:ajax> contains an unknown id 'ausgabe' - cannot locate it in the context of the component menge
What I thought was take the ajax tag set up a function (take the current order) and render an output text where the calculated price is shown directly. I called those function in german so bestellungAufnehmen = takeOrder and preisBerechnen = calculatePrice.
Thanks if someone could help me!
Here is the xhtml:
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<p:dataTable id="table" var="pizza" value="#{model.getPizzen()}">
<p:column headerText="Nr">
<h:outputText value="#{pizza.nr}"/>
</p:column>
<p:column headerText="Artikel">
<h:outputText value="#{pizza.name}"/>
</p:column>
<p:column headerText="Preis">
<h:outputText value="#{pizza.preis}"/>
</p:column>
<p:column headerText ="Menge">
<h:inputText id="menge" value="#{bestellung.anzahl}">
<f:ajax event="keyup" render="ausgabe" listener="#{bestellung.bestellungAufnehmen(pizza)}"/>
</h:inputText>
</p:column>
</p:dataTable>
<h:outputLabel value="Zu Zahlen: "/>
<h:outputText id="ausgabe" value="#{bestellung.preisBerechnen()} €"/>
</h:form>
</h:body>
and here is the the Bean with those functions.
#Named
#SessionScoped
public class Bestellung implements Serializable {
private static int bstzaehler=0;
private int bstnr;
private Map<String,Bestellposten> posten;
private int anzahl;
public Bestellung(){
this.bstnr=++bstzaehler;
this.posten = new HashMap<>();
}
/**
* #return the bstnr
*/
public int getBstnr() {
return bstnr;
}
/**
* #param bstnr the bstnr to set
*/
public void setBstnr(int bstnr) {
this.bstnr = bstnr;
}
public void bestellungAufnehmen(Pizza pizza){
if(this.posten.containsKey(pizza.getName()) == false){
Bestellposten b = new Bestellposten(this.getAnzahl(), pizza);
this.posten.put(pizza.getName(),b);
} else {
if(this.getAnzahl() > 0 ){
Bestellposten tmp = this.posten.get(pizza.getName());
tmp.setMenge(this.getAnzahl());
} else {
this.posten.remove(pizza.getName());
}
}
System.out.println("groesse: "+posten.size());
System.out.println("akt preis: "+this.preisBerechnen());
}
/**
* #return the anzahl
*/
public int getAnzahl() {
return anzahl;
}
/**
* #param anzahl the anzahl to set
*/
public void setAnzahl(int anzahl) {
this.anzahl = anzahl;
}
public double preisBerechnen(){
double sum = 0.0;
for(String key : this.posten.keySet()){
Pizza tmp = this.posten.get(key).getPizza();
sum += tmp.getPreis() * this.posten.get(key).getMenge();
}
return sum;
}
}
Try giving the full qualified id for the component:
<h:form id="frmPizza">
<p:dataTable id="table" var="pizza" value="#{model.getPizzen()}">
<p:column headerText="Nr">
<h:outputText value="#{pizza.nr}"/>
</p:column>
<p:column headerText="Artikel">
<h:outputText value="#{pizza.name}"/>
</p:column>
<p:column headerText="Preis">
<h:outputText value="#{pizza.preis}"/>
</p:column>
<p:column headerText ="Menge">
<h:inputText id="menge" value="#{bestellung.anzahl}">
<f:ajax event="keyup" render=":frmPizza:ausgabe" listener="#{bestellung.bestellungAufnehmen(pizza)}"/>
</h:inputText>
</p:column>
</p:dataTable>
<h:outputLabel value="Zu Zahlen: "/>
<h:outputText id="ausgabe" value="#{bestellung.preisBerechnen()} €"/>
</h:form>
I think, you should use update attribute to update that outputText, like update=":FormId:ausgabe"
<f:ajax event="keyup"
render=":frmPizza:ausgabe"
listener="#{bestellung.bestellungAufnehmen(pizza)}"
update=":frmPizza:ausgabe" />
The solution of luiggi worked but i couldnt answer directly because of my "low-level" here.
Iam not on my computer right now but isnt "update" an attribute of p:ajax and not of f:ajax and is the same as render? but i will try it aswell later on.
thx!

Resources