I created another page which is to document employee (travel) expenses, but we call it "Driver Money" instead. This xhtml page contains p:dataTable p:subTable as well, and I wanted to document my experience/findings here.
Anyway, to meet a requirement requested by one of my brothers, I added a Paid Yes/No (selectOneMenu) and paid date (p:calendar). To duplicate behavior as on other existing pages, when Paid yes/no is (selectOneMenu) is changed by enduser, then paid date will be defaulted to current date or set to Null (if paid = No), and then is done via an AJAX request/update. That worked fine, but that was too much work for the target enduser which would use the page more than anyone else would, so I removed the selectOneMenu and p:calendar, also because of issues I had with 'java double comparison' (if expense money > 0.0, etc...). anyway, the selectOneMenu p:ajax successfully called bean method.
Hmmm, i cannot remember... i had an issue adding some type of p:commandLink or p:ajax that seemed as though it never called the bean for whatever reason, and I think it was the selectOneMenu that I mentioned in the previous paragraph above. BUT, there is a p:commandLInk on every row to re-calculate totals per row, enduser click on the Totals hyperlink, and totals for that row will be updated via AJAX (p:commandLink).
Below is the xhtml for this page, and all is working well. View p:commandLInk in f:facet header and p:commandLink in each row (for calculating row total).
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:o="http://omnifaces.org/ui"
xmlns:of="http://omnifaces.org/functions">
<ui:composition>
<h:form id="driverMoneyForm">
<ui:include src="/pf_ajaxStatus.xhtml"/>
<p:growl id="formMessages" showDetail="true" showSummary="false" />
<p:layout style="position: absolute; top: 0px; bottom: 5px; left: 5px; right: 5px; overflow: auto;">
<p:layoutUnit position="north" size="160">
<p:panel id="browseDriverMoneyPanel" styleClass="panel-title-centeralign" header="DRIVER MONEY">
<h:panelGrid columns="2" cellspacing="1">
<h:outputText value="Order:" />
<h:selectOneMenu id="filterOrderId" value="#{pf_ordersController.filterOrderId}">
<f:selectItem itemLabel="#{pf_ordersController.selectOneFilterOrderId}" itemValue="0" />
<f:selectItems value="#{pf_ordersController.selectOneOrderForDriverMoney}"
var="selectOneOrder" itemLabelEscaped="false"
itemValue="#{selectOneOrder.orderId}"
itemLabel="#{pf_ordersController.getOrderTitleWithOCPOC(selectOneOrder)}"/>
<p:ajax partialSubmit="true" listener="#{pf_ordersController.filterOrderIdSelected()}" update=":pageContentPanel"/>
</h:selectOneMenu>
</h:panelGrid>
<h:panelGroup layout="block" style="width: 100% !important; text-align: center !important;" >
<h:panelGrid columns="4" width="100%" style="text-align: center !important;" >
<h:panelGrid columns="2" cellspacing="1">
<h:outputText value="Driver:" />
<h:selectOneMenu id="filterDriver" value="#{pf_ordersController.filterDriver}">
<f:selectItem itemLabel="#{pf_ordersController.selectOneFilterDriver}" itemValue="0" />
<f:selectItems value="#{pf_ordersController.selectOneDriverForPayrollAndDriverMoney}"
var="selectOneDriver" itemLabel="#{selectOneDriver.driverName}" itemValue="#{selectOneDriver.driverId}"/>
<p:ajax partialSubmit="true" listener="#{pf_ordersController.filterDriverSelected()}" update=":pageContentPanel"/>
</h:selectOneMenu>
</h:panelGrid>
<h:panelGrid columns="2" cellspacing="1">
<h:outputText value="Trip Date FROM:" />
<p:inputText id="filterTripDateFromOnMobile"
value="#{pf_ordersController.filterTripDateFrom}"
label="Trip Date FROM" type="date"
rendered="#{pf_usersController.loggedInViaAndroid == 'Y'}">
<f:convertDateTime pattern="yyyy-MM-dd" />
<p:ajax partialSubmit="false" update=":pageContentPanel"
listener="#{pf_ordersController.filterTripDateFromSelectedOnMobile()}"/>
</p:inputText>
<p:calendar id="filterTripDateFrom" value="#{pf_ordersController.filterTripDateFrom}"
mode="popup" showOn="button" navigator="true" effect="fadeIn"
pattern="MM/dd/yyyy" size="12"
rendered="#{pf_usersController.loggedInViaAndroid == 'N'}">
<p:ajax partialSubmit="true" event="dateSelect" listener="#{pf_ordersController.filterTripDateFromSelected}" update=":pageContentPanel" />
</p:calendar>
</h:panelGrid>
<h:panelGrid columns="2">
<h:outputText value="Trip Date TO:" />
<p:inputText id="filterTripDateToOnMobile"
value="#{pf_ordersController.filterTripDateTo}"
label="Trip Date TO" type="date"
rendered="#{pf_usersController.loggedInViaAndroid == 'Y'}">
<f:convertDateTime pattern="yyyy-MM-dd" />
<p:ajax partialSubmit="false" update=":pageContentPanel"
listener="#{pf_ordersController.filterTripDateToSelectedOnMobile()}"/>
</p:inputText>
<p:calendar id="filterTripDateTo" value="#{pf_ordersController.filterTripDateTo}"
mode="popup" showOn="button" navigator="true" effect="fadeIn"
pattern="MM/dd/yyyy" size="12"
rendered="#{pf_usersController.loggedInViaAndroid == 'N'}">
<p:ajax partialSubmit="true" event="dateSelect" listener="#{pf_ordersController.filterTripDateToSelected}" update=":pageContentPanel" />
</p:calendar>
</h:panelGrid>
<h:panelGroup>
<p:commandLink value="Save changes" update=":pageContentPanel"
actionListener="#{pf_ordersController.saveDriverMoneyOrderList()}"/>
</h:panelGroup>
</h:panelGrid>
</h:panelGroup>
</p:panel>
</p:layoutUnit>
<p:layoutUnit position="center">
<h:inputHidden id="viewOrderId" value="#{pf_ordersController.selectedOrderId}" />
<p:dataTable id="driverMoneyDataTable" var="order"
value="#{pf_ordersController.driverMoneyOrderList}"
style="font-size: 75% !important;">
<p:columnGroup type="header">
<p:row>
<p:column headerText="Order"/>
<p:column colspan="9" headerText=""/>
</p:row>
<p:row>
<p:column headerText="" />
<p:column headerText="Name" />
<p:column headerText="Begin/End" />
<p:column headerText="Layovers" />
<p:column headerText="Parking" />
<p:column headerText="Permits" />
<p:column headerText="Tolls" />
<p:column headerText="Meals" />
<p:column headerText="Gratuity" />
<p:column headerText="Total Cash" />
</p:row>
</p:columnGroup>
<p:subTable var="orderDriver" value="#{order.orderDrivers}">
<f:facet name="header">
<p:commandLink value="View" update=":pageContentPanel"
onstart="document.getElementById('driverMoneyForm:viewOrderId').value = #{order.orderId};"
actionListener="#{pf_ordersController.prepareViewOnly()}"/>
<h:outputText escape="false" value=" | "/>
<h:outputText escape="false"
value="#{order.rowNumber} of #{pf_ordersController.driverMoneyOrderList.size()}: #{order.orderTitle} #{order.orderDrivers.size()} row(s)"/>
</f:facet>
<p:column style="text-align: left !important;">
<h:outputText value="#{orderDriver.orderCostDetails.serviceAbbr}#{orderDriver.orderCostDetails.nbrOfPassengers}" />
</p:column>
<p:column>
<h:outputText value="#{orderDriver.driver.driverName}" />
</p:column>
<p:column>
<h:outputText escape="false"
value="#{pf_ordersController.getTripDateDisplay(orderDriver.beginDate, orderDriver.endDate, true, true, true)}"/>
</p:column>
<p:column>
<p:inputText size="7" styleClass="number_alignright"
label="Layovers" value="#{orderDriver.layovers}">
<f:convertNumber minFractionDigits="2"/>
</p:inputText>
</p:column>
<p:column>
<p:inputText size="7" styleClass="number_alignright"
label="Parking" value="#{orderDriver.parking}">
<f:convertNumber minFractionDigits="2"/>
</p:inputText>
</p:column>
<p:column>
<p:inputText size="7" styleClass="number_alignright"
label="Permits" value="#{orderDriver.permits}">
<f:convertNumber minFractionDigits="2"/>
</p:inputText>
</p:column>
<p:column>
<p:inputText size="7" styleClass="number_alignright"
label="Tolls" value="#{orderDriver.tolls}">
<f:convertNumber minFractionDigits="2"/>
</p:inputText>
</p:column>
<p:column>
<p:inputText size="7" styleClass="number_alignright"
label="Meals" value="#{orderDriver.meals}">
<f:convertNumber minFractionDigits="2"/>
</p:inputText>
</p:column>
<p:column>
<p:inputText size="7" styleClass="number_alignright"
label="Gratuity" value="#{orderDriver.gratuity}">
<f:convertNumber minFractionDigits="2"/>
</p:inputText>
</p:column>
<p:column style="text-align: right !important;">
<p:commandLink title="Click # to update value."
partialSubmit="false" update=":pageContentPanel">
<h:outputText value="#{pf_ordersController.getOrderDriverTotalCash(orderDriver)}">
<f:convertNumber minFractionDigits="2" type="currency"/>
</h:outputText>
</p:commandLink>
</p:column>
</p:subTable>
<p:columnGroup type="footer">
<p:row>
<p:column headerText="" />
<p:column headerText="Name" />
<p:column headerText="Begin/End" />
<p:column headerText="Layovers" />
<p:column headerText="Parking" />
<p:column headerText="Permits" />
<p:column headerText="Tolls" />
<p:column headerText="Meals" />
<p:column headerText="Gratuity" />
<p:column headerText="Total Cash" />
</p:row>
<p:row>
<p:column headerText="Order"/>
<p:column colspan="9" headerText=""/>
</p:row>
</p:columnGroup>
</p:dataTable>
</p:layoutUnit>
</p:layout>
</h:form>
</ui:composition>
</html>
Oh, I did recognize that my footer columnGroup is not displaying for whatever reason.