Primefaces 3.0 : TreeNode and ContextMenu - java

In my application, I have a tree with various object types (sources, tables, etc).
I'd like to enable a context menu for the different types of object (add, delete, edit etc).
How can I use context menu on tree nodes in Primefaces ?

Never did it in practice (I am still on Primefaces 2.x), but from theory the facelet code should look something like this:
<h:form>
<p:tree value="#{myBean.tree}" var="node" id="tree"
selectionMode="single" selection="#{myBean.selectedNode}">
<p:treeNode>
<h:outputText value="#{node}" />
</p:treeNode>
</p:tree>
<p:contextMenu for="tree" id="menu">
<p:menuitem value="Add" actionListener="#{myBean.add}" />
...
</p:contextMenu>
</h:form>
Usage of p:contextMenu and p:tree is shown in Primefaces showcase.

Related

/welcomePrimefaces.xhtml #18,39 <p:layout> Tag Library supports namespace: http://primefaces.org/ui, but no tag was defined for name: layoutl

I was writing the first entity class in the entity package but I didn't want to delete te WelcomePrimefaces because I want to use it to try how to use some codes in it. The WelcomePrimefaces was working well but after I wrote the first Entity Class WelcomePrimeces didn't work.
I get this...
/welcomePrimefaces.xhtml #18,39 <p:layout> Tag Library supports namespace: http://primefaces.org/ui, but no tag was defined for name: layout
I have not change the code it gives me from the begining so I would like to know what is happening here.
this is the code from 18 line.
<p:layout fullPage="true">
<p:layoutUnit position="north" size="100" resizable="true" closable="true" collapsible="true">
Header
</p:layoutUnit>
<p:layoutUnit position="south" size="100" closable="true" collapsible="true">
Footer
</p:layoutUnit>
<p:layoutUnit position="west" size="175" header="Left" collapsible="true">
<p:menu>
<p:submenu label="Resources">
<p:menuitem value="Demo" url="http://www.primefaces.org/showcase-labs/ui/home.jsf" />
<p:menuitem value="Documentation" url="http://www.primefaces.org/documentation.html" />
<p:menuitem value="Forum" url="http://forum.primefaces.org/" />
<p:menuitem value="Themes" url="http://www.primefaces.org/themes.html" />
</p:submenu>
</p:menu>
</p:layoutUnit>
<p:layoutUnit position="center">
Welcome to PrimeFaces
</p:layoutUnit>
</p:layout>
I was expecting netbeans show me the error in the firt Entity Class I was doing, not the error in WelcomePrimefaces.
I alredy have the pool conexion well done to the database with Mysql and persistence with EclipseLink
I am using netbeans 15
Layout was removed in PF 10.0.0 see: ticket: https://github.com/primefaces/primefaces/issues/2168
You can use Layout from PrimeFaces Extensions: https://www.primefaces.org/showcase-ext/views/layout.jsf;

PrimeFaces Tree - show different context menu when selecting multiple nodes

I'm working on a PrimeFaces web app. I just started getting into it so bear with me.
I have a Tree with multiple types of nodes - each with their own context menu.
My problem is that I want to be able to show different context menus when a single node is selected and when multiple are.
The Tree's selection mode should obviously be multiple.
Code:
<!-- Here should be context menu for when multiple nodes are selected -->
<!-- <p:contextMenu for="tree"> -->
<!-- <p:menuitem value="Multiple Items Selected"> -->
<!-- </p:menuitem> -->
<!-- </p:contextMenu> -->
<p:contextMenu for="tree" nodeType="type1">
<p:menuitem value="Type 1 Selected">
</p:menuitem>
</p:contextMenu>
<p:contextMenu for="tree" nodeType="type2">
<p:menuitem value="Type 2 Selected">
</p:menuitem>
</p:contextMenu>
<p:contextMenu for="tree" nodeType="type3">
<p:menuitem value="Type 3 Selected">
</p:menuitem>
</p:contextMenu>
<p:tree id="tree" value="#{treeBean.root}" var="node"
selectionMode="multiple">
<p:treeNode type="type1">
<h:outputText value="#{node}" />
</p:treeNode>
<p:treeNode type="type2">
<h:outputText value="#{node}" />
</p:treeNode>
<p:treeNode type="type3">
<h:outputText value="#{node}" />
</p:treeNode>
</p:tree>
Thanks very much!
I solved this purely in the client side by changing the CSS of the menu items I wanted to hide.
I used a single context menu both for single selection and multiple but I hide the items I don't want to show for multiple selection.
Every menu item I wanted to hide in case of multiple selection got a style="class: multiple_tree_cm;".
I used the context menu event on the tree.
Example tree:
<p:tree id="tree" widgetVar="treeWV">
<p:ajax event"contextMenu" onstart="updateTreeContextMenu();"/>
<p:treeNode .../>
</p:tree>
example context menu:
<p:contextMenu for="tree">
<p:menuitem ... styleclass="multiple_tree_cm"/> <!-- don't want to show this for multiple selection -->
</p:contextMenu>
I hide the menu items by adding a css class to the multiple_tree_cm class menu items.
Like this:
function updateTreeContextMenu(event) {
if (PF('treeWV') && PF('treeWV').selections && PF('treeWV').selections.length === 1) {
$('.multiple_tree_cm').removeClass('disabled');
} else {
$('.multiple_tree_cm').addClass('disabled');
}
}
css:
.multiple_tree_cm {}
.disabled { height: 0 !important; display: none !important; }

Composition is not rendered in Richfaces tabPanel

I am a user of JSF and Richfaces. I will simplify the code about my question to make things easier.
I have a composition named 'mytab.xhtml' defined like following:
<cc:interface>
<cc:attribute name="header" required="true"/>
</cc:interface>
<cc:implementation>
<rich:tab id="my-tab" header="#{cc.attrs.header}" >
<cc:insertChildren />
</rich:tab>
</cc:implementation>
This composition is used in another xhtml file like following:
<rich:tabPanel id="tp" switchType="ajax" headerPosition="top" >
<ic:mytab id="tab1" header="header1">
<h:outputText>content1</h:outputText>
</ic:mytab>
<ic:mytab id="tab2" header="header2">
<h:outputText>content1</h:outputText>
</ic:mytab>
</rich:tabPanel>
But it is very strange that the tab is not rendered at all.
To find the reason, if I add an outputText in the composition definition file like this:
<cc:interface>
<cc:attribute name="header" required="true"/>
</cc:interface>
<cc:implementation>
<h:outputText>#{cc.attrs.header}</h:outputText>
<rich:tab id="my-tab" header="#{cc.attrs.header}" >
<cc:insertChildren />
</rich:tab>
</cc:implementation>
The outputText will be rendered, but tab is not rendered.
Or, if I change one of the tab to richfaces tab directly:
<rich:tabPanel id="tp" switchType="ajax" headerPosition="top" >
<ic:mytab id="tab1" header="header1">
<h:outputText>content1</h:outputText>
</ic:mytab>
<rich:tab id="tab2" header="header2">
<h:outputText>content1</h:outputText>
</rich:tab>
</rich:tabPanel>
The first tab will not be rendered, but the second tab will be rendered.
Thank you if you could give me any help.
Composite components are rendered as own UINamingContainer. So between the UITabPanel and the UITab-component now is a UINamingContainer, UITab might not know what to do with it (same problem with datatable, by the way). What you can do is to use a classic facelet tag instead.

facelets skins are not assigned after reRender to surrounding panel

I have a table with <a:commandLink> that opens <rich:modalPanel> with additional info on the selected item. It works using reRendering modalPanel's inner <a:outputPanel> on click on the commandLink. Now the issue that all my facelets become usual input items (i.e simple selects instead of comboboxes) after reRender. Is there any way to make the server add the ui info to the reRendered result?
UPD I see the following messages in log
10:55:30,483 INFO [facelet] Facelet[/account/registration.xhtml] was modified # 10:55:30 AM, flushing component applied # 10:54:36 AM
UPD2 The issue happens only with the components that replace usual select, like selectOneMenu or selectonelistbox.
Code examples:
<rich:modalPanel id="fieldPropertiesPanel" >
<f:facet name="header">
<h:outputText value="Customize Field" />
</f:facet>
<f:facet name="controls">
<h:outputLink value="#"
onclick="#{rich:component('fieldPropertiesPanel')}.hide(); return false;">
X
</h:outputLink>
</f:facet>
<rich:panel id="fieldPropertiesContent">
<s:decorate styleClass="itemType" template="/layout/edit.xhtml">
<h:selectOneMenu value="#{accountHome.currFieldType}">
<s:selectItems itemLabel="#{fieldType}" itemValue="#{fieldType}"
label="#{messages['ProjectFieldType_enum.'.concat(fieldType)]}"
value="#{accountHome.projectFieldTypes}" var="fieldType" />
</h:selectOneMenu>
</s:decorate>
</rich:panel>
</rich:modalPanel>
and the calling commandLink
<a:commandLink value="Edit" oncomplete="Richfaces.showModalPanel('fieldPropertiesPanel');"
reRender="fieldPropertiesContent" />

Javabean validation error inside JSF/PrimeFaces dialog

Recently I have update my application to JSF 2.1.7 and PrimeFaces 3.4.2. When the below dialog is used for adding a new group, I get an "Name size must be between 1 and 40" validation error, prior to saving the new group. It happens when I click the picker's add button. I understand that this message is shown because the validation failed. The validation error doesn't appear when I add immediate=true to p:commandButton. I don't know what triggered the validation.
<h:form id="formg" prependId="false">
<!-- messages -->
<p:growl id="msgsg" showDetail="true" />
<!-- data table -->
<ui:include src="/WEB-INF/flows/groupsTable.xhtml" />
<p:separator />
<!-- bottom tool bar -->
<ui:include src="/WEB-INF/flows/groupsToolBar.xhtml" />
<!-- preview, edit dialog -->
<ui:include src="/WEB-INF/flows/groupsDialog.xhtml" />
</h:form>
<p:dialog id="dialogg" header="#{groupsBean.dialogTitle}"
widgetVar="groupsDialog" dynamic="true" resizable="false" width="800"
height="600" showEffect="fade" hideEffect="fade" modal="true">
<p:ajax event="close" listener="#{groupsBean.refresh}"
immediate="true" update=":formg" global="false" process="#this" />
<p:tabView id="tabPicker">
<p:tab title="General">
<h:panelGrid id="displayg" columns="2">
<h:outputText value="#Group name*:" />
<p:inputText value="#{groupsBean.selectedGroup.name}" size="40"
readonly="#{!groupsBean.updatable}" maxlength="40" />
</h:panelGrid>
</p:tab>
<p:tab title="Members">
<ui:include src="/WEB-INF/custom/picker.xhtml">
... some params passed to picker
</ui:include>
</p:tab>
</p:tabView>
</p:dialog>
The picker is similar to <p:password> and it is made up from two p:dataTable components and 4 buttons between them. The buttons are grouped together with a h:panelGrid. The button attributes are similar. Here is button sample code:
<p:outputPanel autoUpdate="true">
<p:commandButton actionListener="#{eval.evaluateAsMethod(pickerAdd)}"
update="source, target, #{messages}" immediate="true"
disabled="#{pickerSourceDisabled}"
icon="ui-icon ui-icon-arrowthick-1-s" />
</p:outputPanel>
source, target are the ids of the two datatables. pickerAdd is passed as param with a value of groupsBean.picker.add. The tables contain FooDomain objects.
public class FooDomain implements Serializable {
...
#NotNull
#Size(min = 1, max = 40)
#Column(name = "NAME")
private String name;
...
}
The PrimeFaces <p:commandButton> processes by default the entire form (as in, process="#form"), so it would by default trigger all validations. Your validation error is coming from the #Size restriction on the property. If you would like to process only the button's own action, then you should add process="#this".
<p:commandButton ... process="#this" />
The immediate="true" can also be used to solve it, but it behaves under the covers somewhat different: the entire form is still processed, but the action is invoked in APPLY_REQUEST_VALUES phase instead of INVOKE_ACTION phase. And only the input components which also have immediate="true" set will also be processed and others will be skipped.

Categories

Resources