null pointer in a primefaces dataTable - jsf

I have a p:dataTable and the selected value is throwing null pointer when Im tring to get it,this situation is after put the datatable inside a modal p:dialog, but if remove the modal atribute works fine.
PD:the modal p:dialog was behid the overlay like this question
Primefaces - AjaxStatus - Dialog is behind the overlay
the answer is not working for me, because Im using primefaces 5.1, so I have to use appendTo="#(body)"
I don´t know if that is important for my problem.
Resume: the null pointer exist if the p:dialog is modal.
Here is my code
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<ui:composition template="/resources/sysged.xhtml"
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"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<ui:define name="vDoc">
<h:form id="form">
<p:panel header="Document">
<h:panelGrid columns="4">
<p:commandButton id="prev"
actionListener="#{DocumentController.priviousPage()}"
icon="ui-icon-circle-triangle-w" update="docImage next prev"
disabled="#{DocumentController.inicioLista}" />
<p:commandButton id="next"
actionListener="#{DocumentController.nextPage()}"
icon="ui-icon-circle-triangle-e" update="docImage prev next"
disabled="#{DocumentController.finalLista}" />
<p:commandButton id="anotacoes" value="Anotaçoes"
onclick="PF('dialogAnotacao').show();" />
<p:button id="voltar" outcome="pesquisaDocumento.xhtml"
value="Voltar" />
</h:panelGrid>
</p:panel>
</h:form>
<h:form id="panotation">
<p:dialog id="dialogAnotacao" closeOnEscape="true" header="Anotaçoes"
widgetVar="dialogAnotacao" modal="true" resizable="false"
appendTo="#(body)" draggable="true">
<p:dataTable id="tanotation" var="anotation"
value="#{DocumentController.arquivo.anotacaoList}"
selectionMode="single"
selection="#{DocumentController.selected}"
rowKey="#{anotation.i}">
<p:column headerText="Indice" style="text-align:left">
<h:outputText value="#{anotation.i}" />
</p:column>
<p:column headerText="text" style="text-align:left">
<h:outputText value="#{anotation.text}" />
</p:column>
</p:dataTable>
<p:contextMenu for="tanotation">
<p:menuitem value="do" update="tanotation"
icon="ui-icon-close" actionListener="#{DocumentController.doit}">
</p:menuitem>
</p:contextMenu>
</p:dialog>
</h:form>
</ui:define>
</ui:composition>
My method in the managedBean
public void doit() {
System.out.println(selected);
}

You append your <p:dialog> to the body of the html page(see appendTo attribute), as a result it is not included in any <h:form>.
This could be a problem for your <p:dataTable>
Could you place your <h:form id="panotation"> inside of your <p:dialog> and not outside ?

Related

Why is a p:panelGrid's p:row's rendered attribute ignored and not ignored in identical p:dialogs when ui:included?

I have an index.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:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Project1</title>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:body>
<ui:composition template="template.xhtml">
<ui:define name="content">
<h:form id="mainForm">
<ui:include src="/WEB-INF/includes/offer.xhtml">
</ui:include>
<p:messages/>
</h:form>
</ui:define>
</ui:composition>
</h:body>
</html>
using template.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:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<ui:insert name="content"/>
</h:body>
</html>
and including /WEB-INF/includes/offer.xhtml
<ui:composition>
<ui:include src="/WEB-INF/dialogs/offerdialog.xhtml">
</ui:include>
<p:commandButton value="Dialog 1 (doesn't repond to mode change)"
onsuccess="PF('myDialogVar1').show();">
</p:commandButton>
<p:commandButton value="Dialog 2 (does respond to mode change)"
onsuccess="PF('myDialogVar').show();">
</p:commandButton>
</ui:composition>
including /WEB-INF/dialogs/offerdialog.xhtml
<ui:composition>
<p:dialog id="myDialog1" widgetVar="myDialogVar1" modal="true">
<h:form>
<h:panelGroup>
<p:outputLabel value="Edit mode:"/>
<p:selectOneButton value="#{offers.creationMode}">
<f:selectItems value="#{offers.creationModes}"/>
<p:ajax update="#form"/>
</p:selectOneButton>
</h:panelGroup>
<p:panelGrid>
<p:row>
<p:column>
<p:outputLabel value="Row 1:"/>
</p:column>
<p:column>
<p:inputText>
<p:ajax/>
</p:inputText>
</p:column>
</p:row>
<p:row rendered="#{offers.displayAdvancedModeComponents()}">
<p:column>
<p:outputLabel value="Row 2:"/>
</p:column>
<p:column>
<p:inputText>
<p:ajax/>
</p:inputText>
</p:column>
</p:row>
</p:panelGrid>
</h:form>
</p:dialog>
<p:dialog id="myDialog" widgetVar="myDialogVar" modal="true">
<h:form>
<h:panelGroup>
<p:outputLabel value="Edit mode:"/>
<p:selectOneButton value="#{offers.creationMode}">
<f:selectItems value="#{offers.creationModes}"/>
<p:ajax update="#form"/>
</p:selectOneButton>
</h:panelGroup>
<p:panelGrid>
<p:row>
<p:column>
<p:outputLabel value="Row 1:"/>
</p:column>
<p:column>
<p:inputText>
<p:ajax/>
</p:inputText>
</p:column>
</p:row>
<p:row rendered="#{offers.displayAdvancedModeComponents()}">
<p:column>
<p:outputLabel value="Row 2:"/>
</p:column>
<p:column>
<p:inputText>
<p:ajax/>
</p:inputText>
</p:column>
</p:row>
</p:panelGrid>
</h:form>
</p:dialog>
</ui:composition>
The first dialog myDialog does not respond to changes of the creation mode (BASIC and ADVANCED) whereas the second identical myDialog does. The first one should respond as well like it does when everything is declared in index.xhtml without using the template.
The dialogs are identical in order to show that the issue occuring for the first dialog and not for the second doesn't have anything to do with the structure of the dialog. The example doesn't have any function except illustrating the unexpected behavior (p:inputText isn't bound to backing bean values, etc.).
MCVE is at https://github.com/krichter722/primefaces-datatable-row-not-updated.
I'm using Primefaces 6.1.

tabView in PrimeFaces 5.0 doesn't call tabChange event

I use PrimeFaces 5.0 and jsf 2.2. Here is my page that contains PrimeFaces tabview
<h:panelGroup layout="block" style="position:absolute;top:60px;width:100%;">
<p:tabView id="tabs" activeIndex="#{TabsManagerBean.activeIndex}" onTabShow="$('#tvlistr').click();" dynamic="true"
value="#{TabsManagerBean.tabs}" var="tab">
<p:ajax event="tabChange" listener="#{TabsManagerBean.onTabChange}" />
<p:tab title="#{tab}" titleStyle="width:180px" />
</p:tabView>
<p:commandLink id="tvlistr" style="display:none;" action="#{TabsManagerBean.navigate}"/>
</h:panelGroup>
My onTabChange method
public void onTabChange(TabChangeEvent evt) {
logger.debug("Tab changed to: {}.", evt.getData());
selectedTab = (String) evt.getData();
...
}
and the problem that this method isn't called. i need this method to be called before
<p:commandLink id="tvlistr" style="display:none;" action="#{TabsManagerBean.navigate}"/>
Updated: here is my h:form
<!DOCTYPE html>
<html 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:p="http://primefaces.org/ui">
<f:view locale="en">
<h:head>
<title>#{appMsg.common_pms}</title>
<!-- main JavaScript file -->
<h:outputScript name="js/main.js" />
</h:head>
<h:body>
<h:form id="formId" prependId="false">
<ui:include src="progressbar.xhtml" />
<h:panelGroup id="header" layout="block" style="position:absolute;top:0;width:100%;height:90px;">
<ui:include src="header.xhtml" />
</h:panelGroup>
<h:panelGroup layout="block" style="position:absolute;top:60px;width:100%;">
<p:tabView id="tabs" activeIndex="#{TabsManagerBean.activeIndex}" onTabShow="$('#tvlistr').click();" dynamic="true"
value="#{TabsManagerBean.tabs}" var="tab">
<p:ajax event="tabChange" listener="#{TabsManagerBean.onTabChange}" />
<p:tab title="#{tab}" titleStyle="width:180px" />
</p:tabView>
<h:commandLink id="tvlistr" style="display:none;" action="#{TabsManagerBean.navigate}">
<f:ajax event="action" />
</h:commandLink>
</h:panelGroup>
<h:panelGroup id="footer" layout="block" style="position:absolute;height:20px;width:100%;bottom:0;background-color: #005696">
<ui:include src="/templates/version.xhtml" />
</h:panelGroup>
</h:form>
</h:body>
</f:view>
I had a similar problem with Primefaces 5.1
As long as i put the tabview into a form everything worked fine.
But because i wanted to use seperate forms in my tabs i had to remove the surrounding form of the tabview to avoid nested forms.
Without the surrounding form the ajax event didn´t get triggered any more when changing the tab.
My solution was to use a remotecommand in a form parallel to the tabview.
The remotecommand is triggered by the onTabChange attribute of the tabview element.
At that call i forwarded the index parameter to the global request parameters.
<p:tabView id="rootTabMenu" styleClass="tabcontainer" prependId="false"
activeIndex="#{sessionData.activeTabIndex}" widgetVar="rootTabMenu"
onTabChange="tabChangeHelper([{name: 'activeIndex', value: index}])">
// Tabs...
</p:tabView>
<h:form id="tabChangeHelperForm">
<p:remoteCommand name="tabChangeHelper" actionListener="#{sessionData.onTabChange()}" />
</h:form>
In the backing bean i catched the value again from the request parameter map and set the active index.
public void onTabChange()
{
FacesContext context = FacesContext.getCurrentInstance();
Map<String, String> paramMap = context.getExternalContext().getRequestParameterMap();
String paramIndex = paramMap.get("activeIndex");
setActiveTabIndex(Integer.valueOf(paramIndex));
System.out.println("Active index changed to " + activeTabIndex);
}
Hope that can help you
This is likely a bug related to dynamically built tabs. Removing the "var" and "value" and presenting static tags will cause the listener to fire properly. Might want to file a bug report.
<p:tabView id="tabs" activeIndex="#{TabsManagerBean.activeIndex}" onTabShow="$('#tvlistr').click();" dynamic="true">
<p:ajax event="tabChange" listener="#{TabsManagerBean.onTabChange}" />
<p:tab title="First tab" titleStyle="width:180px" />
<p:tab title="Second tab" titleStyle="width:180px" />
</p:tabView>

Primefaces' p:dialog with form doesn't behave as expected

I generated a Primefaces based CRUD website starting from JPA Entities with netbeans and after adjusting the Update dialog to fit my needs I am experiencing several problems. The domain Model is quite easy: I have an entity Invitation which contains several Guests.
#Entity
public class Invitation implements Serializable {
...
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "invitationId")
private List<Guest> guestList;
public List<Guest> getGuestList() {
return guestList;
}
...
}
I have an overview page (list.xhtml) where all the invitations are listed and the user can pick one to edit it.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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:p="http://primefaces.org/ui" template="/template/layout.xhtml">
<ui:define name="content">
<h:form id="InvitationListForm">
<p:dataTable var="invitation" id="datalist"
value="#{invitationController.invitations}" resizableColumns="true"
selectionMode="single" selection="#{invitationController.selected}"
rowKey="#{invitation.invitationId}" paginator="true" rows="10"
rowsPerPageTemplate="10,30,50,100" draggableColumns="true">
<p:ajax event="rowSelect" update="createButton editButton " />
<p:ajax event="rowUnselect" update="createButton editButton " />
<p:column headerText="Name">
<h:outputText id="invitationName" value="#{invitation.name}" />
</p:column>
...
<f:facet name="footer">
<p:commandButton id="createButton" icon="ui-icon-plus"
value="#{msgs.lbl_add_new}" update=":InvitationCreateForm"
oncomplete="PF('InvitationCreateDialog').show()" />
<p:commandButton id="editButton" icon="ui-icon-pencil"
value="#{msgs.lbl_edit}" update=":InvitationEditForm"
oncomplete="PF('InvitationEditDialog').show()"
disabled="#{empty invitationController.selected}" />
</f:facet>
</p:dataTable>
</h:form>
<ui:include src="create.xhtml" />
<ui:include src="edit.xhtml" />
</ui:define>
</ui:composition>
Note that layout.xhtml doesn't contain any form (no nested forms).
The dialog edit.xhtml is divided into 2 parts: one where the user can enter the invitation "head" information and another one with a datatable where she can edit / add / delete guests.
<!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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<body>
<ui:composition>
<h:form id="InvitationEditForm">
<p:dialog id="InvitationEditDlg" widgetVar="InvitationEditDialog"
modal="true" resizable="false" appendTo="#(body)"
header="#{msgs.lbl_add_new}">
<h:panelGroup id="display">
<p:panelGrid columns="2"
rendered="#{invitationController.selected != null}">
<p:outputLabel value="#{msgs.lbl_name}" for="name" />
<p:inputText id="name"
value="#{invitationController.selected.name}" required="true"/>
...
</p:panelGrid>
<p:dataTable var="aGuest" id="guestTable" style="width: 1200px;"
value="#{invitationController.selected.guestList}"
resizableColumns="false" rowIndexVar="idx" draggableColumns="true">
<p:column width="80" headerText="#{msgs.lbl_name}">
<p:inputText id="guestName" value="#{aGuest.name}" />
</p:column>
...
<p:column width="20">
<p:commandButton
actionListener="#{invitationController.addNewGuest}"
id="addGuestButton" update="guestTable" icon="ui-icon-plusthick"
title="+" />
<p:commandButton
actionListener="#{invitationController.deleteGuest(idx)}"
id="deleteGuestButton" update="guestTable"
icon="ui-icon-minusthick" title="-" immediate="true"
rendered="#{invitationController.selected.guestList.size()>1}" />
</p:column>
</p:dataTable>
<p:commandButton actionListener="#{invitationController.save}"
value="#{msgs.lbl_save}"
update="display,:InvitationListForm:datalist,:growl"
oncomplete="handleSubmit(args,'InvitationEditDialog');" />
<p:commandButton value="#{msgs.lbl_cancel}" immediate="true"
actionListener="#{invitationController.cancel}"
onclick="PF('InvitationEditDialog').hide()" />
</h:panelGroup>
</p:dialog>
</h:form>
</ui:composition>
</body>
</html>
And the Controller
#SessionScoped
#Named
public class InvitationController implements Serializable {
private Invitation selected; //with getter and setter
}
Now, I think my problem should be in the combination of p:dialog and h:form.
The original generated version of edit.xhtml had the form InvitationEditForm nested within the dialog and not the contrary as I posted above. The problem with that was after clicking editButton the dialog was loaded, but the dataTable was always filled with guests of the first Invitation I selected in my session (more strangely, suppose the first invitation in the session had just a guest A: after selecting an Invitation with 2 guests B and C I got A and B displayed). As the controller was returning the right guestList(), I supposed there was a problem with update and inverting form and display solved this problem..
Unfortunately this didn't solve all the problems, as now the actionListener for addGuestButton and deleteGuestButton doesn't get invoked anymore..
I am really confused: can you please help me to fix my code? Thanks in advance!

Using contextMenu on a dataTable inside a tab

I'm trying to add a contextMenu to a dataTable contained inside a tab. I have been able to get the menu to show up on a dataTable which is not inside a tab and was also to get it to show up on the entire tab...but not specifically on the dataTable.
I've tried several different references in the 'for' attribute of the contextMenu...some blow up, some do not but the menu doesn't show up on right-click.
I'm using PrimeFaces 4.0. Any suggestions?
<!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"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
<h:form id="someForm">
<p:tabView id="tv" var="tb" value="#{TempBeans.tabs}">
<p:ajax event="tabClose" listener="#{TempBeans.tabClose}"
update="#form" />
<p:tab id="tempTab" title="#{tb.name}" closable="true">
<p:dataTable id="dTable" var="d" value="#{tb.dtbs}">
<p:column id="column1" headerText="name">
<h:outputText value="#{d.name}" />
</p:column>
<p:column id="column2" headerText="id">
<h:outputText value="#{d.id}" />
</p:column>
</p:dataTable>
</p:tab>
</p:tabView>
<p:contextMenu for=":someForm:tv:dTable">
<p:menuitem value="TableView" update="#form" icon="ui-icon-search" />
<p:menuitem value="TableDelete" update="#form" icon="ui-icon-close" />
</p:contextMenu>
</h:form>
</h:body>
</html>
Well, I was able to get the context menu to appear by changing the table to be selectable...which is sort of what I wanted anyway. However, now I have another problem...If I make the selectionMode "multiple" and use ctrl-clicks to select rows it seems to register the last right-click as a single click.
click one row
ctrl-click second row
ctrl-click third row
right-click one of the rows...deselects other rows
So it seems I would have to force my users to:
click one row
ctrl-click second row
ctrl-right-click third row
AAAAAAAAAAAAAAAAAAAAAAAAAAARRRRGH!! Deal-breaker...looks like I'm going back to prehistoric ui times and implementing multiple selection with checkboxes.
Please someone tell me I'm wrong and there's a simple way to make it not behave like this.
Anyway, here is how I eventually managed to get a contextMenu to show up:
<!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" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
<h:form id="someForm">
<p:tabView id="tv" var="tb" value="#{TempBeans.tabs}">
<p:ajax event="tabClose" listener="#{TempBeans.tabClose}" update="#form" />
<p:tab id="tempTab" title="#{tb.name}" closable="true">
<p:dataTable id="dTable" var="d" value="#{tb.dtbs}" selection="#{tb.selectedDTBs}" selectionMode="multiple" rowKey="#{d.name}">
<p:column id="column1" headerText="name">
<h:outputText value="#{d.name}" />
</p:column>
<p:column id="column2" headerText="id">
<h:outputText value="#{d.id}" />
</p:column>
</p:dataTable>
<p:contextMenu id="cMenuId" for="dTable">
<p:menuitem value="TableView" update="#form" icon="ui-icon-search" />
<p:menuitem value="TableDelete" update="#form" icon="ui-icon-close" />
</p:contextMenu>
</p:tab>
</p:tabView>
</h:form>
</h:body>
</html>

JSF:Primefaces: Cannot open Dialog from Bean using RequestContext

I am not able to open Dialog from my Bean. I have also tried actionListener instead of action
This is how my JSF looks like:
<ui:composition template="../templates/site.xhtml"
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:p="http://primefaces.org/ui"
xmlns:sec="http://www.springframework.org/security/tags">
<!-- remove me just for encoding check ä -->
<ui:define name="content">
<h:form id="form">
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Button" type="button" id="myButton"
action="#{testBean.showDialog}" />
</h:panelGrid>
</h:form>
<p:dialog id="testDialog" widgetVar="testDialog2"
header="My Test Dialog" modal="true" appendToBody="true">
<h:form>
<h:outputText value="Output" />
</h:form>
</p:dialog>
</ui:define>
And this is my Bean
#Component
#Scope("view")
public class TestBean {
public void showDialog(){
RequestContext.getCurrentInstance().execute("testDialog2.show()");
}
}
Your showDialog() method is not called at all. Remove type="button" as you want to use AJAX enable submit, not push button.

Resources