Extra JSF lifecycle after a4j:support
willy_makeit Oct 26, 2007 2:35 PMI have a rather complex JSP that includes an inner JSP with a tabbedPane. The tabbedPane has a tab with a table containing
a link displaying a price which, upon clicking, changes the link to an HtmlInput. The HtmlInput has an a4j:support with an
action that accepts the changed price (recalculating other amounts surrounding the price) and then reRenders the table upon
the 'onChange' event.
Everything works fine - after the event fires the prices/amounts are changed and the table is reRendered with the HtmlInput
reverting back to a link. However, if I then click a button on the parent JSP (to go to the next page, for instance), the
JSP lifecycle steps through each phase but doesn't fire the action tied to the button. Click the button again, and now it
works as expected.
Why the extra lifecycle? Is A4J not finishing something on the a4j:support event that finishes when the button is clicked?
The button on the parent JSP and the included JSP with it's table/links/a4j:support etc., are all under one h:form. Here are
some code snippets:
Rich Column for price on table:
<rich:column> <f:facet name="header"> <h:outputText value="Price"/> </f:facet> <h:commandLink id="linkPropListPrice" value="#{item.proposedDiscountPrice}" rendered="#{!SpreadsheetTabBean.renderProposedPriceInput && !SpreadsheetTabBean.spreadsheet.uploaded}" action="#{SpreadsheetTabBean.showProposedPriceInput}" immediate="true"/> <h:inputText id="inPropListPrice" value="#{item.proposedDiscountPrice}" rendered="#{SpreadsheetTabBean.renderProposedPriceInput}" immediate="true" valueChangeListener="#{SpreadsheetTabBean.listenProposed}" > <a4j:support immediate="true" action="#{SpreadsheetTabBean.changeProposedPrice}" event="onchange" reRender="proposedTable"/> </h:inputText> </rich:column>
Bean methods:
public String changeProposedPrice() { this.setRenderProposedPriceInput(false); spreadsheet.setProposedPriceAt(this.getNewValue(), this.getDiscountLevelChanged()); ssSvc.saveSpreadsheet(spreadsheet); FacesContext context = FacesContext.getCurrentInstance(); context.renderResponse(); return null; } public void listenProposed(ValueChangeEvent e) { BigDecimal bd = (BigDecimal)e.getNewValue(); UIComponent component = e.getComponent(); String id = component.getId(); if (id != null && id.equals("inPropListPrice")) { if (bd.scale() < 2) { bd = bd.setScale(2, RoundingMode.HALF_UP); } } this.setNewValue(bd); PricingModel pm = (PricingModel)proposedModel.getRowData(); this.setDiscountLevelChanged(pm.getDiscountPercent()); }
And here's an a4j:log - Nothing added to the log when the button was clicked -
debug[11:04:15,859]: Have Event [object Object] with properties: target: [object HTMLInputElement], srcElement: undefined, type: change debug[11:04:15,859]: NEW AJAX REQUEST !!! with form :main debug[11:04:15,859]: parameter main:ed:pl:proposedTable:1:_id85 with value main:ed:pl:proposedTable:1:_id85 debug[11:04:15,859]: Start XmlHttpRequest debug[11:04:15,859]: Reqest state : 1 debug[11:04:15,859]: QueryString: AJAXREQUEST=main%3Aed%3Apl%3A_id78&main%3Aed%3A_id63_indexSubmit=&main%3Aed%3Apl%3AproposedTable%3A0%3AinPropListPrice=9.45&main%3Aed%3Apl %3AproposedTable%3A1%3AinPropListPrice=7&main%3Aed%3Apl%3AproposedTable%3A2%3AinPropListPrice=8.55&main%3Aed%3Apl%3AproposedTable%3A3 %3AinPropListPrice=8.10&main%3A_id208=&main%3AstateToken=3&main=main&main%3A_idcl=&main%3Aed%3Apl%3AproposedTable%3A1%3A_id85=main%3Aed %3Apl%3AproposedTable%3A1%3A_id85& debug[11:04:15,859]: Reqest state : 1 debug[11:04:17,515]: Reqest state : 2 debug[11:04:17,515]: Reqest state : 3 debug[11:04:17,515]: Reqest state : 3 debug[11:04:17,515]: Reqest state : 4 debug[11:04:17,515]: Reqest end with state 4 debug[11:04:17,515]: Response with content-type: text/xml;charset=UTF-8 debug[11:04:17,515]: Full response content: <?xml version="1.0"?> <html xmlns="http://www.w3.org/1999/xhtml"><head><link type="text/css" rel="stylesheet" href="/pricemodeling/a4j.res/org/richfaces/renderkit/html/css/table.xcss/DATA/eAFbJaehBAADeAET.jsf" /><script type="text/javascript" src="/pricemodeling/a4j.res/org.ajax4jsf.framework.ajax.AjaxScript.jsf"> </script><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Price Modeling - Spreadsheet Detail</title><link type="text/css" rel="stylesheet" href="../style.css" /></head><body><table cellspacing="0" cellpadding="0" border="0" bgcolor="#007AAD"><tbody><tr align="left" valign="middle"><td align="left"><img src="/kolcStatic/Images/fadebg.jpg" height="50" border="0" alt="(Banner)" /></td></tr><tr><td colspan="3"><img src="/kolcStatic/Images/blackgray.gif" width="100%" height="4" border="0" /></td></tr></tbody></table><center></center> <font class="alertText" size="1" face="Arial, Helvetica, sans-serif"><b>Built:</b> P1-b008 on 23 Oct, 2007 9:00am by Tim Stuck</font> <table class="dr-table rich-table proposedPriceTable" id="main:ed:pl:proposedTable" border="0" cellpadding="0" cellspacing="0"><colgroup span="4"></colgroup><thead><tr class="dr-table-subheader rich-table-subheader dataHeader"><td class="dr-table-subheadercell rich-table-subheadercell dataHeader" scope="col">Level</td><td class="dr-table-subheadercell rich-table-subheadercell dataHeader" scope="col">Price</td><td class="dr-table-subheadercell rich-table-subheadercell dataHeader" scope="col">GM%</td><td class="dr-table-subheadercell rich-table-subheadercell dataHeader" scope="col">%Change</td></tr></thead><tbody><tr class="dr-table-firstrow rich-table-firstrow rowLight"><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id295"><span style="font-style: bold">-5.00</span></td><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id298"><a id="main:ed:pl:proposedTable:0:linkPropListPrice" href="#" onclick="document.forms['main']['main:_idcl'].value='main:ed:pl:proposedTable:0:linkPropListPrice'; document.forms['main'].submit(); return false;">7.35</a></td><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id302"><a id="main:ed:pl:proposedTable:0:linkPropGM" href="#" onclick="document.forms['main']['main:_idcl'].value='main:ed:pl:proposedTable:0:linkPropGM'; document.forms['main'].submit(); return false;">63.27</a></td><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id306"><a id="main:ed:pl:proposedTable:0:linkPropPercentChange" href="#" onclick="document.forms['main']['main:_idcl'].value='main:ed:pl:proposedTable:0:linkPropPercentChange'; document.forms['main'].submit(); return false;">0.27</a></td></tr><tr class="dr-table-firstrow rich-table-firstrow rowDark"><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id295"><span style="font-style: bold">List</span></td><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id298"><a id="main:ed:pl:proposedTable:1:linkPropListPrice" href="#" onclick="document.forms['main']['main:_idcl'].value='main:ed:pl:proposedTable:1:linkPropListPrice'; document.forms['main'].submit(); return false;">7.00</a></td><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id302"><a id="main:ed:pl:proposedTable:1:linkPropGM" href="#" onclick="document.forms['main']['main:_idcl'].value='main:ed:pl:proposedTable:1:linkPropGM'; document.forms['main'].submit(); return false;">61.43</a></td><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id306"><a id="main:ed:pl:proposedTable:1:linkPropPercentChange" href="#" onclick="document.forms['main']['main:_idcl'].value='main:ed:pl:proposedTable:1:linkPropPercentChange'; document.forms['main'].submit(); return false;">0.29</a></td></tr><tr class="dr-table-firstrow rich-table-firstrow rowLight"><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id295"><span style="font-style: bold">5.00</span></td><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id298"><a id="main:ed:pl:proposedTable:2:linkPropListPrice" href="#" onclick="document.forms['main']['main:_idcl'].value='main:ed:pl:proposedTable:2:linkPropListPrice'; document.forms['main'].submit(); return false;">6.65</a></td><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id302"><a id="main:ed:pl:proposedTable:2:linkPropGM" href="#" onclick="document.forms['main']['main:_idcl'].value='main:ed:pl:proposedTable:2:linkPropGM'; document.forms['main'].submit(); return false;">59.40</a></td><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id306"><a id="main:ed:pl:proposedTable:2:linkPropPercentChange" href="#" onclick="document.forms['main']['main:_idcl'].value='main:ed:pl:proposedTable:2:linkPropPercentChange'; document.forms['main'].submit(); return false;">0.30</a></td></tr><tr class="dr-table-firstrow rich-table-firstrow rowDark"><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id295"><span style="font-style: bold">10.00</span></td><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id298"><a id="main:ed:pl:proposedTable:3:linkPropListPrice" href="#" onclick="document.forms['main']['main:_idcl'].value='main:ed:pl:proposedTable:3:linkPropListPrice'; document.forms['main'].submit(); return false;">6.30</a></td><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id302"><a id="main:ed:pl:proposedTable:3:linkPropGM" href="#" onclick="document.forms['main']['main:_idcl'].value='main:ed:pl:proposedTable:3:linkPropGM'; document.forms['main'].submit(); return false;">57.14</a></td><td class="dr-table-cell rich-table-cell" id="main:ed:pl:proposedTable:_id306"><a id="main:ed:pl:proposedTable:3:linkPropPercentChange" href="#" onclick="document.forms['main']['main:_idcl'].value='main:ed:pl:proposedTable:3:linkPropPercentChange'; document.forms['main'].submit(); return false;">0.32</a></td></tr></tbody></table><span id="main:ed:pl:err"></span><meta name="Ajax-Update-Ids" content="main:ed:pl:proposedTable,main:ed:pl:err" /><span id="ajax-update-ids"><input type="hidden" name="jsf_sequence" value="1" /></span><meta id="Ajax-Response" name="Ajax-Response" content="true" /><!-- MYFACES JAVASCRIPT --> </body></html> debug[11:04:17,515]: Update page by list of rendered areas from response main:ed:pl:proposedTable,main:ed:pl:err debug[11:04:17,515]: search for elements by name 'script' in element #document debug[11:04:17,515]: getElementsByTagName found 1 debug[11:04:17,515]: <script> in response with src=/pricemodeling/a4j.res/org.ajax4jsf.framework.ajax.AjaxScript.jsf debug[11:04:17,531]: Such element exist in document debug[11:04:17,531]: search for elements by name 'link' in element #document debug[11:04:17,531]: getElementsByTagName found 2 debug[11:04:17,531]: <link> in response with src=/pricemodeling/a4j.res/org/richfaces/renderkit/html/css/table.xcss/DATA/eAFbJaehBAADeAET.jsf debug[11:04:17,531]: Such element exist in document debug[11:04:17,531]: <link> in response with src=../style.css debug[11:04:17,531]: Such element exist in document debug[11:04:17,531]: Attempt to update part of page for Id: main:ed:pl:proposedTable debug[11:04:17,531]: call getElementById for id= main:ed:pl:proposedTable debug[11:04:17,531]: Replace content of node by replaceChild() debug[11:04:17,531]: search for elements by name 'script' in element table debug[11:04:17,531]: getElementsByTagName found 0 debug[11:04:17,531]: Scripts in updated part count : 0 debug[11:04:17,546]: Update part of page for Id: main:ed:pl:proposedTable successful debug[11:04:17,546]: Attempt to update part of page for Id: main:ed:pl:err debug[11:04:17,546]: call getElementById for id= main:ed:pl:err debug[11:04:17,546]: Replace content of node by replaceChild() debug[11:04:17,546]: search for elements by name 'script' in element span debug[11:04:17,546]: getElementsByTagName found 0 debug[11:04:17,546]: Scripts in updated part count : 0 debug[11:04:17,546]: Update part of page for Id: main:ed:pl:err successful debug[11:04:17,546]: call getElementById for id= ajax-update-ids debug[11:04:17,546]: Hidden JSF state fields: [object HTMLSpanElement] debug[11:04:17,546]: search for elements by name 'input' in element span debug[11:04:17,546]: getElementsByTagName found 1 debug[11:04:17,546]: Replace value for inputs: 17 by new values: 1 debug[11:04:17,546]: Input in response: jsf_sequence debug[11:04:17,546]: search for elements by name 'INPUT' in element span debug[11:04:17,546]: getElementsByTagName found 0 debug[11:04:17,546]: Replace value for inputs: 17 by new values: 0
Thanks for looking at this long post.