Update shopping cart when change spinner value - ajax

I have a shopping cart, in my application is a Datatable. I have a spinner to show the number of that product, and I want that when spinner value changes, refresh my shopping cart, this is my code:
<p:dataTable var="carro" value="#{productoBean.productos}">
<f:facet name="header">
<h:outputText value="Carrito de la Compra" />
</f:facet>
<p:column headerText="Producto">
<h:outputText value="#{carro.producto.nombre}" />
</p:column>
<p:column headerText="Cantidad">
<p:spinner value="#{carro.cantidad}">
<p:ajax listener="#{productoBean.refreshCantidad}" update="#this" />
</p:spinner>
</p:column>
<p:column headerText="Precio/Unidad">
<h:outputText value="#{carro.producto.precioUnidad} €" />
</p:column>
<p:column headerText="Valor">
<h:outputText value="#{carro.valor} €" />
</p:column>
</p:dataTable>
I don't know how get the item which spinner change and update its values.
Please I need help, Thanks in advance.
Greetings.

Finally I did:
<p:column headerText="Cantidad">
<p:spinner value="#{carro.cantidad}" valueChangeListener="#{productoBean.updateCantidad}">
<p:ajax event="change" listener="#{productoBean.refreshCantidad(carro)}" update=":formCarrito" />
</p:spinner>
</p:column>
In productoBean.updateCantidad I have:
public void updateCantidad(ValueChangeEvent event) {
cantidad = (Integer) event.getNewValue();
}
And in productoBean.refreshCantidad(carro) as can be seen, carro is the param of the method:
public void refreshCantidad(Compra compra) {
carritoBean.addProduct(compra.getProducto(), cantidad);
}
This way I know what's the last value of the spinner and I can update my shopping cart.
Greetings.

Related

Attempting to edit a datatable nested inside of an editable datatable (Ajax Error I think)

I am attempting to make a nested (Through row expansion) data table editable which is inside of another editable datatable. It appears to be having a problem with the ajax rowEdit event. When I only have one datatable as editable e.g. comment out the nested ajax tag it works. But when I try to use both It returns an error saying :
Method not found: com.aglabexpress.Admin.Billing.CompleteInvoiceController#1146df77.editInvoiceItem(javax.faces.event.AjaxBehaviorEvent)"
Is this because of the double ajax events?
How do I rectify this while keeping both tables editable?
HTMLX:
<h:form id="mainForm" >
<p:dataTable id="mainFormTable" editable="true" value="#{completeInvoiceController.labNumberBill}" var="lab" paginator="true" rows="10" rowStyleClass="#{lab.colorStatus}">
<p:ajax event="rowEdit" listener="#{completeInvoiceController.editBill}" />
<p:column>
<p:rowToggler/>
</p:column>
...
...
<p:column headerText="Date" footerText="Date">
<p:cellEditor>
<f:facet name="output">
<p:outputLabel value="#{lab.creationDateString}" />
</f:facet>
<f:facet name="input">
<p:calendar value="#{lab.creationDate}" />
</f:facet>
</p:cellEditor>
</p:column>
...
...
<p:column headerText="Edit">
<p:rowEditor />
</p:column>
<p:rowExpansion>
<p:dataTable value="#{lab.invoiceItems}" var="item" editable="true">
<p:ajax event="rowEdit" listener="#{completeInvoiceController.editInvoiceItem}" />
...
...
<p:column headerText="Description" footerText="Description">
<p:cellEditor>
<f:facet name="output">
<p:outputLabel value="#{item.description}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{item.description}" />
</f:facet>
</p:cellEditor>
</p:column>
...
...
<p:column headerText="Edit">
<p:rowEditor />
</p:column>
</p:dataTable>
</p:rowExpansion>
Beans
public void editInvoiceItem(RowEditEvent event){
InvoiceItemConstructor itc = (InvoiceItemConstructor) event.getObject();
if(cih == null){
cih = new CompleteInvoiceHelper();
}
cih.updateItem(itc);
}
public void editBill(RowEditEvent event){
CompleteInvoiceLabNumberBill bill = (CompleteInvoiceLabNumberBill) event.getObject();
if(cih == null){
cih = new CompleteInvoiceHelper();
}
cih.updateBill(bill);
}
You need to replace your nested datatable event method signature to
public void editInvoiceItem(javax.faces.event.AjaxBehaviorEvent event)
Is this because of the double ajax events?
Yes. This is a known issue (which had been originally reported for nested p:tabView) which seems to be fixed since PrimeFaces 5.0.
You can find further information in a thread (from July 2013) of the PrimeFaces forum

Refresh p:dataTable without button click

I have a bean:
#ManagedBean
#SessionScoped
public class MainTable
{
static List<MainTableRow> rows;
public MainTable()
{
rows = new ArrayList<>();
}
public static boolean addRow(MainTableRow mainTableRow)
{
return rows.add(mainTableRow);
}
public List<MainTableRow> getRows()
{
return rows;
}
public void setRows(List<MainTableRow> rows)
{
MainTable.rows = rows;
}
}
And my xhtml page is:
<h:body>
<h3>Query Modeling Tool - Select Excel file</h3>
<h:form>
<p:fileUpload
fileUploadListener="#{fileUploadController.handleFileUpload}"
mode="advanced" dragDropSupport="false" update="messages"
sizeLimit="10000000" fileLimit="3" allowTypes="/(\.|\/)(xls)$/"
style="font-size: 14px" />
<p:growl id="messages" showDetail="true" />
<p:dataTable id="dataTable" var="mainTableRow"
value="#{mainTable.rows}" style="font-size: 14px">
<f:facet name="header">Main Table</f:facet>
<p:column sortBy="" headerText="Index">
<h:outputText value="#{mainTableRow.index}" />
</p:column>
<p:column sortBy="" headerText="Query">
<h:outputText value="#{mainTableRow.query}" />
</p:column>
<p:column sortBy="" headerText="S1">
<h:outputText value="#{mainTableRow.s1}" />
</p:column>
<p:column sortBy="" headerText="S2">
<h:outputText value="#{mainTableRow.s2}" />
</p:column>
<p:column sortBy="" headerText="S3">
<h:outputText value="#{mainTableRow.s3}" />
</p:column>
<p:column sortBy="" headerText="S9">
<h:outputText value="#{mainTableRow.s9}" />
</p:column>
<p:column sortBy="" headerText="Uygunluk">
<h:outputText value="#{mainTableRow.uygunluk}" />
</p:column>
<p:column sortBy="" headerText="Kural">
<h:outputText value="#{mainTableRow.kural}" />
</p:column>
<p:column sortBy="" headerText="Kaynak">
<h:outputText value="#{mainTableRow.kaynak}" />
</p:column>
<p:column sortBy="" headerText="Query Type">
<h:outputText value="#{mainTableRow.queryType}" />
</p:column>
<p:column sortBy="" headerText="User Intent">
<h:outputText value="#{mainTableRow.userIntent}" />
</p:column>
</p:dataTable>
</h:form>
</h:body>
"rows" in MainTable is filled by another class, after uploading a file.
After uploading I want to refresh dataTable without clicking any button.
How can I do it?
It can be solved by one of the following points:
1. <p:fileUpload> has an attribute update that is used to ajax-update the components with a specified list of comma/space-separated ids, so you need to add id of your data table to that attribute:
<p:fileUpload ... update="messages dataTable" />
2. When a file has been uploaded, the table can also be updated programmatically in your action method:
RequestContext context = RequestContext.getCurrentInstance();
context.addPartialUpdateTarget("<path_to_your_table>");
See also:
jsf/primfaces update ui components from server event

how to detect which row is concerned when changing autocomplete object inside datatable primefaces

I have this datatable :
<p:commandLink value="ajouter Ligne" update="lesarticles"
process="#this" actionListener="#{commandeMB.addLigne}" />
<p:dataTable id="lesarticles" var="car" widgetVar="carsTable"
rowKey="#{car.ligneCommandeFournisseurId}" selectionMode="single"
selection="#{commandeMB.selectedLigneCommandeFournisseur}"
value="#{commandeMB.commande.ligneCommandeFournisseurs}"
>
<p:column headerText="Numero">
<p:autoComplete id="art" required="true" var="p"
itemLabel="#{p.numero}" itemValue="#{p}" dropdown="true"
requiredMessage="Valeur requise" value="#{car.article}"
forceSelection="true" converter="#{articleConverter}"
completeMethod="#{commandeMB.completeArticle}">
<p:column>#{p.numero}</p:column>
<p:column>#{p.designation}</p:column>
<p:ajax event="itemSelect" listener="#{commandeMB.handleSelect}"
update="designation unite pu" />
</p:autoComplete>
<p:message for="art" display="text" />
</p:column>
<p:column headerText="designation">
<h:outputText id="designation"
value="#{car.article.designation}" />
</p:column>
<p:column headerText="unité">
<h:outputText id="unite"
value="#{car.article.unite.libelle}" />
</p:column>
<p:column headerText="PU">
<h:inputText id="pu" styleClass="monpu"
value="#{car.PUAchat}" />
</p:column>
<p:column headerText="Quantité">
<h:inputText binding="#{qte}" styleClass="maqte" value="#{car.qte}" >
</h:inputText>
</p:column>
<p:column headerText="Mt">
<h:outputText id="mt" styleClass="monmt"
value="#{car.mtLigne}" />
</p:column>
</p:dataTable>
I want when the user select one article(product in english) (througt autocomplete) I can detect which row is concerned by this selection to do do some treatements on managed bean side
as you see in the code I retrieve the selected article by :
public void handleSelect(SelectEvent event){
Article art = (Article) event.getObject();
}
but I want to retrieve also the row which contains this new article in the datatable
how can I achieve this
thank you in advance
<p:dataTable rowIndex="myIndex"/>
Then you can bind this value via;
<f:setPropertyActionListener target="#{bean.index}" value="#{myIndex}"/>
Or;
<f:param name="myIndex" value="#{myIndex}"></f:param>
To be able to retrieve the value which comes with f:param:
Map<String, String> map = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
int index = Integer.parseInt(map.get("myIndex"));
You can put those in a p:commandLink, p:commandButton or p:ajax.
I resolved this problem by that :
<p:column headerText="Numero">
<p:autoComplete id="art"
required="#{commandeMB.validation}" var="p"
itemLabel="#{p.numero}" itemValue="#{p}" dropdown="true"
requiredMessage="Valeur requise" value="#{car.article}"
forceSelection="true" converter="#{articleConverter}"
completeMethod="#{commandeMB.completeArticle}">
<p:column>#{p.numero}</p:column>
<p:column>#{p.designation}</p:column>
<p:ajax event="itemSelect" listener="#{commandeMB.handleSelect}"
update="designation unite pu mt" />
</p:autoComplete>
<p:message for="art" display="text" />
</p:column>
and in the managed bean I retrieve the concerned row by this :
FacesContext context = FacesContext.getCurrentInstance();
LigneCommandeFournisseur ligne_concernee =
context.getApplication().evaluateExpressionGet(context, "#{car}", LigneCommandeFournisseur.class);

Incell Editing in datatable for primefaces not sending edited values to event

I want a table with in-line editing option in datatable. I am able to write full code but when i am clicking on edit button, the value which i am getting from event object from server side is same as old. I am not getting new values.
how to get new values from event object.
<p:dataTable id="dataTable"
var="osList"
value="#{WLMPortalViewController.allOSInfo}" rowKey="#{osList.osName}"
paginator="true" rows="5"
paginatorPosition="bottom"
editable="true" >
<p:ajax event="rowEdit" update="#this" listener="#{WLMPortalDataController.saveOSData}"/>
<p:column headerText="Options" >
<p:rowEditor />
</p:column>
<p:column headerText="Version" >
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{osList.osVersion}" />
</f:facet>
<f:facet name="input">
<p:inputText id="inputosVer" required="true" requiredMessage="* Version can't Empty." value="#{osList.osVersion}" />
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
and my server side code look like this
public void saveOSData(RowEditEvent event){
System.out.print(event.getObject());
}

AJAX event is only firing once in a Primefaces dataTable

I have a dataTable that gets populated with rows. On clicking on a row, the include webpage updates with new infomation. Unfortunately, the ajax event only fires once. Here's the code:
.xhtml
<h:form id="form">
<f:loadBundle basename="com.company.messages" var="msgs" />
<p:tabView id="tabView" effect="fade" effectDuration="fast">
<p:tab title="#{msgs.activeInterestPlansTab}">
<p:dataTable var="plan" value="#{interestPlanReports.activePlans}"
rowKey="#{plan.planNumber}"
selection="#{interestPlanReports.selectedPlan}"
selectionMode="single">
<p:ajax event="rowSelect" listener="#{interestPlanReports.onRowSelect}"
update=":form:tabView:tiers" oncomplete="interestPlanPanel.show()" />
<p:ajax event="rowUnselect" listener="#{interestPlanReports.onRowUnselect}"
update=":form:tabView:tiers" oncomplete="interestPlanPanel.show()"/>
<p:column headerText="Plan Number">
#{plan.planNumber}
</p:column>
<p:column headerText="Description">
#{plan.planDescription}
</p:column>
<p:column headerText="Base Plan" >
#{plan.basePlanNumber}
</p:column>
<p:column headerText="Base">
#{plan.interestRateCodeReadable}
</p:column>
<p:column headerText="Base Rate">
<!-- #{plan.baseRatePlan} -->
TODO
</p:column>
<p:column headerText="Premium">
TODO
</p:column>
<p:column headerText="Effective Date">
<h:outputText value="#{plan.effectiveDate}" >
<f:convertDateTime pattern="MM/dd/yyyy" />
</h:outputText>
</p:column>
<p:column headerText="Expiration Date">
<h:outputText value="#{plan.expirationDate}" >
<f:convertDateTime pattern="MM/dd/yyyy" />
</h:outputText>
</p:column>
</p:dataTable>
<p:panel id="tiers" widget="interestPlanPanel">
<ui:include src="/interestplansearch/interestPlanDetail.xhtml">
<ui:param name="interestPlan" value="#{interestPlanReports.selectedPlan}"/>
</ui:include>
</p:panel>
</p:tab>
bean
public InterestPlan getSelectedPlan() {
if (selectedPlan == null)
{
selectedPlan = activePlans.get(0);
}
return selectedPlan;
}
public void setSelectedPlan(InterestPlan selectedPlan) {
this.selectedPlan = selectedPlan;
}
public void onRowSelect(SelectEvent event)
{
setSelectedPlan( (InterestPlan)event.getObject() );
}
public void onRowUnselect(UnselectEvent event) {
setSelectedPlan( (InterestPlan)event.getObject() );
}
Not sure what I'm missing. I appreciate any feedback. Thanks
UPDATE: Removing oncomplete from both rowSelect and rowUnselect fixes the issue on FireFox. However, on IE the first row select updates the panel. Any additional selects reverts to the original selection (update not row)

Resources