I've got this piece of code, which doesn't do exactly what I thought. I try to set property by Ajax and then re-render one component. My .xhtml looks like this
<h:form>
<h:commandButton value="Render!" >
<f:ajax render=":result" listener="#{eFindUser.findUser}" />
</h:commandButton>
</h:form>
<h:panelGroup id="result" layout="block" rendered="#{eFindUser.responseRendered}" >
This is some text that is supposed to be rendered later
</h:panelGroup>
the backing bean looks like this
#Named(value = "eFindUser")
#ViewScoped
public class EFindUserManagedBean implements Serializable{
private boolean responseRendered = false;
/**
* Creates a new instance of EFindUserManagedBean
*/
public EFindUserManagedBean() {
}
public void findUser(AjaxBehaviorEvent abe) {
responseRendered = !responseRendered;
System.out.println("finding..... ("+ responseRendered+")" + this);
}
public boolean isResponseRendered() {
return responseRendered;
}
public void setResponseRendered(boolean responseRendered) {
this.responseRendered = responseRendered;
}
}
When I re-click the button, the property is not changed. There is a message in serverlog, which says
INFO: finding..... (true)backingbeans.EFindUserManagedBean#5736b751
INFO: finding..... (true)backingbeans.EFindUserManagedBean#23959d6f
Clearly there is some issue with the managed bean as it is created every time there is a request even if it should be view-scoped.
What should I change so the panelgroup(id:"result") could change it's visibility? No richfaces or any other technology allowed.
Thank you very much for your answers
You can't render dynamically a JSF component that is not rendered all time. The object must exist in the DOM client side. When using rendered="false", the output is not generated server side.
Change your code like this :
<h:form>
<h:commandButton value="Render!" >
<f:ajax render=":result" listener="#{eFindUser.findUser}" />
</h:commandButton>
</h:form>
<h:panelGroup id="result">
<h:panelGroup layout="block" rendered="#{eFindUser.responseRendered}" >
This is some text that is supposed to be rendered later
</h:panelGroup>
</h:panelGroup>
With that, the DOM will always contain something with the id="result".
This works for me:
<ui:composition>
<h:form id="mainForm">
<h:commandButton value="Render!" action="#{eFindUser.findUser}">
<f:ajax event="action" render=":result" />
</h:commandButton>
</h:form>
<h:panelGroup id="result" layout="block" rendered="#{eFindUser.responseRendered}" >
This is some text that is supposed to be rendered later
</h:panelGroup>
</ui:composition>
Bean:
#ManagedBean
#ViewScoped
public class EFindUser implements Serializable{
private static final long serialVersionUID = -7106162864352727534L;
private boolean responseRendered = false;
public EFindUser() {
}
public void findUser() {
responseRendered = !responseRendered;
System.out.println("finding..... ("+ responseRendered+")" + this);
}
public boolean isResponseRendered() {
return responseRendered;
}
public void setResponseRendered(boolean responseRendered) {
this.responseRendered = responseRendered;
}
}
Take a look on JSF 2.0 + Ajax Hello World Example
Related
I am trying to dynamically load a view using <f:ajax render=":component"/>.
That part works with no problems. Using commandLinks in that view, however, does not.
Container that loads the target view dynamically:
<h:form>
<h:commandLink>
<f:param name="tmp2" value="tmp/newxhtml.xhtml"/>
<f:ajax render=":newXhtml"/>
</h:commandLink>
</h:form>
<h:panelGroup layout="block" id="newXhtml">
<ui:include src="#{param['tmp2']}"/>
</h:panelGroup>
When clicking the commandLink, the tmp2 value is set and the 'newXhtml' is re-rendered through ajax.
This link is on the included .xhtml and is not working:
<h:form>
<h:commandLink>
<f:ajax listener="#{backingBean.sampleMethod}"/>
</h:commandLink>
</h:form>
BackingBean.java:
public class BackingBean{
public void sampleMethod() {
//breakpoint here is never hit
}
}
I got it to work when I'm not using <f:ajax> to include the page but rather use normal <h:commandLink> with the action attribute which will save the include page into a #SessionScope bean.
The including xhtml:
<h:form>
<f:ajax render=":newXhtml">
<h:commandLink action="#{includeBean.setIncludePage('tmp/newXhtml.xhtml')}">
</h:commandLink>
</f:ajax>
</h:form>
<h:panelGroup layout="block" id="newXhtml">
<ui:include src="#{includeBean.includePage}"/>
</h:panelGroup>
The included .xhtml can stay the same.
And the backing bean for the include page:
#Named
#SessionScope
public class IncludeBean implements Serializable {
private static final long serialVersionUID = 1L;
private String includePage;
#PostConstruct
public void init() {
includePage = "tmp/newxhtml.xhtml";
}
public String getIncludePage() {
return includePage;
}
public void setIncludePage(String includePage) {
this.includePage = includePage;
}
}
I am trying to make a form with options to add rows. However, after I type in some input and click the add button again, the input I enter disappears. I'm not sure what is wrong with my code. In addition, when I click the add button, the page refreshes. Is there way to stop this page refresh?
Person.java
public class Person{
private List<String> guys = new ArrayList<String>();
public List<String> getGuys() {
return guys;
}
public void setGuys(List<String> guys) {
this.guys = guys;
public void addNewItem(){
guys.add("");
}
}
form.xhtml
<h:form>
<h:panelGrid columns="2">
<h:outputText value="Guys: " />
<h:dataTable value="#{person.guys}" var="men">
<h:column>
<p:inputText value="#{men}" />
</h:column>
</h:dataTable>
<h:commandButton name="add" value="Add" action="#{person.addNewItem}" />
</h:panelGrid>
<br />
<h:commandButton name="submit" type="submit" value="Submit"></h:commandButton>
</h:form>
Provided that the bean is placed in the right scope for the functional requirement, the view scope, the only major mistake left is that you're expecting that the String class has some magic setter method.
It hasn't. The String class is immutable. The following will never work on a String:
<p:inputText value="#{men}" />
You have 2 options:
Create a real model class. You can find complete examples in the following answers:
How to dynamically add JSF components
Recommended JSF 2.0 CRUD frameworks
Set the value by row index instead:
<h:dataTable binding="#{table}" value="#{person.guys}">
<h:column>
<p:inputText value="#{person.guys[table.rowIndex]}" />
</h:column>
</h:dataTable>
(note: no additional bean property necessary for the table! the code is as-is)
This does basically a person.getGuys().add(table.getRowIndex(), submittedValue). I.e. the setter is invoked on the List itself, which works perfectly fine. See also the following related answers concerning ui:repeat:
Using <ui:repeat><h:inputText> on a List<String> doesn't update model values
How map multiple inputText to an array property?
You never update your list, you are just adding empty items. You should do something like this:
Person.java (viewscoped)
public class Person implements Serializable {
private List<String> guys = new ArrayList<String>();
private HtmlDataTable dtGuys;
public void addNewItem() {
guys.add("");
}
public void addToList(ValueChangeEvent e) {
guys.set(dtGuys.getRowIndex(), e.getNewValue().toString());
}
public String save() {
System.out.println("saving...");
for (String item : guys) {
System.out.println("item= " + item);
}
return null;
}
//gettes and setters
}
form.xhtml
<h:form id="frmPrincipal">
<h:panelGrid columns="2">
<h:outputText value="Guys: " />
<h:dataTable value="#{person.guys}" var="men" binding="#{person.dtGuys}" >
<h:column>
<p:inputText value="#{men}" valueChangeListener="#{person.addToList}" />
</h:column>
</h:dataTable>
<h:commandButton name="add" value="Add" action="#{person.addNewItem}" />
</h:panelGrid>
<br />
<h:commandButton id="submit" name="submit" value="Submit" action="#{person.save}"/>
</h:form>
Using jsf 2.0.10 and primefaces 3.5
Its because you don't have an scope for that bean, so its request scoped, so when you call the action the bean is created again, you can fix this using a sessionScope or conversationScope
I'm trying to get some code working in an XHTML/JSF/Spring application through which I send an ID to a bean function and expect a string in return. I haven't found an understandable tutorial on this nor any answered question here on SO.
XHTML:
<h:form>
<h:inputText id="inputId" value="#{npBean.idString}"/>
<a4j:commandButton value="get def" render="out">
<f:param value="#{npBean.idString}" name="id" />
<f:setPropertyActionListener target="#{npBean.definition}"/>
</a4j:commandButton>
<a4j:outputPanel id="out">
<h:outputText id="outputId" value="#{npBean.def}"
rendered="#{not empty npBean.def}"/>
</a4j:outputPanel>
</h:form>
Java:
public String getDefinition(int id)
{
def = this.getXService().getXData(id).getDefinition();
return def;
}
All values shown have their getters and setters in the bean.
What we basically do:
Map the value of the <h:inputText> component to a property (with getter/setter) in the managed-bean (which is called myBean)
By using the reRender attribute of the <a4j:commandButton> component, we point which component on the page to be re-rendered (refreshed) when the button is clicked.
When clicking on the button, the invokeService() method from the managedBean is executed and it updates the other property of the managedBean.
In the <h:panelGroup> below, we have several <h:outputText> components and with the rendered attribute we specify when a component has to be displayed on the page.
Exploring the managed-bean, the only thing that is required, are the accessors for the property, which holds the result from the service invoke.
Here's the *.xhtml sample:
<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:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<a4j:form>
<h:panelGrid columns="3">
<h:outputText value="String value:" />
<h:inputText value="#{myBean.value}" />
<a4j:commandButton value="Click" reRender="out">
<a4j:actionListener listener="#{myBean.invokeService}" />
</a4j:comandButton>
</h:panelGrid>
</a4j:form>
<rich:spacer height="7"/>
<br />
<h:panelGroup id="out">
<h:outputText value="Service returned: " rendered="#{not empty myBean.result}" />
<h:outputText value="#{myBean.result}" />
</h:panelGroup>
</ui:composition>
Managed-bean:
#ManagedBean(name = "myBean")
#SessionScoped //for example
public class MyBean {
private String value;
private String result;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getResult() {
return result;
}
public void invokeService(ActionEvent actionEvent) {
this.result = "Hello, " + value + "!";
}
}
As #Luiggi mentioned, the accessor methods MUST meet the following conventions (if we assume you have a private <some-type> property; in the managed-bean.)
public <some-type> getProperty {
return property;
}
public void setProperty(<some-type> property) {
this.property = property:
}
In order to learn how the RichFaces components work, combined with good code examples, I suggest you open this address and play around with the components.
I have the following facelet code which is failing:
<h:form>
<rich:select defaultLabel="Seleccionar región">
<f:selectItems value="#{StaticInfo.regiones}" var="region" itemValue="#{region.reg_Cod}" itemLabel="#{region.reg_Nombre}" />
<a4j:ajax event="change" render="provs" />
</rich:select>
<rich:select id="provs" defaultLabel="Seleccionar provincia">
<f:selectItems value="#{region.provincias}" var="prov" itemValue="#{prov.prov_Cod}" itemLabel="#{prov.prov_Nombre}" />
</rich:select>
</h:form>
Backing bean:
public class StaticInfoBean {
private ArrayList<Region> regiones;
public StaticInfoBean() {
try
{
RegionDAO regDao = new RegionDAO();
regDao.prepareConnection();
ProvinciaDAO provDao = new ProvinciaDAO();
provDao.setCon(regDao.getCon());
ComunaDAO comDao = new ComunaDAO();
comDao.setCon(regDao.getCon());
regiones = regDao.listaRegiones();
for(Region r : regiones)
{
regDao.findProvincias(r);
for(Provincia p : r.getProvincias())
{
provDao.findComunas(p);
for(Comuna c : p.getComunas())
{
comDao.findColegios(c);
}
}
}
regDao.getCon().close();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
public ArrayList<Region> getRegiones() {
return regiones;
}
public void setRegiones(ArrayList<Region> regiones) {
this.regiones = regiones;
}
public String toString() {
return regiones.toString();
}
}
Class Region:
public class Region {
private String Reg_Cod;
private String Reg_Nombre;
private ArrayList<Provincia> provincias;
//Getters and setters
The problem: The first rich:select tag works just fine. However the second one doesn't display any value. Not just that, but I'm working in NetBeans and it doesn't display the list of methods for class Provincia whenever I type "prov" in the EL.
Any help is appreciated.
EDIT: I edited my code and did the following:
<h:form>
<rich:select defaultLabel="Seleccionar región" value="#{StaticInfo.regionElegida}">
<f:selectItems value="#{StaticInfo.regiones}" var="region" itemValue="#{region.reg_Cod}" itemLabel="#{region.reg_Nombre}" />
<a4j:ajax event="click" render="provs" execute="#this" />
<a4j:ajax event="click" render="texto" execute="#this" />
</rich:select>
<h:outputText id="texto" value="#{StaticInfo.regionElegida.reg_Nombre}" />
<rich:select id="provs" defaultLabel="Seleccionar provincia" value="#{StaticInfo.provinciaElegida}" rendered="#{not empty StaticInfo.regionElegida}">
<f:selectItems value="#{StaticInfo.regionElegida.provincias}" var="prov" itemValue="#{prov.prov_Cod}" itemLabel="#{prov.prov_Nombre}" />
</rich:select>
</h:form>
What's surprising is that the outputText isn't being displayed! Why would this happen?
The variable region set in f:selectItems is only available inside its scope.
You have to bind each rich:select to a backing bean property.
So, you need to change your bean code, adding properties for the chosen region to the bean:
public class StaticInfoBean {
private ArrayList<Region> regiones;
private Region regionElegida;
private Provincia provinciaElegida; // <-- you'll probably want this too...
// ... getters and setters and your initialization code
// and you need something to find the real region object that
// used the reg_Cod value got from rich:select, for now you can try this:
public void updateRegionElegida(AjaxBehaviorEvent e){
// set the chosen region to regionElegida,
// or the poor man's converter
for (Region region : regiones){
if(regionElegida.getReg_Cod() == region.getReg_cod()) {
regionElegida = region;
}
}
}
}
and then change your XHTML to something like this:
<h:form>
<rich:select value="#{StaticInfo.regionElegida}"
defaultLabel="Seleccionar región">
<f:selectItems value="#{StaticInfo.regiones}" var="region"
itemValue="#{region.reg_Cod}" itemLabel="#{region.reg_Nombre}" />
<a4j:ajax event="change" render="provs"
listener="#{StaticInfo.updateRegionElegida}" />
</rich:select>
<rich:select id="provs" value="#{StaticInfo.provinciaElegida}"
defaultLabel="Seleccionar provincia">
<f:selectItems value="#{StaticInfo.regionElegida.provincias}" var="prov"
itemValue="#{prov.prov_Cod}" itemLabel="#{prov.prov_Nombre}" />
</rich:select>
</h:form>
Now, the professional way of doing that conversion thing would be to use a custom converter that can find the appropriate instance of a Region object based on the value of the expression itemValue used for its select widget. Check out this example from another question.
Note that rich:select only adds functionality to the default h:selectOneMenu, you would do good checking out its info page here at SO.
I have a scenario to achieve but I don't know how to do it(I'am using primefaces)
The scenario is:
I have a selectOneMenu that contain options that the user can choose one of them,
when the user choose an option ,a "form" or a "Sub-page" should appear below the selectOneMenu , the user should fill it.
The "Sub-page" change according to the choosen option
eg :option1 ---> Sub-Page1
option2 --->Sub-Page2 etc..
JSF
<h:selectOneMenu style="width:200px" immediate="true" value="#{ToolsKPI.myChoice}" onchange="submit()" valueChangeListener="#{BeanTest.selectChangeHandler}" required="true" >
<f:selectItems value="#{ToolsKPI.getMyListKPI()}" />
</h:selectOneMenu>
<p:panel rendered="#{BeanTest.showPanelBool}" >
<h1>KPI1</h1>
<br></br>
<h:inputText value="test1" />
</p:panel>
<p:panel rendered="#{BeanTest.showPanelBool1}" >
<br></br>
<h1>KPI2</h1>
<h:inputText value="test2" />
<h:inputText value="test3" />
</p:panel>
My Bean
public class BeanTest implements java.io.Serializable {
private String myChoice;
private boolean showPanelBool;
private boolean showPanelBool1;
public BeanTest() {
}
//getters ande setters
public void selectChangeHandler(ValueChangeEvent event){
myChoice = (String) event.getNewValue(); // Must however be the exact page URL. E.g. "contact.jsf".
FacesContext.getCurrentInstance().getExternalContext();
if(myChoice.equals("Number Of Closed issues") ){
this.showPanelBool = true;
} else{
this.showPanelBool = false;
this.showPanelBool1 = true;
}
FacesContext.getCurrentInstance().renderResponse();
}
}
You should really post some semblance of the code: a picture something. What you're probably looking for is a "p:outputPanel" component or something similar.
http://www.primefaces.org/showcase/ui/outputPanel.jsf
You can do something with a ValueChangeListener akin to
public void onSelectItem(ValueChangeEvent evt)
{
if("someValue".equals(evt.getNewValue())
showPageOne = true;//boolean
else
showPageTwo = true;//boolean
}
//JSF
<h:form id="myForm">
<h:selectOneMenu valueChangeListener="#{myBean.onSelectItem}" update="myForm">
<f:selectItems value="items">
</h:selectOneMenu>
<p:outputPanel rendered="#{myBean.showPageOne}">
hi I'm page one
</p:outputPanel>
<p:outputPanel rendered="#{myBean.showPageTwo}">
hi I'm page two
</p:outputPanel>
</h:form>
Sorry for the pseudo code, the examples on Primefaces will really help you here. OutputPanel has saved my bacon often. You'll need to specify an update target, but the example is really clear and easy to run. Play with it.
(Also Primefaces is fantastic you'll likely be very happy with their component suite)