]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | describe("Ext.grid.column.Widget", function() {\r |
2 | var webkitIt = Ext.isWebKit ? it : xit,\r | |
3 | synchronousLoad = true,\r | |
4 | proxyStoreLoad = Ext.data.ProxyStore.prototype.load,\r | |
5 | loadStore;\r | |
6 | \r | |
7 | var Model = Ext.define(null, {\r | |
8 | extend: 'Ext.data.Model',\r | |
9 | fields: ['a', 'b', 'c']\r | |
10 | });\r | |
11 | \r | |
12 | var grid, view, store, colRef, navModel;\r | |
13 | \r | |
14 | function generateData(end) {\r | |
15 | var data = [],\r | |
16 | i;\r | |
17 | \r | |
18 | end = end || 10;\r | |
19 | \r | |
20 | for (i = 1; i <= end; i++) {\r | |
21 | data.push({\r | |
22 | id: 'rec' + i,\r | |
23 | a: i + 'a',\r | |
24 | b: i + 'b',\r | |
25 | c: i + 'c'\r | |
26 | });\r | |
27 | }\r | |
28 | \r | |
29 | return data;\r | |
30 | }\r | |
31 | \r | |
32 | function getColCfg(widget) {\r | |
33 | return {\r | |
34 | text: 'Button',\r | |
35 | xtype: 'widgetcolumn',\r | |
36 | width: 200,\r | |
37 | dataIndex: 'a',\r | |
38 | widget: widget\r | |
39 | };\r | |
40 | }\r | |
41 | \r | |
42 | function createGrid(columns, data, cfg) {\r | |
43 | columns = columns || [getColCfg({\r | |
44 | xtype: 'button'\r | |
45 | })];\r | |
46 | \r | |
47 | data = data || generateData(4);\r | |
48 | \r | |
49 | store = new Ext.data.Store({\r | |
50 | model: Model,\r | |
51 | data: data,\r | |
52 | proxy: {\r | |
53 | type: 'memory',\r | |
54 | data: data\r | |
55 | }\r | |
56 | });\r | |
57 | \r | |
58 | grid = new Ext.grid.Panel(Ext.apply({\r | |
59 | renderTo: Ext.getBody(),\r | |
60 | columns: columns,\r | |
61 | width: 1000,\r | |
62 | height: 500,\r | |
63 | border: false,\r | |
64 | store: store,\r | |
65 | viewConfig: {\r | |
66 | mouseOverOutBuffer: 0\r | |
67 | }\r | |
68 | }, cfg));\r | |
69 | view = grid.getView();\r | |
70 | navModel = view.getNavigationModel();\r | |
71 | colRef = grid.getColumnManager().getColumns();\r | |
72 | }\r | |
73 | \r | |
74 | beforeEach(function() {\r | |
75 | // Override so that we can control asynchronous loading\r | |
76 | loadStore = Ext.data.ProxyStore.prototype.load = function() {\r | |
77 | proxyStoreLoad.apply(this, arguments);\r | |
78 | if (synchronousLoad) {\r | |
79 | this.flushLoad.apply(this, arguments);\r | |
80 | }\r | |
81 | return this;\r | |
82 | };\r | |
83 | });\r | |
84 | \r | |
85 | afterEach(function() {\r | |
86 | // Undo the overrides.\r | |
87 | Ext.data.ProxyStore.prototype.load = proxyStoreLoad;\r | |
88 | \r | |
89 | Ext.destroy(grid);\r | |
90 | grid = store = colRef = null;\r | |
91 | });\r | |
92 | \r | |
93 | function getWidget(index, col) {\r | |
94 | col = col || colRef[0];\r | |
95 | return col.getWidget(store.getAt(index));\r | |
96 | }\r | |
97 | \r | |
98 | function getPadding() {\r | |
99 | var cell = grid.getView().getEl().down(colRef[0].getCellInnerSelector());\r | |
100 | return parseInt(cell.getStyle('padding-left'), 10) + parseInt(cell.getStyle('padding-right'), 10);\r | |
101 | }\r | |
102 | \r | |
103 | describe('refocusing after using a column widget to trigger a delete', function() {\r | |
104 | it('should refocus the next row upon deletion', function() {\r | |
105 | createGrid([{\r | |
106 | text: 'Button',\r | |
107 | xtype: 'widgetcolumn',\r | |
108 | width: 200,\r | |
109 | dataIndex: 'a',\r | |
110 | widget: {\r | |
111 | xtype: 'button',\r | |
112 | text: 'Delete row',\r | |
113 | handler: function(button) {\r | |
114 | var rec = button.getWidgetRecord();\r | |
115 | store.remove(rec);\r | |
116 | }\r | |
117 | }\r | |
118 | }]);\r | |
119 | \r | |
120 | var widget0 = getWidget(0),\r | |
121 | rec0 = store.getAt(0),\r | |
122 | rec1 = store.getAt(1),\r | |
123 | toDelete = widget0.getWidgetRecord(),\r | |
124 | newTop = getWidget(1).getWidgetRecord(),\r | |
125 | storeCount = store.getCount();\r | |
126 | \r | |
127 | expect(toDelete).toBe(rec0);\r | |
128 | expect(newTop).toBe(rec1);\r | |
129 | \r | |
130 | // Focus the button, and enter actionable mode, then click the button.\r | |
131 | jasmine.fireMouseEvent(widget0.focusEl, 'mousedown');\r | |
132 | widget0.focusEl.focus();\r | |
133 | jasmine.fireKeyEvent(widget0.focusEl, 'keydown', Ext.event.Event.SPACE);\r | |
134 | \r | |
135 | // That should have deleted a record\r | |
136 | expect(store.getCount()).toBe(storeCount - 1);\r | |
137 | \r | |
138 | // The widget's record must have gone\r | |
139 | expect(store.contains(toDelete)).toBe(false);\r | |
140 | \r | |
141 | // Widget 0 must receive focus when any async focus events have run their course\r | |
142 | waitsFor(function() {\r | |
143 | widget0 = getWidget(0);\r | |
144 | return widget0.hasFocus;\r | |
145 | });\r | |
146 | \r | |
147 | runs(function() {\r | |
148 | // Widget 0 record must be what we got from widget 1 initially\r | |
149 | expect(widget0.getWidgetRecord()).toBe(newTop);\r | |
150 | });\r | |
151 | });\r | |
152 | });\r | |
153 | \r | |
154 | describe("Widget recycling across refresh", function() {\r | |
155 | it("should recycle widgets", function() {\r | |
156 | var cfg = {\r | |
157 | xtype: 'button',\r | |
158 | cls: 'foo'\r | |
159 | };\r | |
160 | \r | |
161 | createGrid([getColCfg(cfg)]);\r | |
162 | var w1 = getWidget(0),\r | |
163 | w2 = getWidget(1),\r | |
164 | w3 = getWidget(2),\r | |
165 | w4 = getWidget(3);\r | |
166 | \r | |
167 | // The store is cleared on reload.\r | |
168 | // Widget instances MUST be collected for reuse.\r | |
169 | store.reload();\r | |
170 | \r | |
171 | // The Widgets should have been reused.\r | |
172 | expect(getWidget(0) === w1).toBe(true);\r | |
173 | expect(getWidget(1) === w2).toBe(true);\r | |
174 | expect(getWidget(2) === w3).toBe(true);\r | |
175 | expect(getWidget(3) === w4).toBe(true);\r | |
176 | });\r | |
177 | });\r | |
178 | \r | |
179 | describe("construction", function() {\r | |
180 | it("should not modify the widget config", function() {\r | |
181 | var cfg = {\r | |
182 | xtype: 'button',\r | |
183 | cls: 'foo'\r | |
184 | };\r | |
185 | \r | |
186 | createGrid([getColCfg(cfg)]);\r | |
187 | expect(cfg).toEqual({\r | |
188 | xtype: 'button',\r | |
189 | cls: 'foo'\r | |
190 | });\r | |
191 | });\r | |
192 | });\r | |
193 | \r | |
194 | describe('widget refocus on row delete', function() {\r | |
195 | // Test that focus reversion upon delete of focus-containing row works.\r | |
196 | webkitIt("should not cause an error when deleting the focused row using an actionable widget", function() {\r | |
197 | createGrid([{\r | |
198 | itemId: 'ct',\r | |
199 | columns: [getColCfg({\r | |
200 | xtype: 'button',\r | |
201 | handler: function(btn) {\r | |
202 | var rec = btn.getWidgetRecord();\r | |
203 | store.remove(rec);\r | |
204 | }\r | |
205 | })]\r | |
206 | }]);\r | |
207 | var btn = colRef[0].getWidget(store.last());\r | |
208 | \r | |
209 | // The mousedown part will focus the button, and flip into actionable mode.\r | |
210 | // The click phase will delete the row.\r | |
211 | // Focus should revert to the previous row\r | |
212 | jasmine.fireMouseEvent(btn.el.dom, 'click');\r | |
213 | \r | |
214 | // Should remove the last record\r | |
215 | expect(view.all.getCount()).toBe(3);\r | |
216 | \r | |
217 | // And focus should have jumped from the mousedowned button (which has gone)\r | |
218 | // to the button above it.\r | |
219 | expect(colRef[0].getWidget(store.last()).hasFocus).toBe(true);\r | |
220 | });\r | |
221 | });\r | |
222 | \r | |
223 | describe("stopSelection", function() {\r | |
224 | beforeEach(function() {\r | |
225 | createGrid();\r | |
226 | });\r | |
227 | \r | |
228 | it("should not select the row on click of the widget with stopSelection: true", function() {\r | |
229 | jasmine.fireMouseEvent(getWidget(0).getEl().dom, 'click');\r | |
230 | expect(grid.getSelectionModel().isSelected(0)).toBe(false);\r | |
231 | });\r | |
232 | \r | |
233 | it("should select the row on click of the widget with stopSelection: false", function() {\r | |
234 | colRef[0].stopSelection = false;\r | |
235 | navModel.setPosition(new Ext.grid.CellContext(grid.view).setPosition(0, 0));\r | |
236 | \r | |
237 | waitsFor(function() {\r | |
238 | return view.containsFocus;\r | |
239 | });\r | |
240 | \r | |
241 | // Wait for focus to be in the view.\r | |
242 | // Because IE has async focusing.\r | |
243 | runs(function() {\r | |
244 | jasmine.fireMouseEvent(getWidget(0).getEl().dom, 'click');\r | |
245 | expect(grid.getSelectionModel().isSelected(0)).toBe(true);\r | |
246 | });\r | |
247 | });\r | |
248 | });\r | |
249 | \r | |
250 | describe("widget scope resolution", function() {\r | |
251 | it("should resolve to a view controller", function() {\r | |
252 | var Cls = Ext.define(null, {\r | |
253 | extend: 'Ext.app.ViewController',\r | |
254 | onButtonClick: function() {}\r | |
255 | });\r | |
256 | \r | |
257 | var ctrl = new Cls();\r | |
258 | createGrid([getColCfg({\r | |
259 | xtype: 'button',\r | |
260 | handler: 'onButtonClick'\r | |
261 | })], undefined, {\r | |
262 | controller: ctrl\r | |
263 | });\r | |
264 | \r | |
265 | spyOn(ctrl, 'onButtonClick');\r | |
266 | jasmine.fireMouseEvent(getWidget(0).getEl().dom, 'click');\r | |
267 | expect(ctrl.onButtonClick).toHaveBeenCalled();\r | |
268 | });\r | |
269 | \r | |
270 | it("should handle scope: 'this'", function() {\r | |
271 | Ext.define('spec.Button', {\r | |
272 | extend: 'Ext.button.Button',\r | |
273 | alias: 'widget.subbutton',\r | |
274 | onButtonClick: function() {}\r | |
275 | });\r | |
276 | \r | |
277 | createGrid([getColCfg({\r | |
278 | xtype: 'subbutton',\r | |
279 | handler: 'onButtonClick',\r | |
280 | scope: 'this'\r | |
281 | })]);\r | |
282 | \r | |
283 | var btn = getWidget(0);\r | |
284 | spyOn(btn, 'onButtonClick');\r | |
285 | \r | |
286 | jasmine.fireMouseEvent(getWidget(0).getEl().dom, 'click');\r | |
287 | expect(btn.onButtonClick).toHaveBeenCalled();\r | |
288 | \r | |
289 | Ext.undefine('spec.Button');\r | |
290 | });\r | |
291 | });\r | |
292 | \r | |
293 | function createBufferedSuite(withBuffered) {\r | |
294 | describe(withBuffered ? "with buffered rendering" : "without buffered rendering", function() {\r | |
295 | function makeGrid(columns, data, cfg) {\r | |
296 | cfg = cfg || {};\r | |
297 | cfg.bufferedRenderer = !!withBuffered;\r | |
298 | createGrid(columns, data, cfg);\r | |
299 | }\r | |
300 | \r | |
301 | function checkPositions(start) {\r | |
302 | start = start || 0;\r | |
303 | \r | |
304 | var col = grid.down('widgetcolumn'),\r | |
305 | view = grid.getView(),\r | |
306 | selector, cells, len, i;\r | |
307 | \r | |
308 | if (col && view.viewReady) {\r | |
309 | selector = col.getCellInnerSelector();\r | |
310 | cells = view.getEl().select(selector, true);\r | |
311 | len = cells.getCount();\r | |
312 | \r | |
313 | for (i = start; i < len; ++i) {\r | |
314 | expect(getWidget(i, col).getEl().dom.parentNode).toBe(cells.item(i).dom);\r | |
315 | }\r | |
316 | }\r | |
317 | }\r | |
318 | \r | |
319 | describe("basic functionality", function() {\r | |
320 | it("should render a widget for each row", function() {\r | |
321 | makeGrid();\r | |
322 | expect(getWidget(0).isComponent).toBe(true);\r | |
323 | expect(getWidget(1).isComponent).toBe(true);\r | |
324 | expect(getWidget(2).isComponent).toBe(true);\r | |
325 | expect(getWidget(3).isComponent).toBe(true);\r | |
326 | checkPositions();\r | |
327 | });\r | |
328 | \r | |
329 | it('should not bust the row height when showing a button', function() {\r | |
330 | var columns = [getColCfg({\r | |
331 | xtype: 'button'\r | |
332 | }), {\r | |
333 | text: 'Data',\r | |
334 | dataIndex: 'b'\r | |
335 | }],\r | |
336 | rowHeight;\r | |
337 | \r | |
338 | // Widget column initially hidden\r | |
339 | columns[0].hidden = true;\r | |
340 | \r | |
341 | makeGrid(columns);\r | |
342 | \r | |
343 | // Capture default, text-only row height\r | |
344 | rowHeight = grid.view.getNode(0).offsetHeight;\r | |
345 | \r | |
346 | // Show the widget column with buttons\r | |
347 | colRef[0].show();\r | |
348 | \r | |
349 | // Showing the button should NOT change the row's height\r | |
350 | // https://sencha.jira.com/browse/EXTJS-13766\r | |
351 | expect(grid.view.getNode(0).offsetHeight).toBe(rowHeight);\r | |
352 | checkPositions();\r | |
353 | });\r | |
354 | \r | |
355 | it("should render the matching xtype", function() {\r | |
356 | makeGrid();\r | |
357 | expect(getWidget(0).getXType()).toBe('button');\r | |
358 | checkPositions();\r | |
359 | });\r | |
360 | \r | |
361 | it("should pass in other configurations", function() {\r | |
362 | makeGrid([getColCfg({\r | |
363 | xtype: 'button',\r | |
364 | enableToggle: true,\r | |
365 | pressed: true\r | |
366 | })]);\r | |
367 | \r | |
368 | var widget = getWidget(0);\r | |
369 | expect(widget.pressed).toBe(true);\r | |
370 | expect(widget.enableToggle).toBe(true);\r | |
371 | checkPositions();\r | |
372 | });\r | |
373 | \r | |
374 | it("should create a new instance for each row", function() {\r | |
375 | makeGrid();\r | |
376 | var w1 = getWidget(0),\r | |
377 | w2 = getWidget(1),\r | |
378 | w3 = getWidget(2),\r | |
379 | w4 = getWidget(3);\r | |
380 | \r | |
381 | expect(w2).not.toBe(w1);\r | |
382 | expect(w3).not.toBe(w1);\r | |
383 | expect(w4).not.toBe(w1);\r | |
384 | \r | |
385 | expect(w3).not.toBe(w2);\r | |
386 | expect(w4).not.toBe(w2);\r | |
387 | \r | |
388 | expect(w4).not.toBe(w3);\r | |
389 | \r | |
390 | checkPositions();\r | |
391 | });\r | |
392 | \r | |
393 | it("should set the value of the defaultBindProperty on the widget to the dataIndex", function() {\r | |
394 | makeGrid();\r | |
395 | expect(getWidget(0).getText()).toBe('1a');\r | |
396 | expect(getWidget(1).getText()).toBe('2a');\r | |
397 | expect(getWidget(2).getText()).toBe('3a');\r | |
398 | expect(getWidget(3).getText()).toBe('4a');\r | |
399 | checkPositions();\r | |
400 | });\r | |
401 | \r | |
402 | it("should not modify the defaultBindProperty if there is no dataIndex", function() {\r | |
403 | makeGrid([{\r | |
404 | xtype: 'widgetcolumn',\r | |
405 | width: 200, \r | |
406 | widget: {\r | |
407 | xtype: 'button',\r | |
408 | text: 'Foo'\r | |
409 | }\r | |
410 | }]);\r | |
411 | expect(getWidget(0).getText()).toBe('Foo');\r | |
412 | expect(getWidget(1).getText()).toBe('Foo');\r | |
413 | expect(getWidget(2).getText()).toBe('Foo');\r | |
414 | expect(getWidget(3).getText()).toBe('Foo');\r | |
415 | checkPositions();\r | |
416 | });\r | |
417 | });\r | |
418 | \r | |
419 | describe("tdCls", function() {\r | |
420 | it("should get the tdCls from the widget", function() {\r | |
421 | makeGrid([getColCfg({\r | |
422 | xtype: 'button',\r | |
423 | getTdCls: function() {\r | |
424 | return 'foo';\r | |
425 | }\r | |
426 | })]);\r | |
427 | expect(view.getCellByPosition({row: 0, column: 0})).toHaveCls('foo');\r | |
428 | expect(view.getCellByPosition({row: 1, column: 0})).toHaveCls('foo');\r | |
429 | expect(view.getCellByPosition({row: 2, column: 0})).toHaveCls('foo');\r | |
430 | expect(view.getCellByPosition({row: 3, column: 0})).toHaveCls('foo');\r | |
431 | });\r | |
432 | \r | |
433 | it("should combine a tdCls on the column with the tdCls on the widget", function() {\r | |
434 | var cfg = getColCfg({\r | |
435 | xtype: 'button',\r | |
436 | getTdCls: function() {\r | |
437 | return 'foo';\r | |
438 | }\r | |
439 | });\r | |
440 | cfg.tdCls = 'bar';\r | |
441 | makeGrid([cfg]);\r | |
442 | expect(view.getCellByPosition({row: 0, column: 0})).toHaveCls('foo');\r | |
443 | expect(view.getCellByPosition({row: 0, column: 0})).toHaveCls('bar');\r | |
444 | expect(view.getCellByPosition({row: 1, column: 0})).toHaveCls('foo');\r | |
445 | expect(view.getCellByPosition({row: 1, column: 0})).toHaveCls('bar');\r | |
446 | expect(view.getCellByPosition({row: 2, column: 0})).toHaveCls('foo');\r | |
447 | expect(view.getCellByPosition({row: 2, column: 0})).toHaveCls('bar');\r | |
448 | expect(view.getCellByPosition({row: 3, column: 0})).toHaveCls('foo');\r | |
449 | expect(view.getCellByPosition({row: 3, column: 0})).toHaveCls('bar');\r | |
450 | });\r | |
451 | });\r | |
452 | \r | |
453 | describe("onWidgetAttach", function() {\r | |
454 | var spy;\r | |
455 | beforeEach(function() {\r | |
456 | spy = jasmine.createSpy();\r | |
457 | });\r | |
458 | \r | |
459 | afterEach(function() {\r | |
460 | spy = null;\r | |
461 | });\r | |
462 | \r | |
463 | it("should call the method during render", function() {\r | |
464 | var cfg = getColCfg({\r | |
465 | xtype: 'button'\r | |
466 | });\r | |
467 | cfg.onWidgetAttach = spy;\r | |
468 | makeGrid([cfg]);\r | |
469 | expect(spy.callCount).toBe(store.getCount());\r | |
470 | });\r | |
471 | \r | |
472 | it("should pass the column, the widget instance and the record", function() {\r | |
473 | var cfg = getColCfg({\r | |
474 | xtype: 'button'\r | |
475 | });\r | |
476 | cfg.onWidgetAttach = spy;\r | |
477 | makeGrid([cfg]);\r | |
478 | \r | |
479 | expect(spy.calls[0].args[0]).toBe(colRef[0]);\r | |
480 | expect(spy.calls[0].args[1].isButton).toBe(true);\r | |
481 | expect(spy.calls[0].args[2]).toBe(store.getAt(0));\r | |
482 | \r | |
483 | expect(spy.calls[1].args[0]).toBe(colRef[0]);\r | |
484 | expect(spy.calls[1].args[1].isButton).toBe(true);\r | |
485 | expect(spy.calls[1].args[2]).toBe(store.getAt(1));\r | |
486 | \r | |
487 | expect(spy.calls[2].args[0]).toBe(colRef[0]);\r | |
488 | expect(spy.calls[2].args[1].isButton).toBe(true);\r | |
489 | expect(spy.calls[2].args[2]).toBe(store.getAt(2));\r | |
490 | \r | |
491 | expect(spy.calls[3].args[0]).toBe(colRef[0]);\r | |
492 | expect(spy.calls[3].args[1].isButton).toBe(true);\r | |
493 | expect(spy.calls[3].args[2]).toBe(store.getAt(3));\r | |
494 | });\r | |
495 | \r | |
496 | it("should get called when a new record is added", function() {\r | |
497 | var cfg = getColCfg({\r | |
498 | xtype: 'button'\r | |
499 | });\r | |
500 | cfg.onWidgetAttach = spy;\r | |
501 | makeGrid([cfg]);\r | |
502 | spy.reset();\r | |
503 | var rec = store.insert(2, {})[0],\r | |
504 | spyCall = spy.mostRecentCall;\r | |
505 | \r | |
506 | expect(spy.callCount).toBe(1);\r | |
507 | expect(spyCall.args[0]).toBe(colRef[0]);\r | |
508 | expect(spyCall.args[1].isButton).toBe(true);\r | |
509 | expect(spyCall.args[2]).toBe(rec);\r | |
510 | });\r | |
511 | \r | |
512 | if (withBuffered) {\r | |
513 | it("should only be called for records in the view", function() {\r | |
514 | var cfg = getColCfg({\r | |
515 | xtype: 'button'\r | |
516 | });\r | |
517 | cfg.onWidgetAttach = spy;\r | |
518 | var data = [],\r | |
519 | i = 0,\r | |
520 | recordSize = 10000;\r | |
521 | \r | |
522 | for (i = 1; i <= recordSize; ++i) {\r | |
523 | data.push({\r | |
524 | id: 'rec' + i\r | |
525 | });\r | |
526 | }\r | |
527 | makeGrid([cfg], data);\r | |
528 | \r | |
529 | var view = grid.getView(),\r | |
530 | nodes = view.getNodes(),\r | |
531 | firstNode = nodes[0],\r | |
532 | len = nodes.length;\r | |
533 | \r | |
534 | expect(spy.callCount).toBeLessThan(recordSize);\r | |
535 | for (i = 0; i < len; ++i) {\r | |
536 | expect(spy.calls[i].args[2]).toBe(store.getAt(i));\r | |
537 | }\r | |
538 | checkPositions();\r | |
539 | \r | |
540 | spy.reset();\r | |
541 | // Force it to the end, wait for the re-render\r | |
542 | grid.bufferedRenderer.scrollTo(recordSize * 100);\r | |
543 | waitsFor(function() {\r | |
544 | return view.getNodes()[0] !== firstNode;\r | |
545 | });\r | |
546 | \r | |
547 | runs(function() {\r | |
548 | nodes = view.getNodes();\r | |
549 | len = nodes.length;\r | |
550 | var offset = recordSize - len;\r | |
551 | \r | |
552 | for (i = 0; i < len; ++i) {\r | |
553 | expect(spy.calls[i].args[2]).toBe(store.getAt(i + offset));\r | |
554 | }\r | |
555 | checkPositions(offset);\r | |
556 | });\r | |
557 | });\r | |
558 | }\r | |
559 | \r | |
560 | describe("scope", function() {\r | |
561 | it("should default the scope to the column", function() {\r | |
562 | var cfg = getColCfg({\r | |
563 | xtype: 'button'\r | |
564 | });\r | |
565 | cfg.onWidgetAttach = spy;\r | |
566 | makeGrid([cfg]);\r | |
567 | expect(spy.mostRecentCall.object).toBe(colRef[0]);\r | |
568 | });\r | |
569 | \r | |
570 | it("should use a passed scope", function() {\r | |
571 | var cfg = getColCfg({\r | |
572 | xtype: 'button'\r | |
573 | }), o = {};\r | |
574 | cfg.onWidgetAttach = spy;\r | |
575 | cfg.scope = o;\r | |
576 | makeGrid([cfg]);\r | |
577 | expect(spy.mostRecentCall.object).toBe(o);\r | |
578 | });\r | |
579 | \r | |
580 | it("should be able to resolve to a view controller method", function() {\r | |
581 | var cfg = getColCfg({\r | |
582 | xtype: 'button'\r | |
583 | });\r | |
584 | var ctrl = new Ext.app.ViewController();\r | |
585 | ctrl.doSomething = spy;\r | |
586 | cfg.onWidgetAttach = 'doSomething';\r | |
587 | makeGrid([cfg], null, {\r | |
588 | controller: ctrl\r | |
589 | });\r | |
590 | expect(spy.callCount).toBe(4);\r | |
591 | });\r | |
592 | });\r | |
593 | });\r | |
594 | \r | |
595 | describe("add/remove column", function() {\r | |
596 | it("should render widgets when adding the column dynamically", function() {\r | |
597 | makeGrid([]);\r | |
598 | grid.headerCt.add(getColCfg({\r | |
599 | xtype: 'button'\r | |
600 | }));\r | |
601 | colRef = grid.getColumnManager().getColumns();\r | |
602 | expect(getWidget(0).getText()).toBe('1a');\r | |
603 | expect(getWidget(1).getText()).toBe('2a');\r | |
604 | expect(getWidget(2).getText()).toBe('3a');\r | |
605 | expect(getWidget(3).getText()).toBe('4a');\r | |
606 | checkPositions();\r | |
607 | });\r | |
608 | \r | |
609 | it("should not cause an error when removing", function() {\r | |
610 | makeGrid();\r | |
611 | expect(function() {\r | |
612 | grid.headerCt.remove(colRef[0]);\r | |
613 | }).not.toThrow();\r | |
614 | });\r | |
615 | \r | |
616 | it("should be able to re-use the column", function() {\r | |
617 | makeGrid();\r | |
618 | grid.headerCt.remove(colRef[0], false);\r | |
619 | grid.headerCt.add(colRef[0]);\r | |
620 | expect(getWidget(0).getText()).toBe('1a');\r | |
621 | expect(getWidget(1).getText()).toBe('2a');\r | |
622 | expect(getWidget(2).getText()).toBe('3a');\r | |
623 | expect(getWidget(3).getText()).toBe('4a');\r | |
624 | checkPositions();\r | |
625 | });\r | |
626 | \r | |
627 | it("should be able to move a column to the left", function() {\r | |
628 | makeGrid([{}, getColCfg({\r | |
629 | xtype: 'button'\r | |
630 | })]);\r | |
631 | grid.headerCt.moveBefore(colRef[0], colRef[1]);\r | |
632 | checkPositions();\r | |
633 | });\r | |
634 | \r | |
635 | it("should be able to move a column to the right", function() {\r | |
636 | makeGrid([getColCfg({\r | |
637 | xtype: 'button'\r | |
638 | }), {}]);\r | |
639 | grid.headerCt.moveAfter(colRef[1], colRef[0]);\r | |
640 | checkPositions();\r | |
641 | });\r | |
642 | });\r | |
643 | \r | |
644 | describe("widget sizing", function() {\r | |
645 | it("should not cause an error if the view is not rendered", function() {\r | |
646 | makeGrid(undefined, undefined, {\r | |
647 | renderTo: null\r | |
648 | });\r | |
649 | expect(function() {\r | |
650 | colRef[0].setWidth(400);\r | |
651 | }).not.toThrow();\r | |
652 | });\r | |
653 | \r | |
654 | it("should not cause an error if the store is empty", function() {\r | |
655 | expect(function() {\r | |
656 | makeGrid(undefined, []);\r | |
657 | }).not.toThrow();\r | |
658 | });\r | |
659 | \r | |
660 | it("should not cause an error if there are no records in the view", function() {\r | |
661 | makeGrid();\r | |
662 | store.removeAll();\r | |
663 | expect(function() {\r | |
664 | colRef[0].setWidth(400);\r | |
665 | }).not.toThrow();\r | |
666 | });\r | |
667 | \r | |
668 | it("should not modify the width if the widget is configured with a width", function() {\r | |
669 | makeGrid([getColCfg({\r | |
670 | xtype: 'button',\r | |
671 | width: 50\r | |
672 | })]);\r | |
673 | colRef = grid.getColumnManager().getColumns();\r | |
674 | expect(getWidget(0).getWidth()).toBe(50);\r | |
675 | expect(getWidget(1).getWidth()).toBe(50);\r | |
676 | expect(getWidget(2).getWidth()).toBe(50);\r | |
677 | expect(getWidget(3).getWidth()).toBe(50);\r | |
678 | });\r | |
679 | \r | |
680 | it("should set the width to the column size minus the padding by on initial render", function() {\r | |
681 | makeGrid();\r | |
682 | \r | |
683 | var padding = getPadding();\r | |
684 | \r | |
685 | expect(getWidget(0).getWidth()).toBe(200 - padding);\r | |
686 | expect(getWidget(1).getWidth()).toBe(200 - padding);\r | |
687 | expect(getWidget(2).getWidth()).toBe(200 - padding);\r | |
688 | expect(getWidget(3).getWidth()).toBe(200 - padding);\r | |
689 | });\r | |
690 | \r | |
691 | it("should modify the widget size dynamically", function() {\r | |
692 | makeGrid();\r | |
693 | \r | |
694 | var padding = getPadding();\r | |
695 | \r | |
696 | colRef[0].setWidth(400);\r | |
697 | \r | |
698 | expect(getWidget(0).getWidth()).toBe(400 - padding);\r | |
699 | expect(getWidget(1).getWidth()).toBe(400 - padding);\r | |
700 | expect(getWidget(2).getWidth()).toBe(400 - padding);\r | |
701 | expect(getWidget(3).getWidth()).toBe(400 - padding);\r | |
702 | \r | |
703 | });\r | |
704 | \r | |
705 | it("should modify the size with a flexed column", function() {\r | |
706 | var col = getColCfg({\r | |
707 | xtype: 'button'\r | |
708 | });\r | |
709 | delete col.width;\r | |
710 | col.flex = 1;\r | |
711 | makeGrid([col]);\r | |
712 | \r | |
713 | var padding = getPadding();\r | |
714 | expect(getWidget(0).getWidth()).toBe(1000 - padding);\r | |
715 | expect(getWidget(1).getWidth()).toBe(1000 - padding);\r | |
716 | expect(getWidget(2).getWidth()).toBe(1000 - padding);\r | |
717 | expect(getWidget(3).getWidth()).toBe(1000 - padding);\r | |
718 | \r | |
719 | grid.setWidth(600);\r | |
720 | \r | |
721 | expect(getWidget(0).getWidth()).toBe(600 - padding);\r | |
722 | expect(getWidget(1).getWidth()).toBe(600 - padding);\r | |
723 | expect(getWidget(2).getWidth()).toBe(600 - padding);\r | |
724 | expect(getWidget(3).getWidth()).toBe(600 - padding);\r | |
725 | });\r | |
726 | \r | |
727 | it("should run layouts on components initially and when they are sized", function() {\r | |
728 | var col = getColCfg({\r | |
729 | xtype: 'container',\r | |
730 | layout: 'hbox',\r | |
731 | defaultType: 'component',\r | |
732 | items: [{\r | |
733 | flex: 1,\r | |
734 | html: 'A'\r | |
735 | }, {\r | |
736 | flex: 1,\r | |
737 | html: 'B'\r | |
738 | }]\r | |
739 | }), widget;\r | |
740 | \r | |
741 | delete col.dataIndex;\r | |
742 | \r | |
743 | makeGrid([col], generateData(2));\r | |
744 | \r | |
745 | var padding = getPadding(),\r | |
746 | availWidth = 200 - padding;\r | |
747 | \r | |
748 | function expectWidthAndLayout(c, width, counter) {\r | |
749 | expect(c.getWidth()).toBe(width);\r | |
750 | expect(c.componentLayoutCounter).toBe(counter);\r | |
751 | }\r | |
752 | \r | |
753 | widget = getWidget(0);\r | |
754 | expectWidthAndLayout(widget, availWidth, 1);\r | |
755 | expectWidthAndLayout(widget.items.getAt(0), availWidth / 2, 1);\r | |
756 | expectWidthAndLayout(widget.items.getAt(1), availWidth / 2, 1);\r | |
757 | \r | |
758 | widget = getWidget(1);\r | |
759 | expectWidthAndLayout(widget, availWidth, 1);\r | |
760 | expectWidthAndLayout(widget.items.getAt(0), availWidth / 2, 1);\r | |
761 | expectWidthAndLayout(widget.items.getAt(1), availWidth / 2, 1);\r | |
762 | \r | |
763 | colRef[0].setWidth(400);\r | |
764 | \r | |
765 | availWidth = 400 - padding;\r | |
766 | \r | |
767 | widget = getWidget(0);\r | |
768 | expectWidthAndLayout(widget, availWidth, 2);\r | |
769 | expectWidthAndLayout(widget.items.getAt(0), availWidth / 2, 2);\r | |
770 | expectWidthAndLayout(widget.items.getAt(1), availWidth / 2, 2);\r | |
771 | \r | |
772 | widget = getWidget(1);\r | |
773 | expectWidthAndLayout(widget, availWidth, 2);\r | |
774 | expectWidthAndLayout(widget.items.getAt(0), availWidth / 2, 2);\r | |
775 | expectWidthAndLayout(widget.items.getAt(1), availWidth / 2, 2);\r | |
776 | });\r | |
777 | \r | |
778 | it("should run layouts when the grid has a pending layout", function() {\r | |
779 | var col = getColCfg({\r | |
780 | xtype: 'component'\r | |
781 | }), widget, count;\r | |
782 | \r | |
783 | makeGrid([col], generateData(2));\r | |
784 | \r | |
785 | widget = getWidget(0);\r | |
786 | count = widget.componentLayoutCounter;\r | |
787 | Ext.suspendLayouts();\r | |
788 | grid.setWidth(grid.getWidth() + 100);\r | |
789 | colRef[0].setWidth(400);\r | |
790 | Ext.resumeLayouts(true);\r | |
791 | expect(widget.componentLayoutCounter).toBe(count + 1);\r | |
792 | });\r | |
793 | });\r | |
794 | \r | |
795 | describe("store modifications", function() {\r | |
796 | describe("before render", function() {\r | |
797 | beforeEach(function() {\r | |
798 | makeGrid(undefined, undefined, {\r | |
799 | renderTo: null\r | |
800 | });\r | |
801 | });\r | |
802 | \r | |
803 | it("should not cause an error when adding records", function() {\r | |
804 | expect(function() {\r | |
805 | var rec = store.add({});\r | |
806 | }).not.toThrow();\r | |
807 | });\r | |
808 | \r | |
809 | it("should not cause an error when removing items", function() {\r | |
810 | expect(function() {\r | |
811 | var rec = store.removeAt(0);\r | |
812 | }).not.toThrow();\r | |
813 | });\r | |
814 | \r | |
815 | it("should not cause an error when updating items", function() {\r | |
816 | expect(function() {\r | |
817 | var rec = store.first().set('a', 'X');\r | |
818 | }).not.toThrow();\r | |
819 | });\r | |
820 | \r | |
821 | it("should not cause an error when clearing the store", function() {\r | |
822 | expect(function() {\r | |
823 | store.removeAll();\r | |
824 | }).not.toThrow();\r | |
825 | });\r | |
826 | });\r | |
827 | \r | |
828 | describe("after render", function() {\r | |
829 | beforeEach(function() {\r | |
830 | makeGrid();\r | |
831 | });\r | |
832 | \r | |
833 | it("should add a new widget when adding a record", function() {\r | |
834 | store.add({\r | |
835 | a: 'New'\r | |
836 | });\r | |
837 | expect(getWidget(4).getText()).toBe('New');\r | |
838 | checkPositions();\r | |
839 | });\r | |
840 | \r | |
841 | it("should remove the widget when removing a record", function() {\r | |
842 | store.removeAt(3);\r | |
843 | expect(getWidget(3)).toBeNull();\r | |
844 | checkPositions();\r | |
845 | });\r | |
846 | \r | |
847 | it("should update the defaultBindProperty when changing a value", function() {\r | |
848 | store.first().set('a', 'NewValue');\r | |
849 | \r | |
850 | expect(getWidget(0).getText()).toBe('NewValue');\r | |
851 | checkPositions();\r | |
852 | });\r | |
853 | \r | |
854 | it("should add the cell dirty class when changing a value, and remove it when reverting that change", function() {\r | |
855 | var oldValue = store.first().get('a');\r | |
856 | \r | |
857 | store.first().set('a', 'NewValue');\r | |
858 | \r | |
859 | // Dirty class should be added to the cell\r | |
860 | expect(view.getCellByPosition({\r | |
861 | row: 0,\r | |
862 | column: 0\r | |
863 | }).hasCls(view.dirtyCls)).toBe(true);\r | |
864 | \r | |
865 | store.first().set('a', oldValue);\r | |
866 | \r | |
867 | // Dirty class should be removed from the cell\r | |
868 | expect(view.getCellByPosition({\r | |
869 | row: 0,\r | |
870 | column: 0\r | |
871 | }).hasCls(view.dirtyCls)).toBe(false);\r | |
872 | });\r | |
873 | \r | |
874 | it('should render with a cell dirty class set if the record is already modified', function() {\r | |
875 | // The beforeEach one cannot be used.\r | |
876 | grid.destroy();\r | |
877 | \r | |
878 | makeGrid(null, null, {\r | |
879 | renderTo: null\r | |
880 | });\r | |
881 | store.first().set('a', 'NewValue');\r | |
882 | grid.render(document.body);\r | |
883 | \r | |
884 | // Dirty class should be rendered into the cell\r | |
885 | expect(view.getCellByPosition({\r | |
886 | row: 0,\r | |
887 | column: 0\r | |
888 | }).hasCls(view.dirtyCls)).toBe(true);\r | |
889 | });\r | |
890 | \r | |
891 | it("should remove all widgets when calling removeAll", function() {\r | |
892 | store.removeAll();\r | |
893 | expect(getWidget(0)).toBeNull();\r | |
894 | checkPositions();\r | |
895 | });\r | |
896 | });\r | |
897 | });\r | |
898 | \r | |
899 | describe("widget decoration", function() {\r | |
900 | it("should add a method to get the column from the widget", function() {\r | |
901 | makeGrid();\r | |
902 | expect(getWidget(0).getWidgetColumn()).toBe(colRef[0]);\r | |
903 | expect(getWidget(1).getWidgetColumn()).toBe(colRef[0]);\r | |
904 | expect(getWidget(2).getWidgetColumn()).toBe(colRef[0]);\r | |
905 | expect(getWidget(3).getWidgetColumn()).toBe(colRef[0]);\r | |
906 | });\r | |
907 | \r | |
908 | it("should add a method to get the record from the widget", function() {\r | |
909 | makeGrid();\r | |
910 | expect(getWidget(0).getWidgetRecord()).toBe(store.getAt(0));\r | |
911 | expect(getWidget(1).getWidgetRecord()).toBe(store.getAt(1));\r | |
912 | expect(getWidget(2).getWidgetRecord()).toBe(store.getAt(2));\r | |
913 | expect(getWidget(3).getWidgetRecord()).toBe(store.getAt(3));\r | |
914 | });\r | |
915 | \r | |
916 | it("should have the record/column available before the bind is called", function() {\r | |
917 | var fooRec, barRec, col;\r | |
918 | \r | |
919 | Ext.define('spec.Button', {\r | |
920 | extend: 'Ext.button.Button',\r | |
921 | alias: 'widget.specbutton',\r | |
922 | \r | |
923 | updateText: function(text) {\r | |
924 | col = this.getWidgetColumn();\r | |
925 | if (text === 'foo') {\r | |
926 | fooRec = this.getWidgetRecord();\r | |
927 | } else if (text === 'bar') {\r | |
928 | barRec = this.getWidgetRecord();\r | |
929 | }\r | |
930 | this.callParent(arguments);\r | |
931 | }\r | |
932 | });\r | |
933 | \r | |
934 | makeGrid([getColCfg({\r | |
935 | xtype: 'specbutton'\r | |
936 | })], []);\r | |
937 | \r | |
938 | store.suspendEvents();\r | |
939 | store.add({\r | |
940 | a: 'foo'\r | |
941 | });\r | |
942 | store.resumeEvents();\r | |
943 | grid.getView().refresh();\r | |
944 | \r | |
945 | store.add({\r | |
946 | a: 'bar'\r | |
947 | });\r | |
948 | \r | |
949 | expect(col).toBe(colRef[0]);\r | |
950 | expect(fooRec).toBe(store.getAt(0));\r | |
951 | expect(barRec).toBe(store.getAt(1));\r | |
952 | \r | |
953 | Ext.undefine('spec.Button');\r | |
954 | });\r | |
955 | \r | |
956 | describe("getWidgetRecord", function() {\r | |
957 | it("should have the correct reference when an update causes the view to change", function() {\r | |
958 | makeGrid();\r | |
959 | store.getSorters().add({\r | |
960 | property: 'a'\r | |
961 | });\r | |
962 | store.first().set('a', '5a');\r | |
963 | expect(getWidget(0).getWidgetRecord().getId()).toBe('rec2');\r | |
964 | expect(getWidget(1).getWidgetRecord().getId()).toBe('rec3');\r | |
965 | expect(getWidget(2).getWidgetRecord().getId()).toBe('rec4');\r | |
966 | expect(getWidget(3).getWidgetRecord().getId()).toBe('rec1');\r | |
967 | });\r | |
968 | \r | |
969 | it("should have the correct references when removing records", function() {\r | |
970 | makeGrid();\r | |
971 | store.removeAt(1);\r | |
972 | expect(getWidget(0).getWidgetRecord().getId()).toBe('rec1');\r | |
973 | expect(getWidget(1).getWidgetRecord().getId()).toBe('rec3');\r | |
974 | expect(getWidget(2).getWidgetRecord().getId()).toBe('rec4');\r | |
975 | });\r | |
976 | \r | |
977 | it("should have the correct references when adding records", function() {\r | |
978 | makeGrid();\r | |
979 | store.insert(1, [{}, {}, {}]);\r | |
980 | expect(getWidget(0).getWidgetRecord().getId()).toBe('rec1');\r | |
981 | expect(getWidget(4).getWidgetRecord().getId()).toBe('rec2');\r | |
982 | expect(getWidget(5).getWidgetRecord().getId()).toBe('rec3');\r | |
983 | expect(getWidget(6).getWidgetRecord().getId()).toBe('rec4');\r | |
984 | });\r | |
985 | });\r | |
986 | });\r | |
987 | \r | |
988 | describe("reconfigure", function() {\r | |
989 | it("should be able to reconfigure with adding a column", function() {\r | |
990 | makeGrid([]);\r | |
991 | grid.reconfigure(undefined, [getColCfg({\r | |
992 | xtype: 'button'\r | |
993 | })]);\r | |
994 | colRef = grid.getColumnManager().getColumns();\r | |
995 | expect(getWidget(0).getText()).toBe('1a');\r | |
996 | expect(getWidget(1).getText()).toBe('2a');\r | |
997 | expect(getWidget(2).getText()).toBe('3a');\r | |
998 | expect(getWidget(3).getText()).toBe('4a');\r | |
999 | checkPositions();\r | |
1000 | });\r | |
1001 | \r | |
1002 | it("should be able to reconfigure with removing a column", function() {\r | |
1003 | makeGrid();\r | |
1004 | expect(function() {\r | |
1005 | grid.reconfigure(undefined, [{\r | |
1006 | dataIndex: 'a'\r | |
1007 | }]);\r | |
1008 | }).not.toThrow();\r | |
1009 | });\r | |
1010 | });\r | |
1011 | \r | |
1012 | describe("destroy", function() {\r | |
1013 | it("should destroy components", function() {\r | |
1014 | makeGrid();\r | |
1015 | var count = Ext.ComponentManager.getCount(),\r | |
1016 | toDestroy = 1 + store.getCount();\r | |
1017 | \r | |
1018 | grid.headerCt.remove(colRef[0]);\r | |
1019 | // We're destroying the column + each widget\r | |
1020 | expect(Ext.ComponentManager.getCount()).toBe(count - toDestroy);\r | |
1021 | });\r | |
1022 | });\r | |
1023 | \r | |
1024 | describe('on refresh', function () {\r | |
1025 | describe('beforerefresh', function () {\r | |
1026 | it('should recycle the widget dom tree hierarchy when refreshed', function () {\r | |
1027 | // See EXTJS-14874.\r | |
1028 | // We need the view to overflow to cause the bug in IE 8.\r | |
1029 | var data = generateData(100),\r | |
1030 | childNodes;\r | |
1031 | \r | |
1032 | makeGrid(null, data, {\r | |
1033 | height: 100\r | |
1034 | });\r | |
1035 | \r | |
1036 | // Pick a row that is within the buffere rendered range\r | |
1037 | childNodes = getWidget(1).el.dom.childNodes;\r | |
1038 | \r | |
1039 | expect(childNodes.length).toBe(1);\r | |
1040 | \r | |
1041 | // This will refresh the view and trigger the bug.\r | |
1042 | grid.store.loadData(data);\r | |
1043 | expect(childNodes.length).toBe(1);\r | |
1044 | });\r | |
1045 | });\r | |
1046 | });\r | |
1047 | \r | |
1048 | describe("item removal", function() {\r | |
1049 | it("should recycle dom nodes when items are removed", function() {\r | |
1050 | var data = generateData(100),\r | |
1051 | childNodes;\r | |
1052 | \r | |
1053 | makeGrid(null, data, {\r | |
1054 | height: 100\r | |
1055 | });\r | |
1056 | \r | |
1057 | // Pick a row that is within the buffere rendered range\r | |
1058 | childNodes = getWidget(1).el.dom.childNodes;\r | |
1059 | \r | |
1060 | expect(childNodes.length).toBe(1);\r | |
1061 | \r | |
1062 | store.removeAt(1);\r | |
1063 | \r | |
1064 | expect(childNodes.length).toBe(1);\r | |
1065 | });\r | |
1066 | });\r | |
1067 | \r | |
1068 | describe("hide/show", function() {\r | |
1069 | it("should not create widgets initially when hidden", function() {\r | |
1070 | var count = 0;\r | |
1071 | \r | |
1072 | Ext.define('spec.Foo', {\r | |
1073 | extend: 'Ext.Component',\r | |
1074 | alias: 'widget.foo',\r | |
1075 | \r | |
1076 | initComponent: function() {\r | |
1077 | ++count;\r | |
1078 | this.callParent();\r | |
1079 | }\r | |
1080 | });\r | |
1081 | \r | |
1082 | var col = getColCfg({\r | |
1083 | xtype: 'foo'\r | |
1084 | });\r | |
1085 | col.hidden = true;\r | |
1086 | makeGrid([col]);\r | |
1087 | // Gets called once during construction to set the tdCls\r | |
1088 | expect(count).toBe(1);\r | |
1089 | Ext.undefine('spec.Foo');\r | |
1090 | });\r | |
1091 | \r | |
1092 | it("should size the widgets when hidden initially and then shown", function() {\r | |
1093 | var col = getColCfg({\r | |
1094 | xtype: 'button'\r | |
1095 | });\r | |
1096 | col.hidden = true;\r | |
1097 | makeGrid([col]);\r | |
1098 | colRef[0].show();\r | |
1099 | var padding = getPadding();\r | |
1100 | expect(getWidget(0).getWidth()).toBe(200 - padding);\r | |
1101 | expect(getWidget(1).getWidth()).toBe(200 - padding);\r | |
1102 | expect(getWidget(2).getWidth()).toBe(200 - padding);\r | |
1103 | expect(getWidget(3).getWidth()).toBe(200 - padding);\r | |
1104 | });\r | |
1105 | \r | |
1106 | it("should not cause an error when hiding the last leaf column in a grouped header", function() {\r | |
1107 | makeGrid([{\r | |
1108 | columns: [getColCfg({\r | |
1109 | xtype: 'button'\r | |
1110 | })]\r | |
1111 | }]);\r | |
1112 | expect(function() {\r | |
1113 | colRef[0].hide();\r | |
1114 | }).not.toThrow();\r | |
1115 | });\r | |
1116 | \r | |
1117 | it("should not cause an error when hiding the group header that contains this widget", function() {\r | |
1118 | makeGrid([{\r | |
1119 | itemId: 'ct',\r | |
1120 | columns: [getColCfg({\r | |
1121 | xtype: 'button'\r | |
1122 | })]\r | |
1123 | }]);\r | |
1124 | expect(function() {\r | |
1125 | grid.down('#ct').hide();\r | |
1126 | }).not.toThrow();\r | |
1127 | });\r | |
1128 | });\r | |
1129 | });\r | |
1130 | \r | |
1131 | describe('RadioGroup as a widget', function() {\r | |
1132 | var grid;\r | |
1133 | \r | |
1134 | afterEach(function() {\r | |
1135 | grid.destroy();\r | |
1136 | });\r | |
1137 | \r | |
1138 | it("should be able to update value from column's dataIndex", function() {\r | |
1139 | var store = Ext.create('Ext.data.Store', {\r | |
1140 | fields: ['name', 'progress',\r | |
1141 | {\r | |
1142 | name: 'radio',\r | |
1143 | isEqual: function(v1, v2) {\r | |
1144 | return String(v1.value) === String(v2.value);\r | |
1145 | }\r | |
1146 | }\r | |
1147 | ],\r | |
1148 | data: [{\r | |
1149 | name: 'Test 1',\r | |
1150 | progress: 0.10,\r | |
1151 | radio: {\r | |
1152 | "value": 2\r | |
1153 | }\r | |
1154 | }, {\r | |
1155 | name: 'Test 2',\r | |
1156 | progress: 0.23,\r | |
1157 | radio: {\r | |
1158 | "value": 1\r | |
1159 | }\r | |
1160 | }, {\r | |
1161 | name: 'Test 3',\r | |
1162 | progress: 0.86,\r | |
1163 | radio: {\r | |
1164 | "value": 2\r | |
1165 | }\r | |
1166 | }, {\r | |
1167 | name: 'Test 4',\r | |
1168 | progress: 0.31,\r | |
1169 | radio: {\r | |
1170 | "value": 1\r | |
1171 | }\r | |
1172 | }]\r | |
1173 | }),\r | |
1174 | widgetColumn,\r | |
1175 | radioGroup,\r | |
1176 | radio,\r | |
1177 | rec = store.getAt(0);\r | |
1178 | \r | |
1179 | grid = Ext.create({\r | |
1180 | xtype: 'grid',\r | |
1181 | title: 'Widget Column Demo',\r | |
1182 | store: store,\r | |
1183 | \r | |
1184 | columns: [{\r | |
1185 | text: 'Test Number',\r | |
1186 | dataIndex: 'name',\r | |
1187 | width: 150\r | |
1188 | }, {\r | |
1189 | text: 'Progress',\r | |
1190 | dataIndex: 'progress',\r | |
1191 | width: 100\r | |
1192 | }, {\r | |
1193 | xtype: 'widgetcolumn',\r | |
1194 | header: 'Radio Group',\r | |
1195 | dataIndex: 'radio',\r | |
1196 | width: 170,\r | |
1197 | widget: {\r | |
1198 | xtype: 'radiogroup',\r | |
1199 | \r | |
1200 | // The local config means child Radio names are scoped to this RadioGroup\r | |
1201 | local: true,\r | |
1202 | columns: 1,\r | |
1203 | vertical: true,\r | |
1204 | items: [{\r | |
1205 | boxLabel: 'Item 1',\r | |
1206 | name: 'value',\r | |
1207 | inputValue: '1'\r | |
1208 | }, {\r | |
1209 | boxLabel: 'Item 2',\r | |
1210 | name: 'value',\r | |
1211 | inputValue: '2'\r | |
1212 | }],\r | |
1213 | listeners: {\r | |
1214 | change: function(radioGroup, newValue, oldValue) {\r | |
1215 | radioGroup.getWidgetRecord().set('radio', newValue);\r | |
1216 | }\r | |
1217 | }\r | |
1218 | }\r | |
1219 | }],\r | |
1220 | height: 400,\r | |
1221 | width: 600,\r | |
1222 | renderTo: Ext.getBody()\r | |
1223 | });\r | |
1224 | widgetColumn = grid.down('widgetcolumn');\r | |
1225 | radioGroup = widgetColumn.getWidget(rec);\r | |
1226 | radio = radioGroup.child('radio[inputValue=1]');\r | |
1227 | jasmine.fireMouseEvent(radio.inputEl, 'click');\r | |
1228 | \r | |
1229 | // Record field must have been updated\r | |
1230 | expect(rec.get('radio').value).toBe('1');\r | |
1231 | });\r | |
1232 | });\r | |
1233 | }\r | |
1234 | createBufferedSuite(false);\r | |
1235 | createBufferedSuite(true);\r | |
1236 | });\r |