How to attach an ajax event to a non-ClientBehaviorHolder component - jsf

In a form I have a p:inputText and a p:colorPickeras following :
<h:outputText value="#{messages.titre}" />
<p:inputText value="#{beanPlanningRessource.equipe.typeRessource.titre}">
</p:inputText>
<h:outputText value="#{messages.couleur}" />
<p:colorPicker value="#{beanPlanningRessource.equipe.typeRessource.couleur}">
</p:colorPicker>
And I have a p:commandButton which call a managedBean method as following :
<p:commandButton widgetVar="ajouter_equipe"
style="visibility: hidden;"
actionListener="#{beanPlanningRessource.ajouterEquipe()}" process="#this"
update=":#{p:component('dataTableEquipe')}, :#{p:component('formEquipe')}, :msgs" >
</p:commandButton>
The problem here is that the value in the p:inputText and p:colorPicker are always null in the managed bean, so in the p:inputText I added this line :
<p:ajax event="change" process="#this" />
and nowbeanPlanningRessource.equipe.typeRessource.titre is updated with the value in the p:inputText.
The problem I still have is that the p:colorPicker is a non-ClientBehaviorHolder component so I can't attach p:ajax to it and neither a f:ajax', so the value attached to thep:colorPicker:(beanPlanningRessource.equipe.typeRessource.couleur`) is always null.
How can I solve this?

Beside jquery you can also use the valueChangeListener
html:
<p:colorPicker valueChangeListener="#{beanPlanningRessource.colorChanged}" value="#{beanPlanningRessource.equipe.typeRessource.couleur}"/>
bean:
colorChanged(ValueChangeEvent event){
String newColor = event.getNewValue();
//do whatever you want with the new value
}

Related

How to update a specific cell on a PrimeFaces dataTable

In my dataTable I am linking each article with a specific task.
On the click of a commandButton a list of tasks shows up, so I want on the select of a task, update a specific cell in the dataTable (outputText with id="columnTache") without updating the rest of my dataTable.
<p:dataTable value="#{myController.articleList}"
id="tabArticle"
var="article"
rowKey="#{article.id}" >
<p:column headerText="quantite" >
<pe:inputNumber value="#{article.quantite}" />
</p:column>
<p:column headerText="taches" >
<h:outputText value="#{article.tache.libelleTache}" id="columnTache" />
</p:column>
<p:column headerText="taches" >
<p:commandButton oncomplete="PF('dialogTasks').show();" update=":formSelectAffecterTache">
<p:ajax event="click" listener="#{myController.setArticle(article)}" />
</p:commandButton>
</p:column>
</p:dataTable>
<p:dialog header="#{bundleTech.lbl_taches}" widgetVar="dialogTasks" >
<h:panelGrid columns="1" >
<h:form id="formSelectAffecterTache">
<ui:include src="/pages/listTacheSelect.xhtml">
<ui:param name="bean" value="#{myController}" />
<ui:param name="action" value="affecterTache" />
</ui:include>
</h:form>
</h:panelGrid>
</p:dialog>
The update of my dataTable is in the managed bean:
public void affecterTache() {
article.setTache(selectedSingleTache);
RequestContext.getCurrentInstance().update("form:tabArticle");
}
A dataTable is a naming container, so components within it will be prepended with the dataTable's id. Also, each iteration of data presented in the table (each row) will have effect of the generated ids. Since a form is also a naming container, your outputText component ids will be generated as formId:tabArticle:0:columnTache in the first row, formId:tabArticle:0:columnTache in the second row, etc.
If you would set an id on your commandButton you will get formId:tabArticle:0:myButton, formId:tabArticle:1:myButton etc. You can use this id in your click handler to create the corresponding inputText clientId. But, since you pass article to a method, you are not able to check which button was clicked. So first of all change the click listeners method to:
public void useArticle(AjaxBehaviorEvent event) {
UIComponent component = event.getComponent();
}
Now, you know which button was clicked (event.getComponent()), but you need your article as well. You can set that as an attribute to your button in XHTML:
<p:commandButton id="myButton"
oncomplete="PF('dialogTasks').show();"
update=":formSelectAffecterTache">
<p:ajax event="click"
listener="#{myController.useArticle}" />
<f:attribute name="article"
value="#{article}" />
</p:commandButton>
This attribute can be read in your listener:
Article article = (Article) component.getAttributes().get("article");
Now, for updating the inputText, simply use the button's clientId:
String update = component.getClientId().replace(":myButton", ":columnTache");
Store it in your bean, and when you are ready to do so, update:
RequestContext.getCurrentInstance().update(update);
See also:
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
Send additional parameter to Ajax event listener

Capturing primefaces <p:autoComplete> change event (detect emptying)

i got a question concerning an Primefaces autocomplete. Rigth now i am updating a field with the value of a property of the selected value in the autocomplete, like this:
This is in my xhtml:
<p:autoComplete
value="#{trFitoModel.selectedProducte}"
id="nomComercial"
completeMethod="#{trFitoBacking.completeProducte}"
var="producte" itemLabel="#{producte.nom}"
itemValue="#{producte}" converter="#{ProducteFitoConverter}"
forceSelection="true"
onkeyup="this.value = this.value.toUpperCase();">
<p:ajax event="itemSelect"
listener="#{trFitoBacking.handleSelect}"
update="text" global="false" />
<f:validator validatorId="qea.validators.EmptyFieldValidator" />
<f:attribute name="validationTitle" value=" NomComercial " />
</p:autoComplete>
</p:column>
<p:column>
<h:outputLabel>#{msgI18N.trFito}</h:outputLabel>
<h:outputText id="text"
value="#{traFitoBacking.resgistre}">
</h:outputText>
</p:column>
And this is my Backing Bean:
public void handleSelect(SelectEvent event) {
ProducteFitosanitari p=(ProducteFitosanitari)event.getObject();
setResgistre(Integer.toString(p.getNumRegistre()));
}
This works, but now I'm trying to update the outputText with id "text" with an empty String when the value of the autocomplete is empty.
How can I capture the event triggered when p:autoComplete is emptied?
Primefaces autoComplete generates 2 events: "change" and "itemSelect", for 2 methods of changing its content: typing or selecting from dropdown list. So you need to register 2 p:ajax listeners:
<p:autoComplete ... >
<p:ajax event="itemSelect" listener="#{bean.action}" process="#form"/>
<p:ajax event="change" listener="#{bean.action}" process="#form"/>
</p:autoComplete>
You'll need also 2nd server method signature:
public void action(AjaxBehaviorEvent event)
for capturing 'change' event.
Instead of event you can use onstart attribute with JavaScript to run... More options for p:ajax you'll find in Primefaces Users Guide, section "AjaxBehavior".

Execute Command after hit Enter in a inputText

Mojarra 2.1.5 / PrimeFaces 3.5
I dont know how to explain that.I have one inputText and commandButton
When I type something in inputText and hit Enter I need the commandButton be executed automatically.
<p:inputText id="txtProducao" required="false"
value="#{ManagedBean.xxxPreco.producaoDia}"
requiredMessage="#{bundle.xxPreco_xProdx}>
</p:inputText>
<p:commandButton id="buttonProducaoDia"
icon="ui-icon-check"
actionListener="#{ManagedBean.calculaProdxxx}"
update="txtValorSoma">
</p:commandButton>
I need to type some value for each inputText and after hit Enter I need the respective commandButton be executed :
If you have a single p:commandButton, then pressing ENTER should submit the form. If you have many p:commandButton in the form. You can define the one which is the default submitted button by using the p:defaultCommand.
<p:inputText id="txtProducao" required="false"
value="#{ManagedBean.xxxPreco.producaoDia}"
requiredMessage="#{bundle.xxPreco_xProdx}>
</p:inputText>
<p:commandButton id="buttonProducaoDia"
icon="ui-icon-check"
actionListener="#{ManagedBean.calculaProdxxx}"
update="txtValorSoma">
</p:commandButton>
<p:defaultCommand target="buttonProducaoDia" />
[Edit]
I think that you have to solve it using JavaScript, like this:
<p:inputText id="txtProducao" required="false"
value="#{ManagedBean.xxxPreco.producaoDia}"
requiredMessage="#{bundle.xxPreco_xProdx}>
<p:ajax event="keydown" update="#form" onstart="if (event.keyCode != 13) { return false; }" />
</p:inputText>
You can also add an actionListener to the p:ajax element. In JavaScript, you could also call a submit.

set selected object from selectOneMenu to inputText in jsf

I have problem with jsf. My jsf code is:
<h:form>
<p:selectOneMenu style="text-align:left;"
value="#{contractBean.selectedCust}" converter="CustomerConverter">
<f:selectItems value="#{classificatorBean.customerList}"
var="customer" itemLabel="#{customer.name} #{customer.sname}" itemValue="#{customer}" />
<p:ajax event="change" update="custTel" />
</p:selectOneMenu>
<p:inputText id="custTel" value="#{contractBean.selectedCust.name} " />
</h:form>
and I have managed bean (Contractbean) with getter and setter functions of selectedCust Customer object. My problem is when menu changed object dont show customers tel number.
try to use ajax like this:
<p:ajax event="change" process="#this" update="custTel" />

valuechangelistener does not populate values in text box

Here is my jsp:
<h:selectOneMenu value="#{member.dependentName}" onchange="this.form.submit()"
immediate="true" valueChangeListener="#{member.getDependentAddress}">
<f:selectItems value="#{member.dependentList}" />
</h:selectOneMenu>
<h:inputText value="#{member.personName}" immediate="true" />
<h:inputText value="#{member.dob}" immediate="true" />
And this, the function valuechangelistener fires.
public void getDependentAddress(ValueChangeEvent e) {
setPersonName((getDependentsList().get(e.getNewValue().toString())
.getDependentName()));
setDob(getDependentsList().get(e.getNewValue().toString()).getBirth());
System.out.println("New dob value : " + dob);
System.out.println("New name value : " + personName);
FacesContext.getCurrentInstance().renderResponse();
}
The two sysouts give the new value in the console but once the page loads, the fields are blank. I have tried all scopes for the bean. No go. What am i missing?
Thanks
You missed nothing. You've just something too much. To get it to work, you should remove immediate="true" from the to-be-changed components.
<h:selectOneMenu value="#{member.dependentName}" onchange="this.form.submit()"
immediate="true" valueChangeListener="#{member.getDependentAddress}">
<f:selectItems value="#{member.dependentList}" />
</h:selectOneMenu>
<h:inputText value="#{member.personName}" />
<h:inputText value="#{member.dob}" />
The immediate="true" on an UIInput component will cause its validations phase to take place in apply request values phase instead. This gives you the opportunity to use FacesContext#responseComplete() inside a valueChangeListener method skip other components which doesn't have immediate="true" set from being processed. As you have now, with immediate="true", they are also processed.
Please note that this is essentially a hack from the old JSF 1.x ages. If you're already using JSF 2.x, you should be using <f:ajax listener> instead.
<h:selectOneMenu value="#{member.dependentName}">
<f:selectItems value="#{member.dependentList}" />
<f:ajax listener="#{member.getDependentAddress}" render="name dob" />
</h:selectOneMenu>
<h:inputText id="name" value="#{member.personName}" />
<h:inputText id="dob" value="#{member.dob}" />
with
public void getDependentAddress() {
Dependent dependent = getDependentsList().get(dependentName); // Isn't that actually a Map instead of List?
personName = dependent.getDependentName();
dob = dependent.getBirth();
}

Resources