Primefaces reload page on observer method won't work - jsf

I am running
JakartaEE 9.1
Primefaces 12
Glassfish 6.2.5
I have two browser windows open. I fire an event in one window and receive it in the second one.
This works fine, since my business logic is run through. At the end I do a
PrimeFaces.current().ajax().update("form:roomplanerTimeline");
But it is not working. The error is
PrimeFaces.current().ajax().update() called but component cant be resolved! Expression will just be added to the renderIds: {0}
My roomplaner.xhtml frontend look like this
<ui:composition template="/WEB-INF/template/master_timeline.xhtml"
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">
<ui:define name="content">
<h:form id="form">
<p:growl showSummary="true" showDetail="true"
keepAlive="true" life="5000">
<p:autoUpdate />
</p:growl>
<p:panel>
<p:card class="rommplaner_nav" >
<p:panelGrid id="courseSelection"
columns="2"
...
<p:dataList id="examsList"
value="#{roomController.exams}"
var="exam"
class="exam-card"
emptyMessage="Es sind keine zu verplanenden Prüfungen vorhanden.">
<p:outputPanel id="pnl" class="exam-panel pendingExamItem #{exam.courseNameTrimmed}">
#{exam.moduleShort} (#{exam.registrationCount})
<h:outputText styleClass="pi pi-info-circle" rendered="#{not empty exam.note}"/>
</p:outputPanel>
<p:tooltip for="pnl" position="bottom" hideEvent="mousedown click mouseleave">
<i class="pi pi-credit-card"/><h:outputText value=" #{exam.moduleName}" />
<br />
<i class="pi pi-building"/><h:outputText value=" #{exam.courseName}" />
<br />
<h:outputText styleClass="pi pi-info-circle" rendered="#{not empty exam.note}"/>
<h:outputText value=" #{exam.note}" rendered="#{not empty exam.note}" />
</p:tooltip>
<p:draggable for="pnl" revert="true" appendTo="#(body)" zindex="5" />
</p:dataList>
</p:card>
</p:panel>
<p:panel >
<p:card class="rommplaner_nav" >
<p:timeline id="roomplanerTimeline"
value="#{roomController.model}"
extender="timelineExtender"
var="exam"
varGroup="room"
widgetVar="roomplan"
start="#{roomController.startDay}"
end="#{roomController.endDay}"
min="#{roomController.startTimeline}"
max="#{roomController.endTimeline}"
zoomKey="altKey"
zoomMin="#{roomController.zoomMin}"
zoomMax="#{roomController.zoomMax}"
zoomable="true"
moveable="true"
showMajorLabels="true"
showMinorLabels="true"
stackEvents="true"
orientationAxis="both"
snap="#{'snapTimeline'}"
responsive="true"
showCurrentTime="false"
>
...
The Observer method in the corresponding bean
import jakarta.enterprise.event.Observes;
...
#Named(value = "roomController")
#SessionScoped
public class RoomController implements Serializable {
public void observeEvent(#Observes Pruefplaneintrag movedEvent){
TimelineUpdater timelineUpdater = TimelineUpdater.getCurrentInstance(this.frontendIdTimeline);
LocalDate timestamp = movedEvent.getPPEDatZeit().toLocalDate();
if(timestamp.equals(this.currentPeriodDate)) {
System.out.println("Move Event is on same date -> Action");
// Update timeline
List<TimelineEvent<TimelineItem>> allEvents = model.getEvents();
int i =0;
while(i < allEvents.size()) {
TimelineEvent<TimelineItem> event = allEvents.get(i);
TimelineItem item = event.getData();
if(item.getExamID() == movedEvent.getPpid()) {
System.out.println("Found Event");
event.setStartDate(movedEvent.getPPEDatZeit());
event.setEndDate(event.getStartDate().plusMinutes(item.getDuration()));
model.delete(event);
model.add(event);
model.update(event, timelineUpdater);
this.reloadPage();
break;
}
i++;
}
}
}
And the reload method
private void reloadPage() {
PrimeFaces.current().executeScript("window.location.reload(window.location.href)");
PrimeFaces.current().ajax().update(this.frontendIdCourseSelection);
PrimeFaces.current().ajax().update(this.frontendIdExamslist);
PrimeFaces.current().ajax().update(this.frontendIdTimeline);
//PrimeFaces.current().ajax().update("#all");
System.out.println(FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds());
//FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().
Ajax.update("form:roomplanerTimeline");
/*FacesContext context = FacesContext.getCurrentInstance();
String viewId = context.getViewRoot().getViewId();
ViewHandler handler = context.getApplication().getViewHandler();
UIViewRoot root = handler.createView(context, viewId);
root.setViewId(viewId);
context.setViewRoot(root);*/
}
As you can see I printed out the renderids which are
[messages_left, growl, :form:courseSelection, :form:examsList, form:roomplanerTimeline]
which are present in the xhtml file.
I tried every combination as you can see in the reloadPage method. But nothing works. I have to do a manual refresh via F5 to reload the page and show the changes.
If I do a
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(ec.getRequestContextPath()+"/faces/app/roomplaner.xhtml");
The redirect takes place in the fire event window not in the observer window.
This is the console log
Move Event is on same date -> Action|#]
Found Event|#]
PrimeFaces.current().ajax().update() called but component cant be resolved! Expression will just be added to the renderIds: {0}|#]
PrimeFaces.current().ajax().update() called but component cant be resolved! Expression will just be added to the renderIds: {0}|#]
PrimeFaces.current().ajax().update() called but component cant be resolved! Expression will just be added to the renderIds: {0}|#]
[messages_left, growl, :form:courseSelection, :form:examsList, form:roomplanerTimeline]|#]```

Related

Processing a data table from outside the form

I have a button outside the datatable form which function is to delete the selected row, but the problem is that it returns an empty value of that row in the backing bean, the update of the growl message is done correctly and the action is called too.
However when putting the button inside the form it works fine, but I need it to be in the toolbar which is outside the form.
This is my xhtml code:
<ui:define name="content">
<div class="row">
<p:toolbar id="tb">
<f:facet name="left">
<p:inputText style="margin-right:10px" placeholder="Rechercher..." />
<p:commandButton icon="fa fa-search" />
</f:facet>
<f:facet name="right">
<p:commandButton onclick="PF('analyseForm').show();" icon="fa fa-plus" />
<p:commandButton icon="fa fa-file-pdf-o" />
<p:commandButton process="#this,:form:anaDT" update=":form" action="#{personel.removeSelectedAnalyse}" icon="fa fa-trash-o" />
<!-- this button does the update and runs the action but returns a null value of the selected row-->
</f:facet>
</p:toolbar>
</div>
<div class="row">
<h:form id="form">
<p:growl id="msgs" />
<p:dataTable style="font-size:12px;" id="anaDT" scrollable="true" scrollWidth="100%" var="ana" value="#{personel.analyses}" paginator="true" selectionMode="single" selection="#{personel.selectedAnalyse}" paginatorPosition="bottom" rowKey="#{ana.idAnalyse}"
rows="10">
<!-- columns here -->
<f:facet name="footer">
<!-- this button works fine -->
<p:commandButton class="btn btn-default" process="form:anaDT" update="form" ajax="true" icon="fa fa-trash-o" action="#{personel.removeSelectedAnalyse}" />
</f:facet>
</p:dataTable>
</h:form>
</div>
<p:sticky target=":tb" margin="50" />
</ui:define>
</ui:composition>
Command button outside of a form can not be used to submit a form. If you want to achieve the functionality you desire, one way is to
Have a p:remoteCommand inside the form and bind it to the backing bean method personel.removeSelectedAnalyse and have update="#form"
Invoke the remoteCommand from the command button from the tool bar using onclick attribute and the remoteCommand submits the form. Now the backing bean will have the submitted values from the form so you can do the necessary processing and the form will be updated after the Ajax request completes.
Remote Command showcase: https://www.primefaces.org/showcase/ui/ajax/remoteCommand.xhtml
I've changed the rowKey to the entity type, assigning an unique id to the form. There is no need to process the form at the p:commandButton click. I place this button into a <h:form>. Command components always must be there. The entity selection done at row click. When you click on the button it uses the preset entity to remove from the List. Just the rerendering of the <p:dataTable> is needed. And I move the controller into the javax.faces.view.ViewScope. PrimeFaces component use ajax by default so the controllers must be at least as wide scope as view.
The facelet:
?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:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<div class="row" >
<h:form id="toolbarForm">
<p:toolbar id="tb">
<f:facet name="left">
<p:commandButton value="Delete selected User" process="#this" update="myForm" actionListener="#{myBean.deleteUser}"/>
</f:facet>
</p:toolbar>
</h:form>
</div>
<h:form id="myForm">
<p:dataTable id="usersTable" value="#{myBean.users}" var="user" selectionMode="single" selection="#{myBean.selectedUser}" rowKey="#{user}">
<p:column>
<f:facet name="header">ID</f:facet>
#{user.id}
</p:column>
<p:column>
<f:facet name="header">First name</f:facet>
#{user.firstName}
</p:column>
<p:column>
<f:facet name="header">Last name</f:facet>
#{user.lastName}
</p:column>
</p:dataTable>
</h:form>
</h:body>
</html>
The controller:
package x;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
import lombok.Data;
#Data
#Named( value = "myBean" )
#ViewScoped
public class MyBean implements Serializable
{
private List<User> users;
private User selectedUser;
public MyBean()
{
users = new ArrayList<>();
users.add( new User( 1, "First1", "Last1" ) );
users.add( new User( 2, "First2", "Last2" ) );
users.add( new User( 3, "First3", "Last3" ) );
users.add( new User( 4, "First4", "Last4" ) );
users.add( new User( 5, "First5", "Last5" ) );
}
#PostConstruct
public void init()
{
System.out.println( "MyBean.init() called" );
}
public void deleteUser()
{
if ( selectedUser == null )
System.out.println( "Selected User is null" );
else
System.out.println( "The ID of the User to remove: " + Integer.toString( selectedUser.getId() ) );
boolean bn = users.remove( selectedUser );
}
}
The User class:
package x;
import lombok.Data;
#Data
public class User
{
private int id;
private String firstName;
private String lastName;
public User( int id_, String firstName_, String lastName_ )
{
id = id_;
firstName = firstName_;
lastName = lastName_;
}
}
The source contains lombok annotations to avoid boilerplate coding (getter/setter methods)

RequestContext won't work

I am having trouble to update the view from the bean in the back using PrimeFaces's RequestContext. In the example below I have a button and 2 panels. When pressing the button, I want to update one panel, but not the other one.
It does not work though and I can't find the error! requestContext.update("panela"); is fired, but doesn't do its job!
Help greatly appreciated!
The XHTML file:
<!DOCTYPE html>
<html xmlns="http://www.w3c.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head/>
<h:body>
<h:form>
<p:panelGrid columns="1">
<p:commandButton value="Save" actionListener="#{runtimeUpdatesBean.save}" />
<p:panel id="panela">
<h:outputText value="#{runtimeUpdatesBean.texta}"/>
</p:panel>
<p:panel id="panelb">
<h:outputText value="#{runtimeUpdatesBean.textb}"/>
</p:panel>
</p:panelGrid>
</h:form>
</h:body>
</html>
The bean:
package com.glasses.primework;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.context.RequestContext;
#ManagedBean
#SessionScoped
public class RuntimeUpdatesBean {
private String texta;
private String textb;
private boolean outcome;
public String getTexta() {
texta += "a";
System.out.println("RuntimeUpdatesBean.getTexta() = " + texta);
return texta;
}
public String getTextb() {
textb += "b";
System.out.println("RuntimeUpdatesBean.getTextb() = " + textb);
return textb;
}
public void save() {
RequestContext requestContext = RequestContext.getCurrentInstance();
if(outcome) {
System.out.println("RuntimeUpdatesBean.save() = update panela");
requestContext.update("panela");
outcome = false;
} else {
System.out.println("RuntimeUpdatesBean.save() = update panelb");
requestContext.update("panelb");
outcome = true;
}
}
}
Well the problem is the ID of the component that you are referring.
In JSF when you place a component inside h:form (or Some Primefaces components like TabView), that component's Id will be generated based on the h:form id too.
Here is the Example:
<h:form id="panelaForm">
<p:panel id="panela">
....
</p:panel>
</h:form>
In the above case your p:panel's id will be generated as panelaForm:panela.
In your case since you haven't provided any ID for h:form a dynamic id will be attached like for example j_xyz:panela(you can see it using you browser's Inspect Element).
So If you wan to access p:panel with Id panela inside the same h:form then no need to attach the form Id.
But If you want to access the p:panel outside h:form then you need to attach the h:form id to access it.
Solution to you problem is: use an custom ID to your h:form (which is a best practice by the way..) and access the p:panel by attaching that form ID.
<h:form id="panelaForm">
<p:panel id="panela">
....
</p:panel>
</h:form>
And in Managed bean use:
RequestContext.getCurrentInstance().update("panelaForm:panela");
I'm the new guy here (Java EE) however below solution works for me:
<!DOCTYPE html>
<html xmlns="http://www.w3c.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head/>
<h:body>
<h:form id="form">
<p:panelGrid columns="1">
<p:commandButton value="Save" actionListener="#{runtimeUpdatesBean.save}" update=":form" />
<p:panel id="panela">
<h:outputText value="#{runtimeUpdatesBean.texta}"/>
</p:panel>
<p:panel id="panelb">
<h:outputText value="#{runtimeUpdatesBean.textb}"/>
</p:panel>
</p:panelGrid>
</h:form>
</h:body>

Updating components inside a custom ui:component when it is used multiple times on same page

I am building a simple component in JSF (Mojarra 2.1.x) where I have to access parent ui components to update them, currently I'm using binding to achieve this, but it only works as long as I don't use the component more than once on the same page.
So I need a solution that would allow me to use the component multiple times on same page.
In the following code I'm updating commandButton with binding="#{msButton}" and panel with binding="#{msPanel}":
<?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:component 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:c="http://java.sun.com/jsp/jstl/core"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:layout="http://sterz.stlrg.gv.at/jsf/layout"
xmlns:p="http://primefaces.org/ui">
<cc:interface>
<cc:attribute name="controller" required="true" />
<cc:attribute name="converter" required="true" />
</cc:interface>
<cc:implementation>
<p:commandButton id="msButton#{cc.attrs.controller.class.getSimpleName()}" binding="#{msButton}" value="#{msg.mehr} (#{cc.attrs.controller.itemList.size()})" type="button" />
<p:overlayPanel id="msOverlayPanel" for=":#{msButton.clientId}" hideEffect="fade" my="right top" at="right bottom">
<p:panel id="msPanel#{cc.attrs.controller.class.getSimpleName()}" binding="#{msPanel}" styleClass="ui-panel-fit">
<ui:repeat id="repeat" value="#{cc.attrs.controller.itemList}"
var="item">
<p:commandButton id="removeButton"
actionListener="#{cc.attrs.controller.removeItem(item)}"
icon="ui-icon-trash" update=":#{msPanel.clientId} :#{msButton.clientId}" ajax="true"
process="#this" disabled="#{cc.attrs.controller.itemList.size() == 1}"/>
<p:selectBooleanButton id="value1" value="#{item.exclude}"
offLabel="und" onLabel="und nicht" style="width:80px;">
<p:ajax event="change" process="#this" />
</p:selectBooleanButton>
<p:autoComplete converter="#{cc.attrs.converter}"
readonly="#{cc.attrs.readonly}" value="#{item.from}"
dropdown="true"
completeMethod="#{cc.attrs.controller.autocomplete}" var="gp"
itemLabel="#{gp.displayName}" itemValue="#{gp}">
<p:ajax event="itemSelect" process="#this" />
</p:autoComplete>
<h:outputText value=" #{msg.bis} " />
<p:autoComplete converter="#{cc.attrs.converter}"
readonly="#{cc.attrs.readonly}" value="#{item.to}" dropdown="true"
completeMethod="#{cc.attrs.controller.autocomplete}" var="gp"
itemLabel="#{gp.displayName}" itemValue="#{gp}">
<p:ajax event="itemSelect" process="#this" />
</p:autoComplete>
<br />
</ui:repeat>
<hr />
<p:commandButton id="addButton" actionListener="#{cc.attrs.controller.addItem}"
icon="ui-icon-plus" value="#{msg.zufuegen}" update="#parent :#{msButton.clientId}"
ajax="true" process="#this"/>
</p:panel>
</p:overlayPanel>
</cc:implementation>
</ui:component>
Any help is much apprecieted.
The solution is to use the faces component bean
#FacesComponent("com.xxx.MultiselectorIdComponent")
public class MultiselectorIdComponent extends UINamingContainer
{
UIComponent msPanel;
// getters/settter and other ui compunents
}
tell the component interface what faces component bean to use
<cc:interface componentType="com.xxx.MultiselectorIdComponent">
bind the JSF component to the one in the faces component bean
<p:panel binding="#{cc.msPanel}"/>
and to access the components, for example to update the component, we use the binding
<p:commandButton value="My Button" update=":#{cc.msPanel.clientId}"/>
ALSO:
A good practice is to use a parent container (like <div>) with the following ID
<div id="#{cc.clientId}">
Hope this helps,
Regards
You could target the components for update by their style class
<p:commandButton styleClass="msButton" ... />
<p:panel styleClass="msPanel" ... />
And I guess you update them from addButton, which would look like this
<p:commandButton id="addButton" update="#(.msButton, .msPanel)" ... />
It should have no problems working with many cc instances on the same page.
UPDATE
You can try with update="#composite", which should refresh the whole custom component. Or, the cumbersome update="#parent #parent:#parent:#parent:#child(1)" which should target panel and button respectively. Or update="#parent #parent:#parent:#previous", which should do the same. Take a look at chapter 4.3 in Primefaces User Guide for more examples and supported keywords.
I solve similar problem by common bean "bindingBean" stored in ViewContext. BindingBean holds all binded component in internal MAP of component records. The key of hash map is an EL expression - it is factory of the component. EL is used for components creating. Components are hold in records stored in MAP in bind bean.
Example:
<h:panel binding="#{bindBean.get('msPanelFactory.getPanel()').component}"/>
Record:
public class BindingRecord {
private Object component;
private String compExpr;
public BindingRecord(String compExpr) {
this.compExpr = compExpr;
}
public Object getComponent() {
if (component == null) {
component = getValueExprValue("#{" + compExpr + "}");
}
return component;
}
public void setComponent(Object component) {
this.component = component;
}
public Object getStoredComponent() {
return component;
}
}
Binding bean:
public class BindingBean {
private final Map<String, BindingRecord> bindingMap = new HashMap<>();
public BindingRecord get(String key) {
BindingRecord result = bindingMap.get(key);
if (result == null) {
result = new BindingRecord(key);
bindingMap.put(key, result);
}
return result;
}
}
In you case you can use:
<h:panel binding="#{bindingBean.get('panelFactory.create()').component}"/>
Inside composite component you can use trick - Pass component name by composite parameter:
<h:panel binding="#{bindingBean.get('panelFactory.create('.concate(cc.attrs.componentName).concate(')')).component}"/>

Access and refresh dataTable after getting data

I have got some problems with my JSF page, and (probably) with backing bean. I have got own template and I fill the content area with some pages. I have got search page with commandbutton and I would like to get data from database (JPA) and than fill the datatable.
Look at my searchpeople.xhtml:
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="template.xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<ui:define name="content">
<h:form id="sampleform">
<p:accordionPanel activeIndex="-1" id="accordingpanle">
<p:tab title="User options" >
<p:growl id="growl" showDetail="true" showSummary="true"/>
<p:commandButton id="searchbutton" action="#{mb_person.search}" value="Szukaj" update="personsearchresulttable" />
</p:tab>
</p:accordionPanel>
<p:dataTable id="personsearchresulttable" var="person" value="#{mb_person.people}" widgetVar="personTable" style="margin-top: 10px" >
<p:column headerText="Id" style="width:10%">
<h:outputText value="#{person.id}" />
</p:column>
<p:column headerText="Name" style="width:20%">
<h:outputText value="#{person.name}" />
</p:column>
<p:column headerText="Surname" style="width:20%">
<h:outputText value="#{person.surname}" />
</p:column>
<p:column headerText="Company">
<h:outputText value="#{person.companyName}" />
</p:column>
<p:column style="width:4%" headerText="Open">
<h:link outcome="persondetails" value="Open">
<!--<f:param name="personid" value="#{person.id}"/>-->
<f:param name="personid" value="10076"/>
</h:link>
</p:column>
</p:dataTable>
</h:form>
</ui:define>
</ui:composition>
And my backingbean with EJB injection.
#ManagedBean(name="mb_person")
public class MB_Person implements Serializable{
#EJB
private PersonFacade personFacade;
private List<PersonAndCompany> people = new ArrayList<PersonAndCompany>();
public MB_Person() {
}
public List<PersonAndCompany> getPeople() {
return people;
}
public void setPeople(List<PersonAndCompany> people) {
this.people = people;
}
public void search() {
int[] range = {0,5};
setPeople(personFacade.findPersonWithMoreThanXProjects(20));
setPeople(personFacade.findPersonAndCompanyName(range));
for(PersonAndCompany p:people){
System.out.println(p.getName());
}
}
public String goToPersonDatailPage(int id){
return "persondetails.jsf?personid="+id;
}
}
I tried small test and printout all data in method search and I received good results.
Someone can help me how to update dataTable using ajax? In this form I have got an exception
Cannot find component with identifier "personsearchresulttable" referenced from "sampleform:accordingpanle:searchbutton".
Relative client IDs are searched relative to parent NamingContainer component. The <p:accordionPanel> is by itself a NamingContainer. So the relative client ID personsearchresulttable would be searched inside the context of the <p:accordionPanel>. However, it's actually outside the panel, inside the <h:form>.
You need to change the relative client ID to be an absolute client ID.
update=":sampleform:personsearchresulttable"
See also:
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"

display dialog after processing the link action

I have one primeface page certHollderList.xhtml:
In this page i have one expire Link. And on click one action is fired and after processing the action, i want to open one dialog box in same page.
code 1:Expire Link::
<h:commandLink id="expire" value="#{label.expire}" action="expire" immediate="true" oncomplete="dlg3.show()"
update="dialogPanel">
code 2 :: In the same page i added one outputpanel having a dialog box.
<h:form>
<p:outputPanel id="dialogPanel" rendered="# {certHolderSearchHandler.openDialog eq 'Success'}">
<p:dialog header="Expire Holder Information" widgetVar="dlg3"
showEffect="bounce" hideEffect="explode" appendToBody="true">
<p:outputPanel id="dialogPanel1"
rendered="#{certHolderSearchHandler.openDialog eq 'Success'}">
<h:panelGrid columns="2">
<h:outputText value="Do you want to continue?" />
<p:spacer width="30" height="10" />
<h:outputText />
<p:spacer width="30" height="10" />
</h:panelGrid>
<div align="left"><p:commandButton immediate="true"
value="Yes" action="continue" /> <p:spacer width="25" height="5" />
<p:commandButton value="No" action="cancel" /></div>
</p:outputPanel>
</p:dialog>
</p:outputPanel>
</h:form>
And when i clicked the expire link,it doesn't open the dialog page.
Please advise me....:(
Try using the Primefaces model to actually update it:
//JSF
<h:form id="someForm">
<p:commandLink
id = "expire"
value="#{label.expire}"
actionListener="#{myBean.doSomething}"
oncomplete="dialog.show()"
update="dialogForm:dialogPanel"
/>
...
<h:form id="dialogForm">
<p:dialog id="dialog"..... />
</h:form>
//MyBean...
public void doSomething(ActionEvent evt)
{
//Logic
}
What you're missing is that you're not using the Primefaces ajax engine. There's some good tutorials at primefaces.org and the forums are very helpful. The other thing you should know is an action is probably not the best way to handle showing the dialog. There's nothing you can do with an ActionListener and it will give you a very fine level of control on the page. You can then use the action when you actually need to throw something up for navigation.
Here is a tested working example of the above (Primefaces 2.2.1)
//Bean
#ViewScoped
#ManagedBean(name = "demoBean")
public class DemoBean
{
private String hello = "Hello World";
private String notSet = "not set";
public void doAction(ActionEvent evt)
{
notSet = hello;
}
/**
* #return the hello
*/
public String getHello()
{
return hello;
}
/**
* #return the notSet
*/
public String getNotSet()
{
return notSet;
}
/**
* #param hello
* the hello to set
*/
public void setHello(String hello)
{
this.hello = hello;
}
/**
* #param notSet
* the notSet to set
*/
public void setNotSet(String notSet)
{
this.notSet = notSet;
}
}
JSF Demo file as follows:
<?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://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
</h:head>
<h:body class="center" style="zIndex:-3">
<h:form id="commands">
<p:inputText value="#{demoBean.hello}" />
<p:commandButton
value="Open Dialog"
actionListener="#{demoBean.doAction}"
update="dialog"
oncomplete="dialogWidget.show()"
/>
</h:form>
<p:dialog widgetVar="dialogWidget">
<h:form id="dialog">
<p:panel>
<h3>Dialog</h3>
<p>
<h:outputText value="Copied: #{demoBean.notSet}"/>
</p>
</p:panel>
</h:form>
</p:dialog>
</h:body>
The thing to watch out for in Primefaces is that it is not using the built in AJAX implementation (it is compatible, but there can be "double" updates so things don't render properly). As such, when you use the widgetVar you're directly calling a show method from Javascript, you'll notice this code does the update and then calls the method.
<p:commandLink id="expire" value="#{label.expire}" onclick="dlg3.show()">
<f:param name="certHoldertId" value="#{certHolder.accountOwner.itemIdInfo.insurerId}" />
<f:param name="accNumberId" value="#{certHolder.accountNumberId}"/>
</p:commandLink>
#Daniel..Its working fine with button and also able to call the popup on click of this link.But we are able to pass the values with this link. When we try to retrieve the value of certHoldertId varible with FaceContext,its give the null value.I think it return the false value.
How can we send these value with this link?

Resources