How to update outputPanel component from inside tabView component - jsf

I'm trying to update a outputPanel component when a tabView is changed but I could not find the way. Otherway I found was to update the complete form but I would rather to update only the component.
I tried update with :frmTest:grpButtons and frmTest:grpButtons, and the only thing it worked was frmTest.
Any idea about what is wrong.
test.xhtml
<ui:composition 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"
template="/WEB-INF/template.xhtml">
<ui:define name="pageTitle">Test</ui:define>
<ui:define name="content">
<h:form id="frmTest" prependId="true">
<div class="Container100">
<div class="ContainerIndent">
<div class="Card ShadowEffect TexAlLeft">
<p:tabView id="tabView">
<p:ajax event="tabChange" listener="#{testBean.onTabChange}"
update=":frmTest:grpButtons"/>
<p:tab title="First" id="tab1">
<div class="Card ShadowEffect TexAlCenter">
<br/>
<h2>Empty Page 1</h2>
<br/>
<span class="gray">Use this page to start from scratch and place your custom content.</span>
<br/><br/>
</div>
</p:tab>
<p:tab title="Second" id="tab2">
<div class="Card ShadowEffect TexAlCenter">
<br/>
<h2>Empty Page 1</h2>
<br/>
<span class="gray">Use this page to start from scratch and place your custom content.</span>
<br/><br/>
</div>
</p:tab>
</p:tabView>
<p:separator/>
<p:outputPanel id="grpButtons" rendered="#{testBean.showButtons}">
<p:commandButton id="btnSaveSol" value="#{msgs.save}"
styleClass="Fright GreenButton"
action="#{testBean.save}"
ajax="true"
update=":frmTest"/>
</p:outputPanel>
</div>
</div>
</div>
</h:form>
</ui:define>
</ui:composition>
TestBean.java
#ViewScoped
#ManagedBean
public class TestBean implements Serializable {
private static final long serialVersionUID = 4078818945032342504L;
private Arxiu arxiu;
private boolean showButtons = true;
#PostConstruct
private void init() {
loadLocale();
}
//----------------------------------------------------------------
// Methods
//----------------------------------------------------------------
public void onTabChange(TabChangeEvent event) {
showButtons = !event.getTab().getId().equals("tab2");
}
public void save() {
System.out.println("save");
}
//Getters and setters
}

I found a way that works but I still don't know why it doesn't work as I was in the question. Could it be a primefaces error?
I wrapped the outputPanel with a panel and the attribute widgetVar="var" and then update="#widgetVar(var)".
Modifications of code
<p:ajax event="tabChange" listener="#{testBean.onTabChange}"
update="pnlButtons"/>
...
<p:panel id="pnlButtons">
<p:outputPanel id="grpButtons" rendered="#{testBean.showButtons}">
<p:commandButton id="btnSave" value="#{msgs.save}"
styleClass="Fright GreenButton"
action="#{testBean.save}" ajax="true"
rendered="#{testBean.showButtons}"/>
</p:outputPanel>
</p:panel>

Related

primefaces update fails on one page

I'm sure that the question is asked before, but I can't fin my explicit problem, I'm afraid it is only a little typo and I can't see it.
I have a simple page in primefaces 10 with a toolbar, with an add-button, a table and a dialoge for adding the data. The dialog has a rendered tag that the requiered field are only rendered if there is a new variable. Everything I used on several other pages of my project.
The new Variable is initialized perfectly but the inside of the dialog isn't rendered, if I remove the rendered tag the field is rendered, but I have put some test-content into my new Variable and this isn't shown either, so I think that my update doesn't get called but I don't see why.
So here is my code:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE composition 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="layout.xhtml">
<ui:define name="header">
<div id="header">
ChangeLog
</div>
</ui:define>
<ui:define name="main">
<h:form id="changelogfrm">
<p:growl id="messages" showDetail="true" life="3000" />
<div class="card">
<p:toolbar>
<p:toolbarGroup>
<p:commandButton value="Neu" icon="pi pi-plus" actionListener="#{changeloghandler.newChangelog}"
update=":changelogfrm:manage-change-content" oncomplete="PF('manageChangeDialog').show()"
styleClass="ui-button-success" style="margin-right: .5rem" />
</p:toolbarGroup>
</p:toolbar>
<p:dataTable var="change" value="#{changeloghandler.changeLogs}"
showGridlines="true" size="small" id="dtChange">
<p:column headerText="Version">
<h:outputText value="#{change.version}" />
</p:column>
<p:column headerText="Typ">
<h:outputText value="#{change.changeType}"/>
</p:column>
<p:column headerText="Beschreibung">
<h:outputText value="#{change.description}"/>
</p:column>
<p:column headerText="Datum">
<h:outputText value="#{change.date}">
<f:convertDateTime type="date" pattern="dd.MM.yyyy HH:mm"/>
</h:outputText>
</p:column>
</p:dataTable>
<p:dialog header="Change" showEffect="fade" modal="true"
widgetVar="manageChangeDialog" responsive="true">
<p:outputPanel id="manage-change-content" class="ui-fluid">
<p:outputPanel rendered="#{not empty changeloghandler.selected}">
<div class="p-field">
<p:outputLabel for="chBeschreibung">Beschreibung</p:outputLabel>
<p:inputTextarea id="chBeschreibung" value="#{changeloghandler.selected.description}" required="true"/>
</div>
</p:outputPanel>
</p:outputPanel>
<f:facet name="footer">
<p:commandButton value="Save" icon="pi pi-check" actionListener="#{changeloghandler.save}"
update="manage-change-content" process="manage-change-content #this"/>
<p:commandButton value="Cancel" icon="pi pi-times" onclick="PF('manageChangeDialog').hide()"
class="ui-button-secondary"/>
</f:facet>
</p:dialog>
</div>
</h:form>
</ui:define>
</ui:composition>
The save-function in the dialog isn't called either.
I've also checked the html on the site, there is no double-form and the ids are set correctly.
Hope you can help me.
!!!EDIT!!!
Hi, here you have the Bean-Class:
package main.java.handler;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import org.primefaces.PrimeFaces;
import main.java.persistence.entities.ChangeLog;
import main.java.persistence.entities.enums.ChangeType;
import main.java.persistence.entities.enums.Version;
import main.java.persistence.interfaces.ChangeLogDbInterface;
#Named("changeloghandler")
#SessionScoped
public class ChangeLogHandler implements Serializable{
private static final long serialVersionUID = 1L;
private List<ChangeLog> changeLogs;
private ChangeLog selected;
private List<Version> versions;
private ChangeType[] changeTypes;
#PostConstruct
private void init() {
changeLogs = ChangeLogDbInterface.loadChangeLogItems();
versions = new ArrayList<>();
for(Version v : Version.values()) {
if(v.isActive()) versions.add(v);
}
changeTypes = ChangeType.values();
}
public void newChangelog() {
ChangeLog newLog = new ChangeLog();
newLog.setDate(new Timestamp(System.currentTimeMillis()));
this.selected = newLog;
}
public void save() {
if (this.selected.getId() == 0) {
ChangeLogDbInterface.createChangeLogItem(selected);
this.changeLogs.add(this.selected);
}
else {
ChangeLogDbInterface.updateChangeLogItem(selected);
}
PrimeFaces.current().executeScript("PF('manageChangeDialog').hide()");
PrimeFaces.current().ajax().update("changelogfrm:dtChange");
}
public List<ChangeLog> getChangeLogs() { return changeLogs; }
public ChangeLog getSelected() { return selected; }
public List<Version> getVersions() { return versions; }
public ChangeType[] getChangeTypes() { return changeTypes; }
public void setChangeLogs(List<ChangeLog> changeLogs) { this.changeLogs = changeLogs; }
public void setSelected(ChangeLog selected) { this.selected = selected; }
public void setVersions(List<Version> versions) { this.versions = versions; }
public void setChangeTypes(ChangeType[] changeTypes) { this.changeTypes = changeTypes; }
}
!!! EDIT 2 !!!
Here is the template, but I think that doesn't help much either:
<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:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Asset Tool Connector</title>
<link type="text/css"
href="${facesContext.externalContext.requestContextPath}/resources/css/style.css"
rel="stylesheet" />
<link type="image/x-icon"
href="${facesContext.externalContext.requestContextPath}/resources/images/netzwerk.png"
rel="shortcut icon" />
</h:head>
<h:body>
<ui:insert name="header"/>
<f:event listener="#{sessionHandler.checkLoggedIn}" type="preRenderView" />
<div id="menu">
<ui:include src="menu.xhtml" />
</div>
<div id="main">
<ui:insert name="main"/>
</div>
<div id="footer">
<div>
<h:form id="footerForm">
<p:commandButton value="ChangeLog" action="/changelog?faces-redirect=true"/>
</h:form>
</div>
© ATC - by 5332
</div>
</h:body>
</html>
Except the button in the footer links to the page with my issue, if that would be an issue.

Cannot set backing bean parameter using f:setPropertyActionListener

I got trouble in JSF when I try to delete the row content from database through commandLink inside dataTable element.
So I got the bean with viewScopped and managedScoped like this :
#ViewScoped
#ManagedBean
public class DivisiController implements Serializable{
private static final long serialVersionUID = 1L;
private String konten;
private String deskripsi;
private Long id;
private Divisi selectedDivisi;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Divisi getSelectedDivisi() {
if(selectedDivisi == null){
selectedDivisi = new Divisi();
}
return selectedDivisi;
}
public void setSelectedDivisi(Divisi selectedDivisi) {
this.selectedDivisi = selectedDivisi;
}
public String getKonten() {
return konten;
}
public void setKonten(String konten) {
this.konten = konten;
}
public String getDeskripsi() {
return deskripsi;
}
public void setDeskripsi(String deskripsi) {
this.deskripsi = deskripsi;
}
public void halo(){
System.out.println("Hi, I'm halo");
}
public void delete(){
DivisiDAO dao = new DivisiDAO();
dao.beginTransaction();
try{
Divisi persistedDivisi = dao.findReferenceOnly(selectedDivisi.getId());
dao.delete(persistedDivisi);
}
catch(Exception e){
dao.rollback();
addMessage("System Error", "Please try again later.");
e.printStackTrace();
}
dao.commitAndCloseTransaction();
}
public void addMessage(String summary, String detail) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, summary, detail);
FacesContext.getCurrentInstance().addMessage(null, message);
}
}
Then, I try to set selectedDivisi value when delete button clicked from the jsf page. And hope that my delete method would be delete the selected value.
I attempt to send item, as a division value, through f:setPropertyActionListener
But unfortunately, I always stuck with null value at my backing bean (DivisiController).
I try to debug, set breakpoint at my selectedDivisi setter, and the result is, the selectedDivisi value null. It seems like, my selectedDivisi never set with #{item} from my button.
Here is the snippet of, how I manage to draw html from jsf, and call my backing bean to perform an action.
<div class="col-md-12">
<!-- Custom Tabs -->
<h:form id="form">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li class="active" >
<a id="lampiran" data-toggle="tab" href="#tab_2" aria-expanded="false">
<i class="fa fa-list">
</i> Daftar Divisi</a></li>
<li class="">
<a data-toggle="tab" href="#tab_1" aria-expanded="false">
<i class="fa fa-pencil"></i> Buat Divisi</a>
</li>
</ul>
<div class="tab-content">
<div id="tab_2" class="tab-pane active">
<h:panelGroup layout="block" id="berkas" class="row">
<div class="col-md-12">
<div class="box-footer text-right top-buffer">
<ui:include src="list.xhtml"/>
</div>
</div>
</h:panelGroup>
</div><!-- /.tab-pane -->
<div id="tab_1" class="tab-pane">
<h:panelGroup layout="block" id="tembusan" class="row">
<div class="col-md-12">
<ui:include src="create-form.xhtml"/>
</div>
</h:panelGroup>
<div class="box-footer text-right top-buffer">
<h:commandLink action="#{divisiController.create}" class="btn btn-primary">
Buat Baru <i class="fa fa-arrow-circle-right"></i>
</h:commandLink>
</div>
</div><!-- /.tab-pane -->
</div><!-- /.tab-content -->
</div><!-- nav-tabs-custom -->
</h:form>
<p:confirmDialog header="Confirmation"
message="#{divisiController.selectedDivisi.id}"
global="true"
showEffect="fade"
hideEffect="fade"
widgetVar="confirmDialogWidget">
<h:form>
<h:outputText value="#{divisiController.selectedDivisi.id}"/>
<p:commandButton value="Yes" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" action="#{divisiController.delete()}" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
</h:form>
</p:confirmDialog>
</div>
That was the index.html, which included the list.xhtml (as you can see), and here is list.xhtml snippet :
<?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 xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:dv="http://xmlns.jcp.org/jsf/composite/mycomp">
<div class="row">
<div class="col-md-12 complex">
<dv:data-table value="#{divisiController.view()}"
id="surat"
scrollable="true"
scrollableHeight="500">
<p:column headerText="Konten" width="40%" styleClass="text-left" style="width: 44%">
<h:outputText value="#{item.konten}"/>
</p:column>
<p:column headerText="Deskripsi" width="40%" styleClass="text-left" style="width: 44%">
<h:outputText value="#{item.deskripsi}"/>
</p:column>
<p:column headerText="Aksi" styleClass="text-left">
<h:outputLink styleClass="btn btn-primary text-white" value="edit.xhtml">
<i class="fa fa-edit"></i>
<f:param name="id" value="#{item.id}" />
</h:outputLink>
<p:commandLink styleClass="btn btn-primary text-white" update=":form">
<h:panelGroup styleClass="fa fa-trash" />
<f:setPropertyActionListener value="#{item}" target="#{divisiController.selectedDivisi}" />
<p:confirm header="Confirmation" message="Are you sure?" icon="ui-icon-alert" />
</p:commandLink>
</p:column>
</dv:data-table>
</div>
</div>
</ui:composition>
As you can see at the last snippet, I try to set the selectedDivisi through this snippet :
<f:setPropertyActionListener value="#{item}" target="#{divisiController.selectedDivisi}" />
But it always error. And if I try to direct pass the {item} to my delete method from bean (if I set the delete method with input parameter), then it will goes same with the previous technique(from <f:setPropertyActionListener>).
So, how this can happened, and what the thing that makes it mess?
Thanks in advance with your help.
I don't have enough reputation to comment. I think it is setting nulls due to the scope.
If you see #BalusC answer on View scoped managed bean with setPropertyActionListener he advises us to use f:param and f:viewParam in #ViewScoped
Updated on comment from #user3057361: Do not call the action="#{divisiController.delete()} from the confirmDialog's yes Button if you are using the global mode of ConfirmDialog. IMHO, your p:commandLink in list.xhtml should be changed to a . Keep everything else. The yes and no button in the confirmDialog should not have action methods for global confirm dialog. Once you click yes, the action in the caller of your confirmDialog is called automatically

PrimeFaces Dialog not positioning right and some options make it stop working

I've already search trhough other posts for a solution to my problem with no luck, so im posting here. My problem is that primefaces dialog is not showing where it should, at the center of the page, at rare times it does(dont understand why), it works fine but its showing at the left top corner, and if i change the option "draggable" from false to true, the dialog stops working... i call the dialog from a managed bean.
this is the code:
form where i call it:
<h:form style="margin-top: 2%;">
<p:commandButton value="Create Ticket" icon="ui-icon-extlink" action="# {ticketBean.viewCreateCustomized}"/>
</h:form>
ManagedBean that contains the dialog method:
#ManagedBean
#ViewScoped
public class TicketBean implements Serializable {
public void viewTicketCustomized() {
Map<String,Object> options = new HashMap<String, Object>();
options.put("modal", true);
options.put("draggable", false);
options.put("resizable", false);
options.put("contentHeight", 320);
RequestContext.getCurrentInstance().openDialog("createticket", options, null);
}
UPDATE: this is the view that the dialog shows:
<?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"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<h:outputScript name="jquery/jquery-plugins.js" library="primefaces"/>
<title>Create New Account</title>
<link href="#{request.contextPath}/css/simple.css" rel="stylesheet" type="text/css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
$(window).load(function() {
$(".loader").fadeOut("slow");
});
</script>
<style type="text/css">
.ui-widget {
font-size: 110%;
}
</style>
</h:head>
<f:view>
<center><h:form style="margin-top: 2%;">
<p:growl id="msg" showDetail="true"/>
<p:panelGrid columns="2">
<f:facet name="header">Create New Ticket</f:facet>
<h:outputText value="Description:" />
<p:inputTextarea value="#{ticketBean.description}"/>
<h:outputText value="Note:" />
<p:inputTextarea value="#{ticketBean.note}"/>
<f:facet name="footer"><p:commandButton value="Create Ticket" action="# {ticketBean.createTicket}" update="msg"/></f:facet>
</p:panelGrid>
</h:form></center>
</f:view>
</html>
I'm not sure what browser you are using or if your problem is related to the browser at all. But I tried your code and did not succeed to show the dialog. However, when I changed it to the following it worked:
<h:form style="margin-top: 2%;">
<p:commandButton value="Create Ticket" icon="ui-icon-extlink" onclick="test.show();"/>
<p:dialog modal="true" widgetVar="test" draggable="true" resizable="false" contentHeight="320">
</p:dialog>
</h:form>
I'm not sure if there is a reason you have to show the dialog from the managed bean, but if you do, then instead of "onclick.show()" you can do the following:
<h:form style="margin-top: 2%;">
<p:commandButton value="Create Ticket" icon="ui-icon-extlink" action="#{ticketBean.viewTicketCustomized()}"/>
<p:dialog modal="true" widgetVar="test" draggable="true" resizable="false" contentHeight="320">
</p:dialog>
</h:form>
and in your managed bean:
#ManagedBean
#ViewScoped
public class TicketBean implements Serializable {
public void viewTicketCustomized() {
RequestContext context = RequestContext.getCurrentInstance();
context.execute("test.show();");
}

JSF setpropertyactionlistener not being called

I have a f:setPropertyActionListener within a data table and clicking on a command button the setpropertyaction listener is not being called. Any one see where I am going wrong?
thanks
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:form id="userDetailsForm" style="padding:5px">
<p:growl id="messages" showDetail="true" autoUpdate="true" life="2000"/>
<p:spacer height="15"></p:spacer>
<div class="row">
<div class="col-lg-4">
<div class="input-group">
<p:inputText type="text" styleClass="form-control" value="#{emailArticleBean.searchText}" />
<span class="input-group-btn" style="margin:3px;">
<p:commandButton actionListener="#{emailArticleBean.search}" value="Go!" update=":userDetailsForm:emailArticleTable" />
</span>
</div><!-- /input-group -->
</div><!-- /.col-lg-6 -->
</div><!-- /.row -->
<p:spacer height="15"></p:spacer>
<h:messages/>
<div class="row">
<div class="col-lg-1">
</div>
<div class="col-lg-11">
<p:dataTable var="email" value="#{emailArticleBean.emailArticles}" scrollRows="20"
scrollable="true" liveScroll="true" scrollHeight="750" id="emailArticleTable"
>
<p:column>
<p:accordionPanel multiple="true" activeIndex="-1" id="panel#{email.id}">
<p:tab title="#{email.headline}" titleStyleClass="email-header">
<div style="clear:both;margin-bottom:10px;">
<h6 style="font-weight:bold;">Summary</h6>
<h:outputText
value="#{email.summary}" />
</div>
<div style="clear:both;margin-bottom:10px;">
<h6 style="font-weight:bold;">Implication</h6>
<h:outputText
value="#{email.implication}" />
</div>
<div style="float:left;clear:both">
<p:commandButton value="View Existing Actions"
oncomplete="PF('dlg2').show();" update=":userDetailsForm:emailActionDialog">
<f:setPropertyActionListener value="#{email}" target="#{emailArticleBean.selectedEmail}" />
</p:commandButton>
</div>
<br/>
<br/>
<div style="margin-top:10px;">
<h:inputTextarea id="accordian1" value="#{email.tempAction}" cols="90" rows="3" />
</div>
<h6 style="font-weight:bold;">Due Date</h6>
<p:calendar value="#{email.tempDate}" id="popupCal" pattern="dd MMM, yyyy"/>
<p:commandButton actionListener="#{emailArticleBean.updateAction}" value="Add Action"
style="margin-left:5px;">
<f:setPropertyActionListener value="#{email}" target="#{emailArticleBean.selectedEmail}" />
</p:commandButton>
</p:tab>
</p:accordionPanel>
</p:column>
</p:dataTable>
</div>
</div>
<p:dialog id="emailActionDialog" header="Email Actions" widgetVar="dlg2" modal="true" height="100">
<h3>Email Actions</h3>
<p:dataList value="#{emailArticleBean.selectedEmail.actions}" var="action" itemType="disc">
#{action.action} --- #{action.username}
</p:dataList>
</p:dialog>
</h:form>
</html>
In my bean I have the following getter/setter
public EmailArticle getSelectedEmail() {
return selectedEmail;
}
public void setSelectedEmail(EmailArticle selectedEmail) {
this.selectedEmail = selectedEmail;
}
public void updateAction(ActionEvent ae) {
selectedEmail.getActions().add(new EmailActions(emailAction, "testUser", actionDueDate));
selectedEmail.merge();
}
The main problem here is the order of the invocation, first your actionListener is called then
f:setPropertyActionListener.
To solve this, change your actionListener to action, and update your action method to return a String.
Button
<p:commandButton action="#{emailArticleBean.updateAction}"
value="Add Action" style="margin-left:5px;">
<f:setPropertyActionListener value="#{email}"
target="# {emailArticleBean.selectedEmail}" />
</p:commandButton>
updateAction
public String updateAction() {
selectedEmail.getActions().add(new EmailActions(emailAction, "testUser", actionDueDate));
selectedEmail.merge();
return null;
}
OR
you can keep using your actionListener and pass the selectedEmail to it (without using f:setPropertyActionListener).
Button
<p:commandButton actionListener="#{emailArticleBean.updateAction(email)}"
value="Add Action" style="margin-left:5px;">
</p:commandButton>
updateAction
public void updateAction(EmailArticle selectedEmail) {
selectedEmail.getActions().add(new EmailActions(emailAction, "testUser", actionDueDate));
selectedEmail.merge();
}
To understand more the order of the invocation
See:
Differences between action and actionListener

JSF Template - Refreshing template components when changing view

I've got template which has: header, footer, menu (left side), cart (right side) and content at center. I select category from menu and send it via parameter to view page which overrides content from template. Then i use commandButton to add any product to cart. It works but next I select different category from menu view page updates with other products but my cart (included in template) does not. It remains as it was before when I was on the view page with this category. How can I overcome this problem? Thanks for any solution.
template:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:metadata>
<f:viewParam name="category"/>
</f:metadata>
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<h:outputStylesheet name="./css/default.css"/>
<h:outputStylesheet name="./css/cssLayout.css"/>
<title>Drummers Store</title>
</h:head>
<h:body>
<div id="container">
<div id="top">
<div id="top-content">
<div style="text-align: left; margin-left: 50px; margin-top: 20px;">
<p:graphicImage value="./resources/images/logo.png" height="80px" width="80px" />
</div>
<h:form>
<p:menuButton style="font-size: 10px;" value="account_name">
<p:menuitem value="Account Settings" />
<p:separator />
<p:menuitem value="Logut" />
</p:menuButton>
</h:form>
</div>
</div>
<div id="left">
<div id="left-content">
<h:form id="form" style="width: 290px;" >
<p:panelMenu id="categories" style="text-align: center;">
<c:forEach items="#{dSServerBean.categories}" var="c">
<p:submenu label="#{c.category_name}">
<c:forEach items="#{c.sub_categories}" var="s">
<c:if test="#{not s.sub_categories.isEmpty()}">
<p:submenu label="#{s.subCategory_name}">
<c:forEach items="#{s.sub_categories}" var="si">
<p:menuitem value="#{si.subCategory_name}" outcome="productView">
<f:param name="category"
value="#{si.subCategory_name.toLowerCase()}" />
</p:menuitem>
</c:forEach>
</p:submenu>
</c:if>
<c:if test="#{s.sub_categories.isEmpty()}">
<p:menuitem value="#{s.subCategory_name}" outcome="productView">
<f:param name="category"
value="#{s.subCategory_name.toLowerCase()}" />
</p:menuitem>
</c:if>
</c:forEach>
</p:submenu>
</c:forEach>
</p:panelMenu>
</h:form>
</div>
</div>
<div id="right">
<div id="right-content">
<h:form style="width: 85%; margin: 0 auto; margin-top: 50px;">
<p:panel>
<f:facet name="header">Cart</f:facet>
<f:facet name="footer">To pay: 0 $</f:facet>
<p:scrollPanel id="scroll2"
style="height: 200px;
max-height: 200px;
overflow-wrap: break-word;">
<p:dataGrid value="#{dSBean.cart}" var="p"
columns="1" emptyMessage="No products added..."
style="border: 0;">
<h:panelGrid>
<h:outputText style="font-size: 10px;" value="#{p.name}" />
</h:panelGrid>
</p:dataGrid>
</p:scrollPanel>
</p:panel>
</h:form>
</div>
</div>
<div id="center">
<div id="center-content">
<ui:insert name="content" />
</div>
</div>
<div id="bottom">
<div id="bottom-content">
<p style="padding: 1px;">Copyright © <b>Drummers Store</b> 2013</p>
</div>
</div>
</div>
</h:body>
</html>
view:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui">
<f:metadata>
<f:viewParam name="category"/>
</f:metadata>
<body>
<ui:composition template="./templates/mainLayout.xhtml">
<ui:define name="right">
right
</ui:define>
<ui:define name="content">
<h:form>
<p:scrollPanel id="scroll1" style="height: 700px; max-height: 700px; width: 100%;">
<p:dataGrid value="#{dSServerBean.getProducts(param.category)}"
var="product" columns="1">
<p:panel header="#{product.name}">
<h:panelGrid style="width:100%;">
<h:outputText value="#{product.description}" />
<h:commandButton value="DODAJ" action="#{dSBean.addToCart(product)}" >
<f:param name="category" value="#{param.category}" />
</h:commandButton>
</h:panelGrid>
</p:panel>
</p:dataGrid>
</p:scrollPanel>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>
DSServerBean:
#ManagedBean
#ApplicationScoped
public class DSServerBean {
public Set<Category> categories = new CategoriesTemplate().categoriesTemplate;
public static Set<Product> products = new ProductsTemplate().productsTemplate;
public Map<String, Set<Product>> category_products;
public DSServerBean() {
category_products = new TreeMap<>();
for(Category category : categories){
category_products.put(category.getCategory_name().toLowerCase(), new TreeSet<Product>());
for(SubCategory subCategory : category.getSub_categories()){
category_products.put(subCategory.getSubCategory_name().toLowerCase(), new TreeSet<Product>());
for(SubCategory subSubCategory : subCategory.getSub_categories()){
category_products.put(subSubCategory.getSubCategory_name().toLowerCase(), new TreeSet<Product>());
}
}
}
for(Product product : products){
for(String category : product.getCategories().split(",")){
category_products.get(category).add(product);
}
}
}
public Set<Category> getCategories() {
return categories;
}
public Map<String, Set<Product>> getCategory_products() {
return category_products;
}
public List<Product> getProducts(String category){
List<Product> view = new ArrayList<>();
for(Product p : category_products.get(category))
view.add(p);
return view;
}
}
DSBean:
#ManagedBean
#SessionScoped
public class DSBean {
private User logged_user;
private List<Product> cart;
public DSBean(){
logged_user = new User("Marian");
cart = new ArrayList<>();
}
public User getLogged_user() {
return logged_user;
}
public List<Product> getCart() {
return cart;
}
//METHODS
public String addToCart(String product){
System.out.println(product);
for(Product p : DSServerBean.products)
if(p.toString().equals(product))
cart.add(p);
return "productView";
}
}
Ok. I'll found alternative solution, just as I mentioned before. I change view via action attribute (instead outcome attribute) of menuitem which has linked parameter which I obtain in managed bean (not in view like before). Thanks for interest.

Resources