how to display a primefaces progressbar in a dialog - jsf

I am trying to display a progressbar in a dialog for a long operation called from the menu. The dialog does not show up. I am not sure what I am missing. Any help is much appreciated.
MainPage.xhtml -> contains the menu bar which has the longOperation menuitem
<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>
<h:form>
<p:menubar model="#{progressBarExample.model}" styleClass="menubar"
autoDisplay="False" style="margin-bottom:5px;" />
</h:form>
</body>
</html>
progress.xhtml -> contains the progress dialog
<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>
<p:dialog id="progressDialog" widgetVar="progressDialogVar"
modal="true" draggable="true"
resizable="false" header="Progress" >
<h:form>
<p:panel widgetVar="progressPanelVar">
<h:panelGrid id="ProgressPanel" columns="1"
style="margin-bottom:10px" cellpadding="5" width="500px">
<p:progressBar widgetVar="progressbar"
style="height:20px;width:100%;"
mode="indeterminate" />
</h:panelGrid>
</p:panel>
</h:form>
</p:dialog>
</body>
</html>
ProgressBarExample.java contains the backing bean which calls the longOperation and the Progress dialog.
#Named
#ViewScoped
public class ProgressBarExample implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private MenuModel model;
public ProgressBarExample() { }
#PostConstruct
protected void init() {
model = new DefaultMenuModel();
DefaultMenuItem item = new DefaultMenuItem();
item = new DefaultMenuItem();
item.setValue("Long Operation");
item.setCommand("#{progressBarExample.longOperation}");
model.addElement(item);
}
public void longOperation(ActionEvent ae) {
System.out.println("this is a long operation...");
PrimeFaces.current().executeScript("PF('progressDialogVar').show();");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
PrimeFaces.current().executeScript("PF('progressDialogVar').hide();");
}
public MenuModel getModel() {
return model;
}
public void setModel(MenuModel model) {
this.model = model;
}
}

As Primefaces docs stated:
PrimeFaces executeScript provides a way to execute javascript when the
ajax request completes
So, basically, what you can see is: longOperation is called, it does is work and, only after that, you show the progress bar and hide it immediately after, so you see nothing, except if you inspect your browser console.
To achieve your goal you can define your menu item like this:
DefaultMenuItem item = new DefaultMenuItem();
item = new DefaultMenuItem();
item.setValue("Long Operation");
item.setCommand("#{progressBarExample.longOperation}");
item.setOnstart("PF('progressDialogVar').show()");
item.setOncomplete("PF('progressDialogVar').hide()");
model.addElement(item);
Primefaces docs

Related

Primefaces 3.4.1 does not POST with a form inside a dialog

EDIT: the question does not have an answer with the linked resource, but I solved. I'll post the solution.
I'm working on a project that uses Primefaces 3.4.1 (and no, I can't update it).
I created a dialog with some inputs. The method is invoked, but the inputs are not populated in the bean. This does not happen in a "normal" form.
This is the simplified code:
browse.xhtml:
<!DOCTYPE html>
<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:f="http://java.sun.com/jsf/core"
template="../layout/template.xhtml">
<ui:define name="body">
<p:dialog
id="dialog"
visible="#{bean.getDialogVisible()}"
modal="true"
>
<h:form id="form">
<p:inputText
id="x"
styleClass="Form-input"
value="#{bean.x}"
/>
<p:commandButton
value="submit"
action="#{bean.submit()}"
immediate="true"
></p:commandButton>
</h:form>
</p:dialog>
</ui:define>
</ui:composition>
Bean.java:
#ManagedBean
#SessionScoped
public class Bean {
private String x;
private boolean isDialogVisible;
public String getX() {
return x;
}
public void setX(String x) {
this.x = x;
}
public boolean isDialogVisible() {
return isDialogVisible;
}
public void setDialogVisible(boolean isDialogVisible) {
this.isDialogVisible = isDialogVisible;
}
public boolean getDialogVisible() {
boolean res = this.isDialogVisible();
this.setDialogVisible(false);
return res;
}
public void submit() {
logger.info(this.x);
}
}
In loggind and during debugging, x is always null inside the method submit().
PS: note that the commandButton does not invoke submit() at all, if immediate="true" or ajax="false" are not specified.
I removed immediate="true" and added process="#form" to the p:commandButton and now it works.

p:selectManyMenu(with checkbox): Add item and select checkbox at the same time

xhtml code
<p:selectManyMenu id="menuid"
value="#{bean.selectedActivities}"
showCheckbox="true" scrollable="true" scrollHeight="150">
<f:selectItems value="#{bean.activities}" var="activity" itemValue="#{activity}"
itemLabel="#{activity}" />
</p:selectManyMenu>
<p:commandButton value="ADD ACTIVITY" id="addId">
<p:ajax event="click" process="#this" update="menuid" listener="#{bean.addActivity()}"/>
</p:commandButton>
Bean:
private List<String> selectedActivities = new ArrayList<>();
private List<String> activities = new ArrayList<>();
int index = 1;
public void addActivity(){
String activity = "Activity "+ (index ++);
activities.add(activity);
selectedActivities.add(activity);
}
This code is adding new item to the manyMenu but the checkbox is not selected.
Apart from some missing annotations I don't see much wrong. In any case, here is a tested solution based on your code that should work. First let's define the view. This is basically the same as in your example:
<?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:f="http://xmlns.jcp.org/jsf/core" xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>SelectMany Example</title>
</h:head>
<h:body>
<h:form>
<p:selectManyMenu id="menuid"
value="#{selectManyBackingBean.selectedActivities}"
showCheckbox="true" scrollable="true" scrollHeight="150">
<f:selectItems value="#{selectManyBackingBean.activities}" var="activity" itemValue="#{activity}"
itemLabel="#{activity}" />
</p:selectManyMenu>
<p:commandButton value="ADD ACTIVITY" id="addId">
<p:ajax event="click" process="#form" update="menuid"
listener="#{selectManyBackingBean.onAddActivity}"/>
</p:commandButton>
</h:form>
</h:body>
</html>
Then, we define the backing bean:
#Data
#Named
#ViewScoped
public class SelectManyBackingBean implements Serializable {
private List<String> selectedActivities;
private List<String> activities;
private int index;
#PostConstruct
private void init() {
activities = new ArrayList<>();
selectedActivities = new ArrayList<>();
index = 0;
}
public void onAddActivity(){
String activity = "Activity " + (index++);
activities.add(activity);
selectedActivities.add(activity);
}
}
This should give you the expected behavior. Clicking three times on the ADD ACTIVITY button now yields the following result:
Notice the subtle change in the command button from process="#this" to process="#form". This will make sure that any changes you make in the component are also included in the form submission. If you keep it at the original value, any clicks on the check boxes in the menu will not be kept and will reset entries to the previous value when you press the command button (this is because the component in question is not included when the life cycle executes).

Button does not add an item to a selectManyList

I have a JSF page with a h:selectManyList and a Primefaces commandButton. I want to add new elements to the list when I click the button. The button's action method is called, but elements don't show up in the list. I probably just don't see the forest for the trees.
Page:
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head/>
<h:body>
<h:form id="form">
<h:messages id="errors"/>
<h:selectManyListbox id="listBox" value="#{testBean.availableThings}" style="width:100%">
<f:selectItems value="#{testBean.selectedThings}"/>
</h:selectManyListbox>
<br/>
<p:commandButton id="adder" value="Add" action="#{testBean.addThing}"
ajax="true" update="listBox" process="#this listBox"/>
</h:form>
</h:body>
</html>
Backing bean:
import java.util.ArrayList;
import java.util.List;
import javax.faces.model.SelectItem;
#javax.faces.bean.ManagedBean
#javax.faces.bean.ViewScoped
#com.ocpsoft.pretty.faces.annotation.URLMapping(
id = "testbean",
pattern = "/testbean/",
viewId = "/pages/general/testbean.xhtml")
public class TestBean {
private List<SelectItem> availableThings;
private List<String> selectedThings;
public TestBean() {
availableThings = new ArrayList<>();
selectedThings = new ArrayList<>();
}
public List<SelectItem> getAvailableThings() {
return availableThings;
}
public void setAvailableThings(List<SelectItem> list) {
this.availableThings = list;
}
public List<String> getSelectedThings() {
return selectedThings;
}
public void setSelectedThings(List<String> list) {
this.selectedThings = list;
}
public void addThing() {
availableThings.add(new SelectItem("item", "item")); // I get this message
System.err.println("Added item");
}
}
Why doesn't the added item appear in the list and what do I need to do to make it appear?
You reversed the fields in the xhtml.
<h:selectManyListbox id="listBox" value="#{testBean.availableThings}" style="width:100%">
<f:selectItems value="#{testBean.selectedThings}"/>
</h:selectManyListbox>
Should be
<h:selectManyListbox id="listBox" value="#{testBean.selectedThings}" style="width:100%">
<f:selectItems value="#{testBean.availableThings}"/>
</h:selectManyListbox>

Primefaces: open a dialog when an element in a pie chart is clicked

I'm trying to figure out how to open a dialog box when an element in a pie chart is clicked. I'm new to Primefaces, so most of what I've found in searches are more complex examples than what I'm trying to accomplish. The dialog box is opened using the Dialog Framework. I've been able to open the dialog via a command button no problem, so I'm pretty sure the problem isn't with the dialog itself.
Here's the initial page:
<?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"
>
<body>
<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:s="http://jboss.com/products/seam/taglib"
xmlns:p="http://primefaces.org/ui"
xmlns:pm="http://primefaces.org/mobile"
>
<p:panel header="Dashboard" toggleable="true">
<h:form>
<p:growl id="growl" showDetail="true" />
<h:panelGrid columns="2">
<p:chart type="pie" model="#{dashboardPieChart.pieModel1}" style="width:350px; height:200px" >
<p:ajax event="itemSelect" listener="#{dashboardPieChart.itemSelect}"/>
</p:chart>
</h:panelGrid>
<h:outputText id="out" value="#{dashboardPieChart.seriesText}" />
</h:form>
</p:panel>
<script type="text/javascript">
PrimeFaces.info ('Info message');
PrimeFaces.debug('Debug message');
PrimeFaces.warn ('Warning message');
PrimeFaces.error('Error message');
</script>
</ui:composition>
</body>
</html>
And the backing bean:
package com.company.project.model;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.context.RequestContext;
import org.primefaces.event.ItemSelectEvent;
import org.primefaces.model.chart.PieChartModel;
#ManagedBean
#ViewScoped
public class DashboardPieChart implements Serializable {
private static final long serialVersionUID = -9056199453379512637L;
private PieChartModel pieModel1;
private String seriesText;
/*
public DashboardPieChart()
{
init();
}
*/
#PostConstruct
public void init() {
System.out.println("DashboardPieChart - inside init()");
createPieModels();
}
public PieChartModel getPieModel1() {
return pieModel1;
}
private void createPieModels() {
createPieModel1();
}
private void createPieModel1() {
pieModel1 = new PieChartModel();
pieModel1.set("Proposals in Progress", 12);
pieModel1.set("Proposals Completed", 15);
pieModel1.setTitle("Proposals");
pieModel1.setLegendPosition("w");
pieModel1.setDiameter(100);
}
public void itemSelect(ItemSelectEvent event) {
String msgText = "Item Index: " + event.getItemIndex() + ", Series Index:" + event.getSeriesIndex();
System.out.println (msgText);
this.seriesText = msgText;
RequestContext.getCurrentInstance().openDialog("pieChartDrillDownDialog");
}
public String getSeriesText() {
return seriesText;
}
public void setSeriesText(String seriesText) {
this.seriesText = seriesText;
}
}
and this is the dialog I'm trying to open:
<!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:p="http://primefaces.org/ui"
xmlns:pm="http://primefaces.org/mobile"
>
<h:head>
<title>Proposal Status Detail</title>
</h:head>
<h:body>
<h:form>
<p:chart type="pie" model="#{dashboardPieChartDrillDown.pieModel}" style="width:350px; height:200px" >
</p:chart>
</h:form>
</h:body>
</html>
I was able to make it work using remoteCommand:
XHTML:
<p:remoteCommand name="fnc" actionListener="#{playgroundController.showDialog()}"/>
<p:chart type="pie" model="#{playgroundController.pieModel1}" style="width:400px;height:300px">
<p:ajax event="itemSelect" listener="#{playgroundController.itemSelect}" oncomplete="fnc()" />
</p:chart>
BEAN:
public void showDialog() {
RequestContext.getCurrentInstance().openDialog("pieChartDrillDownDialog");
}
public void itemSelect(ItemSelectEvent event) {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Item selected",
"Item Index: " + event.getItemIndex() + ", Series Index:" + event.getSeriesIndex());
FacesContext.getCurrentInstance().addMessage(null, msg);
}

JSF command button not working within included JSF page

I'm try to build application with Primefaces 4.0 and JSF 2.2.5. I need to load content dynamically in accordance with choosen menu item.
Here is my main page:
<?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:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Hello, world!</title>
</h:head>
<h:body>
<p:layout fullPage="true">
<p:layoutUnit position="west" size="15%">
<h:form>
<p:commandButton value="List1" action="#{backingBean.setCurrentPage('included.xhtml')}"
update=":mypanel_id" process="#this"/><br/>
<p:commandButton value="List2"/>
</h:form>
</p:layoutUnit>
<p:layoutUnit position="center">
<p:panel id="mypanel_id">
<ui:include src="#{backingBean.page}"/>
</p:panel>
<p:messages autoUpdate="true" showDetail="true" showSummary="true"/>
</p:layoutUnit>
</p:layout>
</h:body>
</html>
And this is included page:
<?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>Hello,world</title>
</h:head>
<h:body>
<h:outputText value="Included page"/>
<h:form>
<ui:repeat value="#{backingBean.items}" var="item">
<p:fieldset legend="item" toggleable="true">
<h:outputText value="#{item}"/>
<ui:param name="it" value="#{item}"/>
<p:commandButton value="Click" style="margin-left: 50px;"
actionListener="#{backingBean.actionListener}"/>
</p:fieldset>
</ui:repeat>
<p:commandButton value="Test" action="#{backingBean.actionListener}"/>
</h:form>
</h:body>
</html>
Command buttons not work. Not with action nor with actionListener. What i'm doing wrong? How to build page with conditionally rendered elements, such as command buttons and fieldsets?
P.S. Forget to say, that my bean have request scope.
Updated:
public class BackingBean {
private List<String> items;
private String currentItem;
private String page;
public BackingBean() {
items = new ArrayList<String>();
}
public List<String> getItems() {
if (items.size() == 0) {
this.fillAndUpdate();
}
return items;
}
public void setItems(List<String> items) {
this.items = items;
}
public void fillAndUpdate() {
for (int i = 0; i < 5; i++) {
items.add("Item " + String.valueOf(i));
}
}
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
public void setCurrentPage(String page) {
this.page = page;
}
public void actionListener() {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Test"));
}
}
UPDATED
Ok. I found the error (if someone interested). Because my bean has request scope, when i click the button in right panel my view was updated, but list of items was updated too and became empty (request scope). Now i keep selected menu in the session bean, and return that number when view rendered.
try to add ajax="false" in your command buttons

Resources