How to include a primeface column into a composite - jsf

I have a primefaces datatable with a lot of similar columns such as
<p:column filterBy="#{element.value}" filterFunction="#{applicationHelperController.filterByNumber}" styleClass="ps-90-header" >
<f:facet name="header">
<p:tooltip for="#next" value="Some header tooltip"/>
<h:outputText id="#{header}_id" value="Some header" styleClass="ps-90-header" />
</f:facet>
<h:outputText value="#{element.value}" />
</p:column>
Is there a way of creating a composite for it such as to write
<mine:column value="#{element.value}" header="Some header" headerTooltip="Some header tooltip" />
I've been searching/trying things for a day now without any real success.
I've managed to use an <ui:include...> with params but it's almost as verbose as the original
<ui:include src="/WEB-INF/includes/countColumn.xhtml" >
<ui:param name="value" value="#{element.value}"/>
<ui:param name="header" value="Some header"/>
<ui:param name="headerTooltip" value="Some header tooltip"/>
</ui:include>
I've tried using taglib as preconized here How to create a composite component for a datatable column? even if it uses richfaces and this solution Column as Composite Component inside DataTable but none work.
I've also read somewhere that <p:column...> should be a direct child of <p:datatable...> so it is not possible but I believe that was with old primefaces version (3 or 4).
So, does anyone know if it is possible with Primefaces 6 or 8 and if so how?

You can use custom Facelet tags to DRY your code.
Simply create tags for columns like:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<p:column ...>
...
</p:column>
</ui:composition>
This is how a table looks in one of our projects:
<dt:dataTable controller="#{controller}"
sortField="activationDate">
<dt:column id="id"/>
<dt:columnDate id="activationDate"/>
...
<dt:dataTable/>

Related

JSF composite component with own facet inside p:dataTable

I hava a composite component with a PrimeFaces dataTable inside. The column definition should be done outside of this component in a facet definition.
<composite:interface>
<composite:attribute name="domains" required="true"/>
<composite:facet name="domainColumns" required="true"/>
</composite:interface>
<composite:implementation>
<p:dataTable var="var" value="#{cc.attrs.domains}">
<composite:renderFacet name="domainColumns"/>
</p:dataTable>
</composite:implementation>
I want to use this component like shown here:
<my:domainTable domains="#{adminTsWorkspaceBean.domains}">
<f:facet name="domainColumns">
<p:column headerText="Header">
<h:outputText value="#{var.id}" />
</p:column>
</f:facet>
</my:domainTable>
Interestingly: If I use the p:column as a child and not as a facet and then in my component <composite:insertChildren/>, I have the desired output. But of course I can insert the children only at one position in my component. I'm trying to define the column for two different dataTables?

Rerendring a component inside popupPanel fails

I have popupPanel with a simple form (for search) and a dataTable (for search results). I try to Rerender the dataTable after submitting the form and populating the search results which fails. Here is the source code
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
xmlns:rd2="http://www.logica.com/raindance/webcomp"
xmlns:a4j="http://richfaces.org/a4j" template="/layout/template.xhtml">
<ui:define name="head">
</ui:define>
<ui:define name="body" >
.......................................
<rich:popupPanel id="ruleSearchPanel" width="600" lenght="400" autosized="true">
<f:facet name="header">
<h:panelGroup id="modelPanelHeader">
<h:outputText styleClass="modalpanel-header"
value="Search and select a rule set"></h:outputText>
</h:panelGroup>
</f:facet>
<h:form id="searchForm">
<h:panelGrid columns="2" styleClass="center" width="100%">
<h:inputText id="searchForKey" value="#{authRuleRegisterManager.rulSetSearchCriteria}"/>
<a4j:commandButton id="SearchRuleSets" styleClass="plain-btn fright" reRender="ruleSearchPanel"
value="#{messages.search}" type="submit" action="#{authRuleRegisterManager.searchAuthRulesMap(authRuleRegisterManager.rulSetSearchCriteria)}"
/>
</h:panelGrid>
<rich:extendedDataTable id="resultRuleSets"
value="#{authRuleRegisterManager.searchResultsForAuthRuleSets}" selectedClass="active-row"
rows="#{systemSettingsAction.systemSettings.paginationRows.value}"
var="ruleSet"
rowClasses="odd-row-selectable,even-row-selectable"
selectionMode="single">
<rich:column label="ruleset name"
headerClass="left"
styleClass="left" width="70">
<f:facet name="header">
<h:outputText value="name" styleClass="right" />
</f:facet>
<h:outputText value="#{ruleSet.description}" />
</rich:column>
</rich:extendedDataTable>
</h:form>
</rich:popupPanel>
</ui:define>
</ui:composition>
why I cannot rerender my datatable , do I miss something here?
any help will be appreciated.
There is no reRender attribute for <a4j:commandButton> for the version you are using. You can check the tag reference below
a4j:commandButton.
Based on the code I'm seeing (ui:composition not taken into account), if you want to update the dataTable simply change
reRender="ruleSearchPanel"
to
render ="searchForm:resultRuleSets"
If you are confused about determining ids check the link below
How can I know the id of a JSF component so I can use in Javascript
Note: Some of the attributes that you are using are not defined in some of the components that you are using. For example
lenght for rich:popupPanel
selectedClass for rich:extendedDataTable
label for rich:column

Primefaces - Cannot find component with identifier outside the datatable

<ui:define name="content">
<f:view>
<h:form id="myForm" styleClass="form" >
<p:dataTable var="provider" id="ss" value="#{providerSelectBean.providerList}" rowKey="#{provider.license}"
selection="#{providerSelectBean.selectedProvider}" selectionMode="single">
<p:ajax listener="#{providerSelectBean.onRowSelect}"
update=":myForm:output"event="rowSelect"/>
<p:column sortBy="#{provider.license}" width="110" >
<f:facet name="header">
<h:outputText value="License#" />
</f:facet>
<h:outputText value="#{provider.license}" />
</p:column>
<p:column sortBy="#{provider.prgName}" width="110" >
<f:facet name="header">
<h:outputText value="Program Name" />
</f:facet>
<h:outputText value="#{provider.prgName}" />
</p:column>
</p:dataTable><br/>
<p:panelGrid id="output" >
<h:outputText value="License" />
<h:outputText value="#{provider.license}" />
</p:panelGrid>
</h:form>
</f:view>
</ui:define>
This is my first stint with JSF2.0 and primefaces 3.4.1 and the <p:ajax update gives an error
javax.faces.FacesException: Cannot find component with identifier
":myForm:output" referenced from "myForm:ss"
Try to inspect the generated HTML code and see the actual id being generated for your panelGrid and update that id. If it happens to be dynamic, you can always use the JQuery CSS selectors (I find myself doing that pretty often). In your case, you can go like this:
update="#([id$=output])"
This expression stands for every component whose id ends with output. Take a look at the JQuery docs for more info.
You can also use :#{p:component(componentId)} as in
<p:ajax listener="#{providerSelectBean.onRowSelect}"
update=":#{p:component('output')}" event="rowSelect"/>
Quoting BalusC's answer to Get id of parent naming container in template for in render / update attribute:
p:component is a helper function that scans the entire view root for a component with the given ID and then returns its client ID.

Datatable selection not working

When I select a row in my primefaces datatable the row highights, but the selection event is not being invoked and the selected row data is not going to it. Also I notice that my eclipse debugger seems to just hang with PrimeFaces, anyone else notice this? Below is my .xhtml.
<?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"
>
<h:head>
<h:outputStylesheet library="css" name="table-style.css" />
</h:head>
<h:body>
<center>
<p:dataTable var="user" value="#{customer.getCustomerList()}"
selection="#{customer.selectedCustomer}" selectionMode="single"
rowSelectListener="#{custmoer.onUserSelect}" onRowSelectUpdate="userUpdateForm"
onRowUnselectUpdate="userUpdateForm"
paginator="true" rows="5" rowKey="#{user.customerID}" >
<p:column>
<f:facet name="header">
<h:outputText value="Id" />
</f:facet>
<h:outputText value="#{user.customerID}" />
</p:column>
<p:column >
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{user.name}" />
</p:column>
<p:column >
<f:facet name="header">
<h:outputText value="Address" />
</f:facet>
<h:outputText value="#{user.address}" />
</p:column>
</p:dataTable>
<p:inputText id="userUpdateForm" value="#{customer.selectedCustomer.name}" />
</h:form>
</center>
</h:body>
your onXXX attributes are bound to opaque strings, when they're supposed to be bound to javascript fragments (either a method call or a fragment that executes some code). i'm guessing javascript is throwing an exception, and nothing gets sent to the server because execution in the browser halts.
Put the <p:datatable> into a <h:form> component.
May be this is only a missing <h:form> start tag in your post (the </h:form> end tag is included). But forgetting to wrap a data posting component into a <h:form> is a common mistake which leads to the symptoms described by you.
Seems the problem was IE9. Problem disappeared with Firefox.
This can happen if there is another issue in the data table for example in my case the table is editable but I did not add editMode attribute after I added it selection also started working.

How to set colspan and rowspan in JSF panelGrid?

How can I set colspan and rowspan in JSF <h:panelGrid>?
None of both is possible with the standard JSF implementation. There are 3 ways to fix this:
Write plain HTML yourself. A <h:panelGrid> basically renders a HTML <table>. Do the same.
Create a custom HTML renderer which supports this. It'll however be a lot of sweat and pain.
Use a 3rd party component library which supports this.
Tomahawk has a <t:panelGroup> component which supports colspan in <h:panelGrid>.
RichFaces (3.x only) has a <rich:column> component which supports both colspan and rowspan in <rich:dataTable>.
PrimeFaces has a <p:row> next to <p:column> which is supported in both <p:panelGrid> and <p:dataTable> (also with <p:columnGroup>).
Since 24 januari 2012 Primefaces also has the possibility to use colspan and rowspan in the panelGrid component of Primefaces. See:
http://www.primefaces.org/showcase/ui/panel/panelGrid.xhtml
Use: rich:column colspan="2" of RichFaces
<rich:column colspan="2">
<h:outputText value="Ingrese el texto de la imagen" />
</rich:column>
Assume
a message resource file with two entries:
key.row=</td></tr><tr><td key.gt=>
row.xhtml
<ui:composition
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:c="http://java.sun.com/jsp/jstl/core" >
<c:forEach begin="0" end="#{colspan-2}">
<h:panelGroup />
</c:forEach>
<h:panelGroup>
<h:outputText value="#{i18n['key.row']}" escape="false" />
<h:outputText value=" colspan='#{colspan}' #{cellAttributes}" />
<h:outputText value="#{i18n['key.gt']}" escape="false" />
<ui:insert />
</h:panelGroup>
</ui:composition>
then, for example
<h:panelGrid columns="3">
<h:outputText value="r1-c1" />
<h:outputText value="r1-c2" />
<h:outputText value="r1-c3" />
<ui:decorate template="/row.xhtml">
<ui:param name="colspan" value="3" />
<ui:param name="cellAttributes" value=" align='center'" />
<div>Hello!!!!!</div>
</ui:decorate>
Prints a table with 3 rows:
r1-c1, r1-c2 , r1-c3
3 blank cells
a cell aligned center, having colspan 3 and containing a hello div.
I agree with BalusC's answer and want to add, that the Primefaces JSF2 component library also offers this functionality if you use its p:dataTable component. It is called grouping there.
There is no way to define column span in panel grid but if used wisely you can make it happen by just plain tag only. One example I would like to show you.
<h:panelGrid columns="1" >
<h:panelGrid columns="2">
<h:commandButton image="resources/images/Regular5.jpg" action="booking/Create.jsf?faces-redirect=truebookingType=REGULAR">
</h:commandButton>
<h:commandButton id="button2" image="resources/images/Casual2.jpg" action="booking/Create.jsf?faces-redirect=truebookingType=CASUAL">
</h:commandButton>
</h:panelGrid>
<h:panelGrid columns="2">
<h:commandButton id="button3" image="resources/images/Instant2.jpg" action="booking/Create.jsf?faces-redirect=truebookingType=INSTANT">
</h:commandButton>
<h:commandButton id="button4" image="resources/images/Outstation6.jpg" action="booking/Create.jsf?faces-redirect=truebookingType=OUTSTATION">
</h:commandButton>
</h:panelGrid>
<h:commandButton id="button5" image="resources/images/ShareMyCar.jpg" action="booking/Create.jsf?faces-redirect=truebookingType=OUTSTATION">
</h:commandButton>
Please note that button5 spans two columns given the size it requires.

Resources