Merge lp:~barry/lazr-js/482298-picker-batching into lp:lazr-js
- 482298-picker-batching
- Merge into toolchain
Proposed by
Barry Warsaw
Status: | Merged |
---|---|
Approved by: | Barry Warsaw |
Approved revision: | not available |
Merged at revision: | not available |
Proposed branch: | lp:~barry/lazr-js/482298-picker-batching |
Merge into: | lp:lazr-js |
Diff against target: |
325 lines (+138/-51) 3 files modified
examples/picker/index.html (+40/-29) src-js/lazrjs/picker/picker.js (+62/-22) src-js/lazrjs/picker/tests/picker.js (+36/-0) |
To merge this branch: | bzr merge lp:~barry/lazr-js/482298-picker-batching |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brad Crittenden (community) | code | Approve | |
Māris Fogels | code | Pending | |
Review via email: mp+15176@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Barry Warsaw (barry) wrote : | # |
Revision history for this message
Barry Warsaw (barry) wrote : | # |
Um, something's wacky with the diff. If you branch the code, you won't see those conflict markers.
- 149. By Barry Warsaw
-
Merge trunk
Revision history for this message
Barry Warsaw (barry) wrote : | # |
> Um, something's wacky with the diff. If you branch the code, you won't see
> those conflict markers.
nm. conflict resolved
Revision history for this message
Brad Crittenden (bac) : | # |
review:
Approve
(code)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'examples/picker/index.html' | |||
2 | --- examples/picker/index.html 2009-11-19 17:27:44 +0000 | |||
3 | +++ examples/picker/index.html 2009-11-24 00:13:10 +0000 | |||
4 | @@ -112,27 +112,36 @@ | |||
5 | 112 | spin_interval = 2000; | 112 | spin_interval = 2000; |
6 | 113 | } | 113 | } |
7 | 114 | Y.later(spin_interval, null, function () { | 114 | Y.later(spin_interval, null, function () { |
10 | 115 | var results = search_items( | 115 | var results = search_items(e.details[Y.Picker.SEARCH_STRING]); |
9 | 116 | e.details[Y.Picker.SEARCH_STRING]); | ||
11 | 117 | var selected_batch = e.details[Y.Picker.SELECTED_BATCH_VALUE]; | 116 | var selected_batch = e.details[Y.Picker.SELECTED_BATCH_VALUE]; |
12 | 117 | var simple_batching = Y.get('#page-label-1').get('checked'); | ||
13 | 118 | 118 | ||
24 | 119 | // Update the batches only if it's a new search. | 119 | if (simple_batching) { |
25 | 120 | if (selected_batch === undefined) { | 120 | if (selected_batch === undefined) { |
26 | 121 | var batches = []; | 121 | // This is a new search, so select the first batch. |
27 | 122 | // Set up the picker batches if there is more than one | 122 | selected_batch = 0; |
28 | 123 | // results batch. | 123 | } |
29 | 124 | if (results.length > 1) { | 124 | picker.set('batch_count', results.length); |
30 | 125 | Y.Array.each(results, function (batch, i) { | 125 | picker.set('results', results[selected_batch]); |
31 | 126 | batches.push({ | 126 | } |
32 | 127 | name: i+1, | 127 | else { |
33 | 128 | value: i, | 128 | if (selected_batch === undefined) { |
34 | 129 | // This is a new search, so select the first batch. | ||
35 | 130 | // Set up the picker batches if there is more than one | ||
36 | 131 | // results batch. | ||
37 | 132 | var batches = []; | ||
38 | 133 | if (results.length > 1) { | ||
39 | 134 | Y.Array.each(results, function (batch, i) { | ||
40 | 135 | // Stupid batch page labels. | ||
41 | 136 | var label = String.fromCharCode(65 + i); | ||
42 | 137 | batches.push({ value: i, name: label }); | ||
43 | 129 | }); | 138 | }); |
45 | 130 | }); | 139 | } |
46 | 140 | picker.set('batches', batches); | ||
47 | 141 | selected_batch = 0; | ||
48 | 131 | } | 142 | } |
51 | 132 | picker.set('batches', batches); | 143 | picker.set('results', results[selected_batch]); |
50 | 133 | selected_batch = 0; | ||
52 | 134 | } | 144 | } |
53 | 135 | picker.set('results', results[selected_batch]); | ||
54 | 136 | }); | 145 | }); |
55 | 137 | }); | 146 | }); |
56 | 138 | 147 | ||
57 | @@ -227,6 +236,13 @@ | |||
58 | 227 | <input type="text" id="batch-size" value="3" /> | 236 | <input type="text" id="batch-size" value="3" /> |
59 | 228 | </div> | 237 | </div> |
60 | 229 | <div> | 238 | <div> |
61 | 239 | <b>Page labels:</b><br /> | ||
62 | 240 | <input type="radio" name="page-labels" id="page-label-1" | ||
63 | 241 | value="numbers" checked="yes">Numbers<br /> | ||
64 | 242 | <input type="radio" name="page-labels" id="page-label-2" | ||
65 | 243 | value="letters">Letters | ||
66 | 244 | </div> | ||
67 | 245 | <div> | ||
68 | 230 | <button id="show-widget" disabled="true">Show widget</button> | 246 | <button id="show-widget" disabled="true">Show widget</button> |
69 | 231 | </div> | 247 | </div> |
70 | 232 | </div> | 248 | </div> |
71 | @@ -356,24 +372,19 @@ | |||
72 | 356 | picker.after('search', function(e) { | 372 | picker.after('search', function(e) { |
73 | 357 | var search_text = e.details[Y.Picker.SEARCH_STRING]; | 373 | var search_text = e.details[Y.Picker.SEARCH_STRING]; |
74 | 358 | var selected_batch = e.details[Y.Picker.SELECTED_BATCH_VALUE]; | 374 | var selected_batch = e.details[Y.Picker.SELECTED_BATCH_VALUE]; |
75 | 375 | var result_batches = my_perform_search(search_text); | ||
76 | 359 | 376 | ||
77 | 360 | // On a new search, there will be no selected batch. Update the | ||
78 | 361 | // batches so that the Picker can page through them. | ||
79 | 362 | if (selected_batch === undefined) { | 377 | if (selected_batch === undefined) { |
80 | 378 | // On a new search, there will be no selected batch. Update the | ||
81 | 379 | // batches so that the Picker can page through them. | ||
82 | 363 | var batches = []; | 380 | var batches = []; |
83 | 364 | result_batches = my_perform_search(search_text); | ||
84 | 365 | // Iterate over all the results, extending the Picker batches | ||
85 | 366 | // array, so that there is one item per results batch. The | ||
86 | 367 | // Picker batch items must have a 'name' and a 'value'. | ||
87 | 368 | Y.Array.each(result_batches, function(batch, i) { | 381 | Y.Array.each(result_batches, function(batch, i) { |
92 | 369 | batches.push({ | 382 | var roman = roman_numeral(i + 1); |
93 | 370 | name: i + 1, | 383 | batches.push({ value: i, name: roman }); |
90 | 371 | value: i, | ||
91 | 372 | }); | ||
94 | 373 | }); | 384 | }); |
98 | 374 | // If there was only one batch of results, then the Picker | 385 | // If there was only one batch of results, then `batches` will |
99 | 375 | // batches will be of length zero, and the picker will know to | 386 | // be of length zero, and the picker will know to not display |
100 | 376 | // not display the page arrows. | 387 | // the page arrows. |
101 | 377 | picker.set('batches', batches); | 388 | picker.set('batches', batches); |
102 | 378 | selected_batch = 0; | 389 | selected_batch = 0; |
103 | 379 | } | 390 | } |
104 | 380 | 391 | ||
105 | === modified file 'src-js/lazrjs/picker/picker.js' | |||
106 | --- src-js/lazrjs/picker/picker.js 2009-11-18 21:34:09 +0000 | |||
107 | +++ src-js/lazrjs/picker/picker.js 2009-11-24 00:13:10 +0000 | |||
108 | @@ -50,6 +50,7 @@ | |||
109 | 50 | ERROR = 'error', | 50 | ERROR = 'error', |
110 | 51 | RESULTS = 'results', | 51 | RESULTS = 'results', |
111 | 52 | BATCHES = 'batches', | 52 | BATCHES = 'batches', |
112 | 53 | BATCH_COUNT = 'batch_count', | ||
113 | 53 | SEARCH_SLOT = 'search_slot', | 54 | SEARCH_SLOT = 'search_slot', |
114 | 54 | FOOTER_SLOT = 'footer_slot', | 55 | FOOTER_SLOT = 'footer_slot', |
115 | 55 | SELECTED_BATCH = 'selected_batch', | 56 | SELECTED_BATCH = 'selected_batch', |
116 | @@ -217,19 +218,46 @@ | |||
117 | 217 | }, | 218 | }, |
118 | 218 | 219 | ||
119 | 219 | /** | 220 | /** |
120 | 221 | * Return the batch page information. | ||
121 | 222 | * | ||
122 | 223 | * @method _getBatches | ||
123 | 224 | * @protected | ||
124 | 225 | */ | ||
125 | 226 | _getBatches: function() { | ||
126 | 227 | var batches = this.get(BATCHES); | ||
127 | 228 | |||
128 | 229 | if (batches === null) { | ||
129 | 230 | var batch_count = this.get(BATCH_COUNT); | ||
130 | 231 | if (batch_count === null) { | ||
131 | 232 | batches = []; | ||
132 | 233 | } | ||
133 | 234 | else { | ||
134 | 235 | batches = []; | ||
135 | 236 | // Only create batch pages when there's more than one. | ||
136 | 237 | if (batch_count > 1) { | ||
137 | 238 | for (var i = 0; i < batch_count; i++) { | ||
138 | 239 | batches.push({ value: i, name: i + 1 }); | ||
139 | 240 | } | ||
140 | 241 | } | ||
141 | 242 | } | ||
142 | 243 | } | ||
143 | 244 | return batches; | ||
144 | 245 | }, | ||
145 | 246 | |||
146 | 247 | /** | ||
147 | 220 | * Update the batches container in the UI. | 248 | * Update the batches container in the UI. |
148 | 221 | * | 249 | * |
149 | 222 | * @method _syncBatchesUI | 250 | * @method _syncBatchesUI |
150 | 223 | * @protected | 251 | * @protected |
151 | 224 | */ | 252 | */ |
152 | 225 | _syncBatchesUI: function() { | 253 | _syncBatchesUI: function() { |
154 | 226 | var options = this.get(BATCHES); | 254 | var batches = this._getBatches(); |
155 | 227 | 255 | ||
156 | 228 | // Clear previous batches. | 256 | // Clear previous batches. |
157 | 229 | Y.Event.purgeElement(this._batches_box, true); | 257 | Y.Event.purgeElement(this._batches_box, true); |
158 | 230 | this._batches_box.set('innerHTML', ''); | 258 | this._batches_box.set('innerHTML', ''); |
159 | 231 | 259 | ||
161 | 232 | if (options.length === 0) { | 260 | if (batches.length === 0) { |
162 | 233 | this._prev_button = null; | 261 | this._prev_button = null; |
163 | 234 | this._next_button = null; | 262 | this._next_button = null; |
164 | 235 | return; | 263 | return; |
165 | @@ -243,11 +271,11 @@ | |||
166 | 243 | this.set(SELECTED_BATCH, selected); | 271 | this.set(SELECTED_BATCH, selected); |
167 | 244 | this.fire( | 272 | this.fire( |
168 | 245 | SEARCH, this.get(CURRENT_SEARCH_STRING), | 273 | SEARCH, this.get(CURRENT_SEARCH_STRING), |
170 | 246 | options[selected].value); | 274 | batches[selected].value); |
171 | 247 | }, this); | 275 | }, this); |
172 | 248 | this._batches_box.appendChild(this._prev_button); | 276 | this._batches_box.appendChild(this._prev_button); |
173 | 249 | 277 | ||
175 | 250 | Y.Array.each(options, function(data, i) { | 278 | Y.Array.each(batches, function(data, i) { |
176 | 251 | var batch_item = Y.Node.create('<span></span>'); | 279 | var batch_item = Y.Node.create('<span></span>'); |
177 | 252 | batch_item.appendChild( | 280 | batch_item.appendChild( |
178 | 253 | document.createTextNode(data.name)); | 281 | document.createTextNode(data.name)); |
179 | @@ -267,7 +295,7 @@ | |||
180 | 267 | this.set(SELECTED_BATCH, selected); | 295 | this.set(SELECTED_BATCH, selected); |
181 | 268 | this.fire( | 296 | this.fire( |
182 | 269 | SEARCH, this.get(CURRENT_SEARCH_STRING), | 297 | SEARCH, this.get(CURRENT_SEARCH_STRING), |
184 | 270 | this.get(BATCHES)[selected].value); | 298 | batches[selected].value); |
185 | 271 | }, this); | 299 | }, this); |
186 | 272 | }, | 300 | }, |
187 | 273 | 301 | ||
188 | @@ -279,7 +307,6 @@ | |||
189 | 279 | */ | 307 | */ |
190 | 280 | _syncSelectedBatchUI: function() { | 308 | _syncSelectedBatchUI: function() { |
191 | 281 | var idx = this.get(SELECTED_BATCH); | 309 | var idx = this.get(SELECTED_BATCH); |
192 | 282 | |||
193 | 283 | var items = this._batches_box.queryAll('span'); | 310 | var items = this._batches_box.queryAll('span'); |
194 | 284 | if (items.size()) { | 311 | if (items.size()) { |
195 | 285 | this._prev_button.set('disabled', idx === 0); | 312 | this._prev_button.set('disabled', idx === 0); |
196 | @@ -501,19 +528,15 @@ | |||
197 | 501 | this._syncFooterSlotUI(); | 528 | this._syncFooterSlotUI(); |
198 | 502 | }, this); | 529 | }, this); |
199 | 503 | 530 | ||
203 | 504 | // Update the batch list whenever the "batches" property | 531 | // Update the batch list whenever the "batches" or "results" property |
204 | 505 | // is changed, and reset the selected one to the first one. | 532 | // is changed. |
205 | 506 | this.after('batchesChange', function (e) { | 533 | var doBatchesChange = function (e) { |
206 | 507 | this._syncBatchesUI(); | 534 | this._syncBatchesUI(); |
216 | 508 | if (this.get(SELECTED_BATCH) === 0){ | 535 | this._syncSelectedBatchUI(); |
217 | 509 | // If the attribute is already set to the same value, | 536 | }; |
218 | 510 | // the 'after' events won't be triggered, so we have | 537 | |
219 | 511 | // to trigger it manually. | 538 | this.after('batchesChange', doBatchesChange, this); |
220 | 512 | this._syncSelectedBatchUI(); | 539 | this.after('resultsChange', doBatchesChange, this); |
212 | 513 | } else { | ||
213 | 514 | this.set(SELECTED_BATCH, 0); | ||
214 | 515 | } | ||
215 | 516 | }, this); | ||
221 | 517 | 540 | ||
222 | 518 | // Keep the UI in sync with the currently selected batch. | 541 | // Keep the UI in sync with the currently selected batch. |
223 | 519 | this.after('selected_batchChange', function (e) { | 542 | this.after('selected_batchChange', function (e) { |
224 | @@ -561,7 +584,8 @@ | |||
225 | 561 | this.set(CURRENT_SEARCH_STRING, ''); | 584 | this.set(CURRENT_SEARCH_STRING, ''); |
226 | 562 | this.set(ERROR, ''); | 585 | this.set(ERROR, ''); |
227 | 563 | this.set(RESULTS, [{}]); | 586 | this.set(RESULTS, [{}]); |
229 | 564 | this.set(BATCHES, []); | 587 | this.set(BATCHES, null); |
230 | 588 | this.set(BATCH_COUNT, null); | ||
231 | 565 | this._search_input.set('value', ''); | 589 | this._search_input.set('value', ''); |
232 | 566 | this._results_box.set('innerHTML', ''); | 590 | this._results_box.set('innerHTML', ''); |
233 | 567 | }, | 591 | }, |
234 | @@ -702,7 +726,7 @@ | |||
235 | 702 | 726 | ||
236 | 703 | /** | 727 | /** |
237 | 704 | * An extra CSS class to be added to the picker_activator, generally used | 728 | * An extra CSS class to be added to the picker_activator, generally used |
239 | 705 | * to distinguish regular links from js-triggering ones. | 729 | * to distinguish regular links from js-triggering ones. |
240 | 706 | * | 730 | * |
241 | 707 | * @attribute picker_activator_css_class | 731 | * @attribute picker_activator_css_class |
242 | 708 | * @type String | 732 | * @type String |
243 | @@ -773,7 +797,22 @@ | |||
244 | 773 | * @attribute batches | 797 | * @attribute batches |
245 | 774 | * @type Array | 798 | * @type Array |
246 | 775 | */ | 799 | */ |
248 | 776 | batches: {value: []}, | 800 | batches: {value: null}, |
249 | 801 | |||
250 | 802 | /** | ||
251 | 803 | * For simplified batch creation, you can set this to the number of | ||
252 | 804 | * batches in the search results. In this case, the batch labels | ||
253 | 805 | * and values are automatically calculated. The batch name (used as the | ||
254 | 806 | * batch label) will be the batch number starting from 1. The batch value | ||
255 | 807 | * (used as additional details to the SEARCH event) will be the batch | ||
256 | 808 | * number, starting from zero. | ||
257 | 809 | * | ||
258 | 810 | * If 'batches' is set (see above), batch_count is ignored. | ||
259 | 811 | * | ||
260 | 812 | * @attribute batch_count | ||
261 | 813 | * @type Integer | ||
262 | 814 | */ | ||
263 | 815 | batch_count: {value: null}, | ||
264 | 777 | 816 | ||
265 | 778 | /** | 817 | /** |
266 | 779 | * Batch currently selected. | 818 | * Batch currently selected. |
267 | @@ -787,9 +826,10 @@ | |||
268 | 787 | return value || 0; | 826 | return value || 0; |
269 | 788 | }, | 827 | }, |
270 | 789 | validator: function (value) { | 828 | validator: function (value) { |
271 | 829 | var batches = this._getBatches(); | ||
272 | 790 | return Y.Lang.isNumber(value) && | 830 | return Y.Lang.isNumber(value) && |
273 | 791 | value >= 0 && | 831 | value >= 0 && |
275 | 792 | value < this.get(BATCHES).length; | 832 | value < batches.length; |
276 | 793 | }}, | 833 | }}, |
277 | 794 | 834 | ||
278 | 795 | /** | 835 | /** |
279 | 796 | 836 | ||
280 | === modified file 'src-js/lazrjs/picker/tests/picker.js' | |||
281 | --- src-js/lazrjs/picker/tests/picker.js 2009-11-13 20:50:08 +0000 | |||
282 | +++ src-js/lazrjs/picker/tests/picker.js 2009-11-24 00:13:10 +0000 | |||
283 | @@ -532,6 +532,42 @@ | |||
284 | 532 | "There should be a next button."); | 532 | "There should be a next button."); |
285 | 533 | }, | 533 | }, |
286 | 534 | 534 | ||
287 | 535 | test_simplified_batching_interface: function () { | ||
288 | 536 | this.picker.render(); | ||
289 | 537 | this.picker.set('batch_count', 4); | ||
290 | 538 | this.picker.set('results', [ | ||
291 | 539 | { value: 'aardvark', title: 'Aardvarks' }, | ||
292 | 540 | { value: 'bats', title: 'Bats' }, | ||
293 | 541 | { value: 'cats', title: 'Cats' }, | ||
294 | 542 | { value: 'dogs', title: 'Dogs' }, | ||
295 | 543 | { value: 'emus', title: 'Emus' }, | ||
296 | 544 | { value: 'frogs', title: 'Frogs' }, | ||
297 | 545 | { value: 'gerbils', title: 'Gerbils' } | ||
298 | 546 | ]); | ||
299 | 547 | var bb = this.picker.get('boundingBox'); | ||
300 | 548 | Assert.isNotNull( | ||
301 | 549 | bb.query('.yui-picker-batches span'), | ||
302 | 550 | "Container for batches not found."); | ||
303 | 551 | var batches = bb.queryAll('.yui-picker-batches span'); | ||
304 | 552 | Assert.isNotNull(batches, "Batches not found"); | ||
305 | 553 | Assert.areEqual(4, batches.size()); | ||
306 | 554 | ArrayAssert.itemsAreEqual( | ||
307 | 555 | ['1', '2', '3', '4'], | ||
308 | 556 | batches.get('text'), | ||
309 | 557 | "Batches don't contain batch names."); | ||
310 | 558 | ArrayAssert.itemsAreEqual( | ||
311 | 559 | [true, false, false, false], | ||
312 | 560 | batches.hasClass('yui-picker-selected-batch'), | ||
313 | 561 | "Selected batches missing CSS class."); | ||
314 | 562 | |||
315 | 563 | Assert.isNotNull( | ||
316 | 564 | bb.query('.yui-picker-batches .lazr-prev'), | ||
317 | 565 | "There should be a previous button."); | ||
318 | 566 | Assert.isNotNull( | ||
319 | 567 | bb.query('.yui-picker-batches .lazr-next'), | ||
320 | 568 | "There should be a next button."); | ||
321 | 569 | }, | ||
322 | 570 | |||
323 | 535 | test_clicking_a_batch_item_fires_search_event: function () { | 571 | test_clicking_a_batch_item_fires_search_event: function () { |
324 | 536 | this.picker.set('current_search_string', 'search'); | 572 | this.picker.set('current_search_string', 'search'); |
325 | 537 | this.picker.set('batches', [ | 573 | this.picker.set('batches', [ |
Implement a simplified batching API for the Picker. The common case is where the page headings are numbers starting from 1, with values starting from 0. So unless you need to do something fancy, you can just tell the picker how many batches there are and it will do the rest.