Partial Page Rendering (primefaces) need two times click before changing - java

I'm trying to apply this answer to rendering a part of my primefaces page but the problem is that I need to click twice before getting the part changed is there a solution ?
this is my code
index.xhtml
<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"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
</h:head>
<h:body>
<h:panelGroup id="header" layout="block">
<h1>Header</h1>
</h:panelGroup>
<h:panelGroup id="menu" layout="block">
<h:form>
<f:ajax render=":content">
<p:commandButton value="next" action="#{navBean.next}" />
<p:commandButton value="back" action="#{navBean.back}" />
</f:ajax>
</h:form>
</h:panelGroup>
<h:panelGroup id="content" layout="block">
<h:panelGroup rendered="#{navBean.activePage == 'firstAjax'}">
<ui:include src="firstAjax.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{navBean.activePage == 'lastAjax'}">
<ui:include src="lastAjax.xhtml" />
</h:panelGroup>
</h:panelGroup>
</h:body>
</html>
and this is my managedBean
package com.project.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name = "navBean")
#SessionScoped
public class NavBean {
private String activePage = "firstAjax";
public String getActivePage() {
return activePage;
}
public void setActivePage(String activePage) {
this.activePage = activePage;
}
public void next() {
System.out.println("next in " + activePage);
this.setActivePage("lastAjax");
System.out.println("next out " + activePage);
}
public void back() {
System.out.println("back in " + activePage);
this.setActivePage("firstAjax");
System.out.println("back out " + activePage);
}
}
the firstAjax.xhtml and the lastAjax.xhtml is nearly the same
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:form>
<h2>content first</h2>
</h:form>
</ui:composition>

Your page is not working because PrimeFaces has its own ajax engine. You have to use it when using p:commandButton. You don't need to use p:ajax tag, because p:commandButton has ajax behaviour activated by default, just use the update attribute (equivalent to the render attribute of f:ajax component):
<h:form>
<p:commandButton value="next" action="#{navBean.next}" update=":content"/>
<p:commandButton value="back" action="#{navBean.back}" update=":content"/>
</h:form>
If you want to stick to plain jsf use this instead (it looks much more like the example by BalusC you mentioned):
<h:form>
<f:ajax render=":content" >
<h:commandButton value="next" action="#{navBean.next}" />
<h:commandButton value="back" action="#{navBean.back}" />
</f:ajax>
</h:form>
As a final note, it must be said that p:ajax tag (at least in PrimeFaces 4.0) doesn't support the syntax we are using here, outside the p:commandButton components, because it's not able to determine the event attribute and therefore it throws: <p:ajax> Event attribute could not be determined: null

Related

#PostConstruct not called in my jsf page

I have seen many questions around the same topic but none of them helped. In fact I am beginning learning primefaces.
Here is my xhtml page (template):
<?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://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:view contentType="text/html" locale="en">
<h:head>
<title><ui:insert name="title">Master Data</ui:insert></title>
<h:outputStylesheet library="css" name="layout.css"/>
<h:outputStylesheet library="css" name="jsfcrud.css"/>
<h:outputScript library="js" name="jsfcrud.js"/>
</h:head>
<h:body>
<p:growl id="growl" life="3000" />
<h:panelGroup layout="block" styleClass="slogan">
<h:outputText value="Master Data Web module for single line v 1.0"/>
</h:panelGroup>
<h:form id="mainForm" prependId="false">
<h:panelGrid columns="2" columnClasses="chaptersMenuColumn,chaptersContentColumn">
<h:form>
<f:ajax render=":content">
<p:menu>
<p:submenu label="Master Data Sections">
<p:menuitem value="KPI" action="#{KpiBean.setPage('create')}" />
<p:menuitem value="Queues" url=""/>
<p:menuitem value="Causes" url=""/>
<p:menuitem value="SubCauses" url=""/>
</p:submenu>
</p:menu>
</f:ajax>
</h:form>
<h:panelGroup id="content" layout="block">
<ui:include src = "../views/#{KpiBean.page}.xhtml"/>
</h:panelGroup>
</h:panelGrid>
</h:form>
</h:body>
</f:view>
</html>
And here my Bean:
#Named
#SessionScoped
public class KpiBean implements Serializable {
private String page= "View";
#PostConstruct
public void init() {
page = "View"; // Default include.
}
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
}
When I launch my Glassfish server and deploy the build I get that error:
javax.faces.view.facelets.TagAttributeException: /templates/template.xhtml #47,78 <ui:include src="../views/#{KpiBean.page}.xhtml"> Invalid path : ../views/.xhtml
at com.sun.faces.facelets.tag.ui.IncludeHandler.apply(IncludeHandler.java:129)
at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
actually your bean is available under the name kpiBean (camelCase naming, first letter in lowercase).

JSF doesn't update values in the view when f:validateRegex fails

I'm using JSF 2.2 in a web application and I'm having problems in the view when I use f:validateRegex and fails (because when I use immediate="true" and try to navigate to the same page again, the view isn't updated when I have a new Instance of the object in my backing bean). I was thinking richfaces has a bug (because I'm using jsf and richfaces in my main application) so I made a test code with richfaces and without richfaces (only jsf) to identify where is the error, but in both cases the view fails.
Here is my test code without richfaces (Only jsf):
View:
<?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:c="http://xmlns.jcp.org/jsp/jstl/core">
<h:head>
<title>Mis pruebas con JSF</title>
</h:head>
<h:body>
<h:form id="lista">
<h:panelGrid id="principal">
<h:dataTable value="#{indexBB.personas}" var="persona">
<h:column>
<f:facet name="header">Activo</f:facet>
<h:selectBooleanCheckbox value="#{persona.activo}"></h:selectBooleanCheckbox>
</h:column>
<h:column>
<f:facet name="header">Nombre</f:facet>
<h:outputText value="#{persona.nombre}"></h:outputText>
</h:column>
<h:column>
<f:facet name="header">Correo</f:facet>
<h:outputText value="#{persona.correo}"></h:outputText>
</h:column>
</h:dataTable>
<h:commandButton action="#{indexBB.crearPersona}" value="Crear Persona">
</h:commandButton>
<h:commandButton action="#{indexBB.activarBoton}" value="Activar Boton">
</h:commandButton>
</h:panelGrid>
</h:form>
<h:form id="crear">
<h:panelGrid id="secundario" rendered="#{indexBB.crear}">
<h:outputText value="Activo?">
</h:outputText>
<h:selectBooleanCheckbox label="Activo" value="#{indexBB.persona.activo}">
</h:selectBooleanCheckbox>
<br></br>
<h:outputText value="Nombre"></h:outputText>
<h:inputText label="Nombre" value="#{indexBB.persona.nombre}">
</h:inputText>
<br></br>
<h:outputText value="Correo"></h:outputText>
<h:inputText label="Nombre" value="#{indexBB.persona.correo}">
<f:validateRegex
pattern="[\w\.-]*[a-zA-Z0-9_]#[\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]" />
</h:inputText>
<br></br>
<h:commandButton action="#{indexBB.guardarPersona}" value="Guardar Persona">
</h:commandButton>
<h:commandButton action="#{indexBB.cancelar}" value="Cancelar" immediate="true">
</h:commandButton>
</h:panelGrid>
</h:form>
</h:body>
</html>
Bean:
package com.kanayet.martin.view.bb;
import com.kanayet.martin.model.entity.Persona;
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;
#Named(value = "indexBB")
#ViewScoped
public class indexBB implements Serializable {
private Persona persona;
private List<Persona> personas;
private boolean crear;
/**
* Creates a new instance of indexBB
*/
public indexBB() {
}
#PostConstruct
public void onInit(){
personas = new ArrayList<>();
personas.add(new Persona("Martin", "martin#gmail.com", true));
personas.add(new Persona("Andrea", "andrea#gmail.com", true));
personas.add(new Persona("Camilo", "camilo#gmail.com", true));
personas.add(new Persona("Felipe", "felipe#gmail.com", true));
personas.add(new Persona("David", "david#gmail.com", true));
}
public void activarBoton() {
persona = personas.get(0);
}
public void crearPersona(){
crear = true;
persona = new Persona();
}
public void guardarPersona(){
personas.set(0, persona);
}
public void cancelar(){
}
public Persona getPersona() {
return persona;
}
public void setPersona(Persona persona) {
this.persona = persona;
}
public List<Persona> getPersonas() {
return personas;
}
public void setPersonas(List<Persona> personas) {
this.personas = personas;
}
public boolean isCrear() {
return crear;
}
public void setCrear(boolean crear) {
this.crear = crear;
}
}
Model: (Object)
package com.kanayet.martin.model.entity;
public class Persona {
private String nombre;
private String correo;
private Boolean activo;
public Persona() {
}
public Persona(String nombre, String correo, Boolean activo) {
this.nombre = nombre;
this.correo = correo;
this.activo = activo;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getCorreo() {
return correo;
}
public void setCorreo(String correo) {
this.correo = correo;
}
public Boolean getActivo() {
return activo;
}
public void setActivo(Boolean activo) {
this.activo = activo;
}
}
Here is my test code with richfaces: (Bean and Model are the same)
View:
<?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:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Mis pruebas con RichFaces</title>
</h:head>
<h:body>
<h:form id="lista">
<a4j:outputPanel id="principal">
<rich:dataTable id="personas" value="#{indexBB.personas}"
var="persona" rows="50">
<rich:column>
<h:selectBooleanCheckbox label="Activo" value="#{persona.activo}">
</h:selectBooleanCheckbox>
</rich:column>
<rich:column>
<h:outputText value="#{persona.nombre}"></h:outputText>
</rich:column>
<rich:column>
<h:outputText value="#{persona.correo}"></h:outputText>
</rich:column>
</rich:dataTable>
<h:commandButton action="#{indexBB.crearPersona}" value="Crear Persona">
</h:commandButton>
<h:commandButton action="#{indexBB.activarBoton}" value="Activar Boton">
</h:commandButton>
</a4j:outputPanel>
</h:form>
<br></br>
<h:form id="crear">
<a4j:outputPanel id="secundario" rendered="#{indexBB.crear}">
<h:outputText value="Activo?">
</h:outputText>
<h:selectBooleanCheckbox label="Activo" value="#{indexBB.persona.activo}">
</h:selectBooleanCheckbox>
<br></br>
<h:outputText value="Nombre"></h:outputText>
<h:inputText label="Nombre" value="#{indexBB.persona.nombre}">
</h:inputText>
<br></br>
<h:outputText value="Correo"></h:outputText>
<h:inputText label="Nombre" value="#{indexBB.persona.correo}">
<f:validateRegex
pattern="[\w\.-]*[a-zA-Z0-9_]#[\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]" />
</h:inputText>
<br></br>
<h:commandButton action="#{indexBB.guardarPersona}" value="Guardar Persona">
</h:commandButton>
<h:commandButton action="#{indexBB.cancelar}" value="Cancelar" immediate="true">
</h:commandButton>
</a4j:outputPanel>
</h:form>
</h:body>
</html>
The problem is when I click "Crear Persona" button, I write for example "Nombre": Felix and "Correo": Felix and click "Guardar Persona" button so f:validateRegex fails because isn't a valid email, then click "Cancelar" because my final user doesn't know email required value (immediate="true"). Again, click "Crear Persona" button, (new object in my bean) and jsf page isn't updated, the form should be empty but it isn't, in field "Nombre" stills "Felix" value, but in my bean I have a new and empty object without values in its attributes, do you know why?
The problem is with and without richfaces (because I thought the problem could be richfaces, but it isn't), so I don't know why jsf page isn't updated if I have a new object in my bean, I used netbeans debug tool to verify but I'm right, the object that I see in my bean is different (server side new and empty object) but in my JSF page "Nombre" has "Felix" value and I want to know why it happens, and how I can resolve this problem.
Thank you so much.
The problem is that JSF maintains two representations of your model. There is the Java object, IndexBB, but there is also the component tree, the thing that keeps track of UI state.
When you fail validation, the component tree still contains the values entered. (This is a useful feature so that the user can correct the values.) You've used immediate=true to skip validation, but that doesn't reset the component tree values.
In JSF 2.2, you can use resetValues to reset component tree values:
<h:form id="crear">
<h:panelGrid id="secundario" rendered="#{indexBB.crear}">
<h:outputText value="Activo?">
</h:outputText>
<h:selectBooleanCheckbox label="Activo" value="#{indexBB.persona.activo}">
</h:selectBooleanCheckbox>
<br></br>
<h:outputText value="Nombre"></h:outputText>
<h:inputText id="nombreId" label="Nombre" value="#{indexBB.persona.nombre}">
</h:inputText>
<br></br>
<h:outputText value="Correo"></h:outputText>
<h:inputText id="correoId" label="Nombre" value="#{indexBB.persona.correo}">
<f:validateRegex
pattern="[\w\.-]*[a-zA-Z0-9_]#[\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]" />
</h:inputText>
<br></br>
<h:commandButton action="#{indexBB.guardarPersona}" value="Guardar Persona">
</h:commandButton>
<h:commandButton
action="#{indexBB.cancelar}" value="Cancelar">
<f:ajax resetValues="true" render="crear:nombreId crear:correoId"/>
</h:commandButton>
</h:panelGrid>
</h:form>
Changes:
Remove immediate=true.
Add ids to inputs you want to reset.
Add f:ajax to Cancelar button.
Add resetValues property to f:ajax and list your IDs (separate IDs with spaces, not comma).
Make sure your cancelar method actually resets persona -- the code you posted doesn't do this.
If you also want to reset the error messages, add an h:messages to the form, give it an ID, and reset it too.
See also
JSF 2.2: Reset input fields
How to skip validation when a specific button is clicked?

how to send value from commandButton to java bean to change ui

I'm new to jsf.
I'm trying to send value to java bean from commandButton to change src in ui:include and render it with ajax so I when clicked commandButton I could refresh part from the page without load the whole page
and below is my code
\\\\\\\ The Bean File
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
#Named("urls")
#RequestScoped
public class URLPagesBean
{
private String urlSRC = "";
public String getUrlSRC() {
return urlSRC;
}
public void setUrlSRC(String urlSRC) {
this.urlSRC = urlSRC;
}
public String getURL()
{
String url = "";
if(urlSRC == "page1" || urlSRC == "" || urlSRC == null)
{
url = "page1.xhtml";
}
else if (urlSRC == "page2")
{
url = "page2.xhtml";
}
return url;
}
}
/////////////
The Index file
\\\\\\\\\\\\\\\\\\\\\\
<h:body >
<h:panelGroup layout="block" styleClass="mainContentBox">
<h:panelGroup layout="block" styleClass="mainTopBox">
<h:panelGroup layout="block" styleClass="logoBox"></h:panelGroup>
</h:panelGroup>
<h:form id="subMenuForm">
<h:panelGroup layout="block" styleClass="mainLiftBox">
<h:panelGroup id="msgBoard" layout="block" styleClass="mainMenuButtons">Message Board
<h:panelGroup layout="block" styleClass="subMenuBox">
<h:commandButton id="showMsgBoard" styleClass="subMenuButtonCommand" value="Page1"/>
</h:panelGroup>
</h:panelGroup>
<h:panelGroup layout="block" styleClass="mainMenuButtons">Registrations Book
<h:panelGroup layout="block" styleClass="subMenuBox">
<h:commandButton id="registrInternalApprov" styleClass="subMenuButtonCommand" value="Page2">
<f:ajax render="mainCenterBox" />
</h:commandButton>
</h:panelGroup>
</h:panelGroup>
</h:panelGroup>
<h:panelGroup id="mainCenterBox" styleClass="mainCenterBox" layout="block">
<ui:include id="centerView" src="#{urls.URL}"/>
</h:panelGroup>
</h:form>
</h:panelGroup>
</h:body>
///////////////////////////////////////
page1.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:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
<title>Page 1</title>
</h:head>
<h:body>
<ui:fragment>
Page 1
</ui:fragment>
</h:body>
</html>
///////////////////////////
page2.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:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
<title>Page 2</title>
</h:head>
<h:body>
<ui:fragment>
Page 2
</ui:fragment>
</h:body>
</html>
///////////////////////////
Use action attribute of h:commandButton like
<h:commandButton value="Submit"
action="#{registrationAction.submitRegistration}" />

How can I show/hide component with JSF?

How can I show/hide component with JSF?
I am currently trying so do the same with the help of javascript but not successfull.
I cannot use any third party libraries.
Thanks| Abhi
You can actually accomplish this without JavaScript, using only JSF's rendered attribute, by enclosing the elements to be shown/hidden in a component that can itself be re-rendered, such as a panelGroup, at least in JSF2. For example, the following JSF code shows or hides one or both of two dropdown lists depending on the value of a third. An AJAX event is used to update the display:
<h:selectOneMenu value="#{workflowProcEditBean.performedBy}">
<f:selectItem itemValue="O" itemLabel="Originator" />
<f:selectItem itemValue="R" itemLabel="Role" />
<f:selectItem itemValue="E" itemLabel="Employee" />
<f:ajax event="change" execute="#this" render="perfbyselection" />
</h:selectOneMenu>
<h:panelGroup id="perfbyselection">
<h:selectOneMenu id="performedbyroleid" value="#{workflowProcEditBean.performedByRoleID}"
rendered="#{workflowProcEditBean.performedBy eq 'R'}">
<f:selectItem itemLabel="- Choose One -" itemValue="" />
<f:selectItems value="#{workflowProcEditBean.roles}" />
</h:selectOneMenu>
<h:selectOneMenu id="performedbyempid" value="#{workflowProcEditBean.performedByEmpID}"
rendered="#{workflowProcEditBean.performedBy eq 'E'}">
<f:selectItem itemLabel="- Choose One -" itemValue="" />
<f:selectItems value="#{workflowProcEditBean.employees}" />
</h:selectOneMenu>
</h:panelGroup>
Generally, you need to get a handle to the control via its clientId. This example uses a JSF2 Facelets view with a request-scope binding to get a handle to the other control:
<?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">
<h:head><title>Show/Hide</title></h:head>
<h:body>
<h:form>
<h:button value="toggle"
onclick="toggle('#{requestScope.foo.clientId}'); return false;" />
<h:inputText binding="#{requestScope.foo}" id="x" style="display: block" />
</h:form>
<script type="text/javascript">
function toggle(id) {
var element = document.getElementById(id);
if(element.style.display == 'block') {
element.style.display = 'none';
} else {
element.style.display = 'block'
}
}
</script>
</h:body>
</html>
Exactly how you do this will depend on the version of JSF you're working on. See this blog post for older JSF versions: JSF: working with component identifiers.
Use the "rendered" attribute available on most if not all tags in the h-namespace.
<h:outputText value="Hi George" rendered="#{Person.name == 'George'}" />
You should use <h:panelGroup ...> tag with attribute rendered. If you set true to rendered, the content of <h:panelGroup ...> won't be shown. Your XHTML file should have something like this:
<h:panelGroup rendered="#{userBean.showPassword}">
<h:outputText id="password" value="#{userBean.password}"/>
</h:panelGroup>
UserBean.java:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class UserBean implements Serializable{
private boolean showPassword = false;
private String password = "";
public boolean isShowPassword(){
return showPassword;
}
public void setPassword(password){
this.password = password;
}
public String getPassword(){
return this.password;
}
}
One obvious solution would be to use javascript (which is not JSF). To implement this by JSF you should use AJAX. In this example, I use a radio button group to show and hide two set of components. In the back bean, I define a boolean switch.
private boolean switchComponents;
public boolean isSwitchComponents() {
return switchComponents;
}
public void setSwitchComponents(boolean switchComponents) {
this.switchComponents = switchComponents;
}
When the switch is true, one set of components will be shown and when it is false the other set will be shown.
<h:selectOneRadio value="#{backbean.switchValue}">
<f:selectItem itemLabel="showComponentSetOne" itemValue='true'/>
<f:selectItem itemLabel="showComponentSetTwo" itemValue='false'/>
<f:ajax event="change" execute="#this" render="componentsRoot"/>
</h:selectOneRadio>
<H:panelGroup id="componentsRoot">
<h:panelGroup rendered="#{backbean.switchValue}">
<!--switchValue to be shown on switch value == true-->
</h:panelGroup>
<h:panelGroup rendered="#{!backbean.switchValue}">
<!--switchValue to be shown on switch value == false-->
</h:panelGroup>
</H:panelGroup>
Note: on the ajax event we render components root. because components which are not rendered in the first place can't be re-rendered on the ajax event.
Also, note that if the "componentsRoot" and radio buttons are under different component hierarchy. you should reference it from the root (form root).
check this below code.
this is for dropdown menu. In this if we select others then the text box will show otherwise text box will hide.
function show_txt(arg,arg1)
{
if(document.getElementById(arg).value=='other')
{
document.getElementById(arg1).style.display="block";
document.getElementById(arg).style.display="none";
}
else
{
document.getElementById(arg).style.display="block";
document.getElementById(arg1).style.display="none";
}
}
The HTML code here :
<select id="arg" onChange="show_txt('arg','arg1');">
<option>yes</option>
<option>No</option>
<option>Other</option>
</select>
<input type="text" id="arg1" style="display:none;">
or you can check this link
click here

Wired component null in seam EntityHome action

I have a custom EntityHome class. I wire the dependent entity in the wire method, but when I call the action (persist) the wired component is always null.
What could be the reason, similar code generated by seam gen is apparently working.
Here is the entity class.
The round.teeSet component is always null when persist is called, although it is shown in the jsf page.
Note: Seam version: 2.2.0.GA Jboss:
jboss-5.1.0.GA
I have overrden persist method to log the value of the wired element.
#Name("roundHome")
#Scope(ScopeType.CONVERSATION)
public class RoundHome extends EntityHome<Round>{
#In(required = false)
private Golfer currentGolfer;
#In(create = true)
private TeeSetHome teeSetHome;
#Override
public String persist() {
logger.info("Persist called");
if (null != getInstance().getTeeSet() ) {
logger.info("teeSet not null in persist");
} else {
logger.info("teeSet null in persist");
// wire();
}
String retVal = super.persist(); //To change body of overridden methods use File | Settings | File Templates.
return retVal;
}
#Logger
private Log logger;
public void wire() {
logger.info("wire called");
TeeSet teeSet = teeSetHome.getDefinedInstance();
if (null != teeSet) {
getInstance().setTeeSet(teeSet);
logger.info("Successfully wired the teeSet instance with color: " + teeSet.getColor());
}
}
public boolean isWired() {
logger.info("is wired called");
if(null == getInstance().getTeeSet()) {
logger.info("wired teeSet instance is null, the button will be disabled !");
return false;
}
else {
logger.info("wired teeSet instance is NOT null, the button will be enabled !");
logger.info("teeSet color: "+getInstance().getTeeSet().getColor());
return true;
}
}
#RequestParameter
public void setRoundId(Long id) {
super.setId(id);
}
#Override
protected Round createInstance() {
Round round = super.createInstance();
round.setGolfer(currentGolfer);
round.setDate(new java.sql.Date(System.currentTimeMillis()));
return round;
}
}
Here the xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
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:a="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
template="layout/template.xhtml">
<ui:define name="body">
<h:form id="roundform">
<rich:panel>
<f:facet name="header>">
#{roundHome.managed ? 'Edit' : 'Add' } Round
</f:facet>
<s:decorate id="dateField" template="layout/edit.xhtml">
<ui:define name="label">Date:</ui:define>
<rich:calendar id="date" datePattern="dd/MM/yyyy" value="#{round.date}"/>
</s:decorate>
<s:decorate id="notesField" template="layout/edit.xhtml">
<ui:define name="label">Notes:</ui:define>
<h:inputTextarea id="notes" cols="80" rows="3" value="#{round.notes}" />
</s:decorate>
<s:decorate id="totalScoreField" template="layout/edit.xhtml">
<ui:define name="label">Total Score:</ui:define>
<h:inputText id="totalScore" value="#{round.totalScore}" />
</s:decorate>
<s:decorate id="weatherField" template="layout/edit.xhtml">
<ui:define name="label">Weather:</ui:define>
<h:selectOneMenu id="weather" value="#{round.weather}">
<s:selectItems var="_weather" value="#{weatherCategories}" label="#{_weather.label}"
noSelectionLabel=" Select " />
<s:convertEnum/>
</h:selectOneMenu>
</s:decorate>
<div style="clear: both;">
<span class="required">*</span> required fields
</div>
</rich:panel>
<div class="actionButtons">
<h:commandButton id="save" value="Save"
action="#{roundHome.persist}"
rendered="#{!roundHome.managed}" />
<!-- disabled="#{!roundHome.wired}" /> -->
<h:commandButton id="update" value="Update" action="#{roundHome.update}"
rendered="#{roundHome.managed}" />
<h:commandButton id="delete" value="Delete" action="#{roundHome.remove}"
rendered="#{roundHome.managed}" />
<s:button id="discard" value="Discard changes" propagation="end"
view="/Round.xhtml" rendered="#{roundHome.managed}" />
<s:button id="cancel" value="Cancel" propagation="end"
view="/#{empty roundFrom ? 'RoundList' : roundFrom}.xhtml"
rendered="#{!roundHome.managed}" />
</div>
<rich:tabPanel>
<rich:tab label="Tee Set">
<div class="association">
<h:outputText value="Tee set not selected" rendered="#{round.teeSet == null}" />
<rich:dataTable var="_teeSet" value="#{round.teeSet}" rendered="#{round.teeSet != null}">
<h:column>
<f:facet name="header">Course</f:facet>#{_teeSet.course.name}
</h:column>
<h:column>
<f:facet name="header">Color</f:facet>#{_teeSet.color}
</h:column>
<h:column>
<f:facet name="header">Position</f:facet>#{_teeSet.pos}
</h:column>
</rich:dataTable>
</div>
</rich:tab>
</rich:tabPanel>
</h:form>
</ui:define>
</ui:composition>
I suppose You have a single ScopeType.CONVERSATION (RoundHome) instance without any long-running conversation enabled. So you may have a Temporary conversation which survive until The render response phase.
When you submit your form, because you have a Temporary conversation, You just populate what you submit. It explains why your TeeSet is null. (Your submitted form does not contain any reference to a Tee instance)
If you really want your TeeSet survive until The next submit, you must enable a long-running conversation before showing and disable after submitting your form.
Just an advice: Each Home instance is by default ScopeType.CONVERSATION - inherited from Home. So you can set up your RoundHome as follows
#Name("roundHome")
public class RoundHome extends EntityHome<Round> {
...
}

Categories