Search code examples
jsfprimefacesjsf-2

commandButton inside p:datatable is not working


I know there are similiar questions here but none of the solutions worked for me. Before I used primeface datatable every thing was working perfectly but I needed paginator of primefaces so I switched to primeface's datatable instead of default jsf datatable. The problem is I have a column named action where somebuttons will be placed. For instance one of the button is "Buy". When I click this button the program will take from product database and add it to cart database. This is working perfectly with jsf datatable. But in primefaces datatable it's either not doing anything or gives null point exception. This is my xhtml file. It gives null point exception if I click buy button for the first item in the datatable if I click for anything else it's not doing anything.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>Shopping</title>
<h:outputStylesheet library="css" name="Product-table.css" />
</h:head>
<body>

<h:outputLabel value="Welcome  #{loginBean.name}"></h:outputLabel>
<br></br>
<br></br>
<div style="width: 100%;">
    <div style="width: 75%; float: left;">
        <h2>Products</h2>
        <h:form>
            <p:dataTable var="product" value="#{databaseBean.products}"
                filteredValue="#{databaseBean.filteredProducts}"
                widgetVar="productWidget" paginator="true" rows="10"
                paginatorTemplate="{CurrentPageReport} {FirstPageLink}
                 {PreviousPageLink} {PageLinks} {NextPageLink}
                 {LastPageLink} {RowsPerPageDropdown}"
                rowsPerPageTemplate="5,10,15,20,25">

                <f:facet name="header">
                    <p:outputPanel>
                        <h:outputText value="Search:" />
                        <p:inputText id="globalFilter"
                            onkeyup="PF('productWidget').filter()" style="width:150px"
                            placeholder="Search text" />
                    </p:outputPanel>
                </f:facet>

                <p:column headerText="Id" filterBy="#{product.id}" filterMatchMode="contains">
                    <h:outputText value="#{product.id}" />
                </p:column>

                <p:column headerText="Name" filterBy="#{product.name}" filterMatchMode="contains" >
                    <h:outputText value="#{product.name}" />
                </p:column>

                <p:column headerText="Price" filterBy="#{product.price}" filterMatchMode="contains">
                    <h:outputText value="#{product.price}" />
                </p:column>

                <p:column headerText="Quantity" filterBy="#{product.quantity}" filterMatchMode="contains">
                    <h:outputText value="#{product.quantity}" />
                </p:column>

                <p:column headerText="Category" filterBy="#{product.category}" filterMatchMode="contains" >
                    <h:outputText value="#{product.category}" />
                </p:column>
                <p:column>
                    <f:facet name="header">Action</f:facet>
                    <h:form>
                        <h:commandButton type="submit" value="#{product.id}"
                            name="buyLink" action="#{databaseBean.addtoCart}">
                            <f:param name="productId" value="#{product.id}" />
                            <f:param name="userId" value="#{loginBean.name}" />
                        </h:commandButton>
                    </h:form>
                </p:column>
            </p:dataTable>
        </h:form>
    </div>
    <div style="width: 25%; float: right;">
        <h2>Cart</h2>
        <p:dataTable value="#{databaseBean.cart}" var="product"
            styleClass="product-table" headerClass="product-table-header"
            rowClasses="product-table-odd-row,product-table-even-row">
            <p:column>
                <f:facet name="header">Product ID</f:facet>
        #{product.productId}
            </p:column>
            <p:column>
                <f:facet name="header">Quantity</f:facet>
        #{product.quantity}
            </p:column>
        </p:dataTable>
    </div>
</div>

<h:form>
    <h:commandButton action="#{loginBean.logout}" value="logout"></h:commandButton>
</h:form>

This is the method that the button should call. As I said it's working perfectly in default jsf datatable so I do not think anything is wrong with the java code but the problem is in xhtml file.

public void addtoCart(){
    //userId = getUserID();
    ManageCart MC = new ManageCart();
    FacesContext fc = FacesContext.getCurrentInstance();
    Map<String,String> params = 
            fc.getExternalContext().getRequestParameterMap();
    String productIdString =  params.get("productId"); 
    int productId = Integer.parseInt(productIdString);
    MC.addToChart(userId, productId, 1);
    cart = mc.listCart(userId);
    products = mp.listProducts();
}

I would really appreciate any help. Thank you.


Solution

  • I found the solution. I needed to delete tag <h:form></h:form> from the code block of action column and it works.