commandLink only works with a h and p version - jsf

I'm having this really weird issue where my commandLinkonly work if I have BOTH links in the same view.
Works fine, both links:
<ui:composition template="../../template.xhtml" xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:define name="content">
<h:form>
<p:dataTable var="v" value="#{myBean.myList}">
<p:column headerText="Name">
<h:commandLink value="Go to next page" action="#{myBean.doThing(v)}" />
<p:commandLink value="Go to next page" action="#{myBean.doThing(v)}" />
</p:column>
</p:dataTable>
<p:commandButton value="Submit" ajax="false" actionListener="#{myBean.submit}" />
</h:form>
</ui:define>
</ui:composition>
But if I remove either link, it doesn't even reach the method doThing() and reloads an empty page.
My bean:
#ManagedBean(name="myBean")
#RequestScoped
public class MyBean {
private List<Object> myList = new ArrayList<>();
public MyBean() {
}
public String doThing(Object obj) {
// This never prints if I remove one of the links
System.out.println("You're doing the thing!");
return "nextView?faces-redirect=true"
}
// Getters, setters etc.
}
I'm using JSF 2.0 and GlassFish 4.0.
How can I fix this and why is it happening?
I have a commandLink in a p:dataTable in another view and it's working fine.
EDIT:
Added the complete XML for the composition part of the view. The partial is inside a template:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<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>
<!-- css imports, titles etc -->
</h:head>
<h:body>
<ui:insert name="menu">
<ui:include src="./default/content.xhtml" />
</ui:insert>
</h:body>
</html>

Related

Why Faces Message did not show up on some pages even method is called?

I have multiple pages, and on some, the FacesMessage appears, while on others they don't. But I can't figure out why. In my example below, ajax is at false, but on some ajax is at true like everywhere else, but not working even it's same code
In every case the method is called, log proves it, but the message did not show in some case
I have a menu bar, which is included on top of every page, as
<html xmlns="http://www.w3.org/1999/xhtml" xlmns:h="http://java.sun.com/jsf/html" xlmns:f="http://java.sun.com/jsf/core" xlmns:ui="http://java.sun.com/jsf/facelets" xlmns:p="http://primefaces.org/ui">
<f:view contentType="text/html">
<h:head>
<f:facet name="first">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
<title>LOG</title>
</f:facet>
<h:body>
<p:growl showDetail="true" sticky="true">
<p:autoUpdate disabled="false" />
</p:growl>
...
<p:layout>
<p:layoutUnit position="center">
<ui:insert name="center" />
</p:layoutUnit>
</p:layout>
</h:body>
</f:view>
</html>
And working page is like
<!DOCTYPE HTML PUBLIC>
<ui:composition template="/menu.xhtml" xmlns="http://www.w3.org/1999/xhtml"
xlmns:h="http://java.sun.com/jsf/html" xlmns:f="http://java.sun.com/jsf/core"
xlmns:ui="http://java.sun.com/jsf/facelets" xlmns:p="http://primefaces.org/ui">
<ui:define name="center>
<h:form >
<p:commandButton action="#{firstBean.method()}" />
</h:form>
</ui:define>
</ui:composition>
Not working page is like (here ajax at false, but there is also non-working page with ajax true) :
<!DOCTYPE HTML PUBLIC>
<ui:composition template="/menu.xhtml" xmlns="http://www.w3.org/1999/xhtml"
xlmns:h="http://java.sun.com/jsf/html" xlmns:f="http://java.sun.com/jsf/core"
xlmns:ui="http://java.sun.com/jsf/facelets" xlmns:p="http://primefaces.org/ui">
<ui:define name="center>
<h:form enctype="mulipart/form-data" >
<h:inputFile value="#{secondBean.inputFile}" />
<p:commandButton ajax="false" action="#{secondBean.method()}" process="#form" />
</h:form>
</ui:define>
</ui:composition>
And both method() are 100% same :
public void method(){
new JSFUtils().sendMessage("Test 1");
Logger.getAnonymousLogger().severe("Test"); // Always worked, always called
//...
}
Where I have an util class
public calss JSFUtil{
public void sendMessage(String msg){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(Faces.Message.SEVERITY_WARN, "Warn", msg));
}
}

<f:viewParam> not working when using <ui:composition template>

I'd like to create a master-detail screen with request params and requestScoped beans but the view param doesn't get filled.
The link that invokes the redirect:
<h:form>
<p:dataTable var="visit" value="#{visitBean.findAllVisits()}">
<p:column headerText="mdh">
<p:commandLink action="#{visitDetailBean.seeVisitDetails(visit)}">
<h:graphicImage library="images" name="details.png"/>
</p:commandLink>
</p:column>
....
The method behind it:
public String seeVisitDetails(Visit visit) throws IOException {
return "/pages/mdh-details.xhtml?visitId=" + visit.getId()+ ";faces-redirect=true";
}
The details xhtml page:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<f:metadata>
<f:viewParam name="visitId" value="#{visitDetailBean.currentVisitId}" />
</f:metadata>
<ui:composition template="/templates/masterLayout.xhtml">
<ui:define name="content">
<h:outputText value="#{visitDetailBean.currentVisit.name}"/>
test
</ui:define>
</ui:composition>
and last the details Bean:
private long currentVisitId;
public void setCurrentVisitId(long currentVisitId) {
this.currentVisitId = currentVisitId;
}
public long getCurrentVisitId() {
return currentVisitId;
}
public Visit getCurrentVisit() {
return visitService.findVisit(currentVisitId);
}
currentVisitId is always 0.. I actually can't really find it.
When using templating, anything outside <ui:composition> and <ui:define> is ignored. This includes <f:metadata>.
Move it to inside an <ui:define> of the <ui:composition>.
E.g.
<ui:composition template="/templates/masterLayout.xhtml">
<ui:define name="metadata">
<f:metadata>
<f:viewParam ... />
</f:metadata>
</ui:define>
<ui:define name="content">
...
</ui:define>
</ui:composition>
See also:
When using <ui:composition> templating, where should I declare the <f:metadata>?
Unrelated to the concrete problem, you'd better place masterLayout.xhtml in /WEB-INF folder to prevent direct access.
<ui:composition template="/WEB-INF/templates/masterLayout.xhtml">
See also:
Which XHTML files do I need to put in /WEB-INF and which not?

PF5 <p:tree><p:ajax listener> stops working after being refreshed via <p:contextMenu><p:menuItem>, works in PF4

I am using PF5, Jboss7, Mojarra 2.2 with Jdk1.7.
I have a dynamic tree with context menu. When I click on the menuitem, the page appears in the content panel. However, after that, looks like i lose all the listeners on the page including the tree. Cannot expand, second menuitem does not respond, basically, primefaces removes all the listeners on the page or, perhaps removes the form component, not sure.
<?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: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>
<title>IPMS Navigation Tree</title>
<h:outputStylesheet library="stylesheet" name="lookfeel.css" />
</h:head>
<h:body>
<p:layout fullPage="true">
<p:layoutUnit position="west" resizable="true" size="400"
minSize="100">
<h:form id="navForm" prependId="false">
<p:tabView>
<p:tab title="Domains">
<ui:include src="TabDomains.xhtml"/>
</p:tab>
<p:tab title="Orgs">
<ui:include src="TabOrgs.xhtml"/>
</p:tab>
<p:tab title="Admin">
<ui:include src="TabAdmin.xhtml"/>
</p:tab>
</p:tabView>
</h:form>
</p:layoutUnit>
<p:layoutUnit position="center">
<h:form id="frmContent" prependId="false">
<p:panel id="frmPanel">
<ui:include src="#{menuController.page}.xhtml" />
</p:panel>
</h:form>
</p:layoutUnit>
</p:layout>
</h:body>
</html>
TabDomains.xhtml is
<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:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<p:tree id="domains" value="#{treeController.root}"
selectionMode="single"
selection="#{treeController.selectedDomain}"
var="node" dynamic="true" cache="false">
<p:ajax event="expand" listener="#{treeController.onNodeExpand}" />
<p:treeNode>
<h:outputText value="#{node}" />
</p:treeNode>
</p:tree>
<p:contextMenu for="domains">
<p:menuitem id="propertiesMenu" value="Properties" update=":frmContent:frmPanel"
actionListener="#{menuController.viewDomainProperties}">
</p:menuitem>
<p:menuitem id="editZoneMenu" value="Edit Zone" update=":frmContent:frmPanel"
actionListener="#{menuController.viewEditZone}"
icon="ui-icon-close">
</p:menuitem>
</p:contextMenu>
</ui:composition>
And the backing bean is:
public class MenuController extends Controller
{
private static final Logger logger = Logger.getInstance(MenuController.class);
private String page;
public MenuController()
{
super();
this.page="MainContent";
}
public String getPage()
{
return page;
}
public void setPage(String page)
{
this.page = page;
}
public void viewEditZone()
{
logger.debug("begin viewEditZone");
this.page="EditZone";
}
public void viewDomainProperties()
{
logger.debug("begin viewDomainProperties");
this.page="DomainProperties";
}
}
I tested this in PF4 and it works fine. Any help or pointer to fix this is greatly appreciated. Thank You.

primefaces DialogFramework invokes commandButton action on open

this is the page where i call dialog on openDialog metod
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<meta content='text/html; charset=UTF-8' http-equiv="Content-Type"/>
</h:head>
<h:body>
<h:form>
<p:commandButton value="OpenDialog" action="#{cnt.openDialog()}"/>
</h:form>
</h:body>
</html>
and my dialog page is
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<meta content='text/html; charset=UTF-8' http-equiv="Content-Type"/>
</h:head>
<h:body>
<h:form id="insModForm">
<p:panel id="searchCitizenPanel" header="Just Panel" >
<h:panelGrid columns="2">
<h:outputText value="name"/>
<p:inputText value="#{iamasCnt.citizen.name}"/>
<h:outputText value="surname"/>
<p:inputText value="#{iamasCnt.citizen.surname}"/>
<h:outputText value="bdate"/>
<p:calendar value="#{iamasCnt.citizen.bdate}"/>
<h:outputText value=""/>
<p:commandButton value="check" action="#{cnt.searchThis()}" />
</h:panelGrid>
</p:panel>
</h:form>
</h:body>
and CDI where i call prime faces framework dialog
#Named("cnt")
#SessionScoped
public class IAMASController implements Serializable {
public void openDialog() {
logger.info("// opendialog");
Map<String, Object> options = new HashMap<String, Object>();
options.put("modal", true);
options.put("draggable", false);
options.put("resizable", false);
options.put("contentHeight", 720);
options.put("contentWidth", 720);
RequestContext.getCurrentInstance().openDialog("/dialogTest/dialog", options, null);
}
}
i'm newly using primefaces dialog framework got some problems
problem is p:commandButton action searchThis() invokes each time when i open prime faces dialog
I find it! There was such a weird situation
i put comment next to
<p:commandButton value="check" action="#{cnt.searchThis()}"/><!-- action="#{iamasCnt.hiddenSearch()}"-->
due to jsf problem hiddenSearch() action in comment invoked each time when dialog loads so i took off this comment everything works fine

Using <f:view> on the template page in JSF

I have a DataTable (Primefaces 3.5, JSF 2.0) which is populated from a database. In the first column of this table, checkboxes are displayed (multiple row selection).
After selecting row(s), when a button (<p:commandButton>) is pressed, the selected rows are expected to be deleted from the database.
Before deleting row(s), a confirm message regarding the deletion of the selected row(s) is displayed in <p:confirmDialog> with two buttons Yes and No something like the following.
Test.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">
<ui:composition template="template/Template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<ui:define name="title">Test</ui:define>
<ui:define name="content">
<h:form id="form">
<p:dataTable id="dataTable" var="row" value="#{testManagedBean.list}"
selection="#{testManagedBean.selectedValues}"
rowKey="#{row.id}"
rowIndexVar="rowIndex">
<p:column selectionMode="multiple" style="width:5%; text-align: center;">
<f:facet name="footer">
----------------> <p:commandButton actionListener="#{testManagedBean.deleteMultipleActionListener}" oncomplete="confirmDeleteMultiple.show()" update=":form:confirmDialogDeleteMultiple" process=":form:dataTable" icon="ui-icon ui-icon-close"/>
</f:facet>
</p:column>
<p:column headerText="Index">
<h:outputText value="#{rowIndex+1}"/>
</p:column>
<p:column id="id" headerText="Id">
<h:outputText value="#{row.id}"/>
</p:column>
<p:column id="countryName" headerText="Description">
<h:outputText value="#{row.description}"/>
</p:column>
</p:dataTable>
---------------><p:confirmDialog id="confirmDialogDeleteMultiple" widgetVar="confirmDeleteMultiple" appendToBody="true" message="Delete row(s)?" showEffect="true" hideEffect="true" header="Deletion of row." severity="alert" closeOnEscape="true" closable="true">
<p:commandButton id="confirmDeleteMultiple" value="Yes" oncomplete="confirmDeleteMultiple.hide()" actionListener="#{testManagedBean.deleteMultiple}" process="#this dataTable" update="dataTable"/>
<p:commandButton id="declineDeleteMultiple" value="No" onclick="confirmDeleteMultiple.hide()" type="button" />
</p:confirmDialog>
</h:form>
</ui:define>
</ui:composition>
The managed bean:
#ManagedBean
#ViewScoped
public final class TestManagedBean implements Serializable
{
#EJB(mappedName="ejb/JNDI")
private TestService testService;
private List<Test> list;
private List<Test>selectedValues;
public TestManagedBean(){}
#PostConstruct
public void init()
{
list=testService.getList();
}
public List<Test> getList() {
return list;
}
public List<Test> getSelectedValues() {
return selectedValues;
}
public void setSelectedValues(List<Test> selectedValues) {
this.selectedValues = selectedValues;
}
public void deleteMultipleActionListener(ActionEvent actionEvent)
{
//Just show a warning message, when the delete button is pressed.
for(Test test:selectedValues)
{
System.out.println(test.getId()+" : "+test.getDescription());
}//Displays the list.
}
public void deleteMultiple(ActionEvent actionEvent)
{
System.out.println("multiple");
for(Test test:selectedValues)
{
System.out.println(test.getId()+" : "+test.getDescription());
}//The list is not null and empty.
}
}
When the button (indicated by an arrow in XHTML) is pressed, the deleteMultipleActionListener() method in the managed bean is invoked where it simply displays the list which is populated by the selected rows and the confirm dialog as shown in XHTML appears afterwards. (This is just to show a warning message before deletion. The loop in this method is just for the demonstration).
When the Yes button on the confirm dialog is pressed, the deleteMultiple() method is invoked which is responsible for actual deletion of rows (actionListioner in <p:commandButton> inside <p:confirmDialog>) and the deletion of rows should be performed but here the list of the selected rows retrieved here is empty (not null).
The resulting list inside the deleteMultiple() method is empty because of <f:view> on the template page. The template page is shown below.
<?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 lang="#{localeBean.language}"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
--------->
<f:view locale="#{localeBean.locale}" encoding="UTF-8" contentType="text/html">
<f:loadBundle basename="messages.ResourceBundle" var="messages"/>
<h:head><title><ui:insert name="title">Default Title</ui:insert></title></h:head>
<h:body>
<p:layout fullPage="true">
<p:layoutUnit position="north" size="135" collapsed="false" resizable="false" closable="false" collapsible="false" gutter="6">
<h:form>
<h:selectOneMenu id="languages" value="#{localeBean.language}" onchange="submit();" style="position: absolute; right: 0; top: 50px;">
<f:selectItem itemValue="en" itemLabel="English" />
<f:selectItem itemValue="hi" itemLabel="Hindi" />
</h:selectOneMenu>
</h:form>
</p:layoutUnit>
<p:layoutUnit position="west" id="leftPanel" size="225" header="Menu Item" resizable="false" closable="false" collapsible="true" gutter="6">
</p:layoutUnit>
<p:layoutUnit position="center" size="2500" maxSize="2500">
<ui:insert name="content">Put default content here, if any.</ui:insert>
</p:layoutUnit>
</p:layout>
</h:body>
</f:view>
</html>
When I remove this template from the above Test.xhtml page and use this <f:view> tag on the Test.xhtml page itself, everything works fine and the list of the selected rows inside the deleteMultiple() method is obtained correctly.
So, what is going wrong? Why does the list become empty when the Yes button is pressed, if the template page is enclosed by <f:view>? Is it wrong? How to accomplish this? (<f:view> is used for the localization of the application as it can be imagined).
Your problem is solved when you replace the process="#this datatable" in your confirmDeleteMultiple by process="#this", which makes the button component only be processed. In fact you don't need Ajax to process your datatable when you send the deletion confirmation, because values for deletion are already stored in the bean since previous step (that's the main benefit of the view scope).
Making your datatable to be processed in your Ajax request invokes again the setSelectedValues setter, so the original value is getting overriden by the new (empty) selection.

Resources