Turns out that faces-config.xml was overriding the inline annotation ViewScoped in my Controller class w/ RequestScoped. Fixed it and that seem to solve the problem.
This question does not have an answer here commandButton/commandLink/ajax action/listener method not invoked or input value not updated and if you think it does, please provide a working fix/example using primefaces fluidGrid extension.
I am using primefaces ui exension fluidGrid : http://fractalsoft.net/primeext-showcase-mojarra/sections/fluidgrid/dynamic.jsf
I can't seem to invoke profileController.testControl() , if I place the commandButton outside of the fluidGrid it works fine , but not within the grid. Any ideas?
I've tested by changing my bean to #ViewScoped , there are no nested forms etc.
<?xml version="1.0" encoding="UTF-8"?>
<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:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:p="http://primefaces.org/ui"
xmlns:pe="http://primefaces.org/ui/extensions"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="resultList" />
</composite:interface>
<composite:implementation>
<h:form id="form1" rendered="true">
<!-- Grid -->
<pe:fluidGrid value="#{resultList}" var="showvar" hGutter="20" rowKeyVar="rowKey" fitWidth="true" hasImages="true" rendered="true" >
<pe:fluidGridItem rendered="true" >
<p:panel id="seriesPanel" rendered="#{showvar.isSeries()}"></p:panel>
<p:panel id="episodePanel" rendered="#{!showvar.isSeries()}" >
<p:commandButton value="click me" action="#{profileController.testControl()}"/>
<!-- another button attempt that doesn't work -->
<p:commandButton process="fluidGrid" value="click me again" ajax="false" actionListener="#{profileController.testControlEvent()}" />
</p:panel>
</pe:fluidGridItem>
</pe:fluidGrid>
</h:form>
</composite:implementation>
</html>
//Tried with #ViewScoped as well
#Model
public class ProfileController {
public void testControl(){
log.info("---------------------------------------");
log.info("TEST CONTROL CLICKED");
log.info("---------------------------------------");
}
public void testControlEvent(ActionEvent actionEvent){
log.info("---------------------------------------");
log.info("TEST CONTROL CLICKED");
log.info("---------------------------------------");
}
}
I've tried the simple example of having command button inside fluidGrid and it works here.
XHTML File
<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:pe="http://primefaces.org/ui/extensions"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form id="login">
<pe:fluidGrid value="#{tBean.images}" var="showvar" hGutter="20"
rowKeyVar="rowKey" fitWidth="true" hasImages="true" rendered="true">
<pe:fluidGridItem rendered="true">
<p:commandButton value="click me" action="#{tBean.doAction}" />
</pe:fluidGridItem>
</pe:fluidGrid>
</h:form>
</h:body>
</html>
ManagedBean code
package 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;
import org.primefaces.extensions.model.fluidgrid.FluidGridItem;
#ManagedBean(name = "tBean")
#ViewScoped
public class TestBean implements Serializable{
private List<FluidGridItem> images;
#PostConstruct
protected void initialize() {
images = new ArrayList<FluidGridItem>();
for (int j = 0; j < 3; j++) {
for (int i = 1; i <= 10; i++) {
images.add(new FluidGridItem("i" + 1));
}
}
}
public void doAction() {
System.out.println("Im doing action");
}
public List<FluidGridItem> getImages() {
return images;
}
}
Try above and see if that works for you. If it works then try to use in your implementation.
I have sometimes problem with rendered and button not being invoked. Make sure that your rendered="#{!showvar.isSeries()}"
works correct or remove it and try again.
u must update your form i think in your page add
in the button update=":form1:fluidGrid" if dosent work make the ajax on true it helped to solve a problem like this i hope it will help you
Related
I've the below portlet view.xhtml:
<?xml version="1.0"?>
<f:view xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:body>
<h:form>
<h:commandButton value="TESTButton" action="#{navigationViewBean.submit}" />
<h:outputText value="TESTGetter: #{navigationViewBean.testField}" />
</h:form>
</h:body>
</f:view>
And this managed bean:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
#ManagedBean(name = "navigationViewBean")
#RequestScoped
public class NavigationViewBean {
private String testField;
public boolean lol = false;
public void submit() {
System.out.print("TEST BUTTON INVOKED");
}
public String getTestField() {
System.out.print("TEST GETTER INVOKEDx");
return testField;
}
public void setTestField(String testField) {
this.testField = testField;
}
}
The only thing I try to do, is to call a method which prints something to my console. The problem is that no matter what I do, the action method is never invoked. The getter method is properly called.
What am I doing wrong?
Im not sure why, but after adding this line to my liferay-portlet.xml it fixed it.
<requires-namespaced-parameters>false</requires-namespaced-parameters>
And here the whole block:
<portlet>
<portlet-name>Test1</portlet-name>
<icon>/icon.png</icon>
<requires-namespaced-parameters>false</requires-namespaced-parameters>
<header-portlet-css>/css/main.css</header-portlet-css>
</portlet>
I've the below command button and growl component:
<p:commandButton id="reservationAdd" actionListener=" {reservationBean.addReservation()}" value="Dodaj" oncomplete="PF('wdlgAddReservation').hide();" update=":frm" action="#{linkedTimelinesController.createTimeline()}">
<f:ajax execute="reservationAdd" onevent="click" listener="#{messageControler.eventAdded()}" render="dynamic"/>
</p:commandButton>
<p:growl id="msj" autoUpdate="true"/>
I'm adding a faces message as below:
#ManagedBean
public class MessageControler {
public void eventAdded(){
FacesContext.getCurrentInstance().addMessage(null,new FacesMessage(FacesMessage.SEVERITY_INFO,"Rezerwacja zostaĆa dodana",null));
}
}
However, it does not show up in the growl component. How is this caused and how can I solve it?
My following minimal example works, perhaps you check the attributes of your commandButton
page.xhtml
<!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:p="http://primefaces.org/ui">
<f:view>
<h:head/>
<h:body>
<h:form>
<p:commandButton value="Growl">
<f:ajax listener="#{page.triggerEvent}"/>
</p:commandButton>
<p:growl autoUpdate="true"/>
</h:form>
</h:body>
</f:view>
</html>
Page
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
#ManagedBean
public class Page {
public void triggerEvent() {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Test!", null));
}
}
I need to get title of currently active tab inside my TabView. TabView is constructed with dynamic number of tabs with listener attached to "tabChanged":
<p:tabView value="#{bean.list}" var="listItem">
<p:ajax event="tabChange" listener="#{listenerBean.onChange}" />
<p:tab title="#{listItem.stringProperty}">
</p:tab>
</p:tabView>
The problem is that TabChangeEvent object received by onChange(TabChangeEvent event) always contains first tab instead of the active one.
public void onChange(TabChangeEvent event) {
event.getTab().getTitle(); //allways returns title of first tab
}
This behavior is only true for dynamic number of tabs in TabView if I define each tab explicitly, TabChangeEvent works fine.
Any suggestions? Thanks.
I use PrimeFaces 3.5 with JSF2.1 and Servlets 2.5
The following minimal example worked for my like a charm by printing the title of the tab to activate every time I click on it:
page.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">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<f:view>
<h:head/>
<h:body>
<h:form>
<p:tabView value="#{bean.items}"
var="item">
<p:ajax event="tabChange"
listener="#{bean.printTitle}"
update="#form"/>
<p:tab title="#{item}">
</p:tab>
</p:tabView>
</h:form>
</h:body>
</f:view>
</html>
Bean.java
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import org.primefaces.event.TabChangeEvent;
#Named
#ViewScoped
public class Bean implements Serializable {
private final List<String> items = Arrays.asList("Hello", "This", "Is", "TabView");
public List<String> getItems() {
return items;
}
public void printTitle(TabChangeEvent event) {
System.out.println("title = [" + event.getTab().getTitle() + "]");
}
}
What should be the return type for getResponse and submit, and are both necessary?
When a guess is entered in either the firstForm or SecondForm, how do I echo that guess to the same webpage?
Either with ajax, and so not reloading the same page
or
loading a new page, guessResults.xhtml, for example, which echo's the guess.
backing bean, NextClient:
package dur.beans;
import dur.jpa.Client;
import dur.jpa.ClientFacadeLocal;
import java.util.concurrent.atomic.AtomicInteger;
import javax.ejb.EJB;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
#Named("nextClient")
#ApplicationScoped
public class NextClient implements NextClientLocal {
#EJB
private ClientFacadeLocal clientFacade;
private AtomicInteger next = new AtomicInteger(1009);
private AtomicInteger guess = new AtomicInteger(0);
private final boolean correct = true;
#Override
public String getNext() {
next.addAndGet(1);
Client client = clientFacade.find(next.intValue());
return client.toString();
}
#Override
public void setGuess(int guessInt) {
guess = new AtomicInteger(guessInt);
}
#Override
public int getGuess() {
return guess.intValue();
}
//not sure what do with these methods
#Override
public String getResponse() {
return "the guess of " + guess.intValue() + " is " + correct;
}
#Override
public String submit() {
return "the guess of " + guess.intValue() + " is " + correct;
}
}
facelets template client, next.xhtml:
<!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"
>
<h:head></h:head>
<h:body>
This and everything before will be ignored
<ui:composition template="template.xhtml">
<ui:define name="navigation">
<ui:include src="menu.xhtml"/>
</ui:define>
<ui:define name="main">
<h1>next bird</h1>
<p>
#{nextClient.next}
</p>
<p>
<h:panelGroup id="firstPanel">
<h:form id="firstForm">
<h:outputLabel for="input" value="First form input" />
<h:inputText id="input" value="#{nextClient.guess}" required="true" />
<h:commandButton value="Submit form" action="#{nextClient.submit}">
<f:ajax execute="#form" render="#form :secondPanel :secondForm :messages" />
</h:commandButton>
<h:message for="input" />
</h:form>
</h:panelGroup>
<h:panelGroup id="secondPanel">
<h:form id="secondForm">
<h:outputLabel for="input" value="Second form input" />
<h:inputText id="input" value="#{nextClient.guess}" required="true" />
<h:commandButton value="Submit other form" action="#{nextClient.submit}">
<f:ajax execute="#form" render="#form :firstPanel :firstForm :messages" />
</h:commandButton>
<h:message for="input" />
</h:form>
</h:panelGroup>
<h:messages id="messages" globalOnly="true" layout="table" />
</p>
</ui:define>
</ui:composition>
This and everything after will be ignored
</h:body>
</html>
see also:
http://balusc.blogspot.ca/2011/09/communication-in-jsf-20.html#AjaxRenderingOfContentWhichContainsAnotherForm
JSF 2.0 commandButton do nothing
https://javaserverfaces.java.net/nonav/docs/2.0/pdldocs/facelets/h/commandButton.html
http://docs.oracle.com/javaee/7/tutorial/doc/jsf-facelets003.htm
I'm running facelets on Glassfish, using CDI, so am using #Named and not #ManagedBean -- some of the documentation above is more geared for #ManagedBean, but I'm not sure how much that matters.
The goal is one step better than "hello world", "hello world, your guess is " would be a good result. If there's a specific manual, I don't mind a RTFM to that specific documentation. The Oracle docs are probably the best for facelets?
code:
https://github.com/THUFIR/EntAppWeb
This response.xhtml:
<!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">
<h:head>response</h:head>
<h:body>
This and everything before will be ignored
<ui:composition template="template.xhtml">
<ui:define name="navigation">
<ui:include src="menu.xhtml"/>
</ui:define>
<ui:define name="main">
<h1>submitted value</h1>
<p>
#{nextClient.guess}
</p>
<h2>for this bird</h2>
<p>
#{nextClient.client}
</p>
</ui:define>
</ui:composition>
This and everything after will be ignored
</h:body>
</html>
to next.xhtml:
<!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">
<h:head>next</h:head>
<h:body>
This and everything before will be ignored
<ui:composition template="template.xhtml">
<ui:define name="navigation">
<ui:include src="menu.xhtml"/>
</ui:define>
<ui:define name="main">
<h1>next bird</h1>
<p>
#{nextClient.next}
</p>
<p>
<h:panelGroup id="simpleGroup">
<h:form id="simpleForm">
<h:outputLabel for="input" value="First form input" />
<h:inputText id="input" value="#{nextClient.guess}" required="true" />
<h:commandButton value="submit" action="response">
</h:commandButton>
</h:form>
</h:panelGroup>
</p>
</ui:define>
</ui:composition>
This and everything after will be ignored
</h:body>
</html>
using the backing bean NextClient:
package dur.beans;
import dur.jpa.Client;
import dur.jpa.ClientFacadeLocal;
import java.util.concurrent.atomic.AtomicInteger;
import javax.ejb.EJB;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
#Named("nextClient")
#ApplicationScoped
public class NextClient implements NextClientLocal {
#EJB
private ClientFacadeLocal clientFacade;
private AtomicInteger next = new AtomicInteger(1009);
private AtomicInteger guess = new AtomicInteger(0);
private final boolean correct = true;
private Client client = new Client();
#Override
public String getNext() {
next.addAndGet(1);
client = clientFacade.find(next.intValue());
return client.toString();
}
#Override
public void setGuess(int guessInt) {
guess = new AtomicInteger(guessInt);
}
#Override
public int getGuess() {
return guess.intValue();
}
#Override
public Client getClient() {
return client;
}
#Override
public void setClient(Client client) {
this.client = client;
}
}
outputs the submitted value to the response, along with the bird. It might make more sense to output the result to the same page, but this is sufficient.
I think I have run into a bug in Mojarra 2.1.0. Maybe I missed something but damned if I can see it.
I rely a lot of #ViewScoped beans to save state whilst the browser does a lot of AJAX to the server. I find when I use certain tags, the #ViewScoped bean starts getting re-instantiated when it shouldn't be. Here is my test case backing bean:
/*
* TestStuff.java
*/
package test;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
/**
* Backing bean for test.xhtml -- working out AJAX/SVG connection
*
*/
#ManagedBean
#ViewScoped
public class TestStuff implements Serializable {
private int counter = 0;
public TestStuff() {
log("TestStuff(): {0}", this);
}
public String getRandomNumber() {
int i = (int) (Math.random() * 1000000.0);
return String.format("%d", i);
}
public int getCounter() { return counter; }
public List<String> getStuff() {
return Arrays.asList("big", "bad", "wolf");
}
public void pushButton(ActionEvent evt) {
log("TestStuff.pushButton({0}): {1}",
new Object[] { evt, ++counter });
}
}
And here is the JSF Facelets page that uses it:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head>
<title>Test Page</title>
</h:head>
<h:body>
<h1>Test Page</h1>
<p>If you are reading this text, the server
is not properly configured.</p>
<ui:composition id="compRoot" template="/template5.xhtml">
<ui:define name="content">
<h1>Test</h1>
<h:form id="formTest">
<p:commandButton value="Do Me"
actionListener="#{testStuff.pushButton}"
update="testUpdate" />
<p:panel id="testUpdate" >
<h:outputText value="Random output is: " />
<h:outputText
value="#{testStuff.randomNumber}"
/>
<h:outputText value=" Counter is: "/>
<h:outputText
value="#{testStuff.counter}"
/>
</p:panel>
<h:panelGrid columns="5" border="1" >
<c:forEach items="#{testStuff.stuff}" var="x">
<h:outputText value="#{x}" />
</c:forEach>
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
</h:body>
</html>
So here is what goes wrong. When you click on the "Do Me" command button, a new instance of the backing bean gets created each time, just as if it were a #RequestScoped bean. I can see this via the log() call in the constructor.
If you change the bean to #SessionScoped, this doesn't happen. You get one instance of the bean no matter how many times the button is clicked.
HOWEVER -- if you leave it as #ViewScoped, and you take out the c:foreach element and its content, it now no longer re-instantiates the bean each click. In other words it now works as expected.
Is this a mojarra bug or am I doing something wrong here?
This is a known "bug": issue 1665. It's a chicken-egg issue with regard to partial state saving.
In your case, however, you could also just use <ui:repeat>.
<ui:repeat value="#{testStuff.stuff}" var="x">
<h:outputText value="#{x}" />
</ui:repeat>
Your best bet is to try to avoid JSTL tags when using #ViewScoped. The only alternative is to disable partial state saving by a context param in web.xml:
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
But it makes the views more memory hogging.