Wiki source code of ERPrototaculous
Last modified by Ravi Mendis on 2010/11/18 05:07
Hide last authors
author | version | line-number | content |
---|---|---|---|
![]() |
100.1 | 1 | == Introduction == |
2 | |||
![]() |
318.1 | 3 | ERPrototaculous was developed to provide the ajax functionality in ERDivaLook. It's a //pseudo-stateless// Ajax framework for WebObjects. |
![]() |
209.1 | 4 | |
5 | === What is ERPrototaculous? === | ||
6 | |||
![]() |
233.1 | 7 | Features include: |
![]() |
209.1 | 8 | |
![]() |
319.1 | 9 | * 'Organic' support for [[Prototype>>url:http://www.prototypejs.org/||shape="rect"]] and [[Scriptaculous>>url:http://script.aculo.us/||shape="rect"]] in WebObjects. |
![]() |
283.1 | 10 | ** Light-weight dynamic elements to support Prototype |
![]() |
313.1 | 11 | ** Transparent API that doesn't hide or abstract Prototype and Scriptaculous |
12 | ** Sans patches or extensions to Prototype | ||
![]() |
319.1 | 13 | * Use of [[Unobtrusive Javascript>>url:http://en.wikipedia.org/wiki/Unobtrusive_JavaScript||shape="rect"]]. |
![]() |
261.1 | 14 | * Pseudo-stateless ajax responses |
![]() |
245.1 | 15 | * A set of widgets in the Prototype + Scriptaculous family. |
![]() |
233.1 | 16 | |
17 | ==== Unobtrusive Javascript in ERPrototaculous ==== | ||
18 | |||
![]() |
320.1 | 19 | [[doc:WO.Using Unobtrusive JavaScript]] |
![]() |
233.1 | 20 | |
![]() |
320.1 | 21 | {{include/}} |
22 | |||
![]() |
318.1 | 23 | {{code}} |
24 | |||
25 | er.prototaculous.useUnobtrusively = true | ||
26 | |||
27 | {{/code}} | ||
28 | |||
![]() |
259.1 | 29 | ==== Prototype WebObjects Elements ==== |
![]() |
253.1 | 30 | |
![]() |
319.1 | 31 | {{code language="none"}}Ajax.Updater{{/code}} and {{code language="none"}}Ajax.Request{{/code}} have been implemented as WebObjects elements. |
![]() |
259.1 | 32 | |
![]() |
253.1 | 33 | ===== Ajax.Updater ===== |
34 | |||
![]() |
319.1 | 35 | Support for Prototype's [[Ajax.Updater>>url:http://www.prototypejs.org/api/ajax/updater||shape="rect"]] is in the form of three elements: |
![]() |
253.1 | 36 | |
![]() |
261.1 | 37 | * AjaxUpdaterLink |
38 | * AjaxUpdaterButton | ||
![]() |
319.1 | 39 | * AjaxUpdaterForm (with {{code language="none"}}onsubmit{{/code}} for ajax form submission) |
![]() |
253.1 | 40 | |
![]() |
313.1 | 41 | These components will update //any// **container** on the page: |
![]() |
261.1 | 42 | |
![]() |
319.1 | 43 | {{code 0="javascript"}} |
![]() |
313.1 | 44 | |
45 | new Ajax.Updater('container', url, {options}); | ||
46 | |||
47 | {{/code}} | ||
48 | |||
![]() |
261.1 | 49 | ===== Ajax.Request ===== |
50 | |||
![]() |
319.1 | 51 | Prototype's [[Ajax.Request>>url:http://www.prototypejs.org/api/ajax/request||shape="rect"]] is in the form of: |
![]() |
261.1 | 52 | |
53 | * AjaxRequestLink | ||
54 | * AjaxRequestButton | ||
55 | |||
![]() |
313.1 | 56 | These are used for strictly **background** ajax communication: |
![]() |
261.1 | 57 | |
![]() |
319.1 | 58 | {{code 0="javascript"}} |
![]() |
313.1 | 59 | |
60 | new Ajax.Request(url, {options}); | ||
61 | |||
62 | {{/code}} | ||
63 | |||
![]() |
229.1 | 64 | ==== Prototype + Scriptaculous Widgets ==== |
![]() |
211.1 | 65 | |
![]() |
319.1 | 66 | (% class="alternate" %) |
![]() |
209.1 | 67 | * Accordion |
68 | * LightWindow | ||
69 | * ModalBox | ||
70 | * CalendarDateSelect | ||
![]() |
319.1 | 71 | * [[FileUpload>>url:http://valums.com/ajax-upload/||shape="rect"]] |
![]() |
233.1 | 72 | |
![]() |
313.1 | 73 | Support for these widgets have been similarly implemented as **button** and **link** variants, depending whether it is used inside a form or not. |
![]() |
233.1 | 74 | |
![]() |
313.1 | 75 | == Ajax Forms in ERPrototaculous == |
76 | |||
![]() |
319.1 | 77 | Differences from using forms in WebObjects. i.e {{code language="none"}}WOForm{{/code}}: |
![]() |
233.1 | 78 | |
![]() |
313.1 | 79 | 1. All ajax form controls must be named. This includes text fields, selects and buttons. |
![]() |
319.1 | 80 | (WebObjects dynamically assigned names are not compatible with ERPrototaculous). |
81 | 1. All ajax forms in an ERPrototaculous app need to be instances of {{code language="none"}}AjaxUpdaterForm{{/code}}. | ||
![]() |
313.1 | 82 | 1. Ajax form submit buttons can be a: |
![]() |
319.1 | 83 | 1*. Static {{code language="none"}}<button>{{/code}}. |
![]() |
313.1 | 84 | 1*. WOSubmitButton (if the result is to update whole page/app). |
85 | 1*. AjaxUpdaterButton (to update a **container**). Or | ||
86 | 1*. AjaxRequestButton (for a **background** ajax request). | ||
![]() |
261.1 | 87 | |
![]() |
313.1 | 88 | So forms are different in Ajax.framework and ERPrototaculous. |
![]() |
261.1 | 89 | |
![]() |
313.1 | 90 | In ERPrototaculous you may still have typical WebObjects forms (i.e WOForm) as well as use ajax forms (i.e **AjaxUpdaterForm**). |
![]() |
319.1 | 91 | They behave differently in that an AjaxUpdaterForm will update the contents of a container as opposed to the entire page. |
![]() |
261.1 | 92 | |
![]() |
313.1 | 93 | {{warning title="Warning"}} |
![]() |
319.1 | 94 | You must **name your form controls**, otherwise under certain circumstances Prototype (ajax) form submission will break. |
![]() |
313.1 | 95 | {{/warning}} |
![]() |
283.1 | 96 | |
![]() |
319.1 | 97 | = Embrace Statelessness! = |
![]() |
283.1 | 98 | |
![]() |
320.1 | 99 | [[doc:WO.Embrace Statelessness]] |
![]() |
313.1 | 100 | |
![]() |
320.1 | 101 | {{include/}} |
102 | |||
![]() |
319.1 | 103 | ERPrototaculous embraces the stateless model Ajax offers in exchange for simplifying the work WebObjects has to do - it's a win-win! |
![]() |
313.1 | 104 | |
105 | So you may observe one notable difference between the ERPrototaculous and Ajax frameworks is in the way they handle ajax responses. | ||
![]() |
319.1 | 106 | In ERPrototaculous, updates and actions break with typical WebObjects behavior by being pseudo-stateless. |
![]() |
313.1 | 107 | |
108 | === Ajax Response Handling in ERPrototaculous === | ||
109 | |||
110 | In a typical WebObjects application, when a user navigates to the previous page using the browser back button and subsequently clicks on a link in on that page, WebObjects needs to remember how to handle that action and to return the correct page. This is no longer necessary for ajax. | ||
111 | |||
112 | A user never travels backwards or forwards through the ajax application history. | ||
![]() |
319.1 | 113 | (i.e there is no forward/back buttons for ajax requests - just as there aren't forward/back buttons on desktop apps). |
![]() |
313.1 | 114 | |
115 | So for ajax, the current state of the page fragment component is all that is necessary. | ||
116 | |||
![]() |
319.1 | 117 | {{info title="No More ~"You backtracked too far~""}} |
![]() |
321.1 | 118 | A 100% ajax WO-app (like an [[ERDivaLook>>doc:documentation.Home.Frameworks.ERDivaLook.WebHome]] app) is no longer plagued by the well known //limitation// of WebObjects - the browser **backtrack problem**. |
![]() |
313.1 | 119 | {{/info}} |
120 | |||
121 | == Ajax Actions in ERPrototaculous == | ||
122 | |||
![]() |
283.1 | 123 | Typically, in a WebObjects application, an action would return the contents of the entire page. |
124 | |||
![]() |
313.1 | 125 | Ajax responses are mostly page fragments or just part of a page. |
![]() |
319.1 | 126 | So you should make sure the actions in ERPrototaculous (or AjaxUpdaterButton and AjaxRequestButton) return the proper page fragment as opposed to the entire page. |
127 | This is different to how WebObjects normally works, so this is where you need to be careful. | ||
![]() |
283.1 | 128 | |
![]() |
313.1 | 129 | {{note title="Note"}} |
![]() |
319.1 | 130 | ERPrototaculous actions **differ** from Ajax.framework actions - //They must return only the page fragment//. |
![]() |
283.1 | 131 | {{/note}} |
![]() |
313.1 | 132 | |
133 | To assist with page fragments inside **forms**, you can make your ajax action responses a subclass of **WXPageFragment** (a utility to handle the forms processing between Prototype and WebObjects). | ||
134 | |||
135 | == Update Containers in ERPrototaculous == | ||
136 | |||
137 | Perhaps the only real similarity to Ajax.framework is the ajax update container. | ||
![]() |
319.1 | 138 | **WXGenericContainer** is the ERPrototaculous update container. |
139 | It is similar to an AjaxUpdateContainer when it has the binding {{code language="none"}}ajax = true{{/code}}, otherwise it's pretty much like **WOGenericContainer**. | ||
![]() |
313.1 | 140 | |
![]() |
319.1 | 141 | It has been implemented as a utility or //convenience// for Prototype's {{code language="none"}}Ajax.Updater{{/code}}. |
142 | That is it can be used to update from a DOM //event// like popup //onchange//, or from a Prototype //callback// like //onComplete//, etc. | ||
![]() |
313.1 | 143 | |
144 | == Compatibility == | ||
145 | |||
146 | ERPrototaculous can not be used with WebObjects 5.3 as it is dependent on the hooks for ajax added to WebObjects with version 5.4. | ||
147 | |||
![]() |
319.1 | 148 | {{warning title="ERPrototaculous is WebObjects *5.4* compatible only"/}} |
![]() |
313.1 | 149 | |
![]() |
318.1 | 150 | == External Links == |
151 | |||
![]() |
319.1 | 152 | WOWODC '10 (Slides) - [[DirectToWeb 2.0>>url:http://www.wocommunity.org/wowodc10/slides/D2W2.pdf||shape="rect"]] |