You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by de...@apache.org on 2017/09/17 12:29:36 UTC
[myfaces-trinidad] 06/10: Added DOM replace listener and state
change listener support with JSF 2 ajax events
This is an automated email from the ASF dual-hosted git repository.
deki pushed a commit to branch jsf2_ajax
in repository https://gitbox.apache.org/repos/asf/myfaces-trinidad.git
commit 707b01ec44d245c8eacb53548eebc20b87c24686
Author: Andrew Robinson <ar...@apache.org>
AuthorDate: Thu Feb 25 23:43:30 2010 +0000
Added DOM replace listener and state change listener support with JSF 2 ajax events
---
.../src/main/webapp/demos/ajaxPPRDemos.xhtml | 340 +++++++++++----------
.../main/javascript/META-INF/adf/jsLibs/Page.js | 104 ++++++-
2 files changed, 277 insertions(+), 167 deletions(-)
diff --git a/trinidad-examples/trinidad-demo/src/main/webapp/demos/ajaxPPRDemos.xhtml b/trinidad-examples/trinidad-demo/src/main/webapp/demos/ajaxPPRDemos.xhtml
index 46696ce..df31e8f 100644
--- a/trinidad-examples/trinidad-demo/src/main/webapp/demos/ajaxPPRDemos.xhtml
+++ b/trinidad-examples/trinidad-demo/src/main/webapp/demos/ajaxPPRDemos.xhtml
@@ -18,180 +18,190 @@
under the License.
-->
-<ui:composition
- 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:tr="http://myfaces.apache.org/trinidad"
- xmlns:trd="http://myfaces.apache.org/trinidad/demo"
- xmlns:trh="http://myfaces.apache.org/trinidad/html">
- <h:outputScript name="jsf.js" library="javax.faces" target="body" id="os"/>
- <tr:document title="Partial Page Rendering Demos">
- <tr:form>
-
- <tr:panelPage>
- <f:facet name="navigationGlobal">
- <tr:navigationPane hint="buttons">
- <tr:commandNavigationItem text="Return to Feature Demos page"
- immediate="true"
- action="demos"/>
- </tr:navigationPane>
- </f:facet>
- <tr:panelHeader text="Welcome to the Apache Trinidad Partial Page Rendering Demos for JSF 2.0 Ajax">
- <tr:outputFormatted styleUsage="instruction" id="of0"
- value="These demos test Trinidad PPR with JSF 2.0 Ajax using both
- trinidad and JSF components."/>
- <tr:panelGroupLayout layout="vertical">
- <f:facet name="separator">
- <tr:spacer width="30" height="10"/>
- </f:facet>
- <tr:panelHeader text="Command components using JSF 2.0 native Ajax support" id="phCmd">
- <tr:outputFormatted styleUsage="instruction" id="of10"
- value="Tests commandButton components wired to use either Ajax JS API
- by itself or both JSF 2 Ajax and trinidad PPR. Clicking these buttons
- should cause a partial or a full page submit (without errors) and
- update the field on the right."/>
- <tr:spacer height="10" id="sp10"/>
- <tr:panelGroupLayout layout="horizontal" id="pgl10">
- <tr:panelGroupLayout layout="vertical" id="pgl11">
+<ui:composition 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:tr="http://myfaces.apache.org/trinidad"
+ xmlns:trd="http://myfaces.apache.org/trinidad/demo"
+ xmlns:trh="http://myfaces.apache.org/trinidad/html">
+ <tr:document title="Partial Page Rendering Demos"
+ onload="init();">
+ <f:facet name="metaContainer">
+ <tr:group>
+ <trh:script>
+function pprStateChangeFunction(state)
+{
+ var inputText = document.getElementById("it1");
+ if (inputText.value.length)
+ {
+ inputText.value += "\n";
+ }
+ var stateStr = (state == TrRequestQueue.STATE_READY) ? "ready" : "busy";
+ inputText.value += "State has changed to "+stateStr;
+ inputText.scrollTop = inputText.scrollHeight;
+}
+function pprDomReplacementFunction(oldDom, newDom)
+{
+ var inputText = document.getElementById("it1");
+ if (inputText.value.length)
+ {
+ inputText.value += "\n";
+ }
+ if (newDom === document.body)
+ {
+ inputText.value += "Document body was replaced";
+ }
+ else
+ {
+ inputText.value += "DOM element with ID " +
+ newDom.getAttribute("id") + " was replaced";
+ }
+ inputText.scrollTop = inputText.scrollHeight;
+}
+function init()
+{
+ TrPage.getInstance().getRequestQueue().addStateChangeListener(pprStateChangeFunction);
+ TrPage.getInstance().addDomReplaceListener(pprDomReplacementFunction);
+}
+ </trh:script>
+ </tr:group>
+ </f:facet>
+ <tr:form>
+ <tr:panelPage>
+ <f:facet name="navigationGlobal">
+ <tr:panelGroupLayout id="pgl1" layout="horizontal">
+ <f:facet name="separator">
+ <tr:spacer width="10" />
+ </f:facet>
+ <tr:navigationPane hint="buttons">
+ <tr:commandNavigationItem text="Return to Feature Demos page" immediate="true"
+ action="demos"/>
+ </tr:navigationPane>
+ <tr:statusIndicator id="si1" />
+ </tr:panelGroupLayout>
+ </f:facet>
+ <tr:panelHeader text="Welcome to the Apache Trinidad Partial Page Rendering Demos for JSF 2.0 Ajax">
+ <tr:outputFormatted styleUsage="instruction" id="of0"
+ value="These demos test Trinidad PPR with JSF 2.0 Ajax using both trinidad and JSF components."/>
+ <tr:panelGroupLayout layout="vertical">
+ <f:facet name="separator">
+ <tr:spacer width="30" height="10"/>
+ </f:facet>
+ <tr:panelHeader text="Command components using JSF 2.0 native Ajax support" id="phCmd">
+ <tr:outputFormatted styleUsage="instruction" id="of10"
+ value="Tests commandButton components wired to use either Ajax JS API by itself or both JSF 2 Ajax and trinidad PPR. Clicking these buttons should cause a partial or a full page submit (without errors) and update the field on the right."/>
+ <tr:spacer height="10" id="sp10"/>
+ <tr:panelGroupLayout layout="horizontal" id="pgl10">
+ <tr:panelGroupLayout layout="vertical" id="pgl11">
+ <f:facet name="separator">
+ <tr:spacer height="6" id="sp11"/>
+ </f:facet>
+ <tr:outputFormatted styleUsage="instruction"
+ value="tr:commandButton using jsf.ajax.request and partialSubmit=true."
+ id="of11"/>
+ <tr:commandButton id="axBtn1" partialSubmit="true" text="Partial Submit"
+ shortDesc="partialSubmit"
+ actionListener="#{partialDemoUtil.action}"/>
+ <!--f:ajax event="action" render=""/-->
+ <tr:outputFormatted styleUsage="instruction"
+ value="tr:commandButton using jsf.ajax.request." id="of12"/>
+ <tr:commandButton id="axBtn2" text="Full Submit" shortDesc="fullSubmit"
+ actionListener="#{partialDemoUtil.action}"/>
+ <tr:outputFormatted styleUsage="instruction"
+ value="h:commandButton using jsf.ajax.request." id="of13"/>
+ </tr:panelGroupLayout>
+ <tr:spacer width="30" height="10" id="sp12"/>
+ <tr:panelGroupLayout id="pgl12">
+ <tr:panelLabelAndMessage label="Button Clicked: " id="plm10">
+ <tr:outputFormatted id="btnTarget" partialTriggers="axBtn1 axBtn2"
+ styleUsage="instruction"
+ value="#{partialDemoUtil.status.linkUpdate}">
+ <f:convertDateTime pattern="HH:mm:ss"/>
+ </tr:outputFormatted>
+ </tr:panelLabelAndMessage>
+ </tr:panelGroupLayout>
+ </tr:panelGroupLayout>
+ </tr:panelHeader>
+ <tr:panelHeader text="InputText Component using JSF 2.0 Ajax" id="phInput">
+ <tr:outputFormatted styleUsage="instruction"
+ value="Tests autoSubmitting text fields which is also wired to use JSF 2.0 Ajax."/>
+ <tr:panelGroupLayout layout="horizontal" id="pgl20">
<f:facet name="separator">
- <tr:spacer height="6" id="sp11"/>
+ <tr:spacer height="10" id="sp20"/>
</f:facet>
- <tr:outputFormatted styleUsage="instruction" value="tr:commandButton using
- jsf.ajax.request and partialSubmit=true." id="of11"/>
- <tr:commandButton id="axBtn1"
- partialSubmit="true"
- text="Partial Submit"
- shortDesc="partialSubmit"
- actionListener="#{partialDemoUtil.action}"/>
- <!--f:ajax event="action" render=""/-->
- <tr:outputFormatted styleUsage="instruction" value="tr:commandButton using jsf.ajax.request."
- id="of12"/>
- <tr:commandButton id="axBtn2"
- text="Full Submit"
- shortDesc="fullSubmit"
- actionListener="#{partialDemoUtil.action}"/>
-
- <tr:outputFormatted styleUsage="instruction" value="h:commandButton using jsf.ajax.request."
- id="of13"/>
-
-
+ <tr:panelGroupLayout layout="vertical" id="pgl21">
+ <f:facet name="separator">
+ <tr:spacer height="6" id="sp21"/>
+ </f:facet>
+ <tr:outputFormatted styleUsage="instruction"
+ value="tr:inputText with autoSubmit=true."
+ id="of20"/>
+ <tr:inputText id="itxt1" autoSubmit="true"
+ value="#{partialDemoUtil.status.textValue}"
+ label="Enter text and tab out: "
+ valueChangeListener="#{partialDemoUtil.valueChanged}"/>
+ <tr:outputFormatted styleUsage="instruction"
+ value="tr:inputText with autoSubmit=true inside a subform"
+ id="of21"/>
+ <tr:subform id="sf20">
+ <tr:inputText autoSubmit="true" id="itxt2"
+ label="Enter a different text and tab out: "
+ value="#{partialDemoUtil.status.textValue}"
+ valueChangeListener="#{partialDemoUtil.valueChanged}"/>
+ </tr:subform>
+ </tr:panelGroupLayout>
+ <tr:panelLabelAndMessage label="Input entered: ">
+ <tr:outputFormatted id="itTarget" partialTriggers="itxt1 ::sf20:itxt2"
+ styleUsage="instruction"
+ value="#{partialDemoUtil.status.textStateText}"/>
+ </tr:panelLabelAndMessage>
</tr:panelGroupLayout>
-
- <tr:spacer width="30" height="10" id="sp12"/>
-
- <tr:panelGroupLayout id="pgl12">
- <tr:panelLabelAndMessage label="Button Clicked: " id="plm10">
- <tr:outputFormatted id="btnTarget"
- partialTriggers="axBtn1 axBtn2"
- styleUsage="instruction"
- value="#{partialDemoUtil.status.linkUpdate}">
+ </tr:panelHeader>
+ <tr:panelHeader text="Radio Buttons">
+ <tr:outputFormatted styleUsage="instruction"
+ value="This demo shows a two sets of radio buttons which use autoSubmit. There is also an output component which is listening on updates to the radio buttons and displaying status text accordingly."/>
+ <tr:panelGroupLayout layout="horizontal">
+ <tr:panelGroupLayout layout="vertical">
+ <tr:panelGroupLayout layout="horizontal">
+ <tr:outputFormatted styleUsage="instruction"
+ value="selectBooleanRadio buttons"/>
+ <tr:panelGroupLayout layout="vertical">
+ <tr:selectBooleanRadio id="sbr1" group="theGroup" selected="false"
+ text="item 1" autoSubmit="true"
+ valueChangeListener="#{partialDemoUtil.valueChanged}"/>
+ <tr:selectBooleanRadio id="sbr2" group="theGroup" text="item 2"
+ selected="false" autoSubmit="true"
+ valueChangeListener="#{partialDemoUtil.valueChanged}"/>
+ <tr:selectBooleanRadio id="sbr3" group="theGroup" text="item 3"
+ selected="false" autoSubmit="true"
+ valueChangeListener="#{partialDemoUtil.valueChanged}"/>
+ </tr:panelGroupLayout>
+ </tr:panelGroupLayout>
+ <tr:spacer width="30" height="10"/>
+ <tr:panelGroupLayout layout="vertical">
+ <tr:selectOneRadio id="sor1" label="selectOneRadio buttons" autoSubmit="true"
+ valueChangeListener="#{partialDemoUtil.valueChanged}">
+ <tr:selectItem label="item 1" value="1"/>
+ <tr:selectItem label="item 2" value="2"/>
+ <tr:selectItem label="item 3" value="3"/>
+ </tr:selectOneRadio>
+ </tr:panelGroupLayout>
+ </tr:panelGroupLayout>
+ <tr:spacer width="30" height="10"/>
+ <tr:panelLabelAndMessage label="Selected: ">
+ <tr:outputFormatted id="rbTarget" partialTriggers="sbr1 sbr2 sbr3 sor1"
+ styleUsage="instruction"
+ value="#{partialDemoUtil.status.radioStateText}">
<f:convertDateTime pattern="HH:mm:ss"/>
</tr:outputFormatted>
</tr:panelLabelAndMessage>
- </tr:panelGroupLayout>
- </tr:panelGroupLayout>
- </tr:panelHeader>
-
- <tr:panelHeader text="InputText Component using JSF 2.0 Ajax" id="phInput">
- <tr:outputFormatted styleUsage="instruction"
- value="Tests autoSubmitting text fields which is also wired to use JSF
- 2.0 Ajax."/>
- <tr:panelGroupLayout layout="horizontal" id="pgl20">
- <f:facet name="separator">
- <tr:spacer height="10" id="sp20"/>
- </f:facet>
- <tr:panelGroupLayout layout="vertical" id="pgl21">
- <f:facet name="separator">
- <tr:spacer height="6" id="sp21"/>
- </f:facet>
- <tr:outputFormatted styleUsage="instruction" value="tr:inputText with
- autoSubmit=true." id="of20"/>
- <tr:inputText id="itxt1"
- autoSubmit="true"
- value="#{partialDemoUtil.status.textValue}"
- label="Enter text and tab out: "
- valueChangeListener="#{partialDemoUtil.valueChanged}"/>
- <tr:outputFormatted styleUsage="instruction" value="tr:inputText with
- autoSubmit=true inside a subform" id="of21"/>
- <tr:subform id="sf20">
- <tr:inputText autoSubmit="true" id="itxt2" label="Enter a different text and tab out: "
- value="#{partialDemoUtil.status.textValue}"
- valueChangeListener="#{partialDemoUtil.valueChanged}"/>
- </tr:subform>
</tr:panelGroupLayout>
-
- <tr:panelLabelAndMessage label="Input entered: ">
- <tr:outputFormatted id="itTarget"
- partialTriggers="itxt1 ::sf20:itxt2"
- styleUsage="instruction"
- value="#{partialDemoUtil.status.textStateText}"/>
- </tr:panelLabelAndMessage>
- </tr:panelGroupLayout>
- </tr:panelHeader>
-
- <tr:panelHeader text="Radio Buttons">
- <tr:outputFormatted styleUsage="instruction"
- value="This demo shows a two sets of radio buttons which use autoSubmit.
- There is also an output component which is listening on updates to the
- radio buttons and displaying status text accordingly."/>
- <tr:panelGroupLayout layout="horizontal">
- <tr:panelGroupLayout layout="vertical">
- <tr:panelGroupLayout layout="horizontal">
- <tr:outputFormatted styleUsage="instruction"
- value="selectBooleanRadio buttons"/>
- <tr:panelGroupLayout layout="vertical">
- <tr:selectBooleanRadio id="sbr1"
- group="theGroup"
- selected="false"
- text="item 1"
- autoSubmit="true"
- valueChangeListener="#{partialDemoUtil.valueChanged}"/>
- <tr:selectBooleanRadio id="sbr2"
- group="theGroup"
- text="item 2"
- selected="false"
- autoSubmit="true"
- valueChangeListener="#{partialDemoUtil.valueChanged}"/>
- <tr:selectBooleanRadio id="sbr3"
- group="theGroup"
- text="item 3"
- selected="false"
- autoSubmit="true"
- valueChangeListener="#{partialDemoUtil.valueChanged}"/>
- </tr:panelGroupLayout>
- </tr:panelGroupLayout>
- <tr:spacer width="30" height="10"/>
- <tr:panelGroupLayout layout="vertical">
- <tr:selectOneRadio id="sor1"
- label="selectOneRadio buttons"
- autoSubmit="true"
- valueChangeListener="#{partialDemoUtil.valueChanged}">
- <tr:selectItem label="item 1" value="1" />
- <tr:selectItem label="item 2" value="2" />
- <tr:selectItem label="item 3" value="3" />
- </tr:selectOneRadio>
- </tr:panelGroupLayout>
- </tr:panelGroupLayout>
- <tr:spacer width="30" height="10"/>
- <tr:panelLabelAndMessage label="Selected: ">
- <tr:outputFormatted id="rbTarget"
- partialTriggers="sbr1 sbr2 sbr3 sor1"
- styleUsage="instruction"
- value="#{partialDemoUtil.status.radioStateText}">
- <f:convertDateTime pattern="HH:mm:ss"/>
- </tr:outputFormatted>
- </tr:panelLabelAndMessage>
+ </tr:panelHeader>
</tr:panelGroupLayout>
- </tr:panelHeader>
-
-
- </tr:panelGroupLayout>
- </tr:panelHeader>
- </tr:panelPage>
-
+ <tr:panelLabelAndMessage id="plam1" label="Ajax Status Log">
+ <tr:inputText id="it1" value="" simple="true" rows="7" columns="100" />
+ </tr:panelLabelAndMessage>
+ </tr:panelHeader>
+ </tr:panelPage>
</tr:form>
-
</tr:document>
</ui:composition>
\ No newline at end of file
diff --git a/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/Page.js b/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/Page.js
index b9fb298..fcc8288 100644
--- a/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/Page.js
+++ b/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/Page.js
@@ -802,13 +802,113 @@ TrPage._delegateToJSFAjax = function(formId, inputId, event, params)
TrPage.prototype._jsfAjaxCallback = function(data)
{
- if (data.status == "complete")
+ // TODO: move this code into the request queue to stop this gross infringement
+ // of encapsulation
+ switch (data.status)
{
- _pprStopBlocking(window);
+ case "begin":
+ this._requestQueue._state = TrRequestQueue.STATE_BUSY;
+ this._requestQueue._broadcastStateChangeEvent(this._requestQueue._state);
+ break;
+ case "success":
+ try
+ {
+ this._notifyDomReplacementListeners(this._ajaxOldDomElements);
+ }
+ finally
+ {
+ delete this._ajaxOldDomElements;
+ }
+ this._requestQueue._state = TrRequestQueue.STATE_READY;
+ this._requestQueue._broadcastStateChangeEvent(this._requestQueue._state);
+ break;
+ case "complete": default:
+ _pprStopBlocking(window);
+ // Collect the DOM elements that will be replaced to be able to fire the
+ // DOM replacement events
+ this._ajaxOldDomElements = this._getDomToBeUpdated(data.responseCode, data.responseXML);
+ break;
}
}
TrPage.prototype._jsfAjaxErrorCallback = function(data)
{
+ // TODO: move this code into the request queue to stop this gross infringement
+ // of encapsulation
+ this._requestQueue._state = TrRequestQueue.STATE_READY;
+ this._requestQueue._broadcastStateChangeEvent(this._requestQueue._state);
+ delete this._ajaxOldDomElements;
+}
+
+TrPage.prototype._notifyDomReplacementListeners = function(dataArray)
+{
+ var listeners = this._domReplaceListeners;
+ if (!listeners || listeners.length == 0)
+ {
+ return;
+ }
+ for (var i = 0, isize = dataArray.length; i < isize; ++i)
+ {
+ var oldElem = dataArray[i].element;
+ var id = dataArray[i].id;
+ var newElem = id == null ? document.body : document.getElementById(id);
+ for (var j = 0, jsize = listeners.length; j < jsize; ++j)
+ {
+ var currListener = listeners[j];
+ var currInstance = listeners[++j];
+ if (currInstance != null)
+ {
+ currListener.call(currInstance, oldElem, newElem);
+ }
+ else
+ {
+ currListener(oldElem, newElem);
+ }
+ }
+ }
+}
+
+TrPage.prototype._getDomToBeUpdated = function(status, responseXML)
+{
+ // check for a successful request
+ if (status < 200 || status >= 300)
+ {
+ return null;
+ }
+ // see if the response contains changes (not a redirect for example)
+ var nodes = responseXML.getElementsByTagName("partial-response");
+ var responseTypeNode = nodes.length ? nodes[0].firstChild : null;
+ if (!responseTypeNode || responseTypeNode.nodeName !== "changes")
+ {
+ return null;
+ }
+
+ var changeNodes = responseTypeNode.childNodes;
+ var oldElements = [];
+ for (var i = 0, size = changeNodes.length; i < size; ++i)
+ {
+ var node = changeNodes[i];
+ if (node.nodeName !== "update")
+ {
+ // We only care about updates as that is what Trinidad supported for the DOM
+ // replacement notification API
+ continue;
+ }
+
+ var id = node.getAttribute("id");
+ if (id == "javax.faces.ViewState")
+ {
+ continue;
+ }
+ if (id == "javax.faces.ViewRoot" || id == "javax.faces.ViewBody")
+ {
+ oldElements.push({ "id": null, "element": document.body });
+ }
+ else
+ {
+ oldElements.push({ "id": id, "element": document.getElementById(id) });
+ }
+ }
+ return oldElements;
}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
"commits@myfaces.apache.org" <co...@myfaces.apache.org>.