Lifecycle problem - Page being rebuilt on every ajax request
gwate Oct 4, 2011 10:34 AMHey guys,
this is my first post here, and have been trying to figure out this life cycle problem.
The basic problem is that everytime something needs to be submitted or calls for a ajax request, it seems to do a full page reload and rebuilding the view from the ground up again, which cancels any ajax calls. I have also noted that it WILL execute ajax requests up to the Onclick events, anything past that (ondombefore, onsubmit, oncomplete) will not be called and the page is rerendered.
I have dealt with this issue with the Rich:popuppanel, but by using FacesContext.getCurrentInstance().getRenderResponse() in select parts of the code i could by pass the problem, however with a a4j:commandButton, i cannot be so lucky since i am trying to create a popup window based on the current data the user has entered.
Here is my Jsf code
<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:c="http://java.sun.com/jsp/jstl/core" xmlns:t="http://myfaces.apache.org/tomahawk" template="../cmstemplate.xhtml"> <ui:define name="main"> <h:form id="recordData"> <table width="100%" cellpadding="0" cellspacing="0"> <tr> <td> <h2> <h:outputText value="#{msg.dataeditor_pageheader}"/> </h2> </td> <td> <div class="edit-module-div"> <!-- Adding a Cancel button --> <h:commandButton id="cancel-button-top" styleClass="btn" action="#{moduleDataEditAction.cancel}" value="#{msg.moduleeditor_btn_cancel}" immediate="true"> </h:commandButton> </div> </td> </tr> </table> <!-- do not change the name of this form OR any panels ! --> <h:panelGroup id="outerPanel" layout="block" styleClass="block-container client-tools-edit-module"> <h:outputText value="#{moduleDataEditAction.module.name}" style="font-weight:bold"/> <h:panelGroup id="leftPanel" layout="block"> </h:panelGroup> <br class="clear-both" /> </h:panelGroup> <h:panelGroup id="location-selection" layout="block" rendered="#{moduleDataEditAction.renderLocationSelector}"> <div class="underline-header-link"> <a4j:commandLink id="selectAll" action="#{moduleListViewAction.dummyAction}" execute="@this" bypassUpdates="true" limitRender="true" styleClass="btn-text"> <h:outputText value="#{msg.clienttools_selectall}" /> </a4j:commandLink> <!-- This JQueary statement will select all checkboxes within the class "underline-header-link" (referenced by the <div> tag above). --> <rich:jQuery selector="#location-selection #selectAll" timing="domready" query="click(function(){ jQuery('.blocks-location-tags input:checkbox').attr('checked','checked'); });"/> <a4j:commandLink id="deSelectAll" action="#{moduleListViewAction.dummyAction}" execute="@this" bypassUpdates="true" limitRender="true" styleClass="btn-text"> <h:outputText value="#{msg.clienttools_deselectall}" /> </a4j:commandLink> <!-- This JQueary statement will deselect all checkboxes within the class "underline-header-link" (referenced by the <div> tag above). --> <rich:jQuery selector="#location-selection #deSelectAll" timing="domready" query="click(function(event){ event.preventDefault(); jQuery('.blocks-location-tags input:checkbox').removeAttr('checked'); });"/> </div> <div class="blocks-location-tags"> <t:selectManyCheckbox id="locations" layout="pageDirection" layoutWidth="3" value="#{moduleDataEditAction.recordLocationsCurrentRecord}"> <f:selectItems value="#{locationTagBean.selectItemsModuleRecordLocations}" /> </t:selectManyCheckbox> </div> <br class="clear-both" /> </h:panelGroup> <ui:include src="editActionItem_include.xhtml"/> <h:commandButton id="cancel-button-bottom" styleClass="btn" action="#{moduleDataEditAction.cancel}" value="#{msg.moduleeditor_btn_cancel}" immediate="true"> </h:commandButton> <br class="clear-both" /> </h:form> <t:saveState value="#{moduleDataEditAction}"/> <h:outputText id="subComponentBuilder" binding="#{moduleDataEditAction.subComponents}" /> <!-- initialise the media library bean --> <h:outputText id="dummy3" binding="#{mediaAction.dummy}" /> </ui:define> </ui:composition>
The editActionItem_include.xhtml which contains the buttons are as follows:
<ui:component xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"> <a4j:commandButton id="btn-preview" styleClass="btn" rendered="#{moduleDataEditAction.renderPreviewButton}" action="#{moduleDataEditAction.preparePreviewLink}" value="#{msg.moduleeditor_btn_preview}" render="previewLink" oncomplete="openNewWindow(document.getElementById('recordData:previewLink').value); return false;"> </a4j:commandButton> <!-- This will disable the preview button --> <h:commandButton id="btn-preview-disabled" styleClass="btn-disabled" value="#{msg.moduleeditor_btn_preview}" rendered="#{!moduleDataEditAction.renderPreviewButton}"> </h:commandButton> <h:inputHidden id="previewLink" value="#{moduleDataEditAction.previewLink}"/> <h:commandButton id="btn-publish" styleClass="btn" action="#{moduleDataEditAction.saveAsPublish}" value="#{msg.moduleeditor_btn_publish}" rendered="#{moduleDataEditAction.renderPublishButton}"> </h:commandButton> <h:commandButton id="btn-publish-disabled" styleClass="btn-disabled" value="#{msg.moduleeditor_btn_publish}" rendered="#{!moduleDataEditAction.renderPublishButton}"> </h:commandButton> <h:commandButton id="btn-save-draft" styleClass="btn" action="#{moduleDataEditAction.saveAsDraft}" rendered="#{moduleDataEditAction.renderSaveDraftButton}" value="#{msg.moduleeditor_btn_save_draft}"> </h:commandButton> <h:commandButton id="btn-save-disabled" styleClass="btn-disabled" value="#{msg.moduleeditor_btn_save_draft}" rendered="#{!moduleDataEditAction.renderSaveDraftButton}"> </h:commandButton> <h:commandButton id="btn-save-template" styleClass="btn" action="#{moduleDataEditAction.saveAsTemplate}" value="#{msg.moduleeditor_btn_save_template}" rendered="#{moduleDataEditAction.renderTemplateButton}"> </h:commandButton> <h:commandButton id="btn-save-template-disabled" styleClass="btn-disabled" value="#{msg.moduleeditor_btn_save_template}" rendered="#{!moduleDataEditAction.renderTemplateButton}"> </h:commandButton> </ui:component>
It seems on each request that the bindings are rebuilt and forces the page refresh, however the action method is being hit:
<h:outputText id="subComponentBuilder" binding="#{moduleDataEditAction.subComponents}" />
<!-- initialise the media library bean -->
<h:outputText id="dummy3" binding="#{mediaAction.dummy}" />
I am using a session scope, Richfaces 4 with myfaces 2.1.2, and spring 3 to manage my beans.
The action method for the the a4j:commandButton id="btn-preview" is as follows:
/** * Build the string for the adSmart link. */ public void preparePreviewLink() { retrieveFieldValues(); String s = moduleEditorService.getSmartString(currentRecordId, currentModuleData); StringBuilder sb = new StringBuilder(); AssetPreview assetPreview = getAssetPreview(); try { sb.append(PropertiesUtils.getProperty("smartad_server_url")); sb.append("?assetId="); sb.append(assetPreview.getAssetId()); sb.append("&smartStr="); sb.append(s); setPreviewLink(sb.toString()); } catch (CMSException e) { addGlobalMessage("dataeditor_preview_url_error",FacesMessage.SEVERITY_ERROR); logError(String.format("(User %s) Preview URL could not be determined! Make sure parameter 'smartad_server_url' in CMS.properties is present!", getCurrentUser().getUsername()),e); } reloadView(); }
This worked fine in richfaces 3.3.3, and this seems like the only lifecycle issue that effects my whole project, which is contained on just this page.
Any suggestions would be great!