How can dynamically show or hide a panel ?
With the given example below, when I click btn-1 then panel-2 shows and panel-1 hides. But when I click btn-2 nothing happens.
ManagedBean
#ManagedBean
#ViewScoped
public class SampleController implements Serializable {
private Boolean showPanel;
public void button1() {
showPanel = Boolean.FALSE;
}
public void button2() {
showPanel = Boolean.TRUE;
}
public Boolean showPanel1(){
return showPanel;
}
public Boolean showPanel2(){
return ! showPanel;
}
}
XHTML
<h:form id="form">
<h:panelGroup id="container-panel-1">
<h:panelGroup id="panel-1" rendered="#{sampleController.showPanel1()}">
<p:commandButton id="btn-1"
actionListener="#{sampleController.button1}"
update=":form:container-panel-1, :form:container-panel-2" />
</h:panelGroup>
</h:panelGroup>
<h:panelGroup id="container-panel-2">
<h:panelGroup id="panel-2" rendered="#{sampleController.showPanel2()}">
<p:commandButton id="btn-2"
actionListener="#{sampleController.button2}"
update=":form:container-panel-1, :form:container-panel-2" />
</h:panelGroup>
</h:panelGroup>
</h:form>
I hope you can help me with this.
Thank you,
Bell
This code is works:
View:
<h:form id="form">
<h:panelGroup id="container-panel-1">
<h:panelGroup id="panel-1" rendered="#{sampleController.showPanel1()}">
<p:commandButton id="btn-1" value="btn1"
actionListener="#{sampleController.button1}"
update=":form:container-panel-1, :form:container-panel-2" />
</h:panelGroup>
</h:panelGroup>
<h:panelGroup id="container-panel-2">
<h:panelGroup id="panel-2" rendered="#{sampleController.showPanel2()}">
<p:commandButton id="btn-2" value="btn2"
actionListener="#{sampleController.button2}"
update=":form:container-panel-1, :form:container-panel-2" />
</h:panelGroup>
</h:panelGroup>
</h:form>
Bean:
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class SampleController implements Serializable {
private boolean showPanel;
public void button1() {
showPanel = false;
}
public void button2() {
showPanel = true;
}
public boolean showPanel1(){
return showPanel;
}
public boolean showPanel2(){
return ! showPanel;
}
}
Related
I disabled <p:poll> by default with autoStart="false" .
Now i have a dialog opened by commandButton with this example code :
<h:body>
<h:form>
<p:commandButton value="Open Dialog" oncomplete="PF('sampleDialog').show();PF('w_poll').start();"/>
<p:dialog header="Sample Dialog" height="300" width="400" widgetVar="sampleDialog" resizable="false" onHide="PF('w_poll').stop();">
<p:accordionPanel>
<p:ajax event="tabChange" oncomplete="PF('w_poll').start();"/>
<p:tab title="First">
<h:panelGroup id="firstGroup">
<p:poll interval="1"
id="firstPoll"
widgetVar="w_poll"
update="firstLabel"
async="true"
autoStart="false"
global="false"
listener="#{firstCounter.init}"/>
<p:outputLabel value="#{firstCounter.number}" id="firstLabel"/>
</h:panelGroup>
</p:tab>
<p:tab title="Second">
<h:panelGroup id="secondGroup">
<p:poll interval="3"
id="secondPoll"
widgetVar="w_poll"
update="secondLabel"
async="true"
autoStart="false"
global="false"
listener="#{secondCounter.init}"/>
<p:outputLabel value="#{secondCounter.number}" id="secondLabel"/>
</h:panelGroup>
</p:tab>
<p:tab title="Third">
<h:panelGroup id="thirdGroup">
<p:poll interval="5"
id="thirdPoll"
widgetVar="w_poll"
update="thirdLabel"
async="true"
autoStart="false"
global="false"
listener="#{thirdCounter.init}"/>
<p:outputLabel value="#{thirdCounter.number}" id="thirdLabel"/>
</h:panelGroup>
</p:tab>
</p:accordionPanel>
</p:dialog>
</h:form>
</h:body>
Note : you can see poll started on dialog show and stopped on hide .
this is my beans :
public abstract class AbstractBean implements Serializable {
private int number;
public void counter(int sleepTime) {
sleep(sleepTime);
this.number = number + 1;
}
public int getNumber() {
return number;
}
private static void sleep(int time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
now implement three bean with this abstract :
#Named
#ViewScoped
public class FirstCounter extends AbstractBean {
#PostConstruct
public void init() {
counter(1000);
}
}
and another :
#Named
#ViewScoped
public class SecondCounter extends AbstractBean {
#PostConstruct
public void init() {
counter(3000);
}
}
and another :
#Named
#ViewScoped
public class ThirdCounter extends AbstractBean {
#PostConstruct
public void init() {
counter(5000);
}
}
I have two problem :
1) first tab of accordion panel not started counter after dialog opened .
2) change tab event not work . i want to start counter of this same tab .
I wanted process data from other bean, in ActionListener method, but it throw NullPointerException, so i try resafe instance of bean to next instance in init() method with #PostConstruct annotation, but it still throw NullPointerException. I know that can obtain bean throught FacesContext.getCurrentInstance().getApplication().evaluateExpressionGet(context, expression, expectedType);but is it possible throught #ManagedProperty? This is the code:
Login.java
package sklad;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;
public class Login implements ActionListener{
private Osoba os;
#ManagedProperty(value="#{osoba}")
private Osoba osoba;
#PostConstruct
public void init(){
os = osoba;
}
#Override
public void processAction(ActionEvent a) throws AbortProcessingException {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage("zprava", new FacesMessage(os.getId().toString() + " " + os.getHeslo()));
}
public Osoba getOsoba() {
return osoba;
}
public void setOsoba(Osoba osoba) {
this.osoba = osoba;
}
public Osoba getOs() {
return os;
}
public void setOs(Osoba os) {
this.os = os;
}
}
Osoba.java
package sklad;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
#ManagedBean
#SessionScoped
public class Osoba{
private Integer id;
private String heslo;
public Osoba(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getHeslo() {
return heslo;
}
public void setHeslo(String heslo) {
this.heslo = heslo;
}
}
login.xhtml
<!DOCTYPE html>
<html xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>title</title>
<link rel="stylesheet" type="text/css" href="../styles/login.css" />
</h:head>
<h:body>
<p:growl id="growl" showDetail="true" life="3000" />
<p:panel id="panel_login" header="Přihlášení" styleClass="panel">
<p:panelGrid styleClass="panelGrid">
<h:form>
<p:row>
<p:column>
<h:outputText value="ID: " />
</p:column>
<p:column>
<h:inputText id="id_login" value="${osoba.id}" />
</p:column>
</p:row>
<p:row>
<p:column>
<h:outputText value="Heslo: " />
</p:column>
<p:column>
<h:inputSecret id="heslo_login" value="${osoba.heslo}" />
</p:column>
</p:row>
<p:row>
<p:column colspan="2">
<h:commandButton id="btn_login" value="Přihlásit">
<f:actionListener type="sklad.Login"/>
</h:commandButton>
</p:column>
</p:row>
</h:form>
</p:panelGrid>
</p:panel>
</h:body>
</html>
The more traditional way of invoking an action listener is to use a method binding, like so:
#ManagedBean
#RequestScoped
public class Login {
...
public void doLogin(ActionEvent event){
// handle action
}
}
And then in the button:
<h:commandButton id="btn_login" value="Přihlásit" actionListener="#{login.doLogin}"/>
This approach has the benefit of turning Login into a ManagedBean, which will make it so the annotations on it will be processed by JSF - and that makes the #ManagedProperty annotation work as expected.
I am basing my example on the PrimeFaces showcase example for the p:dataTableContextMenu example
The difference being I am trying to delete via a p:confirmDialog but the selected item is always null.
Here's a cut down example
The XHTML
<!DOCTYPE html>
<html xmlns="http://www.w3c.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Example</title>s
</h:head>
<h:body>
<h:form>
<p:confirmDialog widgetVar="cd" severity="alert" header="Confirmation"
message="Are you sure you wish to delete this car?">
<p:commandButton value="Yes" action="#{carTableView.deleteCar}"
update=":dataForm" oncomplete="PF('cd').hide();" />
<p:commandButton value="No" onclick="PF('cd').hide();" type="button" />
</p:confirmDialog>
</h:form>
<h:form id="dataForm">
<p:contextMenu for="cars">
<p:menuitem value="Delete" icon="ui-icon-close"
onclick="PF('cd').show(); return false;" />
<!-- action="#{formsView.deleteForm}" update=":dataForm" /> -->
</p:contextMenu>
<p:dataTable id="cars" var="car" value="#{carTableView.cars}"
rowKey="#{car.id}" selection="#{carTableView.selectedCar}"
selectionMode="single">
<f:facet name="header">
RightClick to View Options
</f:facet>
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Name">
<h:outputText value="#{car.name}" />
</p:column>
</p:dataTable>
</h:form>
</h:body>
</html>
The Model
public class Car
{
private String id;
private String name;
public Car(String id, String name)
{
this.id = id;
this.name = name;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
And the bean
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#SuppressWarnings("serial")
#ManagedBean
#ViewScoped
public class CarTableView implements Serializable
{
private List<Car> cars;
private Car selectedCar;
#PostConstruct
public void init()
{
cars = createCars();
}
private List<Car> createCars()
{
List<Car> list = new ArrayList<Car>();
for (int i = 0; i < 10; i++)
{
list.add(new Car(UUID.randomUUID().toString().substring(0, 8), "Car " + String.valueOf(i + 1)));
}
return list;
}
public void deleteCar()
{
cars.remove(selectedCar);
selectedCar = null;
}
public List<Car> getCars()
{
return cars;
}
public void setCars(List<Car> cars)
{
this.cars = cars;
}
public Car getSelectedCar()
{
return selectedCar;
}
public void setSelectedCar(Car selectedCar)
{
this.selectedCar = selectedCar;
}
}
Now it seems to me that it's the involvement of running the deleteCar action from the p:confirmDialog that is the issue.
I say this as if I change
<p:menuitem value="Delete" icon="ui-icon-close"
onclick="PF('cd').show(); return false;" />
To
<p:menuitem value="Delete" icon="ui-icon-close"
action="#{formsView.deleteForm}" update=":dataForm" />
Then it works. In the p:confirmDialog example the selectedCar in the deleteCar method is always null. Despite specifying a rowKey attribute in p:dataTable
Since you have two forms, enclose <h:setPropertyActionListener > to your <p:menuitem>
Answer: The p:confirmDialog needs to be part of the same h:form as the p:dataTable
I have following subpage in Prime faces 3.2:
<ui:composition template="index.xhtml">
<ui:define name="centerContent">
<h:form id="youtubeform">
<h3 style="margin-top: 0">Music</h3>
<p:ring id="basic" value="#{ringView.items}" var="item">
<p:outputPanel style="text-align: center;" layout="block">
#{item.link}
<br />
<p:commandButton update=":youtubeform:itemDetail" icon="ui-icon-search"
title="View" oncomplete="itemDialog.show()" >
<f:setPropertyActionListener value="oka" target="#{ringView.str2}" />
</p:commandButton>
</p:outputPanel>
</p:ring>
<p:dialog header="YoutubeItem Info" widgetVar="itemDialog"
showEffect="fade" hideEffect="fade" resizable="true" width="300" >
<h:outputText id="itemDetail" value="#{ringView.str2}" />
</p:dialog>
</h:form>
</ui:define>
</ui:composition>
and bean:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class RingView implements Serializable {
private List<YoutubeItem> items;
private YoutubeItem selectedYoutubeItem;
private String str2 = "OK1";
public String getStr2() {
return str2;
}
public void setStr2(String str2) {
this.str2 = str2;
}
public YoutubeItem getSelectedYoutubeItem() {
return selectedYoutubeItem;
}
public void setSelectedYoutubeItem( YoutubeItem selectedYoutubeItem) {
//this.selectedYoutubeItem = new YoutubeItem( "selected" + i);
this.str2 = "setSelectedYoutubeItem";
//this.selectedYoutubeItem = selectedYoutubeItem;
}
#PostConstruct
public void init() {
items = new ArrayList<YoutubeItem>();
items.add( new YoutubeItem( "link1"));
items.add( new YoutubeItem( "link2"));
items.add( new YoutubeItem( "link3"));
//this.selectedYoutubeItem = new YoutubeItem( "selected");
}
public List<YoutubeItem> getItems() {
return items;
}
public void setItems( List<YoutubeItem> items) {
this.items = items;
}
}
The property string str2 is not updated when ring item is called.
I am not able to update both the output panels after the ajax call of a method in the backing bean.
Code looks like below given sample code
abc.xhtml
<p:outputPanel id="criteriaPanel" rendered="#{myBean.showPanel}">
<h:form id="loginForm">
<ui:include src="login.xhtml" />
<p:commandButton action="#{myBean.login}" value="Login" update="criteriaPanel successPanel" />
</h:form>
</p:outputPanel>
<p:outputPanel id="successPanel" rendered="#{!myBean.showPanel}">
<h:form id="successForm">
<ui:include src="success.xhtml" />
</h:form>
</p:outputPanel>
MyBean.java
public class MyBean {
private boolean showPanel = true;
public void login() {
this.setShowPanel(false);
}
public void setShowPanel(boolean showPanel) {
this.showPanel = showPanel;
}
public boolean isShowPanel() {
return showPanel;
}
}