How to use Conversation in Seam 3...
hantsy Sep 5, 2011 10:53 AMI used a Conversation scoped bean to process add/edit action...The problem is
1. If validation failed, the input values are missing(restored to the default, add is empty and 'edit' is the unchanged), in the Seam 2 application, all like these worked well.
Where is wrong
2. I used Richfaces 4.0.0.Final, and I wanted to use a popupPanel to update the some content(added some areacode in the cityEdit page), the field values in the popupPanel were not updated.
3. When the validation was failed in the popupPanel, it did not stop to close popupPanel(closed the popupPanel)...and when I opened the popupPanel again, it highlight the field label and input field...why the validation was delayed...
@Stateful @ConversationScoped @Named("cityEdit") public class CityEditAction { //private static final org.slf4j.Logger logger=LoggerFactory.getLogger(CityEditAction.class); @PersistenceContext() EntityManager em; @Inject Logger log; private City currentCity; private String areaCode; @Inject private Event<City> citySavedEventSrc; @Inject Messages messages; public City getCurrentCity() { return currentCity; } public void setCurrentCity(City currentCity) { this.currentCity = currentCity; } public String getAreaCode() { return areaCode; } public void setAreaCode(String areaCode) { this.areaCode = areaCode; } @PostConstruct public void init() { if (log.isDebugEnabled()) { log.debug("call init..."); } } @Begin public void initAdd() { if (log.isDebugEnabled()) { log.debug("call initAdd..."); } this.currentCity = new City(); } @Begin public void initEdit(City city) { if (log.isDebugEnabled()) { log.debug("call initEdit...@" + city); } this.currentCity = em.merge(city); } public void saveAreaCode() { if (log.isDebugEnabled()) { log.debug("call saveAreaCode..."); log.debug("areacode @"+this.areaCode); } //logger.debug("areacode @"+this.areaCode); this.currentCity.addAreaCode(new CityAreaCode(this.areaCode)); } public void initAddAreaCode() { if (log.isDebugEnabled()) { log.debug("call initAddAreaCode..."); } this.areaCode =""; } public void deleteAreaCode(CityAreaCode c) { if (log.isDebugEnabled()) { log.debug("call initAddAreaCode..."); } this.currentCity.removeAreaCode(c); } @End public void save() { if (log.isDebugEnabled()) { log.debug("call save..."); } if (this.currentCity.getId() == null) { em.persist(this.currentCity); } else { this.currentCity = em.merge(this.currentCity); } System.out.print("@current city @"+this.currentCity); this.citySavedEventSrc.fire(this.currentCity); } public void onSaved( @Observes(during = TransactionPhase.AFTER_SUCCESS) City city) { messages.info(new DefaultBundleKey("city_saved")) .defaults("City saved").params(city.getName()); } @End public void cancel() { if (log.isDebugEnabled()) { log.debug("call end..."); } em.clear(); } }
CityEdit.xhtml
<ui:define name="content"> <div class="section"> <h1>#{cityEdit.currentCity.id==null?'Add City':'Edit City'}</h1> <a4j:outputPanel id="editPane"> <h:form id="editForm"> <fieldset> <p:input id="cityCountry" label="#{messages['City.Country']}" required="true"> <h:selectOneMenu value="#{cityEdit.currentCity.country}" style="width:200px" required="true"> <f:selectItems value="#{countries}" var="c" itemLabel="#{c.name}" /> <f:validateRequired /> <f:converter converterId="countryConverter" /> </h:selectOneMenu> </p:input> <p:input id="cityName" label="#{messages['City.Name']}" required="true"> <h:inputText id="input" value="#{cityEdit.currentCity.name}" style="width:200px"> <f:validateRequired /> </h:inputText> </p:input> <p:output id="cityAreaCodeOP" label="#{messages['City.AreaCode']}" verbatim="true"> <a4j:outputPanel id="areaCodeField"> <ui:repeat var="a" value="#{cityEdit.currentCity.areaCodes}" varStatus="s"> #{a.areaCode} <a4j:commandLink styleClass="no-decor" render="areaCodeField" execute="@this" action="#{cityEdit.deleteAreaCode(a)}" immediate="true" onclick="if(confirm('#{messages['Confirmation.Delete']}')){return true;}"> <h:graphicImage value="/images/icons/delete.gif" alt="Delete areacode" /> </a4j:commandLink> <ui:fragment rendered="#{not empty cityEdit.currentCity.areaCodes and s.index!=fn:length(cityEdit.currentCity.areaCodes)-1}"> , </ui:fragment> </ui:repeat> #{' '} <h:graphicImage value="/images/icons/new.gif" alt="new areacode" /> <a4j:commandLink styleClass="no-decor" render="areaCodeFormInputs" execute="@this" actionListener="#{cityEdit.initAddAreaCode}" oncomplete="#{rich:component('newAreaCodePane')}.show();"> <h:outputText value="#{messages['Link.AddAreaCode']}" /> </a4j:commandLink> </a4j:outputPanel> </p:output> <div class="buttonBox"> <h:commandButton id="save" value="#{messages['Buttons.Save']}" action="#{cityEdit.save}" /> #{' or '} <h:commandLink value="#{messages['Buttons.Cancel']}" action="#{cityEdit.cancel}" immediate="true" /> </div> </fieldset> <rich:popupPanel id="newAreaCodePane" autosized="true" resizeable="false" model="true" width="480" height="180"> <f:facet name="header"> #{messages['City.Title.AddCityAreaCode']} </f:facet> <a4j:outputPanel id="areaCodeFormInputs" layout="block"> <p:input id="cityAreaCode" label="#{messages['City.AreaCode']}" required="true"> <h:inputText id="input" value="#{cityEdit.areaCode}" required="true"> </h:inputText> </p:input> <div class="buttonBox"> <a4j:commandButton id="saveAreaCode" value="#{messages['Buttons.Save']}" action="#{cityEdit.saveAreaCode}" render="editForm:cityAreaCodeOP:areaCodeField, areaCodeFormInputs" execute="newAreaCodePane" oncomplete="if (#{facesContext.maximumSeverity==null}) {#{rich:component('newAreaCodePane')}.hide();}" /> #{' or '} <a4j:commandLink value="#{messages['Buttons.Cancel']}" onclick="#{rich:component('newAreaCodePane')}.hide(); return false;" /> </div> </a4j:outputPanel> </rich:popupPanel> </h:form> </a4j:outputPanel> </div> </ui:define>