Empty Datatable cells using JSF2 Primefaces 6 - primefaces

I have an application loading a datatable from a backing bean. The SubAreas datatable loads the correct number of rows, however they are empty as seen on the image. After debuging I can see that listaArea atribute on the backing bean(responsible for populating the table) is getting the correct data from the database. Area is the entity.
Another datatable on the same screen, called Membros works without a problem.
AREA.XHTML
<div>
<fieldset style="display:#{(areaMB.state == 'update')?'block':'none'}">
<p:dataTable var="teste" id="dtTeste" value="#{areaMB.listaArea}"
widgetVar="dtArea" paginator="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="20, 50, 100"
rows="20" rowKey="#{area.idArea}"
emptyMessage="Nenhum registro" paginatorPosition="bottom">
<p:column headerText="#" width="10%">
<h:outputText value="#{area.idArea}" />
</p:column>
<p:column headerText="Descrição" width="40%"
filterBy="#{area.descricao}"
filterMatchMode="contains">
<h:outputText value="#{area.descricao}" />
</p:column>
<p:column headerText="Sigla" width="20%">
<h:outputText value="#{area.sigla}" />
</p:column>
<p:column headerText="Ativo" width="20%">
<h:outputText value="ATIVO" rendered="#{area.flgAtivo==1}" />
<h:outputText value="INATIVO" rendered="#{area.flgAtivo==0}" />
</p:column>
<p:column headerText="" width="10%" style="text-align:center">
<p:commandButton action="#{areaMB.preparaAlterar}"
update=":formu"
icon="fa fa-pencil" style="margin-right:10px"
title="Alterar"
styleClass="btn btn-default btn-xs">
<f:setPropertyActionListener target="#{areaMB.area}" value="#{area}" />
</p:commandButton>
</p:column>
</p:dataTable>
</fieldset>
</div>
</h:panelGroup>
MANAGED BEAN
#Named
#ViewScoped
public class AreaMB implements Serializable {
private String state = "search";
private String descricao;
private Area area = new Area();
private Area subArea = new Area();
private Usuario usuario = new Usuario();
private AreaUsuario areaUsuario = new AreaUsuario();
private List<Usuario> listaUsuario;
private List<Area> listaArea;
private List<AreaUsuario> listaAreaUsuario;
private List<SelectItem> listaMembro;
private List<Area> listaSubAreas;
private List<TipoArea> listaTipoArea;
private List<Area> listaAreaVinculada;
#PostConstruct
public void init() throws Exception {
pesquisar();
}
public void pesquisar() {
try {
listaArea = AreaService.getInstancia().pesquisar(area, 0, 0);
listaTipoArea = TipoAreaService.getInstancia().getAll();
//a area vinculada nao pode ser ela mesma
listaAreaVinculada = AreaService.getInstancia().getAll();
if (listaAreaVinculada.contains(area)) {
listaAreaVinculada.remove(area);
}
} catch (Exception e) {
// TODO: handle exception
}
}
public void preparaAlterar() {
try {
state = "update";
AreaUsuario au = new AreaUsuario();
au.setIdArea(area.getIdArea());
listaAreaUsuario = AreaUsuarioService.getInstancia().pesquisar(au, AreaUsuarioService.JOIN_USUARIO, 0);
listaMembro = new ArrayList<SelectItem>();
for (AreaUsuario aUsuario : listaAreaUsuario) {
listaMembro.add(new SelectItem(aUsuario.getIdUsuario(), aUsuario.getUsuario().getNome()));
}
listaAreaVinculada.remove(area);
listaSubAreas = AreaService.getInstancia().getSubAreas(area);
} catch (Exception e) {
System.out.println(e.getStackTrace());
}
}
Why is it bringing empty cells?

The var of your dateTable is called teste (var="teste"), while the var used in values and rendered in your h:outputText are area.
You can change to var="area", or change all the values and rendered of the h:outputText to "#{teste.XXX}"

Related

How can I render a row in a dataTable that groups rows according to one of the fields of the bean in Primefaces?

I'm pretty new to Primefaces and I'm having trouble understanding how it works. I'm trying to create a datatable that will show a series of records that are grouped according to one of the fields (area), with a header row indicating the area of the rows beneath it. There is a tag in Primefaces (since 6.0.11), "p:headerRow", but it's unavailable for my version, Primefaces 5.3. There is also an attribute in the "column" tag, "groupRow", but it's unavailable for my version as well. One idea that comes to mind is to use a conditional header row that will show the value of area for the following rows, depending on whether the area has changed (if not, do not show the header; if yes, show it). I wanted to use a variable "areaActual" to keep track of the area being rendered, to be compared with the area of the next row in the table. I hope I'm being clear... But the variable does not seem to work, and the header row does not show up as a header (if I remove the "rendered" condition). Please help!
This is the xhtml.:
<h:panelGroup id="pgbody" styleClass="backBeanChangeBody" rendered="#{informacionpersonal$kardex.existe}">
<p:dataTable id="dataTablePrincipal"
style="height:100%;width:100%" value="#{informacionpersonal$kardex.listaKardex}" var="currentRow" rows="10"
paginator="true" rowsPerPageTemplate="10,15,20,25,30" reflow="true" >
<p: rendered="#{!currentRow.area eq areaActual}">
<p:column id="encabezado" colspan="7">
<p:outputLabel value="#{areaActual}" />
</p:column>
</p:row>
<ui:param name="areaActual" value="#{currentRow.area}" />
<p:row>
<p:column id="column3" sortBy="#{currentRow.espAsignatura}">
<p:outputLabel id="outputText5" value="#{currentRow.espAsignatura}"/>
<f:facet name="header">
<p:outputLabel value="Asignatura"/>
</f:facet>
</p:column>
<p:column id="column5" sortBy="#{currentRow.espPeriodoescolar}">
<p:outputLabel value="#{currentRow.espPeriodoescolar}" />
<f:facet name="header">
<p:outputLabel value="Periodo escolar"/>
</f:facet>
</p:column>
<p:column id="column6" sortBy="#{currentRow.creditos}">
<p:outputLabel value="#{currentRow.creditos}" />
<f:facet name="header">
<p:outputLabel value="Créditos"/>
</f:facet>
</p:column>
<p:column id="column7" sortBy="#{currentRow.espTipoevaluacion}">
<p:outputLabel value="#{currentRow.espTipoevaluacion}" />
<f:facet name="header">
<p:outputLabel value="Tipo de evaluación"/>
</f:facet>
</p:column>
<p:column id="column12" sortBy="#{currentRow.calificacion}">
<p:outputLabel value="#{currentRow.calificacion}"/>
<f:facet name="header">
<p:outputLabel value="Calificación"/>
</f:facet>
</p:column>
</p:row>
</p:dataTable>
</h:panelGroup>
This is the bean:
#ManagedBean(name = "informacionpersonal$kardex")
#ViewScoped
public class kardex extends FacesBean implements Serializable {
private int __placeholder;
private void _init() throws Exception {
selectOneMenu1DefaultItems.setItems(new String[]{"10", "15", "20", "25", "30"});
}
private FormaModal formaModal = (FormaModal) getValue("#{plantilla.formaModal}");
private Boolean notselectedrow = true;
private DefaultSelectionItems selectOneMenu1DefaultItems = new DefaultSelectionItems();
public DefaultSelectionItems getSelectOneMenu1DefaultItems() {
return selectOneMenu1DefaultItems;
}
public void setSelectOneMenu1DefaultItems(DefaultSelectionItems dsi) {
this.selectOneMenu1DefaultItems = dsi;
}
public Boolean getNotselectedrow() {
return notselectedrow;
}
public void setNotselectedrow(Boolean notselectedrow) {
this.notselectedrow = notselectedrow;
}
private TableListDataModel tabla;
public TableListDataModel getTabla() {
return tabla;
}
public void setTabla(TableListDataModel tabla) {
this.tabla = tabla;
}
// </editor-fold>
private Persona alumno;
private Boolean existe;
private List<VEscHistoriaacademica> listaKardex;
public kardex() {
}
#PostConstruct
public void init() {
try {
_init();
} catch (Exception e) {
log("Page1 Initialization Failure", e);
throw e instanceof FacesException ? (FacesException) e : new FacesException(e);
}
listaKardex = new ArrayList<VEscHistoriaacademica>();
}
#PreDestroy
public void destroy() {
}
protected ApplicationBean1 getApplicationBean1() {
return (ApplicationBean1) getBean("ApplicationBean1");
}
protected Controlador getControlador() {
return (Controlador) getBean("Controlador");
}
public Persona getAlumno() {
return alumno;
}
public void setAlumno(Persona alumno) {
this.alumno = alumno;
listaKardex = new ArrayList<VEscHistoriaacademica>();
listaKardex.clear();
listaKardex = getControlador().findByAlumno(alumno.getId());
existe = !listaKardex.isEmpty();
}
public List<VEscHistoriaacademica> getListaKardex() {
return listaKardex;
}
public void setListaKardex(List<VEscHistoriaacademica> listaKardex) {
this.listaKardex= listaKardex;
}
public Boolean getExiste() {
return existe;
}
public void setExiste(Boolean existe) {
this.existe = existe;
}
}
Thank you!

Primefaces initial sort order for multisort dataTable in tabView

I have a page (page1.xhtml) with a tabView and a dataTable within one of the tabs. The dataTableuses lazy loading and should provide multisort mode.
Therefore I use a List<SortMeta> for the sortBy attribute of dataTable as found here (Initial sortorder for PrimeFaces datatable with multisort).
The List<SortMeta> is created in getPreSortOrder() but findComponent() for clientId "myForm:tabs:data:colName" always returns null!
In another constellation (page2.xhtml) where I have the dataTable not in a tabView findComponent() always returns the correct column component!
So the problem seems to be the combination with tabView?!
Any hints welcome - Thank you!
page.xhtml:
<html>
<f:metadata>
<f:viewAction action="#{model.loadData}"/>
</f:metadata>
<ui:composition template="/WEB-INF/template.xhtml">
<ui:define name="content">
<h:form id="myForm">
<p:panelGrid>...</p:panelGrid>
<p:tabView id="tabs">
<p:tab id="tab1">...</p:tab>
<p:tab id="tab2">...</p:tab>
<p:tab id="tab3">
<p:dataTable id="data" lazy="true"
value="#{model.personTableModel}" var="item"
sortMode="multiple" sortBy="#{model.tableMode.preSortOrder}">
<p:column id="colName" sortBy="#{item.name}"> // <-- findComponent for "myForm:tabs:data:colName" always returns null !!!
<h:outputText value="#{item.name}"/>
</p:column>
<p:column id="colAddress" sortBy="#{item.address}">
<h:outputText value="#{item.address}"/>
</p:column>
</p:dataTable>
</p:tab>
</p:tabView>
</h:form>
</ui:define>
</ui:composition>
</html>
page2.xhtml:
<html>
<f:metadata>
<f:viewAction action="#{model.loadData}"/>
</f:metadata>
<ui:composition template="/WEB-INF/template.xhtml">
<ui:define name="content">
<h:form id="myForm">
<p:panelGrid>...</p:panelGrid>
<p:outputPanel id="tables">
<p:fieldset>
<p:dataTable id="data" lazy="true"
value="#{model.personTableModel}" var="item"
sortMode="multiple" sortBy="#{model.tableMode.preSortOrder}">
<p:column id="colName" sortBy="#{item.name}"> // <-- findComponent for "myForm:data:colName" always component
<h:outputText value="#{item.name}"/>
</p:column>
<p:column id="colAddress" sortBy="#{item.address}">
<h:outputText value="#{item.address}"/>
</p:column>
</p:dataTable>
<p:fieldset>
</p:outputPanel>
</h:form>
</ui:define>
</ui:composition>
</html>
Model.java:
#Named // javax.inject.Named
#ViewScoped // javax.faces.view.ViewScoped
public class Model implements Serializable {
private static final String COL_NAME_CLIENT_ID = "myForm:tabs:data:colName";
#Inject PersonTableDataModel personTableDataModel; // with getter & setter
public void loadData() {
List<SortMeta> preSortOrder = getPreSortOrder(COL_NAME_CLIENT_ID, "name", SortOrder.ASCENDING);
personTableDataModel.setPreSortOrder(preSortOrder);
}
private List<SortMeta> getPreSortOrder(String columnId, String sortField, SortOrder sortOrder) {
UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
UIComponent column = viewRoot.findComponent(columnId); // <-- ALWAYS RETURNS NULL
if (Objects.isNull(column)) {
return Collections.emptyList();
}
List<SortMeta> preSortOrder = new ArrayList<>();
SortMeta sm = new SortMeta();
sm.setSortBy((UIColumn) column);
sm.setSortField(sortField);
sm.setSortOrder(sortOrder);
preSortOrder.add(sm);
return preSortOrder;
}
}
PersonTableDataModel.java:
public class PersonTableDataModel extends TableModel<Person> {
}
TableModel.java:
public class TableModel<T> extends LazyDataModel<T> {
private List<SortMeta> preSortOrder; // with getter & setter
}
I am using Primefaces 6.1 on Wildfly 10.0.0.Final
EDIT:
I added a TabChange event listener changeTab() and traversed the UIComponents and at the end the correct clientId is written to the output?!
Model.java:
public void changeTab(TabChangeEvent event) {
TabView tabView = (TabView) event.getComponent();
logger.entry(tabView.getActiveIndex());
Tab tabProzesse = tabView.findTab("myForm:tabs:tab3");
if (Objects.nonNull(tabProzesse)) {
List<UIComponent> childs = tabProzesse.getChildren();
Optional<UIComponent> c = childs.stream().filter(child -> child.getClientId().equals("myForm:tabs:data")).findFirst();
if (c.isPresent() && c.get() instanceof DataTable) {
DataTable t = (DataTable) c.get();
Optional<UIColumn> optColName = t.getColumns().stream().filter(col -> col.getClientId().contains("colName")).findFirst();
optColName.ifPresent(colName -> {
logger.debugf("colName.clientId=%s", colName.getClientId()); // <-- output colName.clientId=myForm:tabs:data:colName
});
}
}
}
I fixed it by this work-around:
added tabChange event listener to tabView and update datatable data
added binding to initial sort column with id colName
set preSortOrder for tableModel in onTabChange listener
page.xhtml:
<p:tabView id="tabs">
<p:ajax event="tabChange" listener="#{model.onTabChange}" update="data"/>
<p:tab id="tab1">...</p:tab>
<p:tab id="tab2">...</p:tab>
<p:tab id="tab3">
<p:dataTable id="data" lazy="true"
value="#{model.personTableModel}" var="item"
sortMode="multiple"
sortBy="#{model.personTableModel.preSortOrder}">
<p:column id="colName" sortBy="#{item.name}" binding="#{mode.colName}">
</p:column>
</p:dataTable>
</p:tab>
</p:tabView>
Model.java:
private UIComponent colName;
public UIComponent getColName() {
return colName;
}
public void setColName(UIComponent colNameProzess) {
this.colName = colName;
}
public void onTabChange(TabChangeEvent event) {
TabView tabView = (TabView) event.getComponent();
UIComponent uiComponent = findComponent(tabView, colName.getId());
if (Objects.nonNull(uiComponent) && uiComponent instanceof org.primefaces.component.api.UIColumn) {
List<SortMeta> preSortOrder = getPreSortOrder(uiComponent, "name", SortOrder.ASCENDING);
personTableDataModel.setPreSortOrder(preSortOrder);
}
}
private List<SortMeta> getPreSortOrder(UIColumn column, String sortField, SortOrder sortOrder) {
List<SortMeta> preSortOrder = new ArrayList<>();
SortMeta sm = new SortMeta();
sm.setSortBy(column);
sm.setSortField(sortField);
sm.setSortOrder(sortOrder);
preSortOrder.add(sm);
return preSortOrder;
}
private UIComponent findComponent(UIComponent uiComponent, String id) {
FacesContext context = FacesContext.getCurrentInstance();
UIComponent base = Objects.nonNull(uiComponent) ? uiComponent : context.getViewRoot();
final UIComponent[] found = new UIComponent[1];
base.visitTree(VisitContext.createVisitContext(context), (context1, component) -> {
if (component.getId().equals(id)) {
found[0] = component;
return VisitResult.COMPLETE;
}
return VisitResult.ACCEPT;
});
return found[0];
}

Primefaces p:ajax and remoteCommand does not update growl messages

In the following example, I modify a datatable using p:ajax then use remoteCommand to update the table. That works. However, I would also like to update growl msgs in the event of an error or success. That doesn't work.
I see from the examples if a button calls an action, then calls remoteCommand, the growl msgs update. However, that won't give me what I need from the ajax cellEdit in a datatable.
How can I update the growl messages from a p:ajax command.
<html xmlns="http://www.w3.org/1999/xhtml"
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:form id="formId">
<p:growl id="msgs" showDetail="true" />
<h:body>
<h:panelGrid>
<!-- Updates wordsId table but not msgs -->
<p:remoteCommand name="onCellEditRemote" update="wordsId msgs"/>
<p:dataTable id="wordsId" var="word" value="#{remoteMessageBean.words}" editable="true" editMode="cell">
<!-- does not update msgs -->
<p:ajax event="cellEdit" listener="#{remoteMessageBean.modifyWordOnCellEdit}" oncomplete="onCellEditRemote()" update="formId:msgs"/>
<p:column headerText="Modify" >
<p:outputLabel value="#{word}" />
</p:column>
<p:column headerText="Modify" >
<p:cellEditor>
<f:facet name="output"><h:outputText value=""/></f:facet>
<f:facet name="input">
<p:inputText id="modelInput" value="#{remoteMessageBean.modifyWord}"/>
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</h:panelGrid>
<p:remoteCommand name="rc" update="msgs" />
<p:commandButton type="button" action="#{remoteMessageBean.buttonAction}" value="Doesnt Work" icon="ui-icon-refresh" update="msgs" />
<p:remoteCommand name="rc2" update="msgs" action="#{remoteMessageBean.buttonAction}" />
<p:commandButton type="button" onclick="rc2()" value="Works" icon="ui-icon-refresh" />
</h:body>
</h:form>
</html>
#ManagedBean
#SessionScoped
public class RemoteMessageBean {
private static Logger logger = Logger.getLogger(RemoteMessageBean.class);
private String modifyWord;
private List<String> words;
public RemoteMessageBean() {
words = new ArrayList<>();
words.add("word1");
words.add("word2");
words.add("word3");
}
public void modifyWordOnCellEdit(CellEditEvent event) {
logger.debug(event);
getWords().add(getModifyWord());
logger.debug("");
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "adding " + getModifyWord(), null);
FacesContext.getCurrentInstance().addMessage(null, msg);
setModifyWord(null);
}
public void buttonAction() {
logger.debug("");
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "buttonAction", null);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public String getModifyWord() {
return modifyWord;
}
public void setModifyWord(String modifyWord) {
this.modifyWord = modifyWord;
}
public List<String> getWords() {
return words;
}
}
I worked around the problem by creating and saving message in modifyWordOnCellEdit then calling displayMessageAction from remoteCommand to display it. Not exactly what I was hoping for but it works.
Jsf Page
<p:remoteCommand name="onCellEditRemote" update="wordsId" action="#{gameBean.displayMessageAction}"/>
Controller
public void displayMessageAction() {
if (getMessage() != null) {
FacesContext.getCurrentInstance().addMessage("growl", getMessage());
setMessage(null);
}
}
public void modifyWordOnCellEdit(CellEditEvent event) {
...
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, exception.getMessage(), null);
setMessage(msg);
}
Its will work add partialsubmit in p:ajax

primefaces: how to refresh dataTable properly after deleting one row

after deleting one row in my dataTable I still have to refresh browser manually to see changes..can you advice me how to properly udpate my dataTable after deleting data pls?
<h:body>
<h:form id="form">
<p:growl id="msgs" showDetail="true" />
<p:dataTable id="items" var="items" value="#{itemView.items}"
editable="true" editMode="cell" widgetVar="cellItems">
<f:facet name="header">
Cell Editing with Click and RightClick
</f:facet>
<p:ajax event="cellEdit" listener="#{itemView.onCellEdit}"
update=":form:msgs" />
<p:column headerText="Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{items.name}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{items.name}" style="width:96%" label="Name" />
</f:facet>
</p:cellEditor>
</p:column>
...next columns
<p:column headerText="Options" style="width:32px">
<p:commandLink id="deleteLink" styleClass="ui-icon ui-icon-trash" action="#{itemView.deleteItem(items.itemId)}" update=":form:items" ajax="true">
<p:confirm header="Confirmation" message="Are you sure?" icon="ui-icon-alert" />
</p:commandLink>
<p:confirmDialog global="true" showEffect="fade" hideEffect="explode">
<p:commandButton value="Yes" type="button" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
</p:confirmDialog>
</p:column>
</p:dataTable>
<p:growl id="growl" life="2000" />
<p:commandButton value="Add Item" id="ajax" update="msgs items" actionListener="#{itemView.buttonAction}" styleClass="ui-priority-primary" />
</h:form>
and this is my controller
public class ItemView implements Serializable {
private List<Item> items;
#ManagedProperty("#{itemService}")
private ItemService serviceItem;
#PostConstruct
public void init() {
items = serviceItem.getAllItems();
}
public List<Item> getItems(){
return items;
}
public List<String> getUseOrNotCriticalCount(){
return serviceItem.getUseOrNotCriticalCount();
}
public void setServiceItem(ItemService serviceItem){
this.serviceItem = serviceItem;
}
public void onRowEdit(RowEditEvent event) {
FacesMessage msg = new FacesMessage("Item Edited");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void onRowCancel(RowEditEvent event) {
FacesMessage msg = new FacesMessage("Edit Cancelled");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
if(newValue != null && !newValue.equals(oldValue)) {
DataTable dataTable = (DataTable) event.getSource();
Item editedItem = (Item) dataTable.getRowData();
serviceItem.edit(editedItem);
System.out.println(editedItem.getName().toString());
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cell Changed", "Old: " + oldValue + ", New:" + newValue);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
public void buttonAction(ActionEvent actionEvent) {
Item item = new Item("Nazov", 0,0,0,false,0,0,0);
serviceItem.add(item);
addMessage("New item has been added!");
}
public void addMessage(String summary) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, summary, null);
FacesContext.getCurrentInstance().addMessage(null, message);
}
public void deleteItem(int itemId){
serviceItem.delete(itemId);
addMessage("Selected item has been deleted!");
}
}
It looks like you're updating correctly on the page, but you need to update on the bean too. So in deleteItem(int itemId) either remove the deleted item from the list of items manually, or call init() for refreshing.

Primefaces contextmenu refresh when click on row of treetable

the situation is the following: I've got a treeTable with 3 different type of objects. The table contains the p:ajax with event="select". I wrote 3 different contextMenus, one for each type... and all works well.
My problem is that I want to enable/disable some of the menuItems; to do that I use the attribute "rendered" with condition based on properties of selected node.
All works, but only the second time I right-click on the same object (the first time the contextMenu isn't filtered).
Here is the code... (I'm including only one type of object for semplicity)
treeTable page:
<h:form id="form" prependId="false">
<p:treeTable value="#{documentsController.root}" var="document" id="docs"
selectionMode="single" selection="#{documentsController.selectedNode}">
<p:ajax event="select" process="#this" update=":form:menus"/>
<p:column headerText="#{msg['name']}">
<h:outputText value="#{document.name}" />
</p:column>
</p:treeTable>
<h:panelGroup id="menus">
<ui:include src="/menu/document_menu.xhtml"/>
</h:panelGroup>
<p:dialog id="document-rename-dialog" widgetVar="documentRenameDialog" header="#{msg.rename}">
<h:panelGrid id="doc-rename" columns="2">
<h:outputLabel for="name" value="#{msg.name}:" />
<h:inputText id="name" value="#{documentsController.name}"/>
</h:panelGrid>
<div class="spacer-10" />
<h:panelGroup layout="block">
<p:commandLink onclick="documentRenameDialog.hide();" value="#{msg.cancel}"/>
<p:commandLink actionListener="#{documentsController.renameDocument(documentsController.selectedNode.data)}"
process="#this :form:document-rename-dialog:doc-rename"
update=":form:docs"
oncomplete="documentRenameDialog.hide();"
value="#{msg.check}">
</h:panelGroup>
</common:dialog>
</h:form>
document_menu page:
<p:contextMenu id="contextMenuDocument" for="docs" nodeType="document">
<p:menuitem value="#{msg.rename}" process="#this docs" update=":form:document-rename-dialog:doc-rename"
actionListener="#{documentsController.setName(documentsController.selectedNode.data.name)}"
rendered="#{documentsController.canWrite}"
icon="ui-icon-pencil" oncomplete="documentRenameDialog.show();"/>
</p:contextMenu>
DocumentsController class:
#ManagedBean
#ViewScoped
public class DocumentsController {
private TreeNode root;
private TreeNode selectedNode;
private String name;
public TreeNode getSelectedNode() {
return selectedNode;
}
public void setSelectedNode(TreeNode selectedNode) {
this.selectedNode = selectedNode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void renameDocument(ArterDocument selectedDocument) {
if(name != null && !name.equals("")) {
System.out.println("Document renamed in: "+name);
((MyDocument)selectedNode.getData()).setName(name);
}
else
addErrorMessage("Error renaming document.");
}
public static boolean canWrite() {
if(((MyDocument)selectedNode.getData()).isWriteable())
return true;
return false;
}
}
The MyDocument class is a simple class with a String (name) and a boolean (writeable).
Can anyone tell me how I can show filtered contextMenu at first shot?
Thank you!