Form fields not clearing after submit
admin.admin.email.tld Jul 26, 2008 1:38 AMI'm doing a Seam presentation next week and have already asked JBoss dev support and they weren't able to solve this problem.
I have a form (see xhtml below) that saves some fields via an Entity class and SFSB to the db (sql server or hsqldb).
The persistence is fine. When the page refreshes after clicking submit, the data in the form is still there in the JSF UI. How can I clear it? This is happening in another xhtml/form using the same entity class.
thx.
createContact.xhtml:
<!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: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" xmlns:s="http://jboss.com/products/seam/taglib" template="layout/template.xhtml"> <ui:define name="body"> <a4j:log popup="true" level="ALL" style="width: 800px; height: 300px;"></a4j:log> <rich:panel header="Create a new contact"> <h:form id="form1"> <rich:messages errorClass="errors" infoClass="successful" rendered="#{createContacts.getDisplayMessages()}"/> <s:validateAll> <h:panelGrid columns="3"> Name: <h:inputText id="contactname" value="#{contact.contactName}" required="true"> <a4j:support ajaxSingle="true" event="onblur"/> </h:inputText> <rich:message for="contactname" styleClass="errors" /> Email: <h:inputText id="email" value="#{contact.email}" required="true"> <a4j:support ajaxSingle="true" event="onblur"/> </h:inputText> <rich:message for="email" styleClass="errors" /> Home phone: <h:inputText id="homephone" value="#{contact.homePhone}" required="true"> <a4j:support ajaxSingle="true" event="onblur"/> </h:inputText> <rich:message for="homephone" styleClass="errors" /> </h:panelGrid> </s:validateAll> <h:commandButton value="Submit" action="#{createContacts.createContact}"/> <h:commandButton value="Help"> <rich:componentControl for="mpHelp" event="onclick" disableDefault="true" operation="show"/> </h:commandButton> </h:form> </rich:panel> <rich:modalPanel id="mpHelp" minHeight="300" minWidth="300"> <f:facet name="header"> <h:outputText value="Help Dialog" /> </f:facet> <h:outputText value="This is a rich:modalPanel example." /> <h:commandButton value="Close"> <rich:componentControl for="mpHelp" event="onclick" disableDefault="true" operation="hide"/> </h:commandButton> </rich:modalPanel> </ui:define> <ui:define name="sidebar"> <p>This facelet features a template facelet, rich:panel, h:form, Hibernate Validators with dynamic AJAX validation, rich:modalPanel and a4j:log.</p> <p>Navigate to http://localhost:8080/Contacts/debug.seam to see the current LRC's and other interesting Seam contextual and component info.</p> <p>Seam automatically calls the validation API when a JSF form is submitted via s:validate tags.</p> <p>When using Seam with Hibernate Validators, like @Email and @Pattern, validation occurs on client-side and server-side. </p> <p>Using FF 3, press CTRL-SHIFT-L to display the a4j:log output and view the AJAX request/reponse. When using a4j:log with IE7 there is a problem/bug: <h:outputLink value="https://jira.jboss.org/jira/browse/RF-4008"/></p> </ui:define> </ui:composition>
CreateContactsAction.java:
package com.cox.contacts.session; import javax.ejb.Stateless; import javax.faces.application.FacesMessage; import javax.persistence.EntityManager; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Out; import org.jboss.seam.annotations.Scope; import org.jboss.seam.faces.FacesMessages; import org.jboss.seam.log.Log; import com.cox.contacts.entity.Contact; @Stateless @Scope(ScopeType.CONVERSATION) //default scope is conversation for SFSB, this component uses a temporary conversation @Name("createContacts") public class CreateContactsAction implements CreateContacts { @In(create=true) private Contact contact; //don't need create=true for entityManager injection, it's auto-created in components.xml @In private EntityManager entityManager; @In(create=true) private FacesMessages facesMessages; @Out(required=false) private Boolean displayMessages; @Logger private Log log; public void createContact() { log.info(this.getClass().getName() + ": createContact() started"); log.info(this.getClass().getName() + contact); entityManager.persist(contact); facesMessages.add(FacesMessage.SEVERITY_INFO, "New contact successfully created."); displayMessages = true; } public Boolean getDisplayMessages() { return displayMessages; } }
Contact.java:
package com.cox.contacts.entity; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import org.hibernate.validator.Email; import org.hibernate.validator.Length; import org.hibernate.validator.NotNull; import org.hibernate.validator.Pattern; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; //Q: what is the default scope for an Entity class? //A: conversation //Q: how can you find out what context a particular Seam component is scoped to? //A: view server.log on startup/deployment of app @Entity @Name("contact") @Scope(ScopeType.CONVERSATION) @Table(name="contacts") public class Contact implements Serializable { private static final long serialVersionUID = 1881413500711441951L; private Long contactId; private String contactName; private String homePhone; private String email; public Contact(String contactName, String homePhone, String email) { this.contactName = contactName; this.homePhone = homePhone; this.email = email; } public Contact() {} //NOTE: when using HSQLDB, comment out the getContactId() and setContactId(), so that the ContactId column is not generated // during hibernate create-drop on startup. @Id //primary key designation @GeneratedValue(strategy=GenerationType.IDENTITY) //use SQL server identity seed @Column(name="ContactId") public Long getContactId() { return contactId; } public void setContactId(Long contactId) { this.contactId = contactId; } //@Id //<-- use for HSQLDB only! @NotNull(message="Contact Name is required") @Length(min=5, max=15, message="Contact name must be 5 to 15 characters long") @Column(name="ContactName") public String getContactName() { return contactName; } public void setContactName(String contactName) { this.contactName = contactName; } @NotNull(message="Home phone is required") @Pattern(regex="^(?:\\([2-9]\\d{2}\\)\\ ?|[2-9]\\d{2}(?:\\-?|\\ ?))[2-9]\\d{2}[- ]?\\d{4}$", message="Home phone is not valid") @Column(name="HomePhone") public String getHomePhone() { return homePhone; } public void setHomePhone(String homePhone) { this.homePhone = homePhone; } @NotNull(message="Email is required") @Email(message="Email is not valid") @Column(name="Email") public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "Contact(" + contactName + ", " + homePhone + ", " + email + ")"; } }