Merge lp:~barry/lazr-js/482298-picker-batching into lp:lazr-js

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
Reviewer Review Type Date Requested Status
Brad Crittenden (community) code Approve
Māris Fogels code Pending
Review via email: mp+15176@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Barry Warsaw (barry) wrote :

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.

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 spin_interval = 2000;
6 }
7 Y.later(spin_interval, null, function () {
8- var results = search_items(
9- e.details[Y.Picker.SEARCH_STRING]);
10+ var results = search_items(e.details[Y.Picker.SEARCH_STRING]);
11 var selected_batch = e.details[Y.Picker.SELECTED_BATCH_VALUE];
12+ var simple_batching = Y.get('#page-label-1').get('checked');
13
14- // Update the batches only if it's a new search.
15- if (selected_batch === undefined) {
16- var batches = [];
17- // Set up the picker batches if there is more than one
18- // results batch.
19- if (results.length > 1) {
20- Y.Array.each(results, function (batch, i) {
21- batches.push({
22- name: i+1,
23- value: i,
24+ if (simple_batching) {
25+ if (selected_batch === undefined) {
26+ // This is a new search, so select the first batch.
27+ selected_batch = 0;
28+ }
29+ picker.set('batch_count', results.length);
30+ picker.set('results', results[selected_batch]);
31+ }
32+ else {
33+ if (selected_batch === undefined) {
34+ // This is a new search, so select the first batch.
35+ // Set up the picker batches if there is more than one
36+ // results batch.
37+ var batches = [];
38+ if (results.length > 1) {
39+ Y.Array.each(results, function (batch, i) {
40+ // Stupid batch page labels.
41+ var label = String.fromCharCode(65 + i);
42+ batches.push({ value: i, name: label });
43 });
44- });
45+ }
46+ picker.set('batches', batches);
47+ selected_batch = 0;
48 }
49- picker.set('batches', batches);
50- selected_batch = 0;
51+ picker.set('results', results[selected_batch]);
52 }
53- picker.set('results', results[selected_batch]);
54 });
55 });
56
57@@ -227,6 +236,13 @@
58 <input type="text" id="batch-size" value="3" />
59 </div>
60 <div>
61+ <b>Page labels:</b><br />
62+ <input type="radio" name="page-labels" id="page-label-1"
63+ value="numbers" checked="yes">Numbers<br />
64+ <input type="radio" name="page-labels" id="page-label-2"
65+ value="letters">Letters
66+ </div>
67+ <div>
68 <button id="show-widget" disabled="true">Show widget</button>
69 </div>
70 </div>
71@@ -356,24 +372,19 @@
72 picker.after('search', function(e) {
73 var search_text = e.details[Y.Picker.SEARCH_STRING];
74 var selected_batch = e.details[Y.Picker.SELECTED_BATCH_VALUE];
75+ var result_batches = my_perform_search(search_text);
76
77- // On a new search, there will be no selected batch. Update the
78- // batches so that the Picker can page through them.
79 if (selected_batch === undefined) {
80+ // On a new search, there will be no selected batch. Update the
81+ // batches so that the Picker can page through them.
82 var batches = [];
83- result_batches = my_perform_search(search_text);
84- // Iterate over all the results, extending the Picker batches
85- // array, so that there is one item per results batch. The
86- // Picker batch items must have a 'name' and a 'value'.
87 Y.Array.each(result_batches, function(batch, i) {
88- batches.push({
89- name: i + 1,
90- value: i,
91- });
92+ var roman = roman_numeral(i + 1);
93+ batches.push({ value: i, name: roman });
94 });
95- // If there was only one batch of results, then the Picker
96- // batches will be of length zero, and the picker will know to
97- // not display the page arrows.
98+ // If there was only one batch of results, then `batches` will
99+ // be of length zero, and the picker will know to not display
100+ // the page arrows.
101 picker.set('batches', batches);
102 selected_batch = 0;
103 }
104
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 ERROR = 'error',
110 RESULTS = 'results',
111 BATCHES = 'batches',
112+ BATCH_COUNT = 'batch_count',
113 SEARCH_SLOT = 'search_slot',
114 FOOTER_SLOT = 'footer_slot',
115 SELECTED_BATCH = 'selected_batch',
116@@ -217,19 +218,46 @@
117 },
118
119 /**
120+ * Return the batch page information.
121+ *
122+ * @method _getBatches
123+ * @protected
124+ */
125+ _getBatches: function() {
126+ var batches = this.get(BATCHES);
127+
128+ if (batches === null) {
129+ var batch_count = this.get(BATCH_COUNT);
130+ if (batch_count === null) {
131+ batches = [];
132+ }
133+ else {
134+ batches = [];
135+ // Only create batch pages when there's more than one.
136+ if (batch_count > 1) {
137+ for (var i = 0; i < batch_count; i++) {
138+ batches.push({ value: i, name: i + 1 });
139+ }
140+ }
141+ }
142+ }
143+ return batches;
144+ },
145+
146+ /**
147 * Update the batches container in the UI.
148 *
149 * @method _syncBatchesUI
150 * @protected
151 */
152 _syncBatchesUI: function() {
153- var options = this.get(BATCHES);
154+ var batches = this._getBatches();
155
156 // Clear previous batches.
157 Y.Event.purgeElement(this._batches_box, true);
158 this._batches_box.set('innerHTML', '');
159
160- if (options.length === 0) {
161+ if (batches.length === 0) {
162 this._prev_button = null;
163 this._next_button = null;
164 return;
165@@ -243,11 +271,11 @@
166 this.set(SELECTED_BATCH, selected);
167 this.fire(
168 SEARCH, this.get(CURRENT_SEARCH_STRING),
169- options[selected].value);
170+ batches[selected].value);
171 }, this);
172 this._batches_box.appendChild(this._prev_button);
173
174- Y.Array.each(options, function(data, i) {
175+ Y.Array.each(batches, function(data, i) {
176 var batch_item = Y.Node.create('<span></span>');
177 batch_item.appendChild(
178 document.createTextNode(data.name));
179@@ -267,7 +295,7 @@
180 this.set(SELECTED_BATCH, selected);
181 this.fire(
182 SEARCH, this.get(CURRENT_SEARCH_STRING),
183- this.get(BATCHES)[selected].value);
184+ batches[selected].value);
185 }, this);
186 },
187
188@@ -279,7 +307,6 @@
189 */
190 _syncSelectedBatchUI: function() {
191 var idx = this.get(SELECTED_BATCH);
192-
193 var items = this._batches_box.queryAll('span');
194 if (items.size()) {
195 this._prev_button.set('disabled', idx === 0);
196@@ -501,19 +528,15 @@
197 this._syncFooterSlotUI();
198 }, this);
199
200- // Update the batch list whenever the "batches" property
201- // is changed, and reset the selected one to the first one.
202- this.after('batchesChange', function (e) {
203+ // Update the batch list whenever the "batches" or "results" property
204+ // is changed.
205+ var doBatchesChange = function (e) {
206 this._syncBatchesUI();
207- if (this.get(SELECTED_BATCH) === 0){
208- // If the attribute is already set to the same value,
209- // the 'after' events won't be triggered, so we have
210- // to trigger it manually.
211- this._syncSelectedBatchUI();
212- } else {
213- this.set(SELECTED_BATCH, 0);
214- }
215- }, this);
216+ this._syncSelectedBatchUI();
217+ };
218+
219+ this.after('batchesChange', doBatchesChange, this);
220+ this.after('resultsChange', doBatchesChange, this);
221
222 // Keep the UI in sync with the currently selected batch.
223 this.after('selected_batchChange', function (e) {
224@@ -561,7 +584,8 @@
225 this.set(CURRENT_SEARCH_STRING, '');
226 this.set(ERROR, '');
227 this.set(RESULTS, [{}]);
228- this.set(BATCHES, []);
229+ this.set(BATCHES, null);
230+ this.set(BATCH_COUNT, null);
231 this._search_input.set('value', '');
232 this._results_box.set('innerHTML', '');
233 },
234@@ -702,7 +726,7 @@
235
236 /**
237 * An extra CSS class to be added to the picker_activator, generally used
238- * to distinguish regular links from js-triggering ones.
239+ * to distinguish regular links from js-triggering ones.
240 *
241 * @attribute picker_activator_css_class
242 * @type String
243@@ -773,7 +797,22 @@
244 * @attribute batches
245 * @type Array
246 */
247- batches: {value: []},
248+ batches: {value: null},
249+
250+ /**
251+ * For simplified batch creation, you can set this to the number of
252+ * batches in the search results. In this case, the batch labels
253+ * and values are automatically calculated. The batch name (used as the
254+ * batch label) will be the batch number starting from 1. The batch value
255+ * (used as additional details to the SEARCH event) will be the batch
256+ * number, starting from zero.
257+ *
258+ * If 'batches' is set (see above), batch_count is ignored.
259+ *
260+ * @attribute batch_count
261+ * @type Integer
262+ */
263+ batch_count: {value: null},
264
265 /**
266 * Batch currently selected.
267@@ -787,9 +826,10 @@
268 return value || 0;
269 },
270 validator: function (value) {
271+ var batches = this._getBatches();
272 return Y.Lang.isNumber(value) &&
273 value >= 0 &&
274- value < this.get(BATCHES).length;
275+ value < batches.length;
276 }},
277
278 /**
279
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 "There should be a next button.");
285 },
286
287+ test_simplified_batching_interface: function () {
288+ this.picker.render();
289+ this.picker.set('batch_count', 4);
290+ this.picker.set('results', [
291+ { value: 'aardvark', title: 'Aardvarks' },
292+ { value: 'bats', title: 'Bats' },
293+ { value: 'cats', title: 'Cats' },
294+ { value: 'dogs', title: 'Dogs' },
295+ { value: 'emus', title: 'Emus' },
296+ { value: 'frogs', title: 'Frogs' },
297+ { value: 'gerbils', title: 'Gerbils' }
298+ ]);
299+ var bb = this.picker.get('boundingBox');
300+ Assert.isNotNull(
301+ bb.query('.yui-picker-batches span'),
302+ "Container for batches not found.");
303+ var batches = bb.queryAll('.yui-picker-batches span');
304+ Assert.isNotNull(batches, "Batches not found");
305+ Assert.areEqual(4, batches.size());
306+ ArrayAssert.itemsAreEqual(
307+ ['1', '2', '3', '4'],
308+ batches.get('text'),
309+ "Batches don't contain batch names.");
310+ ArrayAssert.itemsAreEqual(
311+ [true, false, false, false],
312+ batches.hasClass('yui-picker-selected-batch'),
313+ "Selected batches missing CSS class.");
314+
315+ Assert.isNotNull(
316+ bb.query('.yui-picker-batches .lazr-prev'),
317+ "There should be a previous button.");
318+ Assert.isNotNull(
319+ bb.query('.yui-picker-batches .lazr-next'),
320+ "There should be a next button.");
321+ },
322+
323 test_clicking_a_batch_item_fires_search_event: function () {
324 this.picker.set('current_search_string', 'search');
325 this.picker.set('batches', [

Subscribers

People subscribed via source and target branches