Commit | Line | Data |
720accfe |
1 | <html> |
2 | <head> |
3 | <script language="javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.2.6.js"></script> |
4 | <script language="javascript"> |
5 | |
6 | /* |
7 | |
8 | COPYRIGHT AND LICENCE |
9 | |
10 | Copyright (C) 2006-2008 Infinity Interactive, Inc. |
11 | |
12 | http://www.iinteractive.com |
13 | |
14 | This library is free software; you can redistribute it |
15 | and/or modify it under the same terms as Perl itself. |
16 | |
17 | */ |
18 | |
19 | /**************** Templating Objects ****************/ |
20 | |
21 | function Param (value) { this.value = value } |
22 | Param.prototype.find_and_replace = function (template, selector, value) { |
23 | template.find(selector) |
24 | .each(function () { jQuery(this).html(value) }) |
25 | } |
26 | Param.prototype.render = function (template, selector) { |
27 | this.find_and_replace(template, selector, this.value); |
28 | } |
29 | |
30 | function Thunk (func) { |
31 | this.func = func; |
32 | } |
33 | Thunk.prototype = new Param (); |
34 | Thunk.prototype.render = function (template, selector) { |
35 | this.find_and_replace( |
36 | template, |
37 | selector, |
38 | this.func(template, selector) |
39 | ); |
40 | } |
41 | |
42 | function MethodThunk (invocant, method_name) { |
43 | this.func = function () { return invocant[method_name]() } |
44 | } |
45 | MethodThunk.prototype = new Thunk (); |
46 | |
47 | function PropertyThunk (invocant, property_name) { |
48 | this.func = function () { return invocant[property_name] } |
49 | } |
50 | PropertyThunk.prototype = new Thunk (); |
51 | |
52 | function Collection (params) { |
53 | this.css_selector = params['css_selector']; |
54 | this.values = params['values']; |
55 | this.transformer = params['transformer']; |
56 | } |
57 | Collection.prototype = new Param (); |
58 | Collection.prototype.get_values = function () { |
59 | return (this.transformer == undefined) |
60 | ? this.values |
61 | : jQuery.map(this.values, this.transformer) |
62 | } |
63 | Collection.prototype.render = function (template, selector) { |
64 | var selection = template.find(selector).find(this.css_selector); |
65 | var target = selection.parent(); |
66 | target.empty(); |
67 | jQuery.each( |
68 | this.get_values(), |
69 | function () { |
70 | target.append( |
71 | selection.clone(true).process_template(this) |
72 | ) |
73 | } |
74 | ); |
75 | } |
76 | |
77 | function Hierarchy (params) { |
78 | this.list_selector = params['list_selector']; |
79 | this.item_selector = params['item_selector']; |
80 | this.values = params['values']; |
81 | } |
82 | Hierarchy.prototype = new Param (); |
83 | Hierarchy.prototype.get_values = function () { return this.values } |
84 | Hierarchy.prototype.render = function (template, selector) { |
85 | var selection = template.find(selector); |
86 | var list_selection = selection.find(this.list_selector); |
87 | var item_selection = selection.find(this.item_selector); |
88 | |
89 | selection.empty(); |
90 | list_selection.empty(); |
91 | |
92 | var traverse = function (element, tree) { |
93 | // build a node ... |
94 | var node_element = item_selection.clone(true).process_template( |
95 | tree['node'] |
96 | ); |
97 | element.append(node_element); |
98 | // if the node has children then ... |
99 | if (tree['children'] != undefined) { |
100 | var new_element = list_selection.clone(true); |
101 | jQuery.each( |
102 | tree['children'], |
103 | function () { |
104 | traverse(new_element, this); |
105 | node_element.append(new_element); |
106 | } |
107 | ); |
108 | } |
109 | }; |
110 | |
111 | // create the root ... |
112 | var root_node = list_selection.clone(true); |
113 | traverse(root_node, this.get_values()); |
114 | selection.append(root_node); |
115 | } |
116 | |
117 | /************* JQuery Plugin *******************/ |
118 | |
119 | jQuery.fn.extend({ |
120 | process_template : function (params) { |
121 | var template = this; |
122 | jQuery.each( |
123 | params, |
124 | function (selector, param) { |
125 | ((typeof param == 'object') |
126 | ? param |
127 | : new Param (param)).render(template, selector) |
128 | } |
129 | ); |
130 | return template; |
131 | } |
132 | }); |
133 | |
134 | /********************** Paramters ***************************/ |
135 | |
136 | function User (name) { |
137 | this._name = name; |
138 | } |
139 | User.prototype.name = function () { return this._name } |
140 | |
141 | function Product (id, name) { |
142 | this._id = id; |
143 | this.name = name; |
144 | } |
145 | Product.prototype.get_id = function () { return this._id } |
146 | |
147 | var params = { |
148 | '#logo' : new Thunk (function (t, selector) { |
149 | t.find(selector).attr({ |
150 | 'src' : 'http://iinteractive.com/images/logo.gif', |
151 | 'style' : 'padding: 10px;', |
152 | }); |
153 | }), |
154 | '.username' : new MethodThunk (new User ('Stevan'), "name"), |
155 | '#user_quotation' : 'JQuery Rocks', |
156 | '.copyright' : new Thunk (function () { return "Copyright (c) " + (new Date ()).getFullYear() }), |
157 | '#products' : new Collection ({ |
158 | css_selector : '.row', |
159 | values : [ |
160 | new Product (10, 'Foo'), |
161 | new Product (11, 'Bar'), |
162 | new Product (12, 'Baz'), |
163 | ], |
164 | transformer : function (val) { |
165 | return { |
166 | '.id' : val.get_id(), |
167 | '.name' : new PropertyThunk (val, 'name'), |
168 | } |
169 | } |
170 | }), |
171 | '#dogs' : new Collection ({ |
172 | css_selector : '.table_row', |
173 | values : [ |
174 | { '.sound' : "Bark" }, |
175 | { '.sound' : "Woof" }, |
176 | ] |
177 | }), |
178 | '#cats' : new Hierarchy ({ |
179 | list_selector : '.list', |
180 | item_selector : '.item', |
181 | values : { |
182 | node : { '.name' : "Twinkles" }, |
183 | children : [ |
184 | { node : { '.name' : "Shnuckums" } }, |
185 | { |
186 | node : { '.name' : "Bilbo" }, |
187 | children : [ |
188 | { |
189 | node : { '.name' : "Dweezil" }, |
190 | children : [ |
191 | { node : { '.name' : "Tabby" } }, |
192 | ] |
193 | }, |
194 | { node : { '.name' : "Abraxas" } }, |
195 | ] |
196 | }, |
197 | ] |
198 | } |
199 | }), |
200 | '#rooms' : new Hierarchy ({ |
201 | list_selector : '.list', |
202 | item_selector : '.item', |
203 | values : { |
204 | node : { '.name' : "Ceiling" }, |
205 | children : [ |
206 | { node : { '.name' : "Basement" } }, |
207 | { |
208 | node : { '.name' : "Garage" }, |
209 | children : [ |
210 | { node : { '.name' : "Root Cellar" } }, |
211 | { |
212 | node : { '.name' : "Kitchen" }, |
213 | children : [ |
214 | { node : { '.name' : "Under The Stairs" } }, |
215 | ] |
216 | }, |
217 | { node : { '.name' : "Bathroom" } }, |
218 | ] |
219 | }, |
220 | ] |
221 | } |
222 | }), |
223 | }; |
224 | |
225 | $(document).ready(function () { |
226 | $('body').process_template(params); |
227 | }); |
228 | |
229 | </script> |
230 | </head> |
231 | <body> |
232 | <img id="logo" src="http://l.yimg.com/a/i/ww/beta/y3.gif" border="1" /> |
233 | <hr/> |
234 | <div class="username">Foo</div> |
235 | <hr/> |
236 | <p id="user_quotation">Text goes here</p> |
237 | <div id="products" style="border: 1px solid grey; width: 250px"> |
238 | <div class="row" style="border: 1px solid red; padding: 2px; margin: 2px;"> |
239 | <span class="id">ID</span> |
240 | <span class="name">NAME</span> |
241 | </div> |
242 | </div> |
243 | <br/> |
244 | <table id="dogs" border="1"> |
245 | <thead> |
246 | <th>Hello</th> |
247 | </thead> |
248 | <tbody> |
249 | <tr class="table_row"> |
250 | <td>My dog says <span class="sound">NAME</span></td> |
251 | </tr> |
252 | </tbody> |
253 | </table> |
254 | <hr/> |
255 | <div id="cats"> |
256 | <ul class="list"> |
257 | <li class="item">My cat is named <span class="name">NAME</span></li> |
258 | </ul> |
259 | </div> |
260 | <hr/> |
261 | <div id="rooms"> |
262 | <div class="list" style="padding-left: 10px"> |
263 | <div class="item" style="padding-left: 10px">My room is <span class="name">NAME</span></div> |
264 | </div> |
265 | </div> |
266 | <hr/> |
267 | <div class="username">Foo</div> |
268 | <hr/> |
269 | <div class="copyright">Copyleft</div> |
270 | </body> |
271 | </html> |