Duplicate id error with primefaces dialog in template - jsf-2

PF 3.5.10, Mojara 2.1.21, Omnifaces 1.5
I have Facelet-Template with p:menu and p:include for dialog
mytemplate.xhtml:
<h:form> ... <p:menubar>
<p:menuitem value="Start Dialog" oncomplete="mydialogwidget.show()"/>
<p:menuitem value="open another page" action="/app/mypage.xhtml?faces-redirect=true"/>
</p:menubar> ... </h:form>
<ui:insert name="content" />
<ui:include="/app/mydialog.xhtml" />
mydialog.xhtml:
<ui:composition>
<p:dialog widgetVar="mydialogwidget" ...>
<h:form>
<p:datatable binding="#{mybean.table}">
<p:column id="col_first"> ... </p:column>
...
<p:column id="col_last"> ... </p:colum>
</p:datatable>
</h:form>
</p:dialog>
</ui:composition>
mypage.xhtml:
<ui:composition template="/app/mytemplate.xhtml">
<ui:define name="content">
<h:form> ... </h:form>
</ui:define>
</ui:composition>
If I start mypage.xhtml form menue, I become JSF1007 error (Duplicate ids) The component tree will be written to my console. The simplified component tree output:
+id: mydialog
+id: mytable
+id: col_first <<=============
....
+id: col_last
+id:col_first <<========
The mydialog.xhtml will be included only once. The answer to question JSF with Primefaces Menu duplicate Id error? doesn't help me.
How can I aviod this error ? Where comes this error from ?

The prolbem was binding attribute on datatable. See also: Binding attribute causes duplicate component ID found in the view
SessionScoped component was used in multiple views.
I've used EL-table binding and then the problem was disappeared.

Related

Composite method do not resolve parameter if in template

it's a bit similar to this problem https://issues.jboss.org/browse/RF-11469
I have a template containing a composite defined like this:
<h:form id="transfer_list">
<ccs:criteriaPanel header="Critère de recherche"
filterAction="#{controller.filter()}">
<form:criteriaForm bean="#{controller.transferCriteria}"
rendered="#{! empty controller.transferSearchForm}"
mode="UPDATE"
controller="#{controller}" />
</ccs:criteriaPanel>
</h:form>
Controller is defined with a ui:param in the template child.
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
template="/pages/transfer/transferList.xhtml">
<ui:param name="controller" value="#{transferListOpenController}" />
</ui:composition>
Here is the composite impl (criteriaPanel):
<cc:interface>
<cc:attribute name="header" default="#{i18n['HEADER_SEARCH_CRITERIA']}" />
<cc:attribute name="filterAction" method-signature="java.lang.Object filter()" />
<cc:attribute name="update" default="#(.ui-datatable)" />
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<p:panel header="#{cc.attrs.header}" toggleable="true">
<cc:insertChildren />
<f:facet name="footer">
<p:commandButton id="search_btn"
value="#{i18n['BUTTON_FILTER']}"
action="#{cc.attrs.filterAction}"
icon="ui-icon-search"
update="#{cc.attrs.update}" />
<p:commandButton value="#{i18n['BUTTON_CLEAR_FILTER']}"
action="#{cc.attrs.filterAction}"
process="#this"
immediate="true"
update="#{cc.attrs.update}">
<p:ajax update="#form" resetValues="true" />
</p:commandButton>
</f:facet>
<p:defaultCommand target="search_btn" />
</p:panel>
</div>
</cc:implementation>
Clicking on the button "filterAction" result into this:
javax.faces.FacesException: #{cc.attrs.filterAction}:
javax.el.PropertyNotFoundException: Target Unreachable, identifier
[controller] resolved to null at
com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
at
org.primefaces.application.DialogActionListener.processAction(DialogActionListener.java:45)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
I use Tomcat 8.5 for this and Mojarra 2.2.13. It works if I don't put the whole thing in a composite component (criteriaPanel)
UPDATE
Sample available here: https://github.com/Rapster/primefaces-test/tree/issue-sof-45834296
Works fine with MyFaces 2.2.11 and Mojarra 2.2.8-23 and 2.3.2 (I don't know how impactful upgrading to 2.3 can be though...) From what I read here https://stackoverflow.com/a/42656386/4605161, Mojarra 2.2.8 is aimed for WebLogic but it seems I will need this one (and i'm running on Tomcat)
WORKAROUND
Writing this make it work (but that's a workaround i'd rather use template):
<ui:composition xmlns="http://www.w3.org/1999/xhtml">
<ui:param name="controller" value="#{testView}" />
<ui:decorate template="/template.xhtml">
</ui:decorate>
</ui:composition>
Funny thing is if I put ui:param inside ui:decorate I'll end up with the same exception
Should be fixed in 2.2.15, see github.com/javaserverfaces/mojarra/issues/4271

PrimeFaces 3.5: row-specific context menu in datatable

I'm working on a web application using JSF and PrimeFaces. One of the pages displays a table of entities, and I'm supposed to add a context menu to the table.
More specifically: The last column contains a p:menuButton whose content depends on the respective row. The menuItems are stored as a ui:compositionin another file, and I'm supposed to simply include them in the context menu.
The menuitems are dynamic, however. The entities do have a boolean member called enabled. For enabled entities, Edit, Delete, and Disable are displayed. For disabled entities, there's only Enable.
With the code below, the context menu is displayed, but they the content is only updated if I select another row via left click. Right-clicking does select rows, but the selectedPerson of the backingbean is not updated.
Apparently there were some changes in PrimeFaces 3.5. I found many references to the contextMenu ajax event.
But when I add it to the datatable like this:
<p:ajax event="contextMenu" update=":persons-form:contextMenu" />
.. the menu appears but disappears immediately. Presumably, because some update method is getting called. In the short timespan it's displayed, I can see it still showing the old menuitems.
So, to summarize: How can I make a contextmenu working as it should in a datatable with PrimeFaces 3.5? Meaning, right-clicking should select a row and also update the menu before displaying it, as the menuitems depend on the row data.
​
​
personList.xhtml:
<p:contextMenu id="contextMenu" for="persons">
<ui:include src="/layout/personActionMenu.xhtml">
<ui:param name="thePerson" value="#{personListBean.selectedPerson}"/>
</ui:include>
</p:contextMenu>
<p:dataTable id="persons"
value="#{personListBean.allPersons}"
var="p"
rowKey="#{p.id}"
selection="#{personListBean.selectedPerson}"
selectionMode="single"
rowStyleClass="#{p.enabled ? '' : 'disabledTableItem'}">
<p:ajax event="rowSelect" update=":persons-form:contextMenu"/>
<p:column>
<f:facet name="header">Name</f:facet>
<h:outputText value="#{p.name}" />
</p:column>
<p:column>
<p:menuButton value="Actions">
<ui:include src="/layout/personActionMenu.xhtml">
<ui:param name="thePerson" value="#{p}"/>
</ui:include>
</p:menuButton>
</p:column>
</p:dataTable>
</h:form>
personActionMenu.xhtml:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:u="http://java.sun.com/jsf/composite/ui"
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:p="http://primefaces.org/ui">
<p:menuitem rendered="#{personListBean.isEnabled(thePerson)}" outcome="edit.xhtml" value="Edit" icon="ui-icon-gear">
<f:param name="id" value="#{thePerson.id}" />
</p:menuitem>
<p:menuitem actionListener="#{personListBean.deletePerson(thePerson)}" value="Delete" update=":person-form"
icon="ui-icon-close" rendered="#{personListBean.isEnabled(thePerson)}"/>
<p:menuitem actionListener="#{personListBean.toggleEnabled(thePerson)}" update=":persons-form" value="#{personListBean.toggleEnabledMenuItemLabel(thePerson)}" />
</ui:composition>
Please try this:
<p:contextMenu id="contextMenu" for="persons" widgetVar="ctxMenu" beforeShow="return true;">
<ui:include src="/layout/personActionMenu.xhtml">
<ui:param name="thePerson" value="#{personListBean.selectedPerson}"/>
</ui:include>
</p:contextMenu>
<p:dataTable ...>
...
<p:ajax event="contextMenu" update=":persons-form:contextMenu" oncomplete="ctxMenu.show(currentEvent);" />
...
</p:dataTable ...>
This is taken from CannyDuck´s post in the PF forum.
Hope this works for you as well.

How to refer to components located in a different ui:include

On a facelet composed with different ui:include, what would be the best way to refer to a component located in ui:composition 2 from ui:composition 1?
Example:
fileA.xhtml
<ui:composition>
<p:commandButton value="OK" action="#{bean.foo}" update=":componentToUpdate"/>
</ui:composition>
fileB.xhtml
<ui:composition>
<p:panel id="componentToUpdate">
// ...
</p:panel>
</ui:composition>
Here, I'm "hardcoding" the id, "componentToUpdate". I thought of using a parameter:
<ui:include src="fileA.xhtml" >
<ui:param name="myParam" value="myId"/>
</ui:include>
fileB.xhtml
<ui:composition>
<p:panel id="#{myId}">
// ...
</p:panel>
</ui:composition>
Would it be interesting to have a bean that maintains all of these ids?
Hope I'm clear enough, thanks.

Primefaces lightBox closes at click on commandLink

It's just a simple Primefaces lightBox I want to use commandLinks in. Unfortunately it simply closes, when I click a commandLink. Is there a way to keep the lightBox open?
Here an example of what my code looks like:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui" template="template.xhtml">
<ui:define name="content">
<p:lightBox>
<h:outputLink value="#">
<h:outputText value="open lightbox" />
</h:outputLink>
<f:facet name="inline">
<h:form>
<h:commandLink>
commandLink
</h:commandLink>
</h:form>
</f:facet>
</p:lightBox>
</ui:define>
</ui:composition>
Use an ajax (asynchronous) request instead of a synchronous request:
<h:commandLink ...>
<f:ajax ... />
</h:commandLink>
or as you're using PrimeFaces already, just use <p:commandLink> instead (it uses by default already ajax):
<p:commandLink ... />
With ajax, by default no fresh page replacement with the response is performed (which basically "resets" anything to defaults). You can in case of <f:ajax> tell by render attribute which parts of the component tree should be updated in the client side and in <p:commandLink> by the update attribute. E.g. if you want to render/update the parent form only, use #form. E.g.
<p:commandLink ... update="#form" />

Component ID has already been found in the view [duplicate]

This question already has answers here:
Binding attribute causes duplicate component ID found in the view
(2 answers)
Closed 7 years ago.
I have a XHTML page which on submission goes back to itself.
The backing bean is session scoped. On the redirect to itself the page renders the h:datatable twice and gives me duplicate id error.I can visually see the table being rendered twice as well next to each other.
** xhtml page :**
<?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:f="http://java.sun.com/jsf/core">
<f:view>
<h:form >
<h:dataTable binding="#{ecole.dataTable}" value="#{ecole.getEcoleList()}" var="c"
border="0" width="100%" cellpadding="0" cellspacing="0"
styleClass="order-table"
headerClass="order-table-header"
rowClasses="order-table-odd-row,order-table-even-row"
>
<h:column>
<f:facet name="header">
ID
</f:facet>
#{c.idEcole}
</h:column>
<h:column>
<f:facet name="header">
Nom
</f:facet>
#{c.nomEcole}
</h:column>
<h:column>
<f:facet name="header">
Description
</f:facet>
#{c.desc_ecl}
</h:column>
<h:column>
<f:facet styleclass="options-width" name="header">
Options
</f:facet>
<h:commandLink action="#{ecole.editEcoleItem()}" title="Edit" >
<h:graphicImage style="border:0" url="/icones/b_edit.png" />
</h:commandLink>
   
<h:commandLink title="Delete"
onclick="return confirm('Voulez-vous confirmer la suppression?') ;"
action="#{ecole.deleteEcole(c)}"
>
<h:graphicImage style="border:0" url="/icones/b_drop.png" />
</h:commandLink>
</h:column>
</h:dataTable>
<!-- end product-table................................... -->
</h:form>
</f:view>
this is error message shown :
java.lang.IllegalStateException: Component ID j_id15:j_id16:j_id29 has already been found in the view. See below for details.
+id: null
type: javax.faces.component.UIViewRoot#1abe6f6
+id: javax_faces_location_HEAD
type: javax.faces.component.UIPanel#c84a5d
+id: j_id4
type: javax.faces.component.UIOutput#18a5776
+id: j_id22
type: javax.faces.component.UIOutput#1742dcc
+id: j_id19
...
The binding attribute should bind to a request scoped bean or just be removed altogether and be replaced by a better alternative, depending on the concrete functional requirement.
If I get the functional requirement right of being able to retrieve the current item in the editEcoleItem() method, then you can just pass it directly as method argument, exactly as you did in deleteEcole(). This way you can just remove the binding attribute altogether. That's the JSF 2.0 / EL 2.2 way. Perhaps you were focusing too much on old JSF 1.x examples. You shouldn't do that when developing with JSF 2.x.
See also:
A JSF 2.0 CRUD example
How can I pass selected row to commandLink inside dataTable?

Resources