jsf2 cant reference container page's element from composite component - jsf-2

launcher.xhtml
this form uses "thing"
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:custom="http://java.sun.com/jsf/composite/components">
<h:form id="form">
<p:panelGrid
id="pgid"
columns="2">
<h:outputText value="title"/>
<h:outputText value="#{bean.value}"/>
</p:panelGrid>
<custom:thing
via="#{bean.via1}"
viaListener="#{bean.via2Listener()}"
vias="#{bean.vias1}">
</h:form>
thing.xhtml
<p:selectOneMenu
process="#this"
value="#{cc.attrs.via}">
<p:ajax
listener="#{cc.attrs.viaListener}"
update="form:pgid"
/>
<f:selectItems value="#{cc.attrs.vias}"/>
</p:selectOneMenu>
faces can´t find form:pgid. tried with and without prepending "form". thanks

Relative client IDs (those not starting with :) are searched relative to the parent NamingContainer component, which is in your case the composite component itself. So it's looking for form:pgid in the context of <cc:implementation>.
You need to prefix the client ID with : (the default NamingContainer separator character) to make it absolute to the view root.
<p:ajax ... update=":form:pgid" />
See also:
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"

Related

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 work auto complite custom component?

A have found sample on internet(IBM site http://www.ibm.com/developerworks/web/library/j-jsf2fu-0410/index.html#listing1) and on some book that with JSF can make auto complete drop down list. Like on google search page. The main point of this is in using composite component page. It look like:
<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:composite="http://java.sun.com/jsf/composite">
<!-- INTERFACE -->
<composite:interface>
<composite:attribute name="value" required="true"/>
<composite:attribute name="completionItems" required="true"/>
</composite:interface>
<!-- IMPLEMENATION -->
<composite:implementation>
<div id="#{cc.clientId}">
<h:outputScript library="javascript"
name="prototype-1.6.0.2.js" target="head"/>
<h:outputScript library="javascript"
name="autoComplete.js" target="head"/>
<h:inputText id="input" value="#{cc.attrs.value}"
onkeyup="com.corejsf.updateCompletionItems(this, event)"
onblur="com.corejsf.inputLostFocus(this)"
valueChangeListener="#{autocompleteListener.valueChanged}"/>
<h:selectOneListbox id="listbox" style="display: none"
valueChangeListener="#{autocompleteListener.completionItemSelected}">
<f:selectItems value="#{cc.attrs.completionItems}"/>
<f:ajax render="input"/>
</h:selectOneListbox>
<div>
</composite:implementation>
</ui:composition>
My questions are:
Why we use ui:composition tags with out any parameters.
We have in h:inputText defined valueChangeListener, realized over backend class which has method public void valueChanged(ValueChangeEvent e) with these two lines
UIInput input = (UIInput) e.getSource();
UISelectOne listbox = (UISelectOne) input.findComponent("listbox");
If (UIInput)e.get source return component inputText with id="name". How possible next line
UISelectOne listbox = (UISelectOne)input.findComponent("listbox");
For the first question: <ui:composition template="..."> renders the content's of this tag into the specified template. Since you have no template here, the attribute isn't needed.
For the second question: findComponent searches for the given id in the enclosing NamingContainer, which is your composite component (check the Javadoc for the full algorithm). It's not like jQuery where it only searches "below" the given component.

Datatable don't refresh

Good evening from Sweden!
I try to get a primefaces datatable to refresh. I tried various hints and solutions but nothing is working.
The button triggers a search in the DB and if I refresh the paga manually or if I use the tables sorting-function the result is shown.
Means the code in the backing bean works. But no automatic refresh directly after the button is clicked..
The bean scope is Session.
Here is the page
<!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:head>
<h:body>
<ui:composition template="/templates/BasicTemplate.xhtml">
<ui:define name="content">
<h:form id="src_res">
<h2>Sök klass,undervisningsgrupp eller individ</h2>
<b>Sökord</b>: <h:inputText id="sw" value="#{smsb.searchword}"/>
<p:outputLabel value="Lärare"></p:outputLabel>
<h:selectOneListbox size="1" id="teacher" value="#{smsb.searchteacher}" >
<f:selectItems value="#{smsb.teachers}"/>
</h:selectOneListbox>
<p:commandButton action="#{smsb.searchgrp_user}" value="Sök!" update="src_list"/>
<p:dataTable id="src_list" value="#{smsb.searchresult}" var="obj" >
<p:column width="20%" sortBy="#{obj.groupname}">
<f:facet name="header" >
<h:outputText value="Beteckning"/>
</f:facet>
<h:outputText value="#{obj.groupname}"/>
</p:column>
<p:column width="10%">
<f:facet name="header" >
<h:outputText value="typ"/>
</f:facet>
<h:outputText value="#{obj.klass}"/>
</p:column>
<p:column width="10%" sortBy="#{obj.teacher}">
<f:facet name="header" >
<h:outputText value="lärare"/>
</f:facet>
<h:outputText value="#{obj.teacher}"/>
</p:column>
</p:dataTable>
</h:form>
</ui:define>
</ui:composition>
</h:body>
</html>
Any help or hints?
With regards
Ralf
EDIT
Hello and thanx for the offer to help!
As you guessed searchresult is a list and the Getter is defined by
List<sbasUserList> searchresult;
public List<sbasUserList> getSearchresult() {
return searchresult;
}
search_grp is a method of the backing bean:
public String searchgrp_user(){
//FacesContext context = FacesContext.getCurrentInstance();
ObjectContainer db = this.connBD("sms");
ObjectSet<sbasUserList> res;
this.searchresult = new ArrayList<sbasUserList>() ;
Query query=db.query();
query.constrain(sbasUserList.class);
query.descend("groupname").constrain(this.searchword).like();
query.descend("type").constrain('P').or(query.descend("type").constrain('M'));
query.descend("teacher").constrain(searchteacher).contains();
res = query.execute();
this.searchresult.addAll(res);
System.out.println(this.searchresult.size());
db.close();
return "";
}
The table is filled with the right dat if i update manually the browser. (F5) but certainly would like to have this done automatically.
Sorry folks! The glassfish server I was using wasn't setup right. It showed not all of the errors in the log file. I did a complete new setup of the whole IDE (new Eclipse, new glassfish server, thanx BalusC for the incredible tutorial!!!) and I found all errors. Now it works like it should!
Regards
Ralf

Primefaces 3.4.2 javascript error

I'm developing a web application using the 3.4.2 version of Primefaces. I have a p:pickList on it. Application is working using a general template and each page replaces the general_content of the template, which is being reloaded for every request. My problem is that the picklist is not working (cannot interact with it) because some JavaScript error happens when I load the page. This is my xhtml:
<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:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui"
template="/templates/general_template.xhtml">
<ui:define name="metadata">
<f:metadata>
<f:viewParam id="user" name="user"
value="#{navegableUserData._ParamUser}" />
<f:viewParam id="NavIndex" name="NavIndex"
value="#{navegableUserData._QueueIndex}" />
<f:event type="preRenderView"
listener="#{navegableUserData.initialize}" />
</f:metadata>
<h:message for="user" />
</ui:define>
<ui:define name="general_content">
<h:form id="SystemUserForm">
<p:pickList id="rolePickList" value="#{navegableUserData._ListRoles}"
var="role" itemValue="#{role}" converter="rolConverter">
<f:facet name="sourceCaption">
<h:outputText value="#{msg.AVAILABLE}" />
</f:facet>
<f:facet name="targetCaption">
<h:outputText value="#{msg.ASSIGNED}" />
</f:facet>
<p:column>
<h:outputText value="#{role._Nombre}" />
</p:column>
</p:pickList>
</h:form>
</ui:define>
This is the JavaScript error I have:
Firebug in Firefox
Firebug is telling me the element 'a' cannot be found in the first line of primefaces.js
"a is undefined"
PrimeFaces={escapeClientId:function(a){return"#"+a.replace(/:/g,"\\:")},
...
Inspector in Chrome
Uncaught TypeError: Cannot call method 'replace' of undefined primefaces.js.xhtml:1
PrimeFaces.escapeHTML primefaces.js.xhtml:1
(anonymous function) primefaces.js.xhtml:27
bG.extend.each jquery.js.xhtml:14
bG.fn.bG.each jquery.js.xhtml:14
PrimeFaces.widget.PickList.PrimeFaces.widget.BaseWidget.extend.generateItems primefaces.js.xhtml:27
PrimeFaces.widget.PickList.PrimeFaces.widget.BaseWidget.extend.init primefaces.js.xhtml:27
e.(anonymous function) jquery.js.xhtml:373
c jquery.js.xhtml:373
PrimeFaces.createWidget primefaces.js.xhtml:1
PrimeFaces.cw primefaces.js.xhtml:1
(anonymous function)
It looks like some jquery is failing. With the previous version of Prime, 3.4.1, everything is working fine.
p:pickList (primefaces v3.4.2) requires itemLabel to be specified.
Just add
itemLabel="#{role}"
to your p:pickList

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" />

Resources