Data displayed on datatable can be edited at row or cell level, new rows can be added and edited right away.
<h:form id="form">
<p:growl id="msgs" showDetail="true"/>
<div class="card">
<h5>Row Editing</h5>
<p:dataTable id="products1" var="product" value="#{dtEditView.products1}" editable="true"
style="margin-bottom:20px">
<p:ajax event="rowEdit" listener="#{dtEditView.onRowEdit}" update=":form:msgs"/>
<p:ajax event="rowEditCancel" listener="#{dtEditView.onRowCancel}" update=":form:msgs"/>
<p:column headerText="Code">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{product.code}"/>
</f:facet>
<f:facet name="input">
<p:inputText id="modelInput" value="#{product.code}" style="width:100%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{product.name}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{product.name}" style="width:100%" label="Name"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Status">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{product.inventoryStatus}"/></f:facet>
<f:facet name="input">
<p:selectOneMenu value="#{product.inventoryStatus}" style="width:100%">
<f:selectItems value="#{dtEditView.inventoryStatusList}" var="status"
itemLabel="#{status.text}" itemValue="#{status}"/>
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Price">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{product.price}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</f:facet>
<f:facet name="input">
<p:inputNumber value="#{product.price}" style="width:100%" label="Price" symbol="$"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:6rem">
<p:rowEditor editTitle="Edit Row" cancelTitle="Cancel Edit" saveTitle="Save Row"/>
</p:column>
</p:dataTable>
</div>
<div class="card">
<h5>Cell Editing with Click and RightClick</h5>
<p:dataTable id="products2" var="product" value="#{dtEditView.products2}" editable="true"
editMode="cell" ref="cellProducts">
<p:ajax event="cellEdit" listener="#{dtEditView.onCellEdit}" update=":form:msgs"/>
<p:column headerText="Code">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{product.code}"/>
</f:facet>
<f:facet name="input">
<p:inputText id="modelInput2" value="#{product.code}" style="width:100%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{product.name}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{product.name}" style="width:100%" label="Name"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Status">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{product.inventoryStatus}"/>
</f:facet>
<f:facet name="input">
<p:selectOneMenu value="#{product.inventoryStatus}" style="width:100%">
<f:selectItems value="#{dtEditView.inventoryStatusList}" var="status"
itemLabel="#{status.text}" itemValue="#{status}"/>
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Price">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{product.price}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</f:facet>
<f:facet name="input">
<p:inputNumber value="#{product.price}" style="width:100%" label="Price" symbol="$"/>
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</div>
<div class="card">
<h5>Cell Editing with Double Click Event (dblclick)</h5>
<p:dataTable id="products3" var="product" value="#{dtEditView.products3}" editable="true" editMode="cell"
ref="cellCars2" editInitEvent="dblclick" style="margin-bottom:20px">
<p:ajax event="cellEdit" listener="#{dtEditView.onCellEdit}" update=":form:msgs"/>
<p:column headerText="Code">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{product.code}"/>
</f:facet>
<f:facet name="input">
<p:inputText id="modelInput3" value="#{product.code}" style="width:100%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{product.name}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{product.name}" style="width:100%" label="Name"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Status">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{product.inventoryStatus}"/>
</f:facet>
<f:facet name="input">
<p:selectOneMenu value="#{product.inventoryStatus}" style="width:100%">
<f:selectItems value="#{dtEditView.inventoryStatusList}" var="status"
itemLabel="#{status.text}" itemValue="#{status}"/>
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Price">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{product.price}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</f:facet>
<f:facet name="input">
<p:inputNumber value="#{product.price}" style="width:100%" label="Price" symbol="$"/>
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</div>
<div class="card">
<h5>Row Editing with Add</h5>
<p:dataTable id="products4" ref="products4" var="product" value="#{dtAddRowView.products1}"
editable="true">
<p:ajax event="rowEdit" listener="#{dtAddRowView.onRowEdit}" update=":form:msgs"/>
<p:ajax event="rowEditCancel" listener="#{dtAddRowView.onRowCancel}" update=":form:msgs"/>
<p:column headerText="Code">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{product.code}"/></f:facet>
<f:facet name="input"><p:inputText value="#{product.code}" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Name">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{product.name}"/></f:facet>
<f:facet name="input"><p:inputText value="#{product.name}" style="width:100%"
label="Name"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Status">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{product.inventoryStatus}"/></f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{product.inventoryStatus}" style="width:100%">
<f:selectItems value="#{dtEditView.inventoryStatusList}" var="status"
itemLabel="#{status}" itemValue="#{status}"/>
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Price">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{product.price}"/></f:facet>
<f:facet name="input"><p:inputText value="#{product.price}" style="width:100%"
label="Price"/></f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:6rem">
<p:rowEditor/>
</p:column>
</p:dataTable>
<p:commandButton value="Add new row" process="@this" update=":form:msgs" styleClass="mt-3"
action="#{dtAddRowView.onAddNew()}" oncomplete="PF('products4').addRow();"/>
</div>
<p:contextMenu for="products2" ref="cMenu">
<p:menuitem value="Edit Cell" icon="pi pi-search"
onclick="PF('cellProducts').showCellEditor();return false;"/>
<p:menuitem value="Hide Menu" icon="pi pi-times" onclick="PF('cMenu').hide()"/>
</p:contextMenu>
</h:form>