Wiki source code of ERPrototaculous
Version 200.1 by Ravi Mendis on 2009/07/17 06:30
Show last authors
author | version | line-number | content |
---|---|---|---|
1 | == Introduction == | ||
2 | |||
3 | ERPrototaculous was developed to provide the ajax functionality in ERDivaLook. | ||
4 | |||
5 | === What is ERPrototaculous? === | ||
6 | |||
7 | Features include: | ||
8 | |||
9 | * 'Organic' support for Prototype and Scriptaculous in WebObjects. | ||
10 | ** Light-weight dynamic elements to support Prototype | ||
11 | ** No custom patches to Prototype | ||
12 | ** Sans the need to extend Prototype | ||
13 | * Use of [[Unobtrusive Javascript>>http://en.wikipedia.org/wiki/Unobtrusive_JavaScript]]. | ||
14 | * Pseudo-stateless ajax responses | ||
15 | * A set of widgets in the Prototype + Scriptaculous family. | ||
16 | |||
17 | ==== Unobtrusive Javascript in ERPrototaculous ==== | ||
18 | |||
19 | Unobtrusive javascript is used in contrast to on-demand style of ajax programming. | ||
20 | By including Javascript as well as CSS globally in the page wrapper, CSS and Javascript don't have to load inside each and every ajax requests. | ||
21 | This keeps the ajax responses compact and granular. | ||
22 | |||
23 | The result is **faster** and more **reliable** ajax in WebObjects. | ||
24 | |||
25 | ==== Prototype WebObjects Elements ==== | ||
26 | |||
27 | ##Ajax.Updater## and ##Ajax.Request## have been implemented as WebObjects dynamic elements. | ||
28 | |||
29 | ===== Ajax.Updater ===== | ||
30 | |||
31 | Support for Prototype's [[Ajax.Updater>>http://www.prototypejs.org/api/ajax/updater]] is in the form of three components: | ||
32 | |||
33 | * AjaxUpdaterLink | ||
34 | * AjaxUpdaterButton | ||
35 | * AjaxUpdaterForm (with ##onsubmit## for ajax form submission) | ||
36 | |||
37 | These components will update a **container** on the page: | ||
38 | |||
39 | {{code value="javascript"}} | ||
40 | |||
41 | new Ajax.Updater('container', url, {options}); | ||
42 | |||
43 | {{/code}} | ||
44 | |||
45 | ===== Ajax.Request ===== | ||
46 | |||
47 | Prototype's [[Ajax.Request>>http://www.prototypejs.org/api/ajax/request]] is in the form of: | ||
48 | |||
49 | * AjaxRequestLink | ||
50 | * AjaxRequestButton | ||
51 | |||
52 | These are used for strictly **background** ajax communication: | ||
53 | |||
54 | {{code value="javascript"}} | ||
55 | |||
56 | new Ajax.Request(url, {options}); | ||
57 | |||
58 | {{/code}} | ||
59 | |||
60 | ==== Prototype + Scriptaculous Widgets ==== | ||
61 | |||
62 | * Accordion | ||
63 | * LightWindow | ||
64 | * ModalBox | ||
65 | * CalendarDateSelect | ||
66 | * FileUpload | ||
67 | |||
68 | Support for these widgets have been similarly implemented as **button** and **link** variants, depending whether it is used inside a form or not. | ||
69 | |||
70 | == Ajax Forms in ERPrototaculous == | ||
71 | |||
72 | Differences from using forms in WebObjects. i.e ##WOForm##: | ||
73 | |||
74 | 1. All form controls must be named. This includes text fields, selects and buttons. | ||
75 | (WebObjects dynamically assigned names are not compatible with ERPrototaculous). | ||
76 | 1. All ajax forms in an ERPrototaculous app need to be instances of ##AjaxUpdaterForm##. | ||
77 | 1. Form submit buttons can be a: | ||
78 | |||
79 | * | ||
80 | ** Static ##<button>##. | ||
81 | ** WOSubmitButton (if the result is to update whole page/app). | ||
82 | ** AjaxUpdaterButton (to update a **container**). Or | ||
83 | ** AjaxRequestButton (for a **background** ajax request). | ||
84 | |||
85 | So forms are different in Ajax.framework and ERPrototaculous. | ||
86 | |||
87 | In ERPrototaculous you may still have typical WebObjects forms (i.e WOForm) as well as use ajax forms (i.e **AjaxUpdaterForm**). | ||
88 | They behave differently in that an AjaxUpdaterForm will update the contents of a container as opposed to the entire page. | ||
89 | |||
90 | == Ajax Response Handling in ERPrototaculous == | ||
91 | |||
92 | One notable difference between the ERPrototaculous and Ajax frameworks is in the way they handle ajax responses. | ||
93 | In ERPrototaculous, updates and actions break with "The WebObjects Way" by being pseudo-stateless. | ||
94 | |||
95 | WebObjects typically vends a fresh response for each and every action. With ajax, this is not necessary. | ||
96 | |||
97 | In a typical WebObjects application, when a user clicks on the back button and clicks on a link in on that page in the browser history, WebObjects needs to remember how to handle that action and to return the correct page. This is no longer true for ajax. | ||
98 | The reason is a user never travels backwards or forwards through the ajax application history. | ||
99 | (i.e there is no forward/back buttons in a 100% ajax app - as there aren't in desktop apps). | ||
100 | |||
101 | So for ajax, the current state of the page fragment component is all that is necessary. | ||
102 | |||
103 | == Ajax Actions in ERPrototaculous == | ||
104 | |||
105 | Typically, in a WebObjects application, an action would return the contents of the entire page. | ||
106 | |||
107 | Ajax responses are mostly page fragments or just part of a page. | ||
108 | So you should make sure the actions in ERPrototaculous (or AjaxUpdaterButton and AjaxRequestButton) return the proper page fragment as opposed to the entire page. | ||
109 | This breaks with WO-tradition, so this is where you need to be careful. | ||
110 | |||
111 | {{note title="Actions"}} | ||
112 | |||
113 | ERPrototaculous actions *differ* from Ajax.framework actions - _They must return only the page fragment_. | ||
114 | |||
115 | {{/note}} | ||
116 | |||
117 | 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). | ||
118 | |||
119 | == Update Containers in ERPrototaculous == | ||
120 | |||
121 | Perhaps the only real similarity to Ajax.framework is the ajax update container. | ||
122 | **WXGenericContainer** is the ERPrototaculous update container. | ||
123 | It is similar to an AjaxUpdateContainer when it has the binding ##ajax = true##, otherwise it's pretty much like **WOGenericContainer**. | ||
124 | |||
125 | It has been implemented as a utility or //convenience// for Prototype's ##Ajax.Updater##. |