|
1 <!DOCTYPE html> |
|
2 <html lang="en"> |
|
3 <head> |
|
4 <meta charset="utf-8"> |
|
5 <title>Example: Adding New Object Members During Parsing</title> |
|
6 <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=PT+Sans:400,700,400italic,700italic"> |
|
7 <link rel="stylesheet" href="../../build/cssgrids/cssgrids-min.css"> |
|
8 <link rel="stylesheet" href="../assets/css/main.css"> |
|
9 <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css"> |
|
10 <link rel="shortcut icon" type="image/png" href="../assets/favicon.png"> |
|
11 <script src="../../build/yui/yui-min.js"></script> |
|
12 |
|
13 </head> |
|
14 <body> |
|
15 <!-- |
|
16 <a href="https://github.com/yui/yui3"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a> |
|
17 --> |
|
18 <div id="doc"> |
|
19 <div id="hd"> |
|
20 <h1><img src="http://yuilibrary.com/img/yui-logo.png"></h1> |
|
21 </div> |
|
22 |
|
23 |
|
24 <h1>Example: Adding New Object Members During Parsing</h1> |
|
25 <div class="yui3-g"> |
|
26 <div class="yui3-u-3-4"> |
|
27 <div id="main"> |
|
28 <div class="content"><div class="intro"> |
|
29 <p> |
|
30 This example shows how to use the <code>reviver</code> parameter in <code>JSON.parse()</code> to add new object members and format existing members during the parsing phase. |
|
31 </p> |
|
32 </div> |
|
33 |
|
34 <div class="example yui3-skin-sam"> |
|
35 <div id="demo"> |
|
36 <p>Choose a currency, then get the data</p> |
|
37 <select> |
|
38 <option value="ARS">Argentine Peso</option> |
|
39 <option value="AUD">Australian Dollar</option> |
|
40 <option value="BRL">Brazilian Real</option> |
|
41 <option value="GBP">British Pound</option> |
|
42 <option value="CAD">Canadian Dollar</option> |
|
43 <option value="CNY">Chinese Yuan</option> |
|
44 <option value="COP">Colombian Peso</option> |
|
45 <option value="HRK">Croatian Kuna</option> |
|
46 <option value="CZK">Czech Koruna</option> |
|
47 <option value="DKK">Danish Krone</option> |
|
48 <option value="EEK">Estonian Kroon</option> |
|
49 <option value="EUR">Euro</option> |
|
50 <option value="HKD">Hong Kong Dollar</option> |
|
51 <option value="HUF">Hungarian Forint</option> |
|
52 <option value="ISK">Iceland Krona</option> |
|
53 <option value="INR">Indian Rupee</option> |
|
54 <option value="JPY">Japanese Yen</option> |
|
55 <option value="KRW">Korean Won</option> |
|
56 <option value="LVL">Latvian Lat</option> |
|
57 <option value="LTL">Lithuanian Lita</option> |
|
58 <option value="MYR">Malaysian Ringgit</option> |
|
59 <option value="MXN">Mexican Peso</option> |
|
60 <option value="NZD">New Zealand Dollar</option> |
|
61 <option value="NOK">Norwegian Krone</option> |
|
62 <option value="PHP">Philippine Peso</option> |
|
63 <option value="PLN">Polish Zloty</option> |
|
64 <option value="RUB">Russian Rouble</option> |
|
65 <option value="SGD">Singapore Dollar</option> |
|
66 <option value="SKK">Slovak Koruna</option> |
|
67 <option value="ZAR">South African Rand</option> |
|
68 <option value="LKR">Sri Lanka Rupee</option> |
|
69 <option value="SEK">Swedish Krona</option> |
|
70 <option value="TRY">Turkey Lira</option> |
|
71 <option value="USD" selected="selected">U.S. Dollar</option> |
|
72 <option value="CHF">Swiss Franc</option> |
|
73 <option value="TWD">Taiwan Dollar</option> |
|
74 <option value="THB">Thai Baht</option> |
|
75 </select> |
|
76 <input type="button" id="demo_go" value="Get Data"> |
|
77 |
|
78 <table cellspacing="0"> |
|
79 <caption>Inventory</caption> |
|
80 <thead> |
|
81 <tr> |
|
82 <th>SKU</th> |
|
83 <th>Item</th> |
|
84 <th>Price (USD)</th> |
|
85 <th>Price (<span>USD</span>)</th> |
|
86 </tr> |
|
87 </thead> |
|
88 <tbody> |
|
89 <tr><td colspan="4">Click <em>Get Data</em></td></tr> |
|
90 </tbody> |
|
91 </table> |
|
92 </div> |
|
93 |
|
94 <script> |
|
95 YUI().use("node", "io", "json-parse",function (Y) { |
|
96 |
|
97 // Safari 4.0.3's native JSON does not support adding members during parse, |
|
98 // so use JavaScript implementation for consistency |
|
99 Y.JSON.useNativeParse = false; |
|
100 |
|
101 var example = { |
|
102 rates : {"USD":1,"EUR":0.6661,"GBP":0.5207,"AUD":1.1225,"BRL":1.609,"NZD":1.4198,"CAD":1.0667,"CHF":1.0792,"CNY":6.8587 ,"DKK":4.9702,"HKD":7.8064,"INR":42.0168,"JPY":109.8901,"KRW":1000,"LKR":107.5269,"MXN":10.1317,"MYR" :3.3167,"NOK":5.3277,"SEK":6.2617,"SGD":1.4073,"THB":33.7838,"TWD":31.1526,"VEF":2.1445,"ZAR":7.6923 ,"BGN":1.3028,"CZK":16.0514,"EEK":10.4275,"HUF":158.7302,"LTL":2.2999,"LVL":0.4692,"PLN":2.1758,"RON" :2.3804,"SKK":20.2429,"ISK":4.8008,"HRK":81.3008,"RUB":24.3309,"TRY":1.1811,"PHP":44.2478,"COP":2000 ,"ARS":3.1289}, |
|
103 |
|
104 currency : 'USD', |
|
105 |
|
106 convert : function (k,v) { |
|
107 // 'this' will refer to the object containing the key:value pair, |
|
108 // so this step will add a new object member while leaving the original |
|
109 // intact (but formatted to two decimal places). If the original |
|
110 // is not needed, just return the converted value. |
|
111 if (k === 'Price') { |
|
112 var x = Math.round(v * example.rates[example.currency] * 100) / 100; |
|
113 this.convertedPrice = x.toFixed(2); // added to item |
|
114 return v.toFixed(2); // assigned to item.Price |
|
115 } |
|
116 return v; |
|
117 }, |
|
118 |
|
119 updateTable : function (inventory) { |
|
120 // Update the column header |
|
121 Y.one('#demo table th span').set('innerHTML',example.currency); |
|
122 |
|
123 var tbody = Y.one('#demo table tbody'), |
|
124 html = ['<table><tbody>'], |
|
125 rowTemplate = '<tr><td>{SKU}</td><td>{Item}</td><td>{Price}</td><td>{convertedPrice}</td></tr>', |
|
126 i, len; |
|
127 |
|
128 if (inventory) { |
|
129 for (i = 0, len = inventory.length; i < len; ++i) { |
|
130 html.push(Y.Lang.sub(rowTemplate, inventory[i])); |
|
131 } |
|
132 } else { |
|
133 html.push('<tr><td colspan="4">No Inventory data</td></tr>'); |
|
134 } |
|
135 |
|
136 html.push('</tbody></table>'); |
|
137 |
|
138 tbody.replace(Y.Node.create(html.join('')).one('tbody')); |
|
139 } |
|
140 }; |
|
141 |
|
142 Y.one('#demo_go').on('click', function (e) { |
|
143 // Disable the button temporarily |
|
144 this.set('disabled',true); |
|
145 |
|
146 // Store the requested currency |
|
147 var sel = Y.one("#demo select"); |
|
148 example.currency = sel.get("options").item(sel.get("selectedIndex")).get("value"); |
|
149 |
|
150 Y.io('../assets/json/json-convert-values-response.json',{ |
|
151 timeout : 3000, |
|
152 on : { |
|
153 success : function (xid, res) { |
|
154 var inventory; |
|
155 try { |
|
156 inventory = Y.JSON.parse(res.responseText,example.convert); |
|
157 |
|
158 example.updateTable(inventory); |
|
159 } |
|
160 catch(e) { |
|
161 alert("Error getting inventory data"); |
|
162 } |
|
163 finally { |
|
164 Y.one('#demo_go').set('disabled',false); |
|
165 } |
|
166 }, |
|
167 failure : function () { |
|
168 alert("Error getting inventory data"); |
|
169 } |
|
170 } |
|
171 }); |
|
172 }); |
|
173 |
|
174 // Expose example objects for inspection |
|
175 YUI.example = example; |
|
176 }); |
|
177 </script> |
|
178 |
|
179 </div> |
|
180 |
|
181 <h2>The Data</h2> |
|
182 <p> |
|
183 The data returned from the server will be a JSON string containing this object structure: |
|
184 </p> |
|
185 |
|
186 <pre class="code prettyprint lang-json">[ |
|
187 {"SKU":"23-23874", "Price":23.99, "Item":"Helmet"}, |
|
188 {"SKU":"48-38835", "Price":14.97, "Item":"Football"}, |
|
189 {"SKU":"84-84848", "Price":3.49, "Item":"Goggles"}, |
|
190 {"SKU":"84-84843", "Price":183, "Item":"Badminton Set"}, |
|
191 {"SKU":"84-39321", "Price":6.79, "Item":"Tennis Balls"}, |
|
192 {"SKU":"39-48949", "Price":618, "Item":"Snowboard"}, |
|
193 {"SKU":"99-28128", "Price":78.99, "Item":"Cleats"}, |
|
194 {"SKU":"83-48281", "Price":4.69, "Item":"Volleyball"}, |
|
195 {"SKU":"89-32811", "Price":0.59, "Item":"Sweatband"}, |
|
196 {"SKU":"28-22847", "Price":779.98, "Item":"Golf Set"}, |
|
197 {"SKU":"38-38281", "Price":8.25, "Item":"Basketball Shorts"}, |
|
198 {"SKU":"82-38333", "Price":1.39, "Item":"Lip balm"}, |
|
199 {"SKU":"21-38485", "Price":0.07, "Item":"Ping Pong ball"}, |
|
200 {"SKU":"83-38285", "Price":3.99, "Item":"Hockey Puck"} |
|
201 ]</pre> |
|
202 |
|
203 |
|
204 <h2>Create a <code>reviver</code> function</h2> |
|
205 <p> |
|
206 We'll contain all the moving parts in an <code>example</code> namespace. In it, we'll include the currency exchange rates and a function to reference the rates to add a new member to the JSON response as it is being parsed. |
|
207 </p> |
|
208 |
|
209 <pre class="code prettyprint">YUI().use("node", "io", "json-parse",function (Y) { |
|
210 |
|
211 var example = { |
|
212 rates : {"USD":1,"EUR":0.6661,...,"COP":2000 ,"ARS":3.1289}, |
|
213 |
|
214 currency : 'USD', // updated by the select element |
|
215 |
|
216 convert : function (k,v) { |
|
217 // 'this' will refer to the object containing the key:value pair, |
|
218 // so this step will add a new object member while leaving the original |
|
219 // intact (but formatted to two decimal places). If the original |
|
220 // is not needed, just return the converted value. |
|
221 if (k === 'Price') { |
|
222 var x = Math.round(v * example.rates[example.currency] * 100) / 100; |
|
223 this.convertedPrice = x.toFixed(2); // added to item |
|
224 return v.toFixed(2); // assigned to item.Price |
|
225 } |
|
226 return v; |
|
227 }, |
|
228 … |
|
229 }; |
|
230 …</pre> |
|
231 |
|
232 |
|
233 <h2>Sending the request and parsing the JSON response</h2> |
|
234 <p> |
|
235 When the <em>Get Data</em> button is clicked, we send an io request for the JSON data, and in our <code>success</code> handler, pass our conversion function to <code>JSON.parse()</code> with the response text. The resulting inventory records will have an additional member, <code>convertedPrice</code>. This data is then passed to a UI method to update the inventory table. |
|
236 </p> |
|
237 |
|
238 <pre class="code prettyprint">Y.one('#demo_go').on('click', function (e) { |
|
239 // Disable the button temporarily |
|
240 this.set('disabled',true); |
|
241 |
|
242 // Store the requested currency |
|
243 var sel = Y.one("#demo select"); |
|
244 example.currency = sel.get("options").item(sel.get("selectedIndex")).get("value"); |
|
245 |
|
246 // Send the request for the JSON data |
|
247 Y.io('../assets/json/json-convert-values-response.json',{ |
|
248 timeout : 3000, |
|
249 on : { |
|
250 success : function (xid, res) { |
|
251 var inventory; |
|
252 try { |
|
253 inventory = Y.JSON.parse(res.responseText,example.convert); |
|
254 |
|
255 example.updateTable(inventory); |
|
256 } |
|
257 catch(e) { |
|
258 alert("Error getting inventory data"); |
|
259 } |
|
260 finally { |
|
261 Y.one('#demo_go').set('disabled',false); |
|
262 } |
|
263 }, |
|
264 failure : function () { |
|
265 alert("Error getting inventory data"); |
|
266 } |
|
267 } |
|
268 }); |
|
269 }); |
|
270 |
|
271 }); // End YUI(..).use(..,function (Y) {</pre> |
|
272 |
|
273 |
|
274 <h2>Complete Example Source</h2> |
|
275 |
|
276 <pre class="code prettyprint"><div id="demo"> |
|
277 <p>Choose a currency, then get the data</p> |
|
278 <select> |
|
279 <option value="ARS">Argentine Peso</option> |
|
280 <option value="AUD">Australian Dollar</option> |
|
281 <option value="BRL">Brazilian Real</option> |
|
282 <option value="GBP">British Pound</option> |
|
283 <option value="CAD">Canadian Dollar</option> |
|
284 <option value="CNY">Chinese Yuan</option> |
|
285 <option value="COP">Colombian Peso</option> |
|
286 <option value="HRK">Croatian Kuna</option> |
|
287 <option value="CZK">Czech Koruna</option> |
|
288 <option value="DKK">Danish Krone</option> |
|
289 <option value="EEK">Estonian Kroon</option> |
|
290 <option value="EUR">Euro</option> |
|
291 <option value="HKD">Hong Kong Dollar</option> |
|
292 <option value="HUF">Hungarian Forint</option> |
|
293 <option value="ISK">Iceland Krona</option> |
|
294 <option value="INR">Indian Rupee</option> |
|
295 <option value="JPY">Japanese Yen</option> |
|
296 <option value="KRW">Korean Won</option> |
|
297 <option value="LVL">Latvian Lat</option> |
|
298 <option value="LTL">Lithuanian Lita</option> |
|
299 <option value="MYR">Malaysian Ringgit</option> |
|
300 <option value="MXN">Mexican Peso</option> |
|
301 <option value="NZD">New Zealand Dollar</option> |
|
302 <option value="NOK">Norwegian Krone</option> |
|
303 <option value="PHP">Philippine Peso</option> |
|
304 <option value="PLN">Polish Zloty</option> |
|
305 <option value="RUB">Russian Rouble</option> |
|
306 <option value="SGD">Singapore Dollar</option> |
|
307 <option value="SKK">Slovak Koruna</option> |
|
308 <option value="ZAR">South African Rand</option> |
|
309 <option value="LKR">Sri Lanka Rupee</option> |
|
310 <option value="SEK">Swedish Krona</option> |
|
311 <option value="TRY">Turkey Lira</option> |
|
312 <option value="USD" selected="selected">U.S. Dollar</option> |
|
313 <option value="CHF">Swiss Franc</option> |
|
314 <option value="TWD">Taiwan Dollar</option> |
|
315 <option value="THB">Thai Baht</option> |
|
316 </select> |
|
317 <input type="button" id="demo_go" value="Get Data"> |
|
318 |
|
319 <table cellspacing="0"> |
|
320 <caption>Inventory</caption> |
|
321 <thead> |
|
322 <tr> |
|
323 <th>SKU</th> |
|
324 <th>Item</th> |
|
325 <th>Price (USD)</th> |
|
326 <th>Price (<span>USD</span>)</th> |
|
327 </tr> |
|
328 </thead> |
|
329 <tbody> |
|
330 <tr><td colspan="4">Click <em>Get Data</em></td></tr> |
|
331 </tbody> |
|
332 </table> |
|
333 </div> |
|
334 |
|
335 <script> |
|
336 YUI().use("node", "io", "json-parse",function (Y) { |
|
337 |
|
338 // Safari 4.0.3's native JSON does not support adding members during parse, |
|
339 // so use JavaScript implementation for consistency |
|
340 Y.JSON.useNativeParse = false; |
|
341 |
|
342 var example = { |
|
343 rates : {"USD":1,"EUR":0.6661,"GBP":0.5207,"AUD":1.1225,"BRL":1.609,"NZD":1.4198,"CAD":1.0667,"CHF":1.0792,"CNY":6.8587 ,"DKK":4.9702,"HKD":7.8064,"INR":42.0168,"JPY":109.8901,"KRW":1000,"LKR":107.5269,"MXN":10.1317,"MYR" :3.3167,"NOK":5.3277,"SEK":6.2617,"SGD":1.4073,"THB":33.7838,"TWD":31.1526,"VEF":2.1445,"ZAR":7.6923 ,"BGN":1.3028,"CZK":16.0514,"EEK":10.4275,"HUF":158.7302,"LTL":2.2999,"LVL":0.4692,"PLN":2.1758,"RON" :2.3804,"SKK":20.2429,"ISK":4.8008,"HRK":81.3008,"RUB":24.3309,"TRY":1.1811,"PHP":44.2478,"COP":2000 ,"ARS":3.1289}, |
|
344 |
|
345 currency : 'USD', |
|
346 |
|
347 convert : function (k,v) { |
|
348 // 'this' will refer to the object containing the key:value pair, |
|
349 // so this step will add a new object member while leaving the original |
|
350 // intact (but formatted to two decimal places). If the original |
|
351 // is not needed, just return the converted value. |
|
352 if (k === 'Price') { |
|
353 var x = Math.round(v * example.rates[example.currency] * 100) / 100; |
|
354 this.convertedPrice = x.toFixed(2); // added to item |
|
355 return v.toFixed(2); // assigned to item.Price |
|
356 } |
|
357 return v; |
|
358 }, |
|
359 |
|
360 updateTable : function (inventory) { |
|
361 // Update the column header |
|
362 Y.one('#demo table th span').set('innerHTML',example.currency); |
|
363 |
|
364 var tbody = Y.one('#demo table tbody'), |
|
365 html = ['<table><tbody>'], |
|
366 rowTemplate = '<tr><td>{SKU}</td><td>{Item}</td><td>{Price}</td><td>{convertedPrice}</td></tr>', |
|
367 i, len; |
|
368 |
|
369 if (inventory) { |
|
370 for (i = 0, len = inventory.length; i < len; ++i) { |
|
371 html.push(Y.Lang.sub(rowTemplate, inventory[i])); |
|
372 } |
|
373 } else { |
|
374 html.push('<tr><td colspan="4">No Inventory data</td></tr>'); |
|
375 } |
|
376 |
|
377 html.push('</tbody></table>'); |
|
378 |
|
379 tbody.replace(Y.Node.create(html.join('')).one('tbody')); |
|
380 } |
|
381 }; |
|
382 |
|
383 Y.one('#demo_go').on('click', function (e) { |
|
384 // Disable the button temporarily |
|
385 this.set('disabled',true); |
|
386 |
|
387 // Store the requested currency |
|
388 var sel = Y.one("#demo select"); |
|
389 example.currency = sel.get("options").item(sel.get("selectedIndex")).get("value"); |
|
390 |
|
391 Y.io('../assets/json/json-convert-values-response.json',{ |
|
392 timeout : 3000, |
|
393 on : { |
|
394 success : function (xid, res) { |
|
395 var inventory; |
|
396 try { |
|
397 inventory = Y.JSON.parse(res.responseText,example.convert); |
|
398 |
|
399 example.updateTable(inventory); |
|
400 } |
|
401 catch(e) { |
|
402 alert("Error getting inventory data"); |
|
403 } |
|
404 finally { |
|
405 Y.one('#demo_go').set('disabled',false); |
|
406 } |
|
407 }, |
|
408 failure : function () { |
|
409 alert("Error getting inventory data"); |
|
410 } |
|
411 } |
|
412 }); |
|
413 }); |
|
414 |
|
415 // Expose example objects for inspection |
|
416 YUI.example = example; |
|
417 }); |
|
418 </script></pre> |
|
419 |
|
420 </div> |
|
421 </div> |
|
422 </div> |
|
423 |
|
424 <div class="yui3-u-1-4"> |
|
425 <div class="sidebar"> |
|
426 |
|
427 |
|
428 |
|
429 <div class="sidebox"> |
|
430 <div class="hd"> |
|
431 <h2 class="no-toc">Examples</h2> |
|
432 </div> |
|
433 |
|
434 <div class="bd"> |
|
435 <ul class="examples"> |
|
436 |
|
437 |
|
438 <li data-description="Use JSON to parse data received via XMLHttpRequest via Y.io calls — a simple JSON use case."> |
|
439 <a href="json-connect.html">JSON with Y.io</a> |
|
440 </li> |
|
441 |
|
442 |
|
443 |
|
444 <li data-description="Use the replacer and reviver parameters to reconstitute object instances that have been serialized to JSON."> |
|
445 <a href="json-freeze-thaw.html">Rebuilding Class Instances from JSON Data</a> |
|
446 </li> |
|
447 |
|
448 |
|
449 |
|
450 <li data-description="Use a currency conversion calculation to add a new price member to a JSON response, demonstrating how JSON data, once retrieved, can be transformed during parsing."> |
|
451 <a href="json-convert-values.html">Adding New Object Members During Parsing</a> |
|
452 </li> |
|
453 |
|
454 |
|
455 |
|
456 |
|
457 |
|
458 |
|
459 </ul> |
|
460 </div> |
|
461 </div> |
|
462 |
|
463 |
|
464 |
|
465 <div class="sidebox"> |
|
466 <div class="hd"> |
|
467 <h2 class="no-toc">Examples That Use This Component</h2> |
|
468 </div> |
|
469 |
|
470 <div class="bd"> |
|
471 <ul class="examples"> |
|
472 |
|
473 |
|
474 |
|
475 |
|
476 |
|
477 |
|
478 |
|
479 |
|
480 <li data-description="A basic todo list built with the Model, Model List, and View components."> |
|
481 <a href="../app/app-todo.html">Todo List</a> |
|
482 </li> |
|
483 |
|
484 |
|
485 |
|
486 <li data-description="Portal style example using Drag & Drop Event Bubbling and Animation."> |
|
487 <a href="../dd/portal-drag.html">Portal Style Example</a> |
|
488 </li> |
|
489 |
|
490 |
|
491 </ul> |
|
492 </div> |
|
493 </div> |
|
494 |
|
495 </div> |
|
496 </div> |
|
497 </div> |
|
498 </div> |
|
499 |
|
500 <script src="../assets/vendor/prettify/prettify-min.js"></script> |
|
501 <script>prettyPrint();</script> |
|
502 |
|
503 <script> |
|
504 YUI.Env.Tests = { |
|
505 examples: [], |
|
506 project: '../assets', |
|
507 assets: '../assets/json', |
|
508 name: 'json-convert-values', |
|
509 title: 'Adding New Object Members During Parsing', |
|
510 newWindow: '', |
|
511 auto: false |
|
512 }; |
|
513 YUI.Env.Tests.examples.push('json-connect'); |
|
514 YUI.Env.Tests.examples.push('json-freeze-thaw'); |
|
515 YUI.Env.Tests.examples.push('json-convert-values'); |
|
516 YUI.Env.Tests.examples.push('app-todo'); |
|
517 YUI.Env.Tests.examples.push('portal-drag'); |
|
518 |
|
519 </script> |
|
520 <script src="../assets/yui/test-runner.js"></script> |
|
521 |
|
522 |
|
523 |
|
524 </body> |
|
525 </html> |