]> git.proxmox.com Git - extjs.git/blame - extjs/classic/classic/test/specs/grid/grid.js
add extjs 6.0.1 sources
[extjs.git] / extjs / classic / classic / test / specs / grid / grid.js
CommitLineData
6527f429
DM
1describe("grid-general", function() {\r
2 var grid, store,\r
3 synchronousLoad = true,\r
4 proxyStoreLoad = Ext.data.ProxyStore.prototype.load,\r
5 loadStore;\r
6\r
7 beforeEach(function() {\r
8 // Override so that we can control asynchronous loading\r
9 loadStore = Ext.data.ProxyStore.prototype.load = function() {\r
10 proxyStoreLoad.apply(this, arguments);\r
11 if (synchronousLoad) {\r
12 this.flushLoad.apply(this, arguments);\r
13 }\r
14 return this;\r
15 };\r
16 });\r
17\r
18 afterEach(function() {\r
19 // Undo the overrides.\r
20 Ext.data.ProxyStore.prototype.load = proxyStoreLoad;\r
21\r
22 grid = store = Ext.destroy(grid, store);\r
23 });\r
24\r
25 var scrollbarWidth = Ext.getScrollbarSize().width,\r
26 transformStyleName = 'webkitTransform' in document.documentElement.style ? 'webkitTransform' : 'transform',\r
27 scrollbarsTakeSpace = !!scrollbarWidth,\r
28 // Some tests should only be run if the UI shows space-taking scrollbars.\r
29 // Specifically, those tests which test that the presence or not of a scrollbar in one dimension\r
30 // affects the presence of a scrollbar in the other dimension.\r
31 visibleScrollbarsIt = scrollbarsTakeSpace ? it : xit;\r
32\r
33 function getViewTop(el) {\r
34 var dom = Ext.getDom(el),\r
35 transform;\r
36\r
37 if (Ext.supports.CssTransforms && !Ext.isIE9m) {\r
38 transform = dom.style[transformStyleName];\r
39 return transform ? parseInt(transform.split(',')[1], 10) : 0;\r
40 } else {\r
41 return parseInt(dom.style.top || '0', 10);\r
42 }\r
43 }\r
44\r
45 function createSuite(buffered) {\r
46 describe(buffered ? "with buffered rendering" : "without buffered rendering", function() {\r
47 var GridModel = Ext.define(null, {\r
48 extend: 'Ext.data.Model',\r
49 fields: [\r
50 'field1',\r
51 'field2',\r
52 'field3',\r
53 'field4',\r
54 'field5',\r
55 'field6',\r
56 'field7',\r
57 'field8',\r
58 'field9',\r
59 'field10'\r
60 ]\r
61 }), view, colRef;\r
62\r
63 function makeStore(data) {\r
64 if (!data && data !== null) {\r
65 data = [{\r
66 field1: 1,\r
67 field2: 2,\r
68 field3: 3,\r
69 field4: 4,\r
70 field5: 5,\r
71 field6: 6,\r
72 field7: 7,\r
73 field8: 8,\r
74 field9: 9,\r
75 field10: 10\r
76 }];\r
77 }\r
78 store = new Ext.data.Store({\r
79 model: GridModel,\r
80 data: data\r
81 });\r
82 return store;\r
83 }\r
84\r
85 function makeGrid(columns, data, cfg, options, locked) {\r
86 options = options || {};\r
87 cfg = cfg || {};\r
88\r
89 var i, dataCount, dataRow;\r
90\r
91 if (!options.preventColumnCreate && !columns) {\r
92 columns = [];\r
93 for (i = 1; i < 11; i++) {\r
94 columns.push({\r
95 dataIndex: 'field' + i,\r
96 text: 'Field ' + i,\r
97 width: 90,\r
98 // First column gets locked if we are doing locking tests.\r
99 locked: locked && i === 1\r
100 });\r
101 }\r
102 }\r
103\r
104 // Could pass number of required records\r
105 if (typeof data === 'number') {\r
106 dataCount = data;\r
107 data = [];\r
108 for (i = 0; i < dataCount; i++) {\r
109 dataRow = {\r
110 id: 'rec' + i\r
111 };\r
112 for (var j = 0; j < columns.length; j++) {\r
113 dataRow[columns[j].dataIndex] = (i + 1) + ', ' + (j + 1);\r
114 }\r
115 data.push(dataRow);\r
116 }\r
117 }\r
118\r
119 if (!options.preventStoreCreate) {\r
120 makeStore(data);\r
121 }\r
122\r
123 grid = new Ext.grid.Panel(Ext.apply({\r
124 columns: columns,\r
125 store: store,\r
126 trailingBufferZone: 1000,\r
127 leadingBufferZone: 1000,\r
128 width: 1000,\r
129 height: 500,\r
130 border: false,\r
131 bodyStyle: !cfg.border ? 'border: 0' : '',\r
132 bufferedRenderer: buffered,\r
133 viewConfig: Ext.apply({\r
134 mouseOverOutBuffer: 0\r
135 }, cfg.viewConfig)\r
136 }, cfg));\r
137\r
138 // Don't use renderTo since that may throw and we won't set "grid"\r
139 // and will then leak the component\r
140 if (cfg.renderTo === undefined) {\r
141 grid.render(Ext.getBody());\r
142 }\r
143\r
144 view = grid.getView();\r
145 colRef = grid.getColumnManager().getColumns();\r
146 }\r
147\r
148 afterEach(function () {\r
149 view = colRef = null;\r
150 Ext.data.Model.schema.clear();\r
151 });\r
152\r
153 function getCellText(row, col) {\r
154 var cell = view.getCell(store.getAt(row), colRef[col]),\r
155 selectorView = grid.lockedGrid ? grid.lockedGrid.getView() : view;\r
156\r
157 return cell.down(selectorView.innerSelector).dom.innerHTML;\r
158 }\r
159\r
160 describe("misc tests", function() {\r
161 // EXTJS-16436\r
162 it('should not throw an exception when scrollable:false', function() {\r
163 // Spec will fail if an error is thrown\r
164 makeGrid(null, undefined, {\r
165 scrollable: false\r
166 });\r
167 });\r
168 \r
169 // EXTJS-14858\r
170 it("should not throw an exception when hiding a column in a locked grid during initComponent", function() {\r
171 var Plug = Ext.define(null, {\r
172 extend: 'Ext.AbstractPlugin',\r
173\r
174 init: function(cmp) {\r
175 cmp.hide();\r
176 }\r
177 });\r
178\r
179 makeGrid([{\r
180 plugins: [new Plug()],\r
181 locked: true\r
182 }, {\r
183\r
184 }]);\r
185 });\r
186 // https://sencha.jira.com/browse/EXTJS-14879\r
187 it('should invalidate cached element data when grid DOM is updated', function() {\r
188 makeGrid();\r
189 grid.columns[0].hasCustomRenderer = true;\r
190 Ext.fly(grid.view.all.item(0, true)).addCls('foo-bar');\r
191 expect(Ext.fly(grid.view.all.item(0, true)).hasCls('foo-bar')).toBe(true);\r
192 store.getAt(0).set('field1', 'CHANGED');\r
193\r
194 // After the update, the new state has to be synched.\r
195 expect(Ext.fly(grid.view.all.item(0, true)).hasCls('foo-bar')).toBe(false);\r
196 });\r
197\r
198 it("should not throw an error when the store is loaded in the afterrender of an earlier sibling", function() {\r
199 makeGrid(null, undefined, {\r
200 renderTo: null\r
201 });\r
202\r
203 var ct;\r
204 expect(function() {\r
205 ct = new Ext.container.Container({\r
206 renderTo: Ext.getBody(),\r
207 items: [{\r
208 xtype: 'component',\r
209 html: 'Foo',\r
210 listeners: {\r
211 afterrender: function() {\r
212 var proxy = new Ext.data.proxy.Ajax({\r
213 url: 'foo'\r
214 });\r
215\r
216 spyOn(proxy, 'read').andReturn();\r
217 store.setProxy(proxy);\r
218 store.load();\r
219\r
220 }\r
221 }\r
222 }, grid]\r
223 });\r
224 }).not.toThrow();\r
225 Ext.destroy(ct);\r
226 });\r
227\r
228 it("should not throw an error when the store is loaded in the afterrender event", function() {\r
229 makeGrid(null, [], {\r
230 listeners: {\r
231 afterrender: function() {\r
232 var proxy = new Ext.data.proxy.Ajax({\r
233 url: 'foo'\r
234 });\r
235\r
236 spyOn(proxy, 'read').andReturn();\r
237 store.setProxy(proxy);\r
238 expect(function() {\r
239 store.load();\r
240 }).not.toThrow();\r
241 }\r
242 }\r
243 });\r
244 });\r
245 });\r
246\r
247 describe("autoSizeColumn", function() {\r
248 function getPadding() {\r
249 var cell = grid.getView().getEl().down(colRef[0].getCellInnerSelector()),\r
250 right = Ext.supports.ScrollWidthInlinePaddingBug ? parseInt(cell.getStyle('padding-right'), 10) : 0;\r
251 return parseInt(cell.getStyle('padding-left'), 10) + right;\r
252 }\r
253\r
254 it("should size the column when passed a header", function() {\r
255 makeGrid(null, [{\r
256 field1: '<div style="width: 125px;>a</div>'\r
257 }, {\r
258 field1: '<div style="width: 450px;>b</div>'\r
259 }, {\r
260 field1: '<div style="width: 375px;>c</div>'\r
261 }]);\r
262 grid.getView().autoSizeColumn(colRef[0]);\r
263 expect(colRef[0].getWidth()).toBe(451 + getPadding());\r
264 });\r
265\r
266 it("should size the column when passed a header index", function() {\r
267 makeGrid(null, [{\r
268 field1: '<div style="width: 125px;>a</div>'\r
269 }, {\r
270 field1: '<div style="width: 450px;>b</div>'\r
271 }, {\r
272 field1: '<div style="width: 375px;>c</div>'\r
273 }]);\r
274 grid.getView().autoSizeColumn(0);\r
275 expect(colRef[0].getWidth()).toBe(451 + getPadding());\r
276 });\r
277 });\r
278\r
279 describe("sizing", function() {\r
280 it("should allow for a minHeight on the view with a shrink wrapped grid", function() {\r
281 makeGrid(null, undefined, {\r
282 height: undefined,\r
283 viewConfig: {\r
284 minHeight: 100\r
285 }\r
286 });\r
287 expect(view.getHeight()).toBe(100);\r
288 expect(grid.getHeight()).toBe(100 + grid.headerCt.getHeight());\r
289 });\r
290 });\r
291\r
292 describe("getRowClass", function() {\r
293 var spy;\r
294\r
295 beforeEach(function() {\r
296 spy = jasmine.createSpy();\r
297 makeGrid(null, 3, {\r
298 viewConfig: {\r
299 getRowClass: spy.andCallFake(function(rec) {\r
300 return 'customCls' + store.indexOf(rec) + ' testCls';\r
301 })\r
302 }\r
303 });\r
304 });\r
305\r
306 afterEach(function() {\r
307 spy = null;\r
308 });\r
309\r
310 function getRow(index) {\r
311 var node = view.getNode(index);\r
312 return Ext.fly(node).down(view.rowSelector);\r
313 }\r
314\r
315 it("should be called for each rendered row", function() {\r
316 expect(spy.callCount).toBe(3);\r
317 expect(spy.calls[0].args[0]).toBe(store.getAt(0));\r
318 expect(spy.calls[0].args[1]).toBe(0);\r
319 expect(spy.calls[1].args[0]).toBe(store.getAt(1));\r
320 expect(spy.calls[1].args[1]).toBe(1);\r
321 expect(spy.calls[2].args[0]).toBe(store.getAt(2));\r
322 expect(spy.calls[2].args[1]).toBe(2);\r
323 });\r
324\r
325 it("should be called when refreshing the view", function() {\r
326 spy.reset();\r
327 view.refresh();\r
328 expect(spy.calls[0].args[0]).toBe(store.getAt(0));\r
329 expect(spy.calls[0].args[1]).toBe(0);\r
330 expect(spy.calls[1].args[0]).toBe(store.getAt(1));\r
331 expect(spy.calls[1].args[1]).toBe(1);\r
332 expect(spy.calls[2].args[0]).toBe(store.getAt(2));\r
333 expect(spy.calls[2].args[1]).toBe(2);\r
334 });\r
335\r
336 it("should be called when adding a new record", function() {\r
337 spy.reset();\r
338 store.add({});\r
339 expect(spy.callCount).toBe(1);\r
340 expect(spy.mostRecentCall.args[0]).toBe(store.getAt(3));\r
341 expect(spy.mostRecentCall.args[1]).toBe(3);\r
342 });\r
343\r
344 it("should be called when inserting a new record", function() {\r
345 spy.reset();\r
346 store.insert(0, {});\r
347 expect(spy.callCount).toBe(1);\r
348 expect(spy.mostRecentCall.args[0]).toBe(store.getAt(0));\r
349 expect(spy.mostRecentCall.args[1]).toBe(0);\r
350 });\r
351\r
352 it("should be called when the row is updating", function() {\r
353 spy.reset();\r
354 store.getAt(0).set('field1', 'new value');\r
355 expect(spy.callCount).toBe(1);\r
356 expect(spy.mostRecentCall.args[0]).toBe(store.getAt(0));\r
357 expect(spy.mostRecentCall.args[1]).toBe(0);\r
358 });\r
359\r
360 it("should add the class to the row element", function() {\r
361 expect(getRow(0).hasCls('customCls0')).toBe(true);\r
362 expect(getRow(1).hasCls('customCls1')).toBe(true);\r
363 expect(getRow(2).hasCls('customCls2')).toBe(true);\r
364 });\r
365\r
366 it("should be able to add multiple class names", function() {\r
367 expect(getRow(0).hasCls('customCls0')).toBe(true);\r
368 expect(getRow(0).hasCls('testCls')).toBe(true);\r
369 expect(getRow(1).hasCls('customCls1')).toBe(true);\r
370 expect(getRow(1).hasCls('testCls')).toBe(true);\r
371 expect(getRow(2).hasCls('customCls2')).toBe(true);\r
372 expect(getRow(2).hasCls('testCls')).toBe(true);\r
373 });\r
374 });\r
375\r
376 describe("emptyText", function() {\r
377\r
378 function getEmpty() {\r
379 return grid.getEl().down('.' + grid.emptyCls) || null;\r
380 }\r
381\r
382 describe("when to display", function() {\r
383 it("should display on first refresh with deferEmptyText: false", function() {\r
384 makeGrid(null, null, {\r
385 viewConfig: {\r
386 emptyText: 'Foo',\r
387 deferEmptyText: false\r
388 }\r
389 });\r
390 expect(getEmpty()).not.toBeNull();\r
391 });\r
392\r
393 it("should not display on first refresh with deferEmptyText: true", function() {\r
394 makeGrid(null, null, {\r
395 viewConfig: {\r
396 emptyText: 'Foo',\r
397 deferEmptyText: true\r
398 }\r
399 });\r
400 expect(getEmpty()).toBeNull();\r
401 });\r
402\r
403 it("should display on subsequent refreshes with deferEmptyText: true", function() {\r
404 makeGrid(null, null, {\r
405 viewConfig: {\r
406 emptyText: 'Foo',\r
407 deferEmptyText: true\r
408 }\r
409 });\r
410 grid.getView().refresh();\r
411 expect(getEmpty()).not.toBeNull();\r
412 });\r
413\r
414 it("should display when removing the last record", function() {\r
415 makeGrid(null, 1, {\r
416 viewConfig: {\r
417 emptyText: 'Foo',\r
418 deferEmptyText: true\r
419 }\r
420 });\r
421 store.removeAt(0);\r
422 expect(getEmpty()).not.toBeNull();\r
423 });\r
424\r
425 it("should display when removing all records", function() {\r
426 makeGrid(null, 5, {\r
427 viewConfig: {\r
428 emptyText: 'Foo',\r
429 deferEmptyText: true\r
430 }\r
431 });\r
432 store.removeAll();\r
433 expect(getEmpty()).not.toBeNull();\r
434 });\r
435 });\r
436\r
437 describe("config", function() {\r
438 describe("emptyCls", function() {\r
439 it("should use the passed emptyCls", function() {\r
440 makeGrid(null, null, {\r
441 emptyCls: 'foo',\r
442 viewConfig: {\r
443 emptyText: 'Foo',\r
444 deferEmptyText: false\r
445 }\r
446 });\r
447 expect(getEmpty().hasCls('foo')).toBe(true);\r
448 });\r
449 });\r
450\r
451 describe("emptyText", function() {\r
452 it("should use the passed emptyText", function() {\r
453 makeGrid(null, null, {\r
454 viewConfig: {\r
455 emptyText: 'Foo',\r
456 deferEmptyText: false\r
457 }\r
458 });\r
459 expect(getEmpty().dom).hasHTML('Foo');\r
460 });\r
461 });\r
462 });\r
463\r
464 describe("size", function() {\r
465 it("should set the grid height correctly based on the emptyText when auto heighting", function() {\r
466 makeGrid(null, null, {\r
467 height: null,\r
468 hideHeaders: true,\r
469 viewConfig: {\r
470 emptyText: '<div style="width: 50px; height: 100px;">a</div>',\r
471 deferEmptyText: false\r
472 }\r
473 });\r
474 var otherParts = grid.body.getBorderWidth('tb') + grid.el.down(view.bodySelector).getHeight();\r
475 expect(grid.getHeight()).toBe(100 + getEmpty().getPadding('tb') + otherParts);\r
476 });\r
477 });\r
478\r
479 describe("scrolling", function() {\r
480 it("should keep a horizontal scrollbar if columns are larger than the grid width", function() {\r
481 makeGrid([{\r
482 width: 800\r
483 }, {\r
484 width: 800\r
485 }], 0, {\r
486 viewConfig: {\r
487 emptyText: '<div style="width: 50px; height: 100px;">a</div>',\r
488 deferEmptyText: false\r
489 }\r
490 });\r
491 expect(view.getEl().dom.scrollWidth).toBe(1600);\r
492 });\r
493 });\r
494 });\r
495\r
496 describe("stripeRows", function() {\r
497 var stripeCls = Ext.view.Table.prototype.altRowCls;\r
498\r
499 describe("with stripeRows: false", function() {\r
500 function expectNotStriped() {\r
501 Ext.Array.forEach(grid.getView().getNodes(), function(node) {\r
502 expect(Ext.fly(node).hasCls(stripeCls)).toBe(false);\r
503 });\r
504 }\r
505\r
506 beforeEach(function() {\r
507 makeGrid(null, 11, {\r
508 viewConfig: {\r
509 stripeRows: false\r
510 }\r
511 });\r
512 });\r
513\r
514 it("should not stripe rows on initial render", function() {\r
515 expectNotStriped();\r
516 });\r
517\r
518 it("should not stripe rows when adding records", function() {\r
519 store.add([{}, {}, {}, {}, {}]);\r
520 expectNotStriped();\r
521 });\r
522\r
523 it("should not stripe rows when removing records", function() {\r
524 store.removeAt(0);\r
525 expectNotStriped();\r
526 });\r
527\r
528 it("should not stripe rows when updating records", function() {\r
529 store.getAt(0).set('field1', 'foo');\r
530 expectNotStriped();\r
531 });\r
532\r
533 it("should not stripe rows on refresh", function() {\r
534 grid.getView().refresh();\r
535 expectNotStriped();\r
536 });\r
537 });\r
538\r
539 describe("with stripeRows: true", function() {\r
540 beforeEach(function() {\r
541 makeGrid(null, 11, {\r
542 viewConfig: {\r
543 stripeRows: true\r
544 }\r
545 });\r
546 });\r
547\r
548 function expectStriped() {\r
549 Ext.Array.forEach(grid.getView().getNodes(), function(node, index) {\r
550 if (index % 2 === 1) {\r
551 expect(Ext.fly(node).hasCls(stripeCls)).toBe(true);\r
552 } else {\r
553 expect(Ext.fly(node).hasCls(stripeCls)).toBe(false);\r
554 }\r
555 });\r
556 }\r
557\r
558 it("should stripe rows on initial render", function() {\r
559 expectStriped();\r
560 });\r
561\r
562 it("should stripe rows when appending records", function() {\r
563 store.add([{}, {}, {}, {}, {}]);\r
564 expectStriped();\r
565 });\r
566\r
567 it("should stripe rows when inserting records", function() {\r
568 store.insert(0, {});\r
569 expectStriped();\r
570 }); \r
571\r
572 it("should stripe when removing records", function() {\r
573 store.removeAt(0);\r
574 expectStriped();\r
575 });\r
576\r
577 it("should retain the stripe class when updating records", function() {\r
578 store.getAt(1).set('field1', 'foo');\r
579 expectStriped();\r
580 });\r
581\r
582 it("should stripe when a record update causes the position to change", function() {\r
583 store.sort('field1');\r
584 store.getAt(0).set('field1', '999999999');\r
585 expectStriped();\r
586 });\r
587\r
588 it("should stripe on refresh", function() {\r
589 store.suspendEvents();\r
590 var numbers = [70, 72, 75, 27, 82, 70, 53, 42, 87, 19, 23];\r
591\r
592 store.each(function(rec, index) {\r
593 rec.set('field1', numbers[index]);\r
594 });\r
595 store.sort('field1');\r
596 store.resumeEvents();\r
597 grid.getView().refresh();\r
598 expectStriped();\r
599 });\r
600 });\r
601 });\r
602\r
603 describe("forceFit", function() {\r
604 var data; \r
605 beforeEach(function() {\r
606 data = [];\r
607\r
608 for (var i = 0; i < 50; i++) {\r
609 data.push({\r
610 field1: (i + 1) + ', ' + 1,\r
611 field2: (i + 1) + ', ' + 2,\r
612 field3: (i + 1) + ', ' + 3,\r
613 field4: (i + 1) + ', ' + 4,\r
614 field5: (i + 1) + ', ' + 5,\r
615 field6: (i + 1) + ', ' + 6,\r
616 field7: (i + 1) + ', ' + 7,\r
617 field8: (i + 1) + ', ' + 8,\r
618 field9: (i + 1) + ', ' + 9,\r
619 field10: (i + 1) + ', ' + 10\r
620 });\r
621 }\r
622 });\r
623\r
624 afterEach(function() {\r
625 data = null;\r
626 });\r
627\r
628 describe("starting with no overflow", function() {\r
629 beforeEach(function() {\r
630 makeGrid(null, undefined, {\r
631 forceFit: true,\r
632 width: 400,\r
633 height: 200\r
634 });\r
635 });\r
636\r
637 it('should size the columns to fit within the grid body', function() {\r
638 var emptyStore = new Ext.data.Store({\r
639 autoDestroy: false,\r
640 model: GridModel,\r
641 data: []\r
642 });\r
643\r
644 expect(grid.headerCt.getTableWidth()).toBe(grid.body.getWidth() - grid.body.getBorderWidth('lr'));\r
645\r
646 // Cause overflow by adding 50 new rows\r
647 store.add(data);\r
648\r
649 // Now should fit within the scrollbar\r
650 expect(grid.headerCt.getTableWidth()).toBe(grid.body.getWidth() - grid.body.getBorderWidth('lr') - Ext.getScrollbarSize().width);\r
651\r
652 // Avoid destruction when we unbind\r
653 store.autoDestroy = false;\r
654\r
655 // Reconfigure with an empty store\r
656 grid.reconfigure(emptyStore);\r
657\r
658 // Reconfigure back to full store\r
659 grid.reconfigure(store);\r
660\r
661 // Now should fit within the scrollbar\r
662 expect(grid.headerCt.getTableWidth()).toBe(grid.body.getWidth() - grid.body.getBorderWidth('lr') - Ext.getScrollbarSize().width);\r
663 Ext.destroy(emptyStore);\r
664 });\r
665 });\r
666\r
667 describe("with overflow", function() {\r
668 beforeEach(function() {\r
669 makeGrid(null, data, {\r
670 forceFit: true,\r
671 width: 400,\r
672 height: 200\r
673 });\r
674 });\r
675\r
676 it('should size the columns to fit within the grid body, inside the scrollbar', function() {\r
677 expect(grid.headerCt.getTableWidth()).toBe(grid.body.getWidth() - grid.body.getBorderWidth('lr') - Ext.getScrollbarSize().width);\r
678 });\r
679 });\r
680 });\r
681\r
682 describe("basic settings", function() {\r
683 describe("columns", function() {\r
684 describe("without locking", function() {\r
685 it("should be able to configure without columns", function() {\r
686 expect(function() {\r
687 makeGrid(null, undefined, null, {preventColumnCreate: true});\r
688 }).not.toThrow();\r
689 });\r
690 });\r
691\r
692 describe("with locking", function() {\r
693 it("should be able to configure without columns", function() {\r
694 expect(function() {\r
695 makeGrid(null, undefined, {enableLocking: true}, {preventColumnCreate: true});\r
696 }).not.toThrow();\r
697 });\r
698 });\r
699 });\r
700\r
701 // Note: Arguably, these specs should not be in grid since itemSelector is a view config, but the bug only\r
702 // occurred in a locking grid. See EXTJS-15563.\r
703 describe('itemSelector', function () {\r
704 var itemSelector = Ext.view.Table.prototype.itemSelector;\r
705\r
706 describe('without locking', function () {\r
707 it('should be able to lookup the itemSelector on the view', function () {\r
708 makeGrid();\r
709 expect(view.itemSelector).toBe(itemSelector);\r
710 });\r
711 });\r
712\r
713 describe('with locking', function () {\r
714 it('should be able to lookup the itemSelector on the LockingView', function () {\r
715 makeGrid(null, undefined, null, null, true);\r
716 expect(view.itemSelector).toBe(itemSelector);\r
717 });\r
718 });\r
719 });\r
720\r
721 describe("css classes", function() {\r
722 it("should add the x-grid cls", function() {\r
723 makeGrid();\r
724 expect(grid.el.hasCls('x-grid')).toBe(true);\r
725 });\r
726\r
727 it("should add the x-grid cls when specifying a custom cls", function() {\r
728 makeGrid(undefined, undefined, {\r
729 cls: 'foo'\r
730 });\r
731 expect(grid.el.hasCls('x-grid')).toBe(true);\r
732 expect(grid.el.hasCls('foo')).toBe(true);\r
733 });\r
734 });\r
735\r
736 describe("markDirty", function() {\r
737 var dirtyCls;\r
738\r
739 function makeDirtyGrid(markDirty, preventRender, columns) {\r
740 makeGrid(columns, undefined, {\r
741 renderTo: preventRender ? null : Ext.getBody(),\r
742 viewConfig: {\r
743 markDirty: markDirty,\r
744 mouseOverOutBuffer: 0\r
745 }\r
746 });\r
747 dirtyCls = grid.getView().dirtyCls;\r
748 }\r
749\r
750 afterEach(function() {\r
751 dirtyCls = null;\r
752 });\r
753\r
754 function getCell(record, column) {\r
755 return grid.getView().getCell(record, column);\r
756 }\r
757\r
758 describe("with markDirty: false", function() {\r
759 it("should not render a cell with the dirtyCls initially", function() {\r
760 makeDirtyGrid(false, true);\r
761 store.first().set('field1', 'bleh');\r
762 grid.render(Ext.getBody());\r
763\r
764 expect(grid.getEl().select('.' + dirtyCls).getCount()).toBe(0);\r
765 });\r
766\r
767 it("should not add the dirtyCls when updated with a simple cell updater", function() {\r
768 makeDirtyGrid(false);\r
769 store.first().set('field1', 'bleh');\r
770 expect(grid.getEl().select('.' + dirtyCls).getCount()).toBe(0);\r
771 });\r
772\r
773 it("should not add the dirtyCls when updated with a renderer", function() {\r
774 makeDirtyGrid(false, false, [{\r
775 dataIndex: '',\r
776 renderer: function(v, meta, rec) {\r
777 return rec.get('field1') + rec.get('field2');\r
778 }\r
779 }]);\r
780 store.first().set('field1', 'bleh');\r
781 expect(grid.getEl().select('.' + dirtyCls).getCount()).toBe(0);\r
782 });\r
783 });\r
784\r
785 describe("with markDirty: true", function() {\r
786 it("should not render a cell with the dirtyCls initially if not dirty", function() {\r
787 makeDirtyGrid(true, true);\r
788 grid.render(Ext.getBody());\r
789 \r
790 var rec = store.first();\r
791 for (var i = 0; i < colRef.length; ++i) {\r
792 expect(getCell(rec, colRef[i])).not.toHaveCls(dirtyCls);\r
793 }\r
794 });\r
795\r
796 it("should render a cell with the dirtyCls initially if the cell is dirty", function() {\r
797 makeDirtyGrid(true, true);\r
798 store.first().set('field1', 'bleh');\r
799 grid.render(Ext.getBody());\r
800 \r
801 var rec = store.first();\r
802 expect(getCell(rec, colRef[0])).toHaveCls(dirtyCls);\r
803 for (var i = 1; i < colRef.length; ++i) {\r
804 expect(getCell(rec, colRef[i])).not.toHaveCls(dirtyCls);\r
805 }\r
806 });\r
807\r
808 it("should add the dirtyCls to updated cells", function() {\r
809 makeDirtyGrid(true);\r
810 var rec = store.first();\r
811 rec.set('field1', 'bleh');\r
812 expect(getCell(rec, colRef[0])).toHaveCls(dirtyCls);\r
813 rec.set('field4', 'qwerty');\r
814 expect(getCell(rec, colRef[3])).toHaveCls(dirtyCls);\r
815 });\r
816\r
817 it("should remove the dirtyCls when the cell is no longer dirty", function() {\r
818 makeDirtyGrid(true);\r
819 var rec = store.first(),\r
820 val = rec.get('field1');\r
821\r
822 rec.set('field1', 'asdf');\r
823 expect(getCell(rec, colRef[0])).toHaveCls(dirtyCls);\r
824 rec.set('field1', val);\r
825 expect(getCell(rec, colRef[0])).not.toHaveCls(dirtyCls);\r
826 });\r
827\r
828 it("should remove the dirtyCls on commit", function() {\r
829 makeDirtyGrid(true);\r
830 var rec = store.first();\r
831\r
832 rec.set('field1', 'foo');\r
833 rec.set('field2', 'bar');\r
834 expect(getCell(rec, colRef[0])).toHaveCls(dirtyCls);\r
835 expect(getCell(rec, colRef[1])).toHaveCls(dirtyCls);\r
836\r
837 rec.set('field3', 'baz');\r
838 expect(getCell(rec, colRef[2])).toHaveCls(dirtyCls);\r
839\r
840 rec.commit();\r
841\r
842 expect(getCell(rec, colRef[0])).not.toHaveCls(dirtyCls);\r
843 expect(getCell(rec, colRef[1])).not.toHaveCls(dirtyCls);\r
844 expect(getCell(rec, colRef[2])).not.toHaveCls(dirtyCls);\r
845 });\r
846\r
847 it("should remove the dirtyCls on reject", function() {\r
848 makeDirtyGrid(true);\r
849 var rec = store.first();\r
850\r
851 rec.set('field1', 'foo');\r
852 rec.set('field2', 'bar');\r
853 expect(getCell(rec, colRef[0])).toHaveCls(dirtyCls);\r
854 expect(getCell(rec, colRef[1])).toHaveCls(dirtyCls);\r
855\r
856 rec.set('field3', 'baz');\r
857 expect(getCell(rec, colRef[2])).toHaveCls(dirtyCls);\r
858\r
859 rec.reject();\r
860\r
861 expect(getCell(rec, colRef[0])).not.toHaveCls(dirtyCls);\r
862 expect(getCell(rec, colRef[1])).not.toHaveCls(dirtyCls);\r
863 expect(getCell(rec, colRef[2])).not.toHaveCls(dirtyCls);\r
864 });\r
865 });\r
866 });\r
867 });\r
868\r
869 describe("selection", function() {\r
870 function describeSelectionSuite(withLocking) {\r
871 describe(withLocking ? "with locking" : "without locking", function() {\r
872 var sm;\r
873 beforeEach(function() {\r
874 sm = new Ext.selection.RowModel();\r
875 makeGrid([{\r
876 dataIndex: 'field1',\r
877 locked: withLocking\r
878 }, {\r
879 dataIndex: 'field2'\r
880 }], undefined, {\r
881 selModel: sm\r
882 });\r
883 });\r
884\r
885 afterEach(function() {\r
886 sm = null;\r
887 });\r
888\r
889 it("should bind the store to the selection model", function() {\r
890 expect(sm.getStore()).toBe(grid.getStore());\r
891 });\r
892\r
893 it("should add the selectedItemCls when selected", function() {\r
894 var cls;\r
895 sm.select(0);\r
896 if (withLocking) {\r
897 view = grid.normalGrid.getView();\r
898 cls = view.selectedItemCls;\r
899\r
900 expect(grid.lockedGrid.getView().getNode(0)).toHaveCls(cls);\r
901 expect(view.getNode(0)).toHaveCls(cls);\r
902 } else {\r
903 view = grid.getView();\r
904 cls = view.selectedItemCls;\r
905\r
906 expect(view.getNode(0)).toHaveCls(cls);\r
907 }\r
908 });\r
909\r
910 it("should remove the selectedItemCls when deselected", function() {\r
911 var cls;\r
912 sm.select(0);\r
913 sm.deselect(0);\r
914\r
915 if (withLocking) {\r
916 view = grid.normalGrid.getView();\r
917 cls = view.selectedItemCls;\r
918\r
919 expect(grid.lockedGrid.getView().getNode(0)).not.toHaveCls(cls);\r
920 expect(view.getNode(0)).not.toHaveCls(cls);\r
921 } else {\r
922 view = grid.getView();\r
923 cls = view.selectedItemCls;\r
924\r
925 expect(view.getNode(0)).not.toHaveCls(cls);\r
926 }\r
927 });\r
928\r
929 it("should retain the selectedItemCls when updating a row", function() {\r
930 var cls;\r
931 sm.select(0);\r
932 store.first().commit();\r
933 if (withLocking) {\r
934 view = grid.normalGrid.getView();\r
935 cls = view.selectedItemCls;\r
936\r
937 expect(grid.lockedGrid.getView().getNode(0)).toHaveCls(cls);\r
938 expect(view.getNode(0)).toHaveCls(cls);\r
939 } else {\r
940 view = grid.getView();\r
941 cls = view.selectedItemCls;\r
942\r
943 expect(view.getNode(0)).toHaveCls(cls);\r
944 }\r
945 });\r
946 });\r
947 }\r
948\r
949 describeSelectionSuite(false);\r
950 describeSelectionSuite(true);\r
951 });\r
952 \r
953 describe("renderers", function(){\r
954 describe("scope", function() {\r
955 it("should use the grid as the default scope", function(){\r
956 var scope;\r
957 makeGrid([{\r
958 dataIndex: 'field1',\r
959 text: 'Field1',\r
960 renderer: function(){\r
961 scope = this;\r
962 } \r
963 }]); \r
964 expect(scope).toBe(grid);\r
965 });\r
966 \r
967 it("should use the passed scope", function(){\r
968 var o = {},\r
969 scope;\r
970 \r
971 makeGrid([{\r
972 dataIndex: 'field1',\r
973 text: 'Field1',\r
974 scope: o,\r
975 renderer: function(){\r
976 scope = this;\r
977 } \r
978 }]); \r
979 expect(scope).toBe(o);\r
980 });\r
981 });\r
982 \r
983 describe("params", function(){\r
984 var args;\r
985 beforeEach(function(){\r
986 makeGrid([{\r
987 dataIndex: 'field1',\r
988 renderer: function(){\r
989 args = Array.prototype.slice.call(arguments, 0, arguments.length);\r
990 } \r
991 }]);\r
992 });\r
993 \r
994 it("should pass the value as the first param", function(){\r
995 expect(args[0]).toBe(1);\r
996 });\r
997 \r
998 it("should pass a meta object as the second param", function(){\r
999 expect(Ext.isObject(args[1])).toBe(true);\r
1000 });\r
1001 \r
1002 it("should pass the record as the third param", function(){\r
1003 expect(args[2]).toBe(store.getAt(0));\r
1004 });\r
1005 \r
1006 it("should pass the recordIndex as the fourth param", function(){\r
1007 expect(args[3]).toBe(0);\r
1008 });\r
1009 \r
1010 it("should pass the cellIndex as the fifth param", function(){\r
1011 expect(args[4]).toBe(0);\r
1012 });\r
1013 \r
1014 it("should pass the store as the sixth param", function(){\r
1015 expect(args[5]).toBe(store);\r
1016 });\r
1017 \r
1018 it("should pass the view as the seventh param", function(){\r
1019 expect(args[6]).toBe(grid.getView());\r
1020 });\r
1021 });\r
1022 \r
1023 describe("cellIndex", function(){\r
1024 it("should pass the local index when dealing with locked columns", function(){\r
1025 var indexes = [],\r
1026 fn = function(){\r
1027 indexes.push(arguments[4]);\r
1028 };\r
1029 \r
1030 makeGrid([{\r
1031 locked: true,\r
1032 dataIndex: 'field1',\r
1033 renderer: fn \r
1034 }, {\r
1035 locked: true,\r
1036 dataIndex: 'field2',\r
1037 renderer: fn \r
1038 }, {\r
1039 dataIndex: 'field3',\r
1040 renderer: fn \r
1041 }, {\r
1042 dataIndex: 'field4',\r
1043 renderer: fn \r
1044 }]);\r
1045 expect(indexes).toEqual([0, 1, 0, 1]);\r
1046 });\r
1047 \r
1048 it("should take into account hidden columns when passing cellIdx", function(){\r
1049 var values = [],\r
1050 indexes = [],\r
1051 fn = function(v){\r
1052 values.push(v);\r
1053 indexes.push(arguments[4]);\r
1054 };\r
1055 \r
1056 makeGrid([{\r
1057 dataIndex: 'field1',\r
1058 renderer: fn \r
1059 }, {\r
1060 hidden: true,\r
1061 dataIndex: 'field2',\r
1062 renderer: fn \r
1063 }, {\r
1064 dataIndex: 'field3',\r
1065 renderer: fn \r
1066 }, {\r
1067 hidden: true,\r
1068 dataIndex: 'field4',\r
1069 renderer: fn \r
1070 }, {\r
1071 dataIndex: 'field5',\r
1072 renderer: fn\r
1073 }]);\r
1074 expect(indexes).toEqual([0, 2, 4]);\r
1075 expect(values).toEqual([1, 3, 5]);\r
1076 });\r
1077 });\r
1078 \r
1079 it("should accept a string formatter that maps to Ext.util.Format", function() {\r
1080 var oldFormat = Ext.util.Format.capitalize,\r
1081 called;\r
1082 \r
1083 Ext.util.Format.capitalize = function () {\r
1084 called = true; \r
1085 };\r
1086\r
1087 makeGrid([{\r
1088 dataIndex: 'field1',\r
1089 formatter: 'capitalize'\r
1090 }]);\r
1091\r
1092 expect(called).toBe(true);\r
1093\r
1094 Ext.util.Format.capitalize = oldFormat;\r
1095 });\r
1096\r
1097 it("should accept a scoped formatter", function() {\r
1098 var called = 0;\r
1099\r
1100 var formatter = function (v, a1) {\r
1101 called = v + a1;\r
1102 };\r
1103\r
1104 makeGrid([{\r
1105 dataIndex: 'field1',\r
1106 formatter: 'this.foo(2)'\r
1107 }], undefined, {\r
1108 defaultListenerScope: true,\r
1109 foo: formatter\r
1110 });\r
1111\r
1112 expect(called).toBe(3);\r
1113 });\r
1114\r
1115 it("should treat dynamic renderers as needed to run in all cases", function() {\r
1116 var x = 0;\r
1117\r
1118 var VC = Ext.define(null, {\r
1119 extend: 'Ext.app.ViewController',\r
1120 doRender: function() {\r
1121 return 'x' + ++x;\r
1122 }\r
1123 });\r
1124\r
1125 makeGrid([{\r
1126 dataIndex: 'field1'\r
1127 }, {\r
1128 renderer: 'doRender'\r
1129 }],\r
1130 1, // ONE row of data, so that the first call of the custom renderer\r
1131 // increments x to one, and the second call renders 2.\r
1132 {\r
1133 controller: new VC()\r
1134 });\r
1135\r
1136 var rec = store.getAt(0);\r
1137 expect(getCellText(0, 1)).toBe('x1');\r
1138 rec.set('field1', 'foo');\r
1139 expect(getCellText(0, 1)).toBe('x2');\r
1140 });\r
1141 });\r
1142 \r
1143 describe("model operations", function() {\r
1144 describe("destroy", function() {\r
1145 it("should remove the model when destroy is called", function() {\r
1146 makeGrid([{\r
1147 dataIndex: 'field1'\r
1148 }], [{\r
1149 field1: 'foo'\r
1150 }, {\r
1151 field1: 'bar'\r
1152 }, {\r
1153 field1: 'baz'\r
1154 }]);\r
1155 store.first().erase();\r
1156 expect(grid.getView().getNodes().length).toBe(2);\r
1157 }); \r
1158 }); \r
1159 });\r
1160 \r
1161 describe("reconfigure", function() {\r
1162 function makeReconfigureSuite(beforeRender) {\r
1163 function makeReconfigureGrid(columns, data, cfg, options, locked) {\r
1164 cfg = cfg || {};\r
1165 if (beforeRender) {\r
1166 cfg.renderTo = null;\r
1167 }\r
1168 makeGrid(columns, data, cfg, options, locked);\r
1169 }\r
1170\r
1171 function reconfigure() {\r
1172 grid.reconfigure.apply(grid, arguments);\r
1173 if (beforeRender) {\r
1174 grid.render(Ext.getBody());\r
1175 }\r
1176 }\r
1177\r
1178 describe(beforeRender ? "before render" : "after render", function() {\r
1179 describe("store only", function() {\r
1180 describe("without locking", function() {\r
1181 function expectNodeLength(n) {\r
1182 expect(view.getNodes().length).toBe(n);\r
1183 }\r
1184\r
1185 describe("with no store", function() {\r
1186 beforeEach(function() {\r
1187 makeReconfigureGrid([{\r
1188 dataIndex: 'field1'\r
1189 }], undefined, null, {preventStoreCreate: true});\r
1190 reconfigure(makeStore());\r
1191 });\r
1192\r
1193 it("should render data from the new store", function() {\r
1194 expectNodeLength(1);\r
1195 });\r
1196\r
1197 it("should react to store", function() {\r
1198 store.add({});\r
1199 expectNodeLength(2);\r
1200 });\r
1201\r
1202 it("should react to store remove", function() {\r
1203 store.removeAt(0);\r
1204 expectNodeLength(0);\r
1205 });\r
1206\r
1207 it("should react to store update", function() {\r
1208 store.getAt(0).set('field1', 'Foo');\r
1209 expect(getCellText(0, 0)).toBe('Foo');\r
1210 });\r
1211\r
1212 it("should react to store load", function() {\r
1213 store.loadData([{}, {}, {}, {}, {}, {}]);\r
1214 expectNodeLength(6);\r
1215 });\r
1216\r
1217 it("should bind to the selection model", function() {\r
1218 expect(grid.getView().getSelectionModel().getStore()).toBe(store);\r
1219 });\r
1220 });\r
1221\r
1222 describe("with an existing store", function() {\r
1223 var oldStore;\r
1224\r
1225 beforeEach(function() {\r
1226 makeReconfigureGrid([{\r
1227 dataIndex: 'field1'\r
1228 }], 20);\r
1229 oldStore = store;\r
1230 reconfigure(makeStore());\r
1231 });\r
1232\r
1233 afterEach(function() {\r
1234 oldStore = Ext.destroy(oldStore);\r
1235 });\r
1236\r
1237 it("should render data from the new store", function() {\r
1238 expectNodeLength(1);\r
1239 });\r
1240\r
1241 it("should react to store", function() {\r
1242 store.add({});\r
1243 expectNodeLength(2);\r
1244 });\r
1245\r
1246 it("should react to store remove", function() {\r
1247 store.removeAt(0);\r
1248 expectNodeLength(0);\r
1249 });\r
1250\r
1251 it("should react to store update", function() {\r
1252 store.getAt(0).set('field1', 'Foo');\r
1253 expect(getCellText(0, 0)).toBe('Foo');\r
1254 });\r
1255\r
1256 it("should react to store load", function() {\r
1257 store.loadData([{}, {}, {}, {}, {}, {}]);\r
1258 expectNodeLength(6);\r
1259 });\r
1260\r
1261 it("should bind the new store to the loadMask", function() {\r
1262 expect(grid.getView().loadMask.store).toBe(store);\r
1263 });\r
1264\r
1265 it("should bind to the selection model", function() {\r
1266 expect(grid.getView().getSelectionModel().getStore()).toBe(store);\r
1267 });\r
1268\r
1269 it("should not react to the old store", function() {\r
1270 oldStore.add([{}, {}, {}, {}, {}, {}]);\r
1271 expectNodeLength(1);\r
1272 oldStore.removeAt(0);\r
1273 expectNodeLength(1);\r
1274 oldStore.getAt(0).set('field1', 'Foo');\r
1275 expect(getCellText(0, 0)).toBe('1');\r
1276 oldStore.loadData([{}, {}, {}, {}, {}, {}, {}, {}, {}]);\r
1277 expectNodeLength(1);\r
1278 });\r
1279 });\r
1280 });\r
1281\r
1282 describe("with locking", function() {\r
1283 function expectNodeLength(n) {\r
1284 expect(grid.lockedGrid.getView().getNodes().length).toBe(n);\r
1285 expect(grid.normalGrid.getView().getNodes().length).toBe(n);\r
1286 }\r
1287\r
1288 describe("with no store", function() {\r
1289 beforeEach(function() {\r
1290 makeReconfigureGrid([{\r
1291 locked: true,\r
1292 dataIndex: 'field1'\r
1293 }, {\r
1294 dataIndex: 'field2'\r
1295 }], undefined, null, {preventStoreCreate: true});\r
1296 reconfigure(makeStore());\r
1297 });\r
1298\r
1299 it("should render data from the new store", function() {\r
1300 expectNodeLength(1);\r
1301 });\r
1302\r
1303 it("should react to store", function() {\r
1304 store.add({});\r
1305 expectNodeLength(2);\r
1306 });\r
1307\r
1308 it("should react to store remove", function() {\r
1309 store.removeAt(0);\r
1310 expectNodeLength(0);\r
1311 });\r
1312\r
1313 it("should react to store update", function() {\r
1314 store.getAt(0).set('field1', 'Foo');\r
1315 expect(getCellText(0, 0)).toBe('Foo');\r
1316 });\r
1317\r
1318 it("should react to store load", function() {\r
1319 store.loadData([{}, {}, {}, {}, {}, {}]);\r
1320 expectNodeLength(6);\r
1321 });\r
1322\r
1323 it("should bind to the selection model", function() {\r
1324 expect(grid.getView().getSelectionModel().getStore()).toBe(store);\r
1325 });\r
1326 });\r
1327\r
1328 describe("with an existing store", function() {\r
1329 var oldStore;\r
1330\r
1331 beforeEach(function() {\r
1332 makeReconfigureGrid([{\r
1333 locked: true,\r
1334 dataIndex: 'field1'\r
1335 }, {\r
1336 dataIndex: 'field2'\r
1337 }], 20);\r
1338 oldStore = store;\r
1339 reconfigure(makeStore());\r
1340 });\r
1341\r
1342 afterEach(function() {\r
1343 oldStore = Ext.destroy(oldStore);\r
1344 });\r
1345\r
1346 it("should render data from the new store", function() {\r
1347 expectNodeLength(1);\r
1348 });\r
1349\r
1350 it("should react to store", function() {\r
1351 store.add({});\r
1352 expectNodeLength(2);\r
1353 });\r
1354\r
1355 it("should react to store remove", function() {\r
1356 store.removeAt(0);\r
1357 expectNodeLength(0);\r
1358 });\r
1359\r
1360 it("should react to store update", function() {\r
1361 store.getAt(0).set('field1', 'Foo');\r
1362 expect(getCellText(0, 0)).toBe('Foo');\r
1363 });\r
1364\r
1365 it("should react to store load", function() {\r
1366 store.loadData([{}, {}, {}, {}, {}, {}]);\r
1367 expectNodeLength(6);\r
1368 });\r
1369\r
1370 it("should bind the new store to the loadMask", function() {\r
1371 expect(grid.getView().loadMask.store).toBe(store);\r
1372 });\r
1373\r
1374 it("should bind to the selection model", function() {\r
1375 expect(grid.getView().getSelectionModel().getStore()).toBe(store);\r
1376 });\r
1377\r
1378 it("should not react to the old store", function() {\r
1379 oldStore.add([{}, {}, {}, {}, {}, {}]);\r
1380 expectNodeLength(1);\r
1381 oldStore.removeAt(0);\r
1382 expectNodeLength(1);\r
1383 oldStore.getAt(0).set('field1', 'Foo');\r
1384 expect(getCellText(0, 0)).toBe('1');\r
1385 oldStore.loadData([{}, {}, {}, {}, {}, {}, {}, {}, {}]);\r
1386 expectNodeLength(1);\r
1387 });\r
1388 });\r
1389 });\r
1390 });\r
1391\r
1392 describe("columns only", function() {\r
1393 var oldCols;\r
1394\r
1395 afterEach(function() {\r
1396 oldCols = null;\r
1397 });\r
1398\r
1399 describe("without locking", function() {\r
1400 describe("with no columns", function() {\r
1401 beforeEach(function() {\r
1402 makeReconfigureGrid(null, undefined, null, {preventColumnCreate: true});\r
1403 oldCols = colRef;\r
1404 reconfigure(null, [{\r
1405 dataIndex: 'field2'\r
1406 }, {\r
1407 dataIndex: 'field7'\r
1408 }]);\r
1409 colRef = grid.getVisibleColumnManager().getColumns();\r
1410 });\r
1411\r
1412 it("should add the new columns and render the contents", function() {\r
1413 expect(colRef.length).toBe(2);\r
1414 expect(getCellText(0, 0)).toBe('2');\r
1415 expect(getCellText(0, 1)).toBe('7');\r
1416 });\r
1417 });\r
1418\r
1419 describe("with existing columns", function() {\r
1420 beforeEach(function() {\r
1421 makeReconfigureGrid([{\r
1422 dataIndex: 'field1'\r
1423 }]);\r
1424 oldCols = colRef;\r
1425 reconfigure(null, [{\r
1426 dataIndex: 'field2'\r
1427 }, {\r
1428 dataIndex: 'field7'\r
1429 }]);\r
1430 colRef = grid.getVisibleColumnManager().getColumns();\r
1431 });\r
1432\r
1433 it("should add the new columns and render the contents", function() {\r
1434 expect(colRef.length).toBe(2);\r
1435 expect(getCellText(0, 0)).toBe('2');\r
1436 expect(getCellText(0, 1)).toBe('7');\r
1437 });\r
1438\r
1439 it("should destroy old columns", function() {\r
1440 expect(oldCols[0].destroyed).toBe(true);\r
1441 });\r
1442 });\r
1443\r
1444 it("should only refresh after the columns have been rendered", function() {\r
1445 var spy = jasmine.createSpy(),\r
1446 renderCount, refreshCounter, view;\r
1447\r
1448 makeReconfigureGrid();\r
1449 view = grid.getView();\r
1450 refreshCounter = view.refreshCounter || 0;\r
1451 view.on('refresh', function() {\r
1452 renderCount = spy.callCount;\r
1453 });\r
1454\r
1455 reconfigure(null, [{\r
1456 dataIndex: 'field2',\r
1457 listeners: {\r
1458 afterrender: spy\r
1459 }\r
1460 }, {\r
1461 dataIndex: 'field7',\r
1462 listeners: {\r
1463 afterrender: spy\r
1464 }\r
1465 }]);\r
1466 expect(renderCount).toBe(2);\r
1467 expect(view.refreshCounter).toBe(refreshCounter + 1);\r
1468 });\r
1469 });\r
1470\r
1471 describe("with locking", function() {\r
1472 describe("with no columns", function() {\r
1473 beforeEach(function() {\r
1474 makeReconfigureGrid(null, undefined, {enableLocking: true}, {preventColumnCreate: true});\r
1475 oldCols = colRef;\r
1476 reconfigure(null, [{\r
1477 locked: true,\r
1478 dataIndex: 'field2'\r
1479 }, {\r
1480 dataIndex: 'field7'\r
1481 }]);\r
1482 colRef = grid.getVisibleColumnManager().getColumns();\r
1483 });\r
1484\r
1485 it("should add the new columns and render the contents", function() {\r
1486 expect(colRef.length).toBe(2);\r
1487 expect(getCellText(0, 0)).toBe('2');\r
1488 expect(getCellText(0, 1)).toBe('7');\r
1489 });\r
1490\r
1491 it("should process locked/unlocked columns", function() {\r
1492 expect(grid.lockedGrid.getVisibleColumnManager().getColumns().length).toBe(1);\r
1493 expect(grid.normalGrid.getVisibleColumnManager().getColumns().length).toBe(1);\r
1494 });\r
1495 });\r
1496\r
1497 describe("with existing columns", function() {\r
1498 beforeEach(function() {\r
1499 makeReconfigureGrid([{\r
1500 locked: true,\r
1501 dataIndex: 'field1'\r
1502 }, {\r
1503 dataIndex: 'field3'\r
1504 }]);\r
1505 oldCols = colRef;\r
1506 reconfigure(null, [{\r
1507 locked: true,\r
1508 dataIndex: 'field2'\r
1509 }, {\r
1510 dataIndex: 'field7'\r
1511 }]);\r
1512 colRef = grid.getVisibleColumnManager().getColumns();\r
1513 });\r
1514\r
1515 it("should add the new columns and render the contents", function() {\r
1516 expect(colRef.length).toBe(2);\r
1517 expect(getCellText(0, 0)).toBe('2');\r
1518 expect(getCellText(0, 1)).toBe('7');\r
1519 });\r
1520\r
1521 it("should process locked/unlocked columns", function() {\r
1522 expect(grid.lockedGrid.getVisibleColumnManager().getColumns().length).toBe(1);\r
1523 expect(grid.normalGrid.getVisibleColumnManager().getColumns().length).toBe(1);\r
1524 });\r
1525\r
1526 it("should destroy old columns", function() {\r
1527 expect(oldCols[0].destroyed).toBe(true);\r
1528 expect(oldCols[1].destroyed).toBe(true);\r
1529 });\r
1530 });\r
1531\r
1532 it("should only refresh after the columns have been rendered", function() {\r
1533 var spy = jasmine.createSpy(),\r
1534 renderCount, refreshCounter, view;\r
1535\r
1536 makeReconfigureGrid([{\r
1537 locked: true,\r
1538 dataIndex: 'field1'\r
1539 }, {\r
1540 dataIndex: 'field3'\r
1541 }]);\r
1542\r
1543 view = grid.lockedGrid.getView();\r
1544 refreshCounter = view.refreshCounter || 0;\r
1545\r
1546 view.on('refresh', function() {\r
1547 renderCount = spy.callCount;\r
1548 });\r
1549\r
1550\r
1551 reconfigure(null, [{\r
1552 locked: true,\r
1553 dataIndex: 'field2',\r
1554 listeners: {\r
1555 afterrender: spy\r
1556 }\r
1557 }, {\r
1558 dataIndex: 'field7',\r
1559 listeners: {\r
1560 afterrender: spy\r
1561 }\r
1562 }]);\r
1563 expect(renderCount).toBe(2);\r
1564 expect(view.refreshCounter).toBe(refreshCounter + 1);\r
1565 });\r
1566 });\r
1567 });\r
1568\r
1569 describe("store & columns", function() {\r
1570 var oldCols, oldStore;\r
1571\r
1572 afterEach(function() {\r
1573 Ext.destroy(oldStore);\r
1574 oldStore = oldCols = null;\r
1575 });\r
1576\r
1577 describe("without locking", function() {\r
1578 function expectNodeLength(n) {\r
1579 expect(view.getNodes().length).toBe(n);\r
1580 }\r
1581\r
1582 describe("with no store and no columns", function() {\r
1583 beforeEach(function() {\r
1584 makeReconfigureGrid(null, undefined, null, {preventStoreCreate: true, preventColumnCreate: true});\r
1585 oldCols = colRef;\r
1586 oldStore = store;\r
1587 reconfigure(makeStore(), [{\r
1588 dataIndex: 'field2'\r
1589 }, {\r
1590 dataIndex: 'field7'\r
1591 }]);\r
1592 colRef = grid.getVisibleColumnManager().getColumns();\r
1593 });\r
1594\r
1595 it("should render data from the new store", function() {\r
1596 expectNodeLength(1);\r
1597 });\r
1598\r
1599 it("should react to store", function() {\r
1600 store.add({});\r
1601 expectNodeLength(2);\r
1602 });\r
1603\r
1604 it("should react to store remove", function() {\r
1605 store.removeAt(0);\r
1606 expectNodeLength(0);\r
1607 });\r
1608\r
1609 it("should react to store update", function() {\r
1610 store.getAt(0).set('field2', 'Foo');\r
1611 expect(getCellText(0, 0)).toBe('Foo');\r
1612 });\r
1613\r
1614 it("should react to store load", function() {\r
1615 store.loadData([{}, {}, {}, {}, {}, {}]);\r
1616 expectNodeLength(6);\r
1617 });\r
1618\r
1619 it("should bind to the selection model", function() {\r
1620 expect(grid.getView().getSelectionModel().getStore()).toBe(store);\r
1621 });\r
1622\r
1623 it("should add the new columns and render the contents", function() {\r
1624 expect(colRef.length).toBe(2);\r
1625 expect(getCellText(0, 0)).toBe('2');\r
1626 expect(getCellText(0, 1)).toBe('7');\r
1627 });\r
1628 });\r
1629\r
1630 describe("with an existing store and no columns", function() {\r
1631 beforeEach(function() {\r
1632 makeReconfigureGrid(null, undefined, null, {preventColumnCreate: true});\r
1633 oldCols = colRef;\r
1634 oldStore = store;\r
1635 reconfigure(makeStore(), [{\r
1636 dataIndex: 'field2'\r
1637 }, {\r
1638 dataIndex: 'field7'\r
1639 }]);\r
1640 colRef = grid.getVisibleColumnManager().getColumns();\r
1641 });\r
1642\r
1643 it("should render data from the new store", function() {\r
1644 expectNodeLength(1);\r
1645 });\r
1646\r
1647 it("should react to store", function() {\r
1648 store.add({});\r
1649 expectNodeLength(2);\r
1650 });\r
1651\r
1652 it("should react to store remove", function() {\r
1653 store.removeAt(0);\r
1654 expectNodeLength(0);\r
1655 });\r
1656\r
1657 it("should react to store update", function() {\r
1658 store.getAt(0).set('field2', 'Foo');\r
1659 expect(getCellText(0, 0)).toBe('Foo');\r
1660 });\r
1661\r
1662 it("should react to store load", function() {\r
1663 store.loadData([{}, {}, {}, {}, {}, {}]);\r
1664 expectNodeLength(6);\r
1665 });\r
1666\r
1667 it("should bind to the selection model", function() {\r
1668 expect(grid.getView().getSelectionModel().getStore()).toBe(store);\r
1669 });\r
1670\r
1671 it("should not react to the old store", function() {\r
1672 oldStore.add([{}, {}, {}, {}, {}, {}]);\r
1673 expectNodeLength(1);\r
1674 oldStore.removeAt(0);\r
1675 expectNodeLength(1);\r
1676 oldStore.getAt(0).set('field1', 'Foo');\r
1677 expect(getCellText(0, 0)).toBe('2');\r
1678 oldStore.loadData([{}, {}, {}, {}, {}, {}, {}, {}, {}]);\r
1679 expectNodeLength(1);\r
1680 });\r
1681\r
1682 it("should add the new columns and render the contents", function() {\r
1683 expect(colRef.length).toBe(2);\r
1684 expect(getCellText(0, 0)).toBe('2');\r
1685 expect(getCellText(0, 1)).toBe('7');\r
1686 });\r
1687 });\r
1688\r
1689 describe("with no store and existing columns", function() {\r
1690 beforeEach(function() {\r
1691 makeReconfigureGrid([{\r
1692 dataIndex: 'field1'\r
1693 }], undefined, null, {preventStoreCreate: true});\r
1694 oldCols = colRef;\r
1695 oldStore = store;\r
1696 reconfigure(makeStore(), [{\r
1697 dataIndex: 'field2'\r
1698 }, {\r
1699 dataIndex: 'field7'\r
1700 }]);\r
1701 colRef = grid.getVisibleColumnManager().getColumns();\r
1702 });\r
1703\r
1704 it("should render data from the new store", function() {\r
1705 expectNodeLength(1);\r
1706 });\r
1707\r
1708 it("should react to store", function() {\r
1709 store.add({});\r
1710 expectNodeLength(2);\r
1711 });\r
1712\r
1713 it("should react to store remove", function() {\r
1714 store.removeAt(0);\r
1715 expectNodeLength(0);\r
1716 });\r
1717\r
1718 it("should react to store update", function() {\r
1719 store.getAt(0).set('field2', 'Foo');\r
1720 expect(getCellText(0, 0)).toBe('Foo');\r
1721 });\r
1722\r
1723 it("should react to store load", function() {\r
1724 store.loadData([{}, {}, {}, {}, {}, {}]);\r
1725 expectNodeLength(6);\r
1726 });\r
1727\r
1728 it("should bind to the selection model", function() {\r
1729 expect(grid.getView().getSelectionModel().getStore()).toBe(store);\r
1730 });\r
1731\r
1732 it("should add the new columns and render the contents", function() {\r
1733 expect(colRef.length).toBe(2);\r
1734 expect(getCellText(0, 0)).toBe('2');\r
1735 expect(getCellText(0, 1)).toBe('7');\r
1736 });\r
1737\r
1738 it("should destroy old columns", function() {\r
1739 expect(oldCols[0].destroyed).toBe(true);\r
1740 });\r
1741 });\r
1742\r
1743 describe("with an existing store and existing columns", function() {\r
1744 beforeEach(function() {\r
1745 makeReconfigureGrid([{\r
1746 dataIndex: 'field1'\r
1747 }]);\r
1748 oldCols = colRef;\r
1749 oldStore = store;\r
1750 reconfigure(makeStore(), [{\r
1751 dataIndex: 'field2'\r
1752 }, {\r
1753 dataIndex: 'field7'\r
1754 }]);\r
1755 colRef = grid.getVisibleColumnManager().getColumns();\r
1756 });\r
1757\r
1758 it("should render data from the new store", function() {\r
1759 expectNodeLength(1);\r
1760 });\r
1761\r
1762 it("should react to store", function() {\r
1763 store.add({});\r
1764 expectNodeLength(2);\r
1765 });\r
1766\r
1767 it("should react to store remove", function() {\r
1768 store.removeAt(0);\r
1769 expectNodeLength(0);\r
1770 });\r
1771\r
1772 it("should react to store update", function() {\r
1773 store.getAt(0).set('field2', 'Foo');\r
1774 expect(getCellText(0, 0)).toBe('Foo');\r
1775 });\r
1776\r
1777 it("should react to store load", function() {\r
1778 store.loadData([{}, {}, {}, {}, {}, {}]);\r
1779 expectNodeLength(6);\r
1780 });\r
1781\r
1782 it("should bind to the selection model", function() {\r
1783 expect(grid.getView().getSelectionModel().getStore()).toBe(store);\r
1784 });\r
1785\r
1786 it("should not react to the old store", function() {\r
1787 oldStore.add([{}, {}, {}, {}, {}, {}]);\r
1788 expectNodeLength(1);\r
1789 oldStore.removeAt(0);\r
1790 expectNodeLength(1);\r
1791 oldStore.getAt(0).set('field1', 'Foo');\r
1792 expect(getCellText(0, 0)).toBe('2');\r
1793 oldStore.loadData([{}, {}, {}, {}, {}, {}, {}, {}, {}]);\r
1794 expectNodeLength(1);\r
1795 });\r
1796\r
1797 it("should add the new columns and render the contents", function() {\r
1798 expect(colRef.length).toBe(2);\r
1799 expect(getCellText(0, 0)).toBe('2');\r
1800 expect(getCellText(0, 1)).toBe('7');\r
1801 });\r
1802\r
1803 it("should destroy old columns", function() {\r
1804 expect(oldCols[0].destroyed).toBe(true);\r
1805 });\r
1806 });\r
1807\r
1808 it("should only refresh after the columns have been rendered", function() {\r
1809 var spy = jasmine.createSpy(),\r
1810 renderCount, refreshCounter, view;\r
1811\r
1812 makeReconfigureGrid();\r
1813\r
1814 oldStore = store;\r
1815 view = grid.getView();\r
1816 refreshCounter = view.refreshCounter || 0;\r
1817\r
1818 view.on('refresh', function() {\r
1819 renderCount = spy.callCount;\r
1820 });\r
1821 \r
1822 reconfigure(store, [{\r
1823 dataIndex: 'field2',\r
1824 listeners: {\r
1825 afterrender: spy\r
1826 }\r
1827 }, {\r
1828 dataIndex: 'field7',\r
1829 listeners: {\r
1830 afterrender: spy\r
1831 }\r
1832 }]);\r
1833 expect(renderCount).toBe(2);\r
1834 expect(view.refreshCounter).toBe(refreshCounter + 1);\r
1835 });\r
1836 });\r
1837\r
1838 describe("with locking", function() {\r
1839 function expectNodeLength(n) {\r
1840 expect(grid.lockedGrid.getView().getNodes().length).toBe(n);\r
1841 expect(grid.normalGrid.getView().getNodes().length).toBe(n);\r
1842 }\r
1843\r
1844 describe("with no store and no columns", function() {\r
1845 beforeEach(function() {\r
1846 makeReconfigureGrid(null, undefined, {enableLocking: true}, {preventStoreCreate: true, preventColumnCreate: true});\r
1847 oldCols = colRef;\r
1848 oldStore = store;\r
1849 reconfigure(makeStore(), [{\r
1850 locked: true,\r
1851 dataIndex: 'field2'\r
1852 }, {\r
1853 dataIndex: 'field7'\r
1854 }]);\r
1855 colRef = grid.getVisibleColumnManager().getColumns();\r
1856 });\r
1857\r
1858 it("should render data from the new store", function() {\r
1859 expectNodeLength(1);\r
1860 });\r
1861\r
1862 it("should react to store", function() {\r
1863 store.add({});\r
1864 expectNodeLength(2);\r
1865 });\r
1866\r
1867 it("should react to store remove", function() {\r
1868 store.removeAt(0);\r
1869 expectNodeLength(0);\r
1870 });\r
1871\r
1872 it("should react to store update", function() {\r
1873 store.getAt(0).set('field2', 'Foo');\r
1874 expect(getCellText(0, 0)).toBe('Foo');\r
1875 });\r
1876\r
1877 it("should react to store load", function() {\r
1878 store.loadData([{}, {}, {}, {}, {}, {}]);\r
1879 expectNodeLength(6);\r
1880 });\r
1881\r
1882 it("should bind to the selection model", function() {\r
1883 expect(grid.getView().getSelectionModel().getStore()).toBe(store);\r
1884 });\r
1885\r
1886 it("should add the new columns and render the contents", function() {\r
1887 expect(colRef.length).toBe(2);\r
1888 expect(getCellText(0, 0)).toBe('2');\r
1889 expect(getCellText(0, 1)).toBe('7');\r
1890 });\r
1891\r
1892 it("should process locked/unlocked columns", function() {\r
1893 expect(grid.lockedGrid.getVisibleColumnManager().getColumns().length).toBe(1);\r
1894 expect(grid.normalGrid.getVisibleColumnManager().getColumns().length).toBe(1);\r
1895 });\r
1896 });\r
1897\r
1898 describe("with an existing store and no columns", function() {\r
1899 beforeEach(function() {\r
1900 makeReconfigureGrid(null, undefined, {enableLocking: true}, {preventColumnCreate: true});\r
1901 oldCols = colRef;\r
1902 oldStore = store;\r
1903 reconfigure(makeStore(), [{\r
1904 locked: true,\r
1905 dataIndex: 'field2'\r
1906 }, {\r
1907 dataIndex: 'field7'\r
1908 }]);\r
1909 colRef = grid.getVisibleColumnManager().getColumns();\r
1910 });\r
1911\r
1912 it("should render data from the new store", function() {\r
1913 expectNodeLength(1);\r
1914 });\r
1915\r
1916 it("should react to store", function() {\r
1917 store.add({});\r
1918 expectNodeLength(2);\r
1919 });\r
1920\r
1921 it("should react to store remove", function() {\r
1922 store.removeAt(0);\r
1923 expectNodeLength(0);\r
1924 });\r
1925\r
1926 it("should react to store update", function() {\r
1927 store.getAt(0).set('field2', 'Foo');\r
1928 expect(getCellText(0, 0)).toBe('Foo');\r
1929 });\r
1930\r
1931 it("should react to store load", function() {\r
1932 store.loadData([{}, {}, {}, {}, {}, {}]);\r
1933 expectNodeLength(6);\r
1934 });\r
1935\r
1936 it("should bind to the selection model", function() {\r
1937 expect(grid.getView().getSelectionModel().getStore()).toBe(store);\r
1938 });\r
1939\r
1940 it("should not react to the old store", function() {\r
1941 oldStore.add([{}, {}, {}, {}, {}, {}]);\r
1942 expectNodeLength(1);\r
1943 oldStore.removeAt(0);\r
1944 expectNodeLength(1);\r
1945 oldStore.getAt(0).set('field1', 'Foo');\r
1946 expect(getCellText(0, 0)).toBe('2');\r
1947 oldStore.loadData([{}, {}, {}, {}, {}, {}, {}, {}, {}]);\r
1948 expectNodeLength(1);\r
1949 });\r
1950\r
1951 it("should add the new columns and render the contents", function() {\r
1952 expect(colRef.length).toBe(2);\r
1953 expect(getCellText(0, 0)).toBe('2');\r
1954 expect(getCellText(0, 1)).toBe('7');\r
1955 });\r
1956\r
1957 it("should process locked/unlocked columns", function() {\r
1958 expect(grid.lockedGrid.getVisibleColumnManager().getColumns().length).toBe(1);\r
1959 expect(grid.normalGrid.getVisibleColumnManager().getColumns().length).toBe(1);\r
1960 });\r
1961 });\r
1962\r
1963 describe("with no store and existing columns", function() {\r
1964 beforeEach(function() {\r
1965 makeReconfigureGrid([{\r
1966 locked: true,\r
1967 dataIndex: 'field1'\r
1968 }, {\r
1969 dataIndex: 'field3'\r
1970 }], undefined, null, {preventStoreCreate: true});\r
1971 oldCols = colRef;\r
1972 oldStore = store;\r
1973 reconfigure(makeStore(), [{\r
1974 locked: true,\r
1975 dataIndex: 'field2'\r
1976 }, {\r
1977 dataIndex: 'field7'\r
1978 }]);\r
1979 colRef = grid.getVisibleColumnManager().getColumns();\r
1980 });\r
1981\r
1982 it("should render data from the new store", function() {\r
1983 expectNodeLength(1);\r
1984 });\r
1985\r
1986 it("should react to store", function() {\r
1987 store.add({});\r
1988 expectNodeLength(2);\r
1989 });\r
1990\r
1991 it("should react to store remove", function() {\r
1992 store.removeAt(0);\r
1993 expectNodeLength(0);\r
1994 });\r
1995\r
1996 it("should react to store update", function() {\r
1997 store.getAt(0).set('field2', 'Foo');\r
1998 expect(getCellText(0, 0)).toBe('Foo');\r
1999 });\r
2000\r
2001 it("should react to store load", function() {\r
2002 store.loadData([{}, {}, {}, {}, {}, {}]);\r
2003 expectNodeLength(6);\r
2004 });\r
2005\r
2006 it("should bind to the selection model", function() {\r
2007 expect(grid.getView().getSelectionModel().getStore()).toBe(store);\r
2008 });\r
2009\r
2010 it("should add the new columns and render the contents", function() {\r
2011 expect(colRef.length).toBe(2);\r
2012 expect(getCellText(0, 0)).toBe('2');\r
2013 expect(getCellText(0, 1)).toBe('7');\r
2014 });\r
2015\r
2016 it("should process locked/unlocked columns", function() {\r
2017 expect(grid.lockedGrid.getVisibleColumnManager().getColumns().length).toBe(1);\r
2018 expect(grid.normalGrid.getVisibleColumnManager().getColumns().length).toBe(1);\r
2019 });\r
2020\r
2021 it("should destroy old columns", function() {\r
2022 expect(oldCols[0].destroyed).toBe(true);\r
2023 expect(oldCols[1].destroyed).toBe(true);\r
2024 });\r
2025 });\r
2026\r
2027 describe("with an existing store and existing columns", function() {\r
2028 beforeEach(function() {\r
2029 makeReconfigureGrid([{\r
2030 locked: true,\r
2031 dataIndex: 'field1'\r
2032 }, {\r
2033 dataIndex: 'field3'\r
2034 }]);\r
2035 oldCols = colRef;\r
2036 oldStore = store;\r
2037 reconfigure(makeStore(), [{\r
2038 locked: true,\r
2039 dataIndex: 'field2'\r
2040 }, {\r
2041 dataIndex: 'field7'\r
2042 }]);\r
2043 colRef = grid.getVisibleColumnManager().getColumns();\r
2044 });\r
2045\r
2046 it("should render data from the new store", function() {\r
2047 expectNodeLength(1);\r
2048 });\r
2049\r
2050 it("should react to store", function() {\r
2051 store.add({});\r
2052 expectNodeLength(2);\r
2053 });\r
2054\r
2055 it("should react to store remove", function() {\r
2056 store.removeAt(0);\r
2057 expectNodeLength(0);\r
2058 });\r
2059\r
2060 it("should react to store update", function() {\r
2061 store.getAt(0).set('field2', 'Foo');\r
2062 expect(getCellText(0, 0)).toBe('Foo');\r
2063 });\r
2064\r
2065 it("should react to store load", function() {\r
2066 store.loadData([{}, {}, {}, {}, {}, {}]);\r
2067 expectNodeLength(6);\r
2068 });\r
2069\r
2070 it("should bind to the selection model", function() {\r
2071 expect(grid.getView().getSelectionModel().getStore()).toBe(store);\r
2072 });\r
2073\r
2074 it("should not react to the old store", function() {\r
2075 oldStore.add([{}, {}, {}, {}, {}, {}]);\r
2076 expectNodeLength(1);\r
2077 oldStore.removeAt(0);\r
2078 expectNodeLength(1);\r
2079 oldStore.getAt(0).set('field1', 'Foo');\r
2080 expect(getCellText(0, 0)).toBe('2');\r
2081 oldStore.loadData([{}, {}, {}, {}, {}, {}, {}, {}, {}]);\r
2082 expectNodeLength(1);\r
2083 });\r
2084\r
2085 it("should add the new columns and render the contents", function() {\r
2086 expect(colRef.length).toBe(2);\r
2087 expect(getCellText(0, 0)).toBe('2');\r
2088 expect(getCellText(0, 1)).toBe('7');\r
2089 });\r
2090\r
2091 it("should process locked/unlocked columns", function() {\r
2092 expect(grid.lockedGrid.getVisibleColumnManager().getColumns().length).toBe(1);\r
2093 expect(grid.normalGrid.getVisibleColumnManager().getColumns().length).toBe(1);\r
2094 });\r
2095\r
2096 it("should destroy old columns", function() {\r
2097 expect(oldCols[0].destroyed).toBe(true);\r
2098 expect(oldCols[1].destroyed).toBe(true);\r
2099 });\r
2100 });\r
2101\r
2102 it("should only refresh after the columns have been rendered", function() {\r
2103 var spy = jasmine.createSpy(),\r
2104 renderCount, refreshCounter, view;\r
2105\r
2106 makeReconfigureGrid([{\r
2107 locked: true,\r
2108 dataIndex: 'field1'\r
2109 }, {\r
2110 dataIndex: 'field3'\r
2111 }]);\r
2112 oldStore = store;\r
2113\r
2114 view = grid.lockedGrid.getView();\r
2115 refreshCounter = view.refreshCounter || 0;\r
2116\r
2117 view.on('refresh', function() {\r
2118 renderCount = spy.callCount;\r
2119 });\r
2120 \r
2121 reconfigure(makeStore(), [{\r
2122 locked: true,\r
2123 dataIndex: 'field2',\r
2124 listeners: {\r
2125 afterrender: spy\r
2126 }\r
2127 }, {\r
2128 dataIndex: 'field7',\r
2129 listeners: {\r
2130 afterrender: spy\r
2131 }\r
2132 }]);\r
2133 expect(renderCount).toBe(2);\r
2134 expect(view.refreshCounter).toBe(refreshCounter + 1);\r
2135 });\r
2136 });\r
2137 });\r
2138 });\r
2139 }\r
2140\r
2141 makeReconfigureSuite(false);\r
2142 makeReconfigureSuite(true);\r
2143\r
2144 it("should only refresh the view once", function() {\r
2145 var count = 0;\r
2146 makeGrid([{\r
2147 dataIndex: 'field1'\r
2148 }]);\r
2149 grid.getView().on('refresh', function() {\r
2150 ++count;\r
2151 });\r
2152 grid.reconfigure(null, [{\r
2153 dataIndex: 'field2'\r
2154 }, {\r
2155 dataIndex: 'field3'\r
2156 }, {\r
2157 dataIndex: 'field4'\r
2158 }, {\r
2159 dataIndex: 'field5'\r
2160 }, {\r
2161 dataIndex: 'field6'\r
2162 }, {\r
2163 dataIndex: 'field7'\r
2164 }]);\r
2165 expect(count).toBe(1);\r
2166 });\r
2167 });\r
2168\r
2169 if (buffered) {\r
2170 describe('buffered row rendering', function() {\r
2171 var view,\r
2172 rows,\r
2173 bufferedRenderer,\r
2174 data,\r
2175 scrollTop,\r
2176 viewSize,\r
2177 rowHeight;\r
2178\r
2179 beforeEach(function() {\r
2180\r
2181 // Important\r
2182 // The scrollHeight matching must allow a 1px deviation.\r
2183 // ScrollHeight is sometimes reported as 1px more than the actual content height.\r
2184 var i, j,\r
2185 row;\r
2186\r
2187 data = [];\r
2188 for (i = 0; i < 100; i++) {\r
2189 row = {};\r
2190 for (j = 1; j < 11; j++) {\r
2191 row['field' + j] = 'r' + i + ',f' + j;\r
2192 }\r
2193 data.push(row);\r
2194 }\r
2195\r
2196 // Grid and data must be exactly the right shape for the tests to perform as expected!\r
2197 // Enforce buffer zone defaults so that the rendered viewSize is reasonable.\r
2198 // makeGrid function defeats buffered rendering by imposing large buffer zones.\r
2199 makeGrid(null, data, {\r
2200 width: 1000,\r
2201 height: 500,\r
2202 border: false,\r
2203 trailingBufferZone: Ext.grid.plugin.BufferedRenderer.prototype.trailingBufferZone,\r
2204 leadingBufferZone: Ext.grid.plugin.BufferedRenderer.prototype.leadingBufferZone\r
2205 });\r
2206 view = grid.getView();\r
2207 rows = view.all;\r
2208 bufferedRenderer = view.bufferedRenderer;\r
2209\r
2210 // Get as close to 15 visible rows as possible\r
2211 grid.setHeight(bufferedRenderer.rowHeight * 15 + grid.headerCt.getHeight());\r
2212 viewSize = bufferedRenderer.viewSize;\r
2213 });\r
2214\r
2215 it('should handle removing range above the rendered view', function() {\r
2216 var oldRowStartIndex;\r
2217\r
2218 rowHeight = bufferedRenderer.rowHeight;\r
2219\r
2220 expect(rows.getCount()).toBe(viewSize);\r
2221\r
2222 // Constant row height, so we know the scroll range\r
2223 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2224\r
2225 bufferedRenderer.scrollTo(64);\r
2226 scrollTop = view.getScrollY();\r
2227 oldRowStartIndex = rows.startIndex;\r
2228\r
2229 store.removeAt(0, 10);\r
2230\r
2231 // Rendered block has chunked upwards by 10\r
2232 expect(rows.startIndex).toBe(oldRowStartIndex - 10);\r
2233\r
2234 // Constant row height, so we know the scroll range\r
2235 expect(view.el.dom.scrollHeight).toBe(rowHeight * store.getCount());\r
2236\r
2237 // Operation should bump us up the scroll range\r
2238 expect(view.getScrollY()).toBeLessThan(scrollTop);\r
2239\r
2240 // Operation should not affect the rendered row count\r
2241 expect(rows.getCount()).toBe(viewSize);\r
2242\r
2243 // The table should be positioned according to the start index of the rendered view\r
2244 expect(getViewTop(view.body)).toBe(rows.startIndex * rowHeight - view.body.getBorderWidth('t'));\r
2245 });\r
2246\r
2247 it('should handle removing range which intersects the top of the rendered view', function() {\r
2248 rowHeight = bufferedRenderer.rowHeight;\r
2249\r
2250 // Constant row height, so we know the scroll range\r
2251 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2252\r
2253 bufferedRenderer.scrollTo(64);\r
2254 scrollTop = view.getScrollY();\r
2255\r
2256 store.removeAt(rows.startIndex - 10, 20);\r
2257\r
2258 // Constant row height, so we know the scroll range\r
2259 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2260\r
2261 // Operation should bump us up the scroll range\r
2262 expect(view.getScrollY()).toBeLessThan(scrollTop);\r
2263\r
2264 // Operation should not affect the rendered row count\r
2265 expect(rows.getCount()).toBe(viewSize);\r
2266\r
2267 // The table should be positioned according to the start index of the rendered view\r
2268 expect(getViewTop(view.body)).toBe(rows.startIndex * rowHeight - view.body.getBorderWidth('t'));\r
2269 });\r
2270\r
2271 it('should handle removing range wholly within the rendered view', function() {\r
2272 rowHeight = bufferedRenderer.rowHeight;\r
2273\r
2274 // Constant row height, so we know the scroll range\r
2275 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2276\r
2277 bufferedRenderer.scrollTo(64);\r
2278 scrollTop = view.getScrollY();\r
2279\r
2280 store.removeAt(52, 10);\r
2281\r
2282 // Constant row height, so we know the scroll range\r
2283 expect(view.el.dom.scrollHeight).toBe(rowHeight * store.getCount());\r
2284\r
2285 // Operation should not affect scrollTop\r
2286 expect(view.getScrollY()).toBe(scrollTop);\r
2287\r
2288 // Operation should not affect the rendered row count\r
2289 expect(rows.getCount()).toBe(viewSize);\r
2290\r
2291 // The table should be positioned according to the start index of the rendered view\r
2292 expect(getViewTop(view.body)).toBe(rows.startIndex * rowHeight - view.body.getBorderWidth('t'));\r
2293 });\r
2294\r
2295 it('should handle removing range which intersects the bottom of the rendered view', function() {\r
2296 rowHeight = bufferedRenderer.rowHeight;\r
2297\r
2298 // Constant row height, so we know the scroll range\r
2299 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2300\r
2301 bufferedRenderer.scrollTo(64);\r
2302 scrollTop = view.getScrollY();\r
2303\r
2304 store.removeAt(rows.endIndex - 10, 20);\r
2305\r
2306 // Constant row height, so we know the scroll range\r
2307 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2308\r
2309 // Operation should not affect scrollTop\r
2310 expect(view.getScrollY()).toBe(scrollTop);\r
2311\r
2312 // Operation should not affect the rendered row count\r
2313 expect(rows.getCount()).toBe(viewSize);\r
2314\r
2315 // The table should be positioned according to the start index of the rendered view\r
2316 expect(getViewTop(view.body)).toBe(rows.startIndex * rowHeight - view.body.getBorderWidth('t'));\r
2317 });\r
2318\r
2319 it('should handle removing range which removes everything from halfway down rendered view', function() {\r
2320 rowHeight = bufferedRenderer.rowHeight;\r
2321\r
2322 // Constant row height, so we know the scroll range\r
2323 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2324\r
2325 bufferedRenderer.scrollTo(64);\r
2326 scrollTop = view.getScrollY();\r
2327\r
2328 // RemoveAt's second input, the number to remove is sanity checked.\r
2329 // This will remove everything from the middle of the view\r
2330 store.removeAt(Math.floor((rows.endIndex - rows.startIndex) / 2), 1000);\r
2331\r
2332 // Constant row height, so we know the scroll range.\r
2333 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2334\r
2335 // Fewer rows than viewSize now left in store\r
2336 expect(rows.getCount()).toBe(store.getCount());\r
2337\r
2338 // The table should be positioned according to the start index of the rendered view\r
2339 expect(getViewTop(view.body)).toBe(0);\r
2340 });\r
2341\r
2342\r
2343 it('should handle removing range which removes from top to halfway down rendered view', function() {\r
2344 rowHeight = bufferedRenderer.rowHeight;\r
2345\r
2346 // Constant row height, so we know the scroll range\r
2347 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2348\r
2349 bufferedRenderer.scrollTo(64);\r
2350 scrollTop = view.getScrollY();\r
2351\r
2352 // RemoveAt's second input, the number to remove is sanity checked.\r
2353 // This will remove everything from the middle of the view\r
2354 store.removeAt(0, Math.floor(rows.startIndex + viewSize / 2));\r
2355\r
2356 // Constant row height, so we know the scroll range.\r
2357 // Use toBeWithin matcher here.\r
2358 // When there's no need for a stretcher, and the table creates the scroll range\r
2359 // it appears to be 1 greater than the table's offsetHeight.\r
2360 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2361\r
2362 // Fewer rows than viewSize now left in store\r
2363 expect(rows.getCount()).toBe(store.getCount());\r
2364\r
2365 // Operation should bump us to the top\r
2366 expect(view.getScrollY()).toBe(0);\r
2367\r
2368 // The table should be positioned according to the start index of the rendered view\r
2369 expect(getViewTop(view.body)).toBe(0);\r
2370 });\r
2371\r
2372 it('should handle removing range below the rendered view', function() {\r
2373 rowHeight = bufferedRenderer.rowHeight;\r
2374\r
2375 // Constant row height, so we know the scroll range\r
2376 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2377\r
2378 bufferedRenderer.scrollTo(64);//was 50\r
2379 scrollTop = view.getScrollY();\r
2380\r
2381 store.removeAt(rows.endIndex + 10, 10);\r
2382\r
2383 // Constant row height, so we know the scroll range\r
2384 expect(view.el.dom.scrollHeight).toBe(rowHeight * store.getCount());\r
2385\r
2386 // Operation should not affect scrollTop\r
2387 expect(view.getScrollY()).toBe(scrollTop);\r
2388\r
2389 // Operation should not affect the rendered row count\r
2390 expect(rows.getCount()).toBe(viewSize);\r
2391\r
2392 // The table should be positioned according to the start index of the rendered view\r
2393 expect(getViewTop(view.body)).toBe(rows.startIndex * rowHeight - view.body.getBorderWidth('t'));\r
2394 });\r
2395\r
2396 it('should handle removing range which encompasses the rendered view and leaves less than view size rows remaining', function() {\r
2397 rowHeight = bufferedRenderer.rowHeight;\r
2398\r
2399 // Constant row height, so we know the scroll range\r
2400 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2401\r
2402 bufferedRenderer.scrollTo(44);//was 30\r
2403 scrollTop = view.getScrollY();\r
2404\r
2405 store.removeAt(5, 90);\r
2406\r
2407 // No scrolling now with only 10 rows left!\r
2408 expect(view.el.dom.scrollHeight).toBeWithin(1, view.el.dom.clientHeight);\r
2409\r
2410 // Obviously... no scrolling with only 10 rows left!\r
2411 expect(view.getScrollY()).toBe(0);\r
2412\r
2413 // Operation should not affect the rendered row count\r
2414 expect(rows.getCount()).toBe(10);\r
2415\r
2416 // The table should be positioned according to the start index of the rendered view\r
2417 expect(getViewTop(view.body)).toBe(0);\r
2418 });\r
2419\r
2420 it('should handle removing range which encompasses the rendered view', function() {\r
2421 rowHeight = bufferedRenderer.rowHeight;\r
2422\r
2423 // Constant row height, so we know the scroll range\r
2424 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2425\r
2426 bufferedRenderer.scrollTo(44);\r
2427 scrollTop = view.getScrollY();\r
2428\r
2429 store.removeAt(rows.startIndex - 1, viewSize + 2);\r
2430\r
2431 // Constant row height, so we know the scroll range\r
2432 expect(bufferedRenderer.bodyTop + view.body.dom.offsetHeight - 1).toBe(rowHeight * store.getCount());\r
2433\r
2434 // Operation should not affect scrollTop\r
2435 expect(view.el.dom.scrollTop).toBe(scrollTop);\r
2436\r
2437 // We hit the end, so there's a bit lacking at the top\r
2438 expect(rows.getCount()).toBeLessThan(viewSize);\r
2439\r
2440 // The table should be positioned according to the start index of the rendered view\r
2441 expect(getViewTop(view.body)).toBe(Math.max(rows.startIndex * rowHeight, 0));\r
2442 });\r
2443\r
2444 it('should handle removing range which leaves less than the viewSize rows in store', function() {\r
2445 rowHeight = bufferedRenderer.rowHeight;\r
2446\r
2447 // Constant row height, so we know the scroll range\r
2448 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2449\r
2450 bufferedRenderer.scrollTo(34);\r
2451 scrollTop = view.getScrollY();\r
2452\r
2453 store.removeAt(0, store.getCount() - 10);\r
2454\r
2455 // No scrolling now with only 10 rows left!\r
2456 expect(view.el.dom.scrollHeight).toBe(view.el.dom.clientHeight);\r
2457\r
2458 // Obviously... no scrolling with only 10 rows left!\r
2459 expect(view.getScrollY()).toBe(0);\r
2460\r
2461 // View can only contain 10 rows\r
2462 expect(rows.getCount()).toBe(10);\r
2463\r
2464 // The table should be at top\r
2465 expect(getViewTop(view.body)).toBe(0);\r
2466 });\r
2467 \r
2468 it('Should prepend to the rendered block when inserting at position 0', function() {\r
2469 var cell00;\r
2470 scrollTop = view.getScrollY();\r
2471 \r
2472 store.insert(0, {\r
2473 field1: 'Test'\r
2474 });\r
2475 \r
2476 cell00 = Ext.getDom(view.getCellByPosition({\r
2477 row: 0,\r
2478 column: 0\r
2479 }));\r
2480\r
2481 // Operation should bump us down the scroll range\r
2482 expect(view.getScrollY()).toBeGreaterThan(scrollTop);\r
2483\r
2484 // View item must be added\r
2485 expect(Ext.String.trim(cell00.textContent || cell00.innerText)).toBe('Test');\r
2486\r
2487 // The table should be at top\r
2488 expect(getViewTop(view.body)).toBe(0);\r
2489 });\r
2490\r
2491 it('should handle adding range above the rendered view', function() {\r
2492 var oldRowStartIndex;\r
2493\r
2494 rowHeight = bufferedRenderer.rowHeight;\r
2495\r
2496 expect(rows.getCount()).toBe(viewSize);\r
2497\r
2498 // Constant row height, so we know the scroll range\r
2499 expect(view.el.dom.scrollHeight).toBeWithin(1, rowHeight * store.getCount());\r
2500\r
2501 bufferedRenderer.scrollTo(64);\r
2502 scrollTop = view.el.dom.scrollTop;\r
2503 oldRowStartIndex = rows.startIndex;\r
2504\r
2505 // Insert 10 rows above the rendered block\r
2506 store.insert(0, [\r
2507 {}, {}, {}, {}, {}, {}, {}, {}, {}, {}\r
2508 ]);\r
2509\r
2510 // Rendered block has chunked upwards by 10\r
2511 expect(rows.startIndex).toBe(oldRowStartIndex + 10);\r
2512\r
2513 // Constant row height, so we know the scroll range\r
2514 expect(view.el.dom.scrollHeight).toBe(rowHeight * store.getCount());\r
2515\r
2516 // Operation should bump us down the scroll range\r
2517 expect(view.el.dom.scrollTop).toBeGreaterThan(scrollTop);\r
2518\r
2519 // Operation should not affect the rendered row count\r
2520 expect(rows.getCount()).toBe(viewSize);\r
2521\r
2522 // The table should be positioned according to the start index of the rendered view\r
2523 expect(getViewTop(view.body)).toBe(rows.startIndex * rowHeight - view.body.getBorderWidth('t'));\r
2524 });\r
2525\r
2526 it('should render rows when buffered block is less than the view size', function() {\r
2527 var v = viewSize,\r
2528 targetViewSize = v - 10;\r
2529\r
2530 // We need less than viewSize rows to be there\r
2531 store.removeAt(targetViewSize, store.getCount() - targetViewSize);\r
2532\r
2533 // Now there are the number of rows we require (ten less than viewSize for the grid height)\r
2534 // And we're at the top\r
2535 expect(rows.getCount()).toBe(targetViewSize);\r
2536 expect(bufferedRenderer.scrollTop).toBe(0);\r
2537 expect(bufferedRenderer.position).toBe(0);\r
2538 \r
2539 store.add({});\r
2540 \r
2541 // Must has added a row\r
2542 expect(rows.getCount()).toBe(targetViewSize + 1);\r
2543 expect(bufferedRenderer.scrollTop).toBe(0);\r
2544 expect(bufferedRenderer.position).toBe(0);\r
2545 });\r
2546 });\r
2547\r
2548 describe('initial correction of viewSize', function() {\r
2549 describe('when rowHeight is smaller than expected and viewSize has to grow', function() {\r
2550 var i,\r
2551 data,\r
2552 columns,\r
2553 empty = new String(); // Truthy empty string so that renderer does not insert &nbsp;\r
2554\r
2555 beforeEach(function() {\r
2556 data = [];\r
2557 // We need a lot of rows so that we get to add more than the original default viewSize\r
2558 for (i = 0; i < 200; i++) {\r
2559 data.push({\r
2560 field0: 'r' + i + ',f0'\r
2561 });\r
2562 }\r
2563\r
2564 columns = [{\r
2565 dataIndex: 'field0',\r
2566 text: 'Field 0',\r
2567 width: 90,\r
2568\r
2569 // Empty cell. Should only be paddingTop+paddingBottom high\r
2570 renderer: function() {\r
2571 return empty;\r
2572 }\r
2573 }];\r
2574 });\r
2575 \r
2576 it('should append new rows to the view', function() {\r
2577 // Make like mobile dev, and only overhang 1 row each side\r
2578 // Make it tall enough so that the default viewSize of 100 will leave\r
2579 // the view short, and BufferedRenderer will have to add rows.\r
2580 makeGrid(columns, data, {\r
2581 height: 900,\r
2582 border: false,\r
2583\r
2584 // We want to get spies in before render\r
2585 renderTo: null,\r
2586 trailingBufferZone: 1,\r
2587 leadingBufferZone: 1\r
2588 });\r
2589 var getRangeSpy = spyOn(store, 'getRange').andCallThrough();\r
2590\r
2591 grid.render(document.body);\r
2592\r
2593 // Only one refresh. The initial refresh which inserts the default viewSize.\r
2594 // The way we have it set up, this will be a shortfall, and rows will have to be appended.\r
2595 expect(view.refreshCounter).toBe(1);\r
2596\r
2597 // The rendered row count should have been bumped up to the calculated viewSize\r
2598 expect(view.all.getCount()).toBe(view.bufferedRenderer.viewSize);\r
2599 \r
2600 // Two calls to Store#getRange should have been made...\r
2601 expect(getRangeSpy.callCount).toBe(2);\r
2602\r
2603 // First call gets the default view size\r
2604 expect(getRangeSpy.calls[0].args).toEqual([0, Ext.grid.plugin.BufferedRenderer.prototype.viewSize - 1]);\r
2605\r
2606 // Then we top up the view with the missing rows.\r
2607 // Second getRange will have been called with options, so slice to just test start and end indices\r
2608 expect(Ext.Array.slice(getRangeSpy.calls[1].args, 0, 2)).toEqual([Ext.grid.plugin.BufferedRenderer.prototype.viewSize, view.bufferedRenderer.viewSize - 1]);\r
2609 });\r
2610 });\r
2611\r
2612 describe('when rowHeight is larger than expected and viewSize has to shrink', function() {\r
2613 var i,\r
2614 data,\r
2615 columns;\r
2616\r
2617 beforeEach(function() {\r
2618 data = [];\r
2619 // We need a lot of rows so that we get to add more than the original default viewSize\r
2620 for (i = 0; i < 200; i++) {\r
2621 data.push({\r
2622 field0: 'r' + i + ',f0'\r
2623 });\r
2624 }\r
2625\r
2626 columns = [{\r
2627 dataIndex: 'field0',\r
2628 text: 'Field 0',\r
2629 width: 90,\r
2630\r
2631 // Extra tall cell to make the initially rendered view too large.\r
2632 renderer: function() {\r
2633 return '<div style="height:30px"></div>';\r
2634 }\r
2635 }];\r
2636 });\r
2637 \r
2638 it('should append new rows to the view', function() {\r
2639 // Make like mobile dev, and only overhang 1 row each side\r
2640 // Make it tall enough so that the default viewSize of 100 will leave\r
2641 // the view short, and BufferedRenderer will have to add rows.\r
2642 makeGrid(columns, data, {\r
2643 height: 200,\r
2644 border: false,\r
2645\r
2646 // We want to get spies in before render\r
2647 renderTo: null,\r
2648 trailingBufferZone: 1,\r
2649 leadingBufferZone: 1\r
2650 });\r
2651 var getRangeSpy = spyOn(store, 'getRange').andCallThrough(),\r
2652 removeRangeSpy = spyOn(view.all, 'removeRange').andCallThrough();\r
2653\r
2654 grid.render(document.body);\r
2655\r
2656 // Only one refresh. The initial refresh which inserts the default viewSize.\r
2657 // The way we have it set up, this will be a to many, and rows will have to be removed.\r
2658 expect(view.refreshCounter).toBe(1);\r
2659\r
2660 // The rendered row count should have been shrunk to the calculated viewSize\r
2661 expect(view.all.getCount()).toBe(view.bufferedRenderer.viewSize);\r
2662 \r
2663 // One calls to Store#getRange should have been made...\r
2664 expect(getRangeSpy.callCount).toBe(1);\r
2665\r
2666 // First call gets the default view size\r
2667 expect(getRangeSpy.calls[0].args).toEqual([0, Ext.grid.plugin.BufferedRenderer.prototype.viewSize - 1]);\r
2668\r
2669 // Remove removes from the end of the viewSize to the default rendered viewSize\r
2670 // Will have been called with third param, so slice args.\r
2671 expect(Ext.Array.slice(removeRangeSpy.calls[0].args, 0, 2)).toEqual([view.bufferedRenderer.viewSize, Ext.grid.plugin.BufferedRenderer.prototype.viewSize - 1]);\r
2672 });\r
2673 });\r
2674 });\r
2675 }\r
2676\r
2677 describe('shrinkwrap height', function() {\r
2678 var data, columns;\r
2679\r
2680 beforeEach(function() {\r
2681 var i, j,\r
2682 row;\r
2683\r
2684 data = [];\r
2685 for (i = 0; i < 100; i++) {\r
2686 row = {};\r
2687 for (j = 1; j < 11; j++) {\r
2688 row['field' + j] = 'r' + i + ',f' + j;\r
2689 }\r
2690 data.push(row);\r
2691 }\r
2692 \r
2693 columns = [];\r
2694 for (i = 1; i < 11; i++) {\r
2695 columns.push({\r
2696 dataIndex: 'field' + i,\r
2697 text: 'Field ' + i,\r
2698 width: 90\r
2699 });\r
2700 }\r
2701 columns[0].flex = 1;\r
2702 });\r
2703\r
2704 it('should allow unconstrained height grids to expand to accommodate content', function() {\r
2705 makeGrid(columns, data, {\r
2706 height: undefined,\r
2707 border: false\r
2708 });\r
2709 \r
2710 // View and Grid should be stretched vertically to accommodate content.\r
2711 // Flexed column should mean that the horizontal content fits exactly.\r
2712 // All widths should be equal since we configured NO BORDERS.\r
2713 expect(view.getWidth()).toBe(grid.getWidth());\r
2714 expect(view.getHeight()).toBe(grid.getHeight() - grid.body.getBorderWidth('tb') - grid.headerCt.getHeight());\r
2715 expect(view.el.dom.clientWidth).toBe(grid.getWidth());\r
2716 expect(view.el.dom.clientHeight).toBe(view.getHeight());\r
2717 });\r
2718\r
2719 it('should reduce height if shrinkwrap height violates height constraint', function() {\r
2720 makeGrid(columns, data, {\r
2721 maxHeight: 100,\r
2722 border: false\r
2723 });\r
2724 \r
2725 // The width of the View still fits because of the flexed column\r
2726 expect(view.getWidth()).toBe(grid.getWidth());\r
2727\r
2728 // If this system displays scrollbars...\r
2729 // The presence of the vertical scrollbar should mean clientWidth is less than View's full width\r
2730 if (Ext.getScrollbarSize().width) {\r
2731 expect(view.el.dom.clientWidth).toBeLessThan(grid.getWidth());\r
2732 }\r
2733\r
2734 // The height constraint means that the clientHeight is less than the view's scrollable height\r
2735 expect(view.el.dom.clientHeight).toBeLessThan(view.el.dom.scrollHeight);\r
2736 });\r
2737 });\r
2738\r
2739 describe("locking columns", function(){\r
2740 it("should synchronize horizontal scrollbar presence between locked and normal side.", function(){\r
2741 var indexes = [],\r
2742 fn = function(){\r
2743 indexes.push(arguments[4]);\r
2744 };\r
2745\r
2746 makeGrid([{\r
2747 locked: true,\r
2748 dataIndex: 'field1',\r
2749 renderer: fn \r
2750 }, {\r
2751 locked: true,\r
2752 dataIndex: 'field2',\r
2753 renderer: fn \r
2754 }, {\r
2755 dataIndex: 'field3',\r
2756 renderer: fn \r
2757 }, {\r
2758 dataIndex: 'field4',\r
2759 renderer: fn \r
2760 }], undefined, {\r
2761 width: 600,\r
2762 height: 200\r
2763 });\r
2764\r
2765 // The client height should be the same - scrollbars at the bottom should be synched. Either both there or none there.\r
2766 // In this case, there should be none there.\r
2767 expect(grid.lockedGrid.getView().getTargetEl().dom.clientHeight).toEqual(grid.normalGrid.getView().getTargetEl().dom.clientHeight);\r
2768\r
2769 // View's client height is the same as the offset height because there is no horizontal scrollbar \r
2770 expect(grid.lockedGrid.getView().getTargetEl().dom.clientHeight).toEqual(grid.lockedGrid.getView().getTargetEl().dom.offsetHeight);\r
2771\r
2772 // Create horizontal overflow\r
2773 grid.getColumnManager().getColumns()[3].setWidth(500);\r
2774\r
2775 // The client height should be the same - scrollbars at the bottom should be synched. Either both there or none there.\r
2776 // In this case, both should have scrollbars.\r
2777 expect(grid.lockedGrid.getView().getTargetEl().dom.clientHeight).toEqual(grid.normalGrid.getView().getTargetEl().dom.clientHeight);\r
2778\r
2779 // View's client height has been reduced by horizontal scrollbar appearing due to overflow in normal side (if scrollbars take up space)\r
2780 if (scrollbarWidth && Ext.supports.touchScroll !== 2) {\r
2781 expect(grid.lockedGrid.getView().getTargetEl().dom.clientHeight).toBeLessThan(grid.lockedGrid.getView().getTargetEl().dom.offsetHeight);\r
2782 expect(grid.normalGrid.getView().getTargetEl().dom.clientHeight).toBeLessThan(grid.normalGrid.getView().getTargetEl().dom.offsetHeight);\r
2783 }\r
2784 });\r
2785\r
2786 it('should unbind locking view from its store', function() {\r
2787 makeGrid([{\r
2788 locked: true,\r
2789 dataIndex: 'field1'\r
2790 }, {\r
2791 locked: true,\r
2792 dataIndex: 'field2'\r
2793 }, {\r
2794 dataIndex: 'field3'\r
2795 }, {\r
2796 dataIndex: 'field4'\r
2797 }], undefined, {\r
2798 width: 600,\r
2799 height: 200\r
2800 });\r
2801\r
2802 expect(store.hasListeners.refresh).toBeDefined();\r
2803\r
2804 grid.destroy();\r
2805\r
2806 // After destroy, there are no listeners\r
2807 expect(store.hasListeners.refresh).toBeUndefined();\r
2808 });\r
2809\r
2810 describe('loadMask', function () {\r
2811 function returnSucessFalse() {\r
2812 while (Ext.Ajax.mockGetAllRequests().length) {\r
2813 Ext.Ajax.mockComplete({\r
2814 status: 200,\r
2815 responseText: Ext.encode({\r
2816 success: false\r
2817 })\r
2818 });\r
2819 }\r
2820 }\r
2821\r
2822 describe('Proxy throws exception during load', function() {\r
2823 beforeEach(function() {\r
2824 MockAjaxManager.addMethods();\r
2825 });\r
2826\r
2827 afterEach(function() {\r
2828 MockAjaxManager.removeMethods();\r
2829 });\r
2830\r
2831 it('should hide the load mask if the load fails with an exception', function() {\r
2832 makeGrid(null, undefined, {\r
2833 store: {\r
2834 proxy: {\r
2835 type: 'ajax',\r
2836 url: 'fakeUrl',\r
2837 reader: {\r
2838 type: 'json'\r
2839 }\r
2840 }\r
2841 }\r
2842 }, {\r
2843 preventStoreCreate: true\r
2844 });\r
2845 grid.store.loadPage(1);\r
2846\r
2847 // While waiting, the mask should be visible\r
2848 expect(grid.view.loadMask.isVisible()).toBe(true);\r
2849\r
2850 returnSucessFalse();\r
2851\r
2852 // The success: false should\r
2853 // have thrown an exception which should hide the mask\r
2854 expect(grid.view.loadMask.isVisible()).toBe(false);\r
2855 });\r
2856 });\r
2857\r
2858 it('should raise a load mask by default (no loadMask config specified)', function () {\r
2859 makeGrid([{\r
2860 locked: true,\r
2861 dataIndex: 'field1'\r
2862 }, {\r
2863 locked: true,\r
2864 dataIndex: 'field2'\r
2865 }, {\r
2866 dataIndex: 'field3'\r
2867 }, {\r
2868 dataIndex: 'field4'\r
2869 }], undefined, {\r
2870 width: 600,\r
2871 height: 200\r
2872 });\r
2873\r
2874 expect(grid.view.loadMask instanceof Ext.LoadMask).toBe(true);\r
2875 });\r
2876\r
2877 it('should not raise a load mask when set as false in viewConfig', function () {\r
2878 makeGrid([{\r
2879 locked: true,\r
2880 dataIndex: 'field1'\r
2881 }, {\r
2882 locked: true,\r
2883 dataIndex: 'field2'\r
2884 }, {\r
2885 dataIndex: 'field3'\r
2886 }, {\r
2887 dataIndex: 'field4'\r
2888 }], undefined, {\r
2889 viewConfig: {\r
2890 loadMask: false\r
2891 }\r
2892 });\r
2893\r
2894 expect(grid.view.loadMask).toBe(false);\r
2895 });\r
2896\r
2897 it('should raise a load mask when set on the grid', function () {\r
2898 makeGrid([{\r
2899 locked: true,\r
2900 dataIndex: 'field1'\r
2901 }, {\r
2902 locked: true,\r
2903 dataIndex: 'field2'\r
2904 }, {\r
2905 dataIndex: 'field3'\r
2906 }, {\r
2907 dataIndex: 'field4'\r
2908 }], undefined, {\r
2909 loadMask: true\r
2910 });\r
2911\r
2912 expect(grid.loadMask).toBe(true);\r
2913 expect(grid.view.loadMask instanceof Ext.LoadMask).toBe(true);\r
2914 });\r
2915\r
2916 it('should respect the viewConfig definition as final (loadMask == true)', function () {\r
2917 makeGrid([{\r
2918 locked: true,\r
2919 dataIndex: 'field1'\r
2920 }, {\r
2921 locked: true,\r
2922 dataIndex: 'field2'\r
2923 }, {\r
2924 dataIndex: 'field3'\r
2925 }, {\r
2926 dataIndex: 'field4'\r
2927 }], undefined, {\r
2928 loadMask: false,\r
2929 viewConfig: {\r
2930 loadMask: true\r
2931 }\r
2932 });\r
2933\r
2934 expect(grid.loadMask).toBe(false);\r
2935 expect(grid.view.loadMask instanceof Ext.LoadMask).toBe(true);\r
2936 });\r
2937\r
2938 it('should respect the viewConfig definition as final (loadMask == false)', function () {\r
2939 makeGrid([{\r
2940 locked: true,\r
2941 dataIndex: 'field1'\r
2942 }, {\r
2943 locked: true,\r
2944 dataIndex: 'field2'\r
2945 }, {\r
2946 dataIndex: 'field3'\r
2947 }, {\r
2948 dataIndex: 'field4'\r
2949 }], undefined, {\r
2950 loadMask: true,\r
2951 viewConfig: {\r
2952 loadMask: false\r
2953 }\r
2954 });\r
2955\r
2956 expect(grid.loadMask).toBe(true);\r
2957 expect(grid.view.loadMask).toBe(false);\r
2958 });\r
2959 });\r
2960\r
2961 describe('reconfiguring', function () {\r
2962 describe('with CheckboxModel', function () {\r
2963 it('should invalidate the lockedGrid.width so it shrinkwraps', function () {\r
2964 // See EXTJS-13408.\r
2965 var activeHeader;\r
2966\r
2967 this.addMatchers({\r
2968 toBeAtLeast: function (expected) {\r
2969 return expected <= this.actual;\r
2970 }\r
2971 });\r
2972\r
2973 // Let's make it simpler to measure the width by not having any locked columns.\r
2974 // EnableLocking will have the checkbox column added to the lockedGrid partner.\r
2975 makeGrid(null, undefined, {\r
2976 enableLocking: true,\r
2977 selModel: new Ext.selection.CheckboxModel()\r
2978 });\r
2979\r
2980 grid.reconfigure(store, [{\r
2981 dataIndex: 'field1'\r
2982 }, {\r
2983 dataIndex: 'field2'\r
2984 }, {\r
2985 dataIndex: 'field3'\r
2986 }]);\r
2987 \r
2988 var borderWidth = grid.lockedGrid.el.getBorderWidth('lr');\r
2989\r
2990 // First, verify that the width of the lockedGrid is the width of the checkbox\r
2991 // column after reconfigure.\r
2992 expect(grid.lockedGrid.width).toBe(Ext.selection.CheckboxModel.prototype.headerWidth + borderWidth);\r
2993\r
2994 activeHeader = grid.normalGrid.columnManager.getLast();\r
2995\r
2996 // Call lock and pass in the active header.\r
2997 grid.lock(activeHeader);\r
2998\r
2999 // We now expect the locked grid to be at least the width of the checkbox column\r
3000 // plus the newly-locked column.\r
3001 expect(grid.lockedGrid.width).toBe(Ext.selection.CheckboxModel.prototype.headerWidth + activeHeader.width + borderWidth);\r
3002 });\r
3003 });\r
3004 });\r
3005\r
3006 describe('variable row height', function() {\r
3007 var normalRows, lockedRows, i;\r
3008\r
3009 it("should match the row heights between locked sides", function() {\r
3010 makeGrid([{\r
3011 dataIndex: 'name',\r
3012 locked: true,\r
3013 variableRowHeight: true\r
3014 }, {\r
3015 dataIndex: 'email',\r
3016 width: 200\r
3017 }, {\r
3018 dataIndex: 'phone',\r
3019 width: 200\r
3020 }], [{\r
3021 field1: '1<br>'\r
3022 }, {\r
3023 field1: '2<br>1'\r
3024 }, {\r
3025 field1: '3<br>1'\r
3026 }, {\r
3027 field1: '4<br>1'\r
3028 }]);\r
3029\r
3030 normalRows = grid.normalGrid.getView().all;\r
3031 lockedRows = grid.lockedGrid.getView().all;\r
3032\r
3033 // Row heights must be synched between the sides.\r
3034 // Check that they are all equal.\r
3035 for (i = normalRows.startIndex; i <= normalRows.endIndex; i++) {\r
3036 expect(normalRows.item(i, true).offsetHeight).toEqual(lockedRows.item(i, true).offsetHeight);\r
3037 }\r
3038\r
3039 // Move the variableRowHeight "Name" column into the normal grid\r
3040 grid.unlock(grid.getColumnManager().getHeaderAtIndex(0));\r
3041\r
3042 if (buffered) {\r
3043 expect(grid.normalGrid.view.bufferedRenderer.variableRowHeight).toBe(true);\r
3044\r
3045 // Hide the variableRowHeight "Name" column\r
3046 grid.normalGrid.getVisibleColumnManager().getColumns()[0].hide();\r
3047\r
3048 // Now that the only variableRowHeight column is hidden, the buffered renderer should know about that.\r
3049 expect(grid.normalGrid.view.bufferedRenderer.variableRowHeight).toBe(false); \r
3050 }\r
3051 });\r
3052 });\r
3053 });\r
3054\r
3055 describe('ensureVisible', function() {\r
3056 var success,\r
3057 record,\r
3058 htmlEl,\r
3059 detectedScope,\r
3060 rec100,\r
3061 rec400;\r
3062\r
3063 // Each test uses a grid with 500 rows\r
3064 beforeEach(function() {\r
3065 success = false;\r
3066 makeGrid(null, 500);\r
3067 rec100 = store.getAt(100);\r
3068 rec400 = store.getAt(400);\r
3069 });\r
3070 it('should scroll into view when using record ID', function() {\r
3071 grid.ensureVisible('rec400', {\r
3072 callback: function(passedSuccess, passedRecord, passedHtmlEl) {\r
3073 success = passedSuccess;\r
3074 record = passedRecord;\r
3075 htmlEl = passedHtmlEl;\r
3076 detectedScope = this;\r
3077 },\r
3078 select: true\r
3079 });\r
3080 waitsFor(function() {\r
3081 return success;\r
3082 });\r
3083 runs(function() {\r
3084 // Default scope is the grid\r
3085 expect(detectedScope).toBe(grid);\r
3086\r
3087 expect(record).toBe(rec400);\r
3088\r
3089 // Table row scrolled to must be correct\r
3090 expect(htmlEl).toBe(view.getNode(rec400));\r
3091\r
3092 // The select option was passed\r
3093 expect(grid.getSelectionModel().getSelection()[0]).toBe(rec400);\r
3094\r
3095 // The bottom of the row should be within view\r
3096 expect(Ext.fly(htmlEl).getBox().bottom).toBeLessThanOrEqual(view.getBox().bottom);\r
3097\r
3098 grid.ensureVisible('rec100', {\r
3099 callback: function(passedSuccess, passedRecord, passedHtmlEl) {\r
3100 success = passedSuccess;\r
3101 record = passedRecord;\r
3102 htmlEl = passedHtmlEl;\r
3103 detectedScope = this;\r
3104 }\r
3105 });\r
3106 waitsFor(function() {\r
3107 return success;\r
3108 });\r
3109\r
3110 runs(function() {\r
3111 // Default scope is the grid\r
3112 expect(detectedScope).toBe(grid);\r
3113\r
3114 expect(record).toBe(rec100);\r
3115\r
3116 // Table row scrolled to must be correct\r
3117 expect(htmlEl).toBe(view.getNode(rec100));\r
3118\r
3119 // The top of the row should be within view\r
3120 expect(Ext.fly(htmlEl).getBox().top).toBeGreaterThanOrEqual(view.getBox().top);\r
3121 });\r
3122 });\r
3123 });\r
3124 it('should scroll into view when using record', function() {\r
3125 var o = {};\r
3126\r
3127 grid.ensureVisible(rec400, {\r
3128 callback: function(passedSuccess, passedRecord, passedHtmlEl) {\r
3129 success = passedSuccess;\r
3130 record = passedRecord;\r
3131 htmlEl = passedHtmlEl;\r
3132 detectedScope = this;\r
3133 },\r
3134 scope: o\r
3135 });\r
3136 waitsFor(function() {\r
3137 return success;\r
3138 });\r
3139 runs(function() {\r
3140 // Use passed scope\r
3141 expect(detectedScope).toBe(o);\r
3142\r
3143 expect(record).toBe(rec400);\r
3144\r
3145 // Table row scrolled to must be correct\r
3146 expect(htmlEl).toBe(view.getNode(rec400));\r
3147\r
3148 // The bottom of the row should be within view\r
3149 expect(Ext.fly(htmlEl).getBox().bottom).toBeLessThanOrEqual(view.getBox().bottom);\r
3150\r
3151 grid.ensureVisible(rec100, {\r
3152 callback: function(passedSuccess, passedRecord, passedHtmlEl) {\r
3153 success = passedSuccess;\r
3154 record = passedRecord;\r
3155 htmlEl = passedHtmlEl;\r
3156 detectedScope = this;\r
3157 },\r
3158 scope: o\r
3159 });\r
3160 waitsFor(function() {\r
3161 return success;\r
3162 });\r
3163 \r
3164 runs(function() {\r
3165 // Use passed scope\r
3166 expect(detectedScope).toBe(o);\r
3167\r
3168 expect(record).toBe(rec100);\r
3169\r
3170 // Table row scrolled to must be correct\r
3171 expect(htmlEl).toBe(view.getNode(rec100));\r
3172\r
3173 // The top of the row should be within view\r
3174 expect(Ext.fly(view.getNode(rec100)).getBox().top).toBeGreaterThanOrEqual(view.getBox().top);\r
3175 });\r
3176 });\r
3177 });\r
3178 it('should scroll into view when using record index', function() {\r
3179 grid.ensureVisible(400, {\r
3180 callback: function(passedSuccess, passedRecord, passedHtmlEl) {\r
3181 success = passedSuccess;\r
3182 record = passedRecord;\r
3183 htmlEl = passedHtmlEl;\r
3184 }\r
3185 });\r
3186 waitsFor(function() {\r
3187 return success;\r
3188 });\r
3189 runs(function() {\r
3190 expect(record).toBe(rec400);\r
3191\r
3192 // Table row scrolled to must be correct\r
3193 expect(htmlEl).toBe(view.getNode(rec400));\r
3194\r
3195 // The bottom of the row should be within view\r
3196 expect(Ext.fly(htmlEl).getBox().bottom).toBeLessThanOrEqual(view.getBox().bottom);\r
3197\r
3198 grid.ensureVisible(100, {\r
3199 callback: function(passedSuccess, passedRecord, passedHtmlEl) {\r
3200 success = passedSuccess;\r
3201 record = passedRecord;\r
3202 htmlEl = passedHtmlEl;\r
3203 detectedScope = this;\r
3204 }\r
3205 });\r
3206 waitsFor(function() {\r
3207 return success;\r
3208 });\r
3209 \r
3210 runs(function() {\r
3211 expect(record).toBe(rec100);\r
3212\r
3213 // Table row scrolled to must be correct\r
3214 expect(htmlEl).toBe(view.getNode(rec100));\r
3215\r
3216 // The top of the row should be within view\r
3217 expect(Ext.fly(htmlEl).getBox().top).toBeGreaterThanOrEqual(view.getBox().top);\r
3218 });\r
3219 });\r
3220 });\r
3221 });\r
3222\r
3223 describe("scrollbars", function() {\r
3224 function makeScrollSuite(withLocking) {\r
3225 describe(withLocking ? "with locking" : "without locking", function() {\r
3226 var gridRef,\r
3227 originalScrollBarSize,\r
3228 singleRowHeight,\r
3229 maxRowsBeforeScroll,\r
3230 scrollRowSize,\r
3231 borderWidth,\r
3232 colRef,\r
3233 lockedIsVariable,\r
3234 maxRowsBeforeScrollWithHorizontalScrollBar;\r
3235\r
3236 beforeEach(function() {\r
3237 lockedIsVariable = false;\r
3238 originalScrollBarSize = Ext.grid.ColumnLayout.prototype.scrollbarWidth;\r
3239 // Create nice round numbers for calculations so that we can hardcode expected flexed widths\r
3240 Ext.grid.ColumnLayout.prototype.scrollbarWidth = scrollbarsTakeSpace ? 20 : 0;\r
3241\r
3242 if (!singleRowHeight) {\r
3243 // Do this the first time, calculate the height of a single row &\r
3244 // the amount of rows we an have without a vertical scroll\r
3245 borderWidth = 0;\r
3246\r
3247 makeScrollGrid([{\r
3248 dataIndex: 'field1',\r
3249 width: 100\r
3250 }], 10);\r
3251\r
3252 var measureView = (withLocking ? grid.normalGrid : grid).getView(),\r
3253 viewHeight = measureView.getHeight(),\r
3254 measureNode = Ext.fly(measureView.getNode(0));\r
3255\r
3256 singleRowHeight = measureNode.getHeight();\r
3257 \r
3258 // In IE8 we're adding bottom border on all the rows to work around\r
3259 // the lack of :last-child selector, and we compensate that by setting\r
3260 // a negative top margin that equals the border width, so that top and\r
3261 // bottom borders overlap on adjacent rows. Negative margin does not\r
3262 // affect the row's reported height though so we have to compensate\r
3263 // for that effectively invisible additional border width here.\r
3264 // Note that this code mostly duplicates the actual row height\r
3265 // calculation performed in BufferedRenderer.getScrollHeight(),\r
3266 // and the same compensation is applied there as well.\r
3267 if (Ext.isIE8) {\r
3268 singleRowHeight -= measureNode.getBorderWidth('b');\r
3269 }\r
3270 \r
3271 maxRowsBeforeScroll = Math.floor(viewHeight / singleRowHeight);\r
3272 viewHeight -= Ext.getScrollbarSize().width;\r
3273 maxRowsBeforeScrollWithHorizontalScrollBar = Math.floor(viewHeight / singleRowHeight);\r
3274 scrollRowSize = maxRowsBeforeScroll + 100;\r
3275 \r
3276 if (withLocking) {\r
3277 borderWidth = parseInt(grid.lockedGrid.getEl().getStyle('border-right-width'), 10);\r
3278 }\r
3279\r
3280 grid.destroy();\r
3281 store.destroy();\r
3282 gridRef = colRef = null;\r
3283 }\r
3284 });\r
3285\r
3286 afterEach(function() {\r
3287 Ext.grid.ColumnLayout.prototype.scrollbarWidth = originalScrollBarSize;\r
3288 gridRef = colRef = null;\r
3289 lockedIsVariable = false;\r
3290 });\r
3291\r
3292 function makeScrollGrid(columns, data, cfg) {\r
3293 var lockedColWidth = 100;\r
3294\r
3295 if (Ext.isNumber(data)) {\r
3296 data = makeRows(data);\r
3297 }\r
3298 Ext.Array.forEach(columns, function(column, i) {\r
3299 if (!column.dataIndex) {\r
3300 column.dataIndex = 'field' + (i + 1);\r
3301 }\r
3302 });\r
3303 if (withLocking) {\r
3304 columns.unshift({\r
3305 width: lockedColWidth,\r
3306 dataIndex: 'field10',\r
3307 locked: true,\r
3308 variableRowHeight: lockedIsVariable\r
3309 });\r
3310 cfg = cfg || {};\r
3311 cfg.width = 1000 + borderWidth + lockedColWidth;\r
3312 }\r
3313 makeGrid(columns, data, cfg);\r
3314 gridRef = withLocking ? grid.normalGrid : grid;\r
3315 colRef = gridRef.getColumnManager().getColumns();\r
3316 }\r
3317\r
3318 function expectScroll(vertical, horizontal) {\r
3319 var dom = gridRef.getView().getEl().dom;\r
3320\r
3321 // In Mac OS X, scrollbars can be invisible until user hovers mouse cursor\r
3322 // over the scrolled area. This is hard to test so we just assume that\r
3323 // in Mac browsers scrollbars can have 0 width.\r
3324 if (vertical !== undefined) {\r
3325 if (vertical) {\r
3326 if (Ext.isMac) {\r
3327 expect(dom.scrollHeight).toBeGreaterThanOrEqual(dom.clientHeight);\r
3328 }\r
3329 else {\r
3330 expect(dom.scrollHeight).toBeGreaterThan(dom.clientHeight);\r
3331 }\r
3332 }\r
3333 else {\r
3334 expect(dom.scrollHeight).toBeLessThanOrEqual(dom.clientHeight);\r
3335 }\r
3336 }\r
3337\r
3338 if (horizontal !== undefined) {\r
3339 if (horizontal) {\r
3340 if (Ext.isMac) {\r
3341 expect(dom.scrollWidth).toBeGreaterThanOrEqual(dom.clientWidth);\r
3342 }\r
3343 else {\r
3344 expect(dom.scrollWidth).toBeGreaterThan(dom.clientWidth);\r
3345 }\r
3346 }\r
3347 else {\r
3348 expect(dom.scrollWidth).toBeLessThanOrEqual(dom.clientWidth);\r
3349 }\r
3350 }\r
3351 }\r
3352\r
3353 function expectColumnWidths(sizes, manager) {\r
3354 manager = manager || gridRef.getVisibleColumnManager();\r
3355 var columns = manager.getColumns(),\r
3356 len = columns.length,\r
3357 i;\r
3358\r
3359 for (i = 0; i < len; ++i) {\r
3360 expect(columns[i].getWidth()).toBe(sizes[i]);\r
3361 }\r
3362\r
3363 }\r
3364\r
3365 function makeRows(n) {\r
3366 var data = [],\r
3367 i;\r
3368\r
3369 for (i = 1; i <= n; ++i) {\r
3370 data.push({\r
3371 field1: i + '.1',\r
3372 field2: i + '.2',\r
3373 field3: i + '.3',\r
3374 field4: i + '.4',\r
3375 field5: i + '.5',\r
3376 field6: i + '.6',\r
3377 field7: i + '.7',\r
3378 field8: i + '.8',\r
3379 field9: i + '.9',\r
3380 field10: i + '.10'\r
3381\r
3382 });\r
3383 }\r
3384\r
3385 return data;\r
3386 }\r
3387\r
3388 function makeRowDiv(times) {\r
3389 return '<div style="height:' + (singleRowHeight * times) + 'px;">x</div>';\r
3390 }\r
3391\r
3392 describe("basic initial rendering functionality", function() {\r
3393 describe("fixed width columns", function() {\r
3394 it("should not show scrollbars if neither dimensions overflows", function() {\r
3395 makeScrollGrid([{\r
3396 width: 100\r
3397 }, {\r
3398 width: 300\r
3399 }], 1);\r
3400 expectScroll(false, false);\r
3401 expectColumnWidths([100, 300]);\r
3402 });\r
3403\r
3404 it("should show a vertical scrollbar if y overflows", function() {\r
3405 makeScrollGrid([{\r
3406 width: 100\r
3407 }, {\r
3408 width: 300\r
3409 }], scrollRowSize);\r
3410 expectScroll(true, false);\r
3411 expectColumnWidths([100, 300]);\r
3412 });\r
3413\r
3414 it("should show a horizontal scrollbar if x overflows", function() {\r
3415 makeScrollGrid([{\r
3416 width: 600\r
3417 }, {\r
3418 width: 600\r
3419 }], 1);\r
3420 expectScroll(false, true);\r
3421 expectColumnWidths([600, 600]);\r
3422 });\r
3423\r
3424 it("should show both scrollbars if x & y overflow", function() {\r
3425 makeScrollGrid([{\r
3426 width: 600\r
3427 }, {\r
3428 width: 600\r
3429 }], scrollRowSize);\r
3430 expectScroll(true, true);\r
3431 expectColumnWidths([600, 600]);\r
3432 });\r
3433\r
3434 visibleScrollbarsIt("should show a vertical scrollbar if triggered by a horizontal scrollbar", function() {\r
3435 makeScrollGrid([{\r
3436 width: 600\r
3437 }, {\r
3438 width: 600\r
3439 }], maxRowsBeforeScroll);\r
3440 expectScroll(true, true);\r
3441 expectColumnWidths([600, 600]);\r
3442 });\r
3443\r
3444 visibleScrollbarsIt("should show a horizontal scrollbar if triggered by a vertical scrollbar", function() {\r
3445 makeScrollGrid([{\r
3446 width: 499\r
3447 }, {\r
3448 width: 499\r
3449 }], scrollRowSize);\r
3450 expectScroll(true, true);\r
3451 expectColumnWidths([499, 499]);\r
3452 });\r
3453 });\r
3454\r
3455 describe("flexed columns", function() {\r
3456 it("should not show scrollbars if neither dimension overflows", function() {\r
3457 makeScrollGrid([{\r
3458 flex: 1\r
3459 }, {\r
3460 flex: 1\r
3461 }], 1);\r
3462 expectScroll(false, false);\r
3463 expectColumnWidths([500, 500]);\r
3464 });\r
3465\r
3466 it("should not show scrollbars if neither dimension overflows with hideHeaders: true and border: true", function() {\r
3467 makeScrollGrid([{\r
3468 flex: 1\r
3469 }, {\r
3470 flex: 1\r
3471 }], 1, {\r
3472 hideHeaders: true,\r
3473 border: true\r
3474 });\r
3475 expectScroll(false, false);\r
3476\r
3477 // Even though headerCt is squeezed out of visibilty, it must have measurable left/right border widths\r
3478 expectColumnWidths([499, 499]);\r
3479 });\r
3480\r
3481 it("should show a vertical scrollbar if y overflows", function() {\r
3482 makeScrollGrid([{\r
3483 flex: 1\r
3484 }, {\r
3485 flex: 1\r
3486 }], scrollRowSize);\r
3487 expectScroll(true, false);\r
3488 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
3489 });\r
3490\r
3491 it("should show a vertical scrollbar if y overflows with hideHeaders: true and border: true", function() {\r
3492 makeScrollGrid([{\r
3493 flex: 1\r
3494 }, {\r
3495 flex: 1\r
3496 }], scrollRowSize, {\r
3497 hideHeaders: true,\r
3498 border: true\r
3499 });\r
3500 expectScroll(true, false);\r
3501 expectColumnWidths(scrollbarsTakeSpace ? [489, 489] : [499, 499]);\r
3502 });\r
3503\r
3504 describe("min width constraint", function() {\r
3505 // This is essentially the same as combined width + flex, since hitting\r
3506 // a min width is essentially the same as setting a fixed size, but\r
3507 // may hit different parts of the code.\r
3508 \r
3509 it("should show a horizontal scrollbar if x overflows", function() {\r
3510 makeScrollGrid([{\r
3511 flex: 1,\r
3512 minWidth: 600\r
3513 }, {\r
3514 flex: 1,\r
3515 minWidth: 600\r
3516 }]);\r
3517 expectScroll(false, true);\r
3518 expectColumnWidths([600, 600]);\r
3519 });\r
3520\r
3521 it("should show both scrollbars if x & y overflow", function() {\r
3522 makeScrollGrid([{\r
3523 flex: 1,\r
3524 minWidth: 600\r
3525 }, {\r
3526 flex: 1,\r
3527 minWidth: 600\r
3528 }], scrollRowSize);\r
3529 expectScroll(true, true);\r
3530 expectColumnWidths([600, 600]);\r
3531 });\r
3532\r
3533 visibleScrollbarsIt("should show a vertical scrollbar if triggered by a horizontal scrollbar", function() {\r
3534 makeScrollGrid([{\r
3535 flex: 1,\r
3536 minWidth: 600\r
3537 }, {\r
3538 flex: 1,\r
3539 minWidth: 600\r
3540 }], maxRowsBeforeScroll);\r
3541 expectScroll(true, true);\r
3542 expectColumnWidths([600, 600]);\r
3543 });\r
3544\r
3545 visibleScrollbarsIt("should show a horizontal scrollbar if triggered by a vertical scrollbar", function() {\r
3546 makeScrollGrid([{\r
3547 flex: 1,\r
3548 minWidth: 499\r
3549 }, {\r
3550 flex: 1,\r
3551 minWidth: 499\r
3552 }], scrollRowSize);\r
3553 expectScroll(true, true);\r
3554 expectColumnWidths([499, 499]);\r
3555 });\r
3556 });\r
3557 });\r
3558\r
3559 describe("fixed width + flexed columns", function() {\r
3560 it("should not show scrollbars if neither dimensions overflows", function() {\r
3561 makeScrollGrid([{\r
3562 width: 100\r
3563 }, {\r
3564 flex: 1\r
3565 }], 1);\r
3566 expectScroll(false, false);\r
3567 expectColumnWidths([100, 900]);\r
3568 });\r
3569\r
3570 it("should show a vertical scrollbar if y overflows", function() {\r
3571 makeScrollGrid([{\r
3572 width: 100\r
3573 }, {\r
3574 flex: 1\r
3575 }], scrollRowSize);\r
3576 expectScroll(true, false);\r
3577 expectColumnWidths(scrollbarsTakeSpace ? [100, 880] : [100, 900]);\r
3578 });\r
3579\r
3580 it("should adjust the width of all flex columns if a scrollbar shows", function() {\r
3581 makeScrollGrid([{\r
3582 width: 200\r
3583 }, {\r
3584 flex: 1\r
3585 }, {\r
3586 flex: 1\r
3587 }, {\r
3588 flex: 1\r
3589 }], scrollRowSize);\r
3590 expectScroll(true, false);\r
3591 expectColumnWidths(scrollbarsTakeSpace ? [200, 260, 260, 260]: [200, 267, 267, 266]);\r
3592 });\r
3593 });\r
3594 });\r
3595\r
3596 describe("resizing the grid", function() {\r
3597 function changeHeight(numRows) {\r
3598 grid.setHeight(grid.getHeight() + numRows * singleRowHeight);\r
3599 }\r
3600\r
3601 function changeWidth(width) {\r
3602 grid.setWidth(grid.getWidth() + width);\r
3603 }\r
3604\r
3605 describe("fixed width columns", function() {\r
3606 describe("vertically", function() {\r
3607 it("should not show a vertical scrollbar if resize does not cause overflow", function() {\r
3608 makeScrollGrid([{\r
3609 width: 100\r
3610 }, {\r
3611 width: 300\r
3612 }], 1);\r
3613 expectScroll(false, false);\r
3614 changeHeight(-10);\r
3615 expectScroll(false, false);\r
3616 });\r
3617\r
3618 it("should retain a vertical scrollbar if resize does not cause underflow", function() {\r
3619 makeScrollGrid([{\r
3620 width: 100\r
3621 }, {\r
3622 width: 300\r
3623 }], scrollRowSize);\r
3624 expectScroll(true, false);\r
3625 changeHeight(-10);\r
3626 expectScroll(true, false);\r
3627 });\r
3628\r
3629 it("should show a vertical scrollbar if y overflows", function() {\r
3630 makeScrollGrid([{\r
3631 width: 100\r
3632 }, {\r
3633 width: 300\r
3634 }], maxRowsBeforeScroll);\r
3635 expectScroll(false, false);\r
3636 changeHeight(-10);\r
3637 expectScroll(true, false);\r
3638 });\r
3639\r
3640 it("should not show a vertical scrollbar if y underflows", function() {\r
3641 makeScrollGrid([{\r
3642 width: 100\r
3643 }, {\r
3644 width: 300\r
3645 }], maxRowsBeforeScroll + 5);\r
3646 expectScroll(true, false);\r
3647 changeHeight(10);\r
3648 expectScroll(false, false);\r
3649 });\r
3650\r
3651 visibleScrollbarsIt("should show a horizontal scrollbar if triggered by a vertical scrollbar", function() {\r
3652 makeScrollGrid([{\r
3653 width: 495\r
3654 }, {\r
3655 width: 495\r
3656 }], maxRowsBeforeScroll);\r
3657 expectScroll(false, false);\r
3658 changeHeight(-1);\r
3659 expectScroll(true, true);\r
3660 });\r
3661\r
3662 // // EXTJS-15789\r
3663 xit("should not show a horizontal scrollbar if triggered by a vertical scrollbar", function() {\r
3664 makeScrollGrid([{\r
3665 width: 495\r
3666 }, {\r
3667 width: 495\r
3668 }], maxRowsBeforeScroll);\r
3669 changeHeight(-1);\r
3670 expectScroll(true, true);\r
3671 changeHeight(1);\r
3672 expectScroll(false, false);\r
3673 });\r
3674 });\r
3675\r
3676 describe("horizontally", function() {\r
3677 it("should not show a horizontal scrollbar if resize does not cause overflow", function() {\r
3678 makeScrollGrid([{\r
3679 width: 100\r
3680 }, {\r
3681 width: 300\r
3682 }], 1);\r
3683 expectScroll(false, false);\r
3684 changeWidth(200);\r
3685 expectScroll(false, false);\r
3686 });\r
3687\r
3688 it("should retain a horizontal scrollbar if resize does not cause underflow", function() {\r
3689 makeScrollGrid([{\r
3690 width: 600\r
3691 }, {\r
3692 width: 600\r
3693 }], 1);\r
3694 expectScroll(false, true);\r
3695 changeWidth(-100);\r
3696 expectScroll(false, true);\r
3697 });\r
3698\r
3699 it("should show a horizontal scrollbar if x overflows", function() {\r
3700 makeScrollGrid([{\r
3701 width: 400\r
3702 }, {\r
3703 width: 400\r
3704 }], 1);\r
3705 expectScroll(false, false);\r
3706 changeWidth(-400);\r
3707 expectScroll(false, true);\r
3708 });\r
3709\r
3710 it("should not show a horizontal scrollbar if x underflows", function() {\r
3711 makeScrollGrid([{\r
3712 width: 600\r
3713 }, {\r
3714 width: 600\r
3715 }], 1);\r
3716 expectScroll(false, true);\r
3717 changeWidth(400);\r
3718 expectScroll(false, false);\r
3719 });\r
3720\r
3721 visibleScrollbarsIt("should show a vertical scrollbar if triggered by a horizontal scrollbar", function() {\r
3722 makeScrollGrid([{\r
3723 width: 495\r
3724 }, {\r
3725 width: 495\r
3726 }], maxRowsBeforeScroll);\r
3727 expectScroll(false, false);\r
3728 changeWidth(-50);\r
3729 expectScroll(true, true);\r
3730 });\r
3731\r
3732 visibleScrollbarsIt("should not show a vertical scrollbar if triggered by a horizontal scrollbar", function() {\r
3733 // C reate a grid with horizontal scrollbar which has no vertical scrollbar.\r
3734 makeScrollGrid([{\r
3735 width: 505\r
3736 }, {\r
3737 width: 505\r
3738 }], maxRowsBeforeScroll, {\r
3739 height: null\r
3740 });\r
3741\r
3742 // Introduce the vertical scrollbar but only by 5px so that eliminating the vertical scrollbar\r
3743 // will eliminate the need for it.\r
3744 grid.setHeight(grid.getHeight() - 5);\r
3745 expectScroll(true, true);\r
3746\r
3747 // Release the width constraint so that the horizontal scrollbar disappears.\r
3748 // contentHeight now fits\r
3749 changeWidth(50);\r
3750 view.el.setDisplayed(false);\r
3751 waits(1);\r
3752\r
3753 // Allow the reflow before showing and then measuring.\r
3754 runs(function() {\r
3755 view.el.setDisplayed(true);\r
3756 expectScroll(false, false);\r
3757 });\r
3758 });\r
3759 });\r
3760 });\r
3761\r
3762 describe("flexed columns", function() {\r
3763 describe("vertically", function() {\r
3764 it("should not show a vertical scrollbar if resize does not cause overflow", function() {\r
3765 makeScrollGrid([{\r
3766 flex: 1\r
3767 }, {\r
3768 flex: 1\r
3769 }], 1);\r
3770 expectScroll(false, false);\r
3771 expectColumnWidths([500, 500]);\r
3772 changeHeight(-10);\r
3773 expectScroll(false, false);\r
3774 expectColumnWidths([500, 500]);\r
3775 });\r
3776\r
3777 it("should retain a vertical scrollbar if resize does not cause underflow", function() {\r
3778 makeScrollGrid([{\r
3779 flex: 1\r
3780 }, {\r
3781 flex: 1\r
3782 }], scrollRowSize);\r
3783 expectScroll(true, false);\r
3784 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
3785 changeHeight(-10);\r
3786 expectScroll(true, false);\r
3787 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
3788 });\r
3789\r
3790 it("should show a vertical scrollbar if y overflows", function() {\r
3791 makeScrollGrid([{\r
3792 flex: 1\r
3793 }, {\r
3794 flex: 1\r
3795 }], maxRowsBeforeScroll);\r
3796 expectScroll(false, false);\r
3797 expectColumnWidths([500, 500]);\r
3798 changeHeight(-10);\r
3799 expectScroll(true, false);\r
3800 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
3801 });\r
3802\r
3803 it("should not show a vertical scrollbar if y underflows", function() {\r
3804 makeScrollGrid([{\r
3805 flex: 1\r
3806 }, {\r
3807 flex: 1\r
3808 }], maxRowsBeforeScroll + 5);\r
3809 expectScroll(true, false);\r
3810 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
3811 changeHeight(10);\r
3812 expectScroll(false, false);\r
3813 expectColumnWidths([500, 500]);\r
3814 });\r
3815 });\r
3816 // Horizontally omitted\r
3817 });\r
3818\r
3819 describe("fixed width + flexed columns", function() {\r
3820 describe("vertically", function() {\r
3821 it("should not show a vertical scrollbar if resize does not cause overflow", function() {\r
3822 makeScrollGrid([{\r
3823 width: 300\r
3824 }, {\r
3825 flex: 1\r
3826 }], 1);\r
3827 expectScroll(false, false);\r
3828 expectColumnWidths([300, 700]);\r
3829 changeHeight(-10);\r
3830 expectScroll(false, false);\r
3831 expectColumnWidths([300, 700]);\r
3832 });\r
3833\r
3834 it("should retain a vertical scrollbar if resize does not cause underflow", function() {\r
3835 makeScrollGrid([{\r
3836 width: 300\r
3837 }, {\r
3838 flex: 1\r
3839 }], scrollRowSize);\r
3840 expectScroll(true, false);\r
3841 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
3842 changeHeight(-10);\r
3843 expectScroll(true, false);\r
3844 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
3845 });\r
3846\r
3847 it("should show a vertical scrollbar if y overflows", function() {\r
3848 makeScrollGrid([{\r
3849 width: 300\r
3850 }, {\r
3851 flex: 1\r
3852 }], maxRowsBeforeScroll);\r
3853 expectScroll(false, false);\r
3854 expectColumnWidths([300, 700]);\r
3855 changeHeight(-10);\r
3856 expectScroll(true, false);\r
3857 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
3858 });\r
3859\r
3860 it("should not show a vertical scrollbar if y underflows", function() {\r
3861 makeScrollGrid([{\r
3862 width: 300\r
3863 }, {\r
3864 flex: 1\r
3865 }], maxRowsBeforeScroll + 5);\r
3866 expectScroll(true, false);\r
3867 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
3868 changeHeight(10);\r
3869 expectScroll(false, false);\r
3870 expectColumnWidths([300, 700]);\r
3871 });\r
3872 });\r
3873 // Horizontally omitted\r
3874 });\r
3875 });\r
3876\r
3877 describe("column operations", function() {\r
3878 var minColWidth = Ext.grid.plugin.HeaderResizer.prototype.minColWidth;\r
3879\r
3880 describe("resizing", function() {\r
3881 describe("fixed width columns", function() {\r
3882 it("should show a horizontal scrollbar if resizing causes overflow", function() {\r
3883 makeScrollGrid([{\r
3884 width: 100\r
3885 }, {\r
3886 width: 300\r
3887 }], 1);\r
3888 expectScroll(false, false);\r
3889 colRef[0].setWidth(800);\r
3890 expectScroll(false, true);\r
3891 });\r
3892\r
3893 it("should not show a horizontal scrollbar if resizing causes underflow", function() {\r
3894 makeScrollGrid([{\r
3895 width: 600\r
3896 }, {\r
3897 width: 600\r
3898 }], 1);\r
3899 expectScroll(false, true);\r
3900 colRef[0].setWidth(300);\r
3901 expectScroll(false, false);\r
3902 });\r
3903\r
3904 it("should show a vertical scrollbar if resizing causes overflow", function() {\r
3905 makeScrollGrid([{\r
3906 width: 600\r
3907 }, {\r
3908 width: 300\r
3909 }], maxRowsBeforeScroll);\r
3910 expectScroll(false, false);\r
3911 colRef[0].setWidth(800);\r
3912 expectScroll(scrollbarsTakeSpace, true);\r
3913 });\r
3914\r
3915 it("should not show a vertical scrollbar if resizing causes underflow", function() {\r
3916 makeScrollGrid([{\r
3917 width: 600\r
3918 }, {\r
3919 width: 600\r
3920 }], maxRowsBeforeScroll);\r
3921 expectScroll(scrollbarsTakeSpace, true);\r
3922 colRef[0].setWidth(300);\r
3923 expectScroll(false, false);\r
3924 });\r
3925 });\r
3926\r
3927 // Intentionally leaving out flex only\r
3928\r
3929 describe("fixed width + flexed columns", function() {\r
3930 it("should show a horizontal scrollbar if resizing causes overflow", function() {\r
3931 makeScrollGrid([{\r
3932 width: 300\r
3933 }, {\r
3934 flex: 1\r
3935 }], 1);\r
3936 expectScroll(false, false);\r
3937 expectColumnWidths([300, 700]);\r
3938 colRef[0].setWidth(1200);\r
3939 expectScroll(false, true);\r
3940 expectColumnWidths([1200, minColWidth]);\r
3941 });\r
3942\r
3943 it("should not show a horizontal scrollbar if resizing causes underflow", function() {\r
3944 makeScrollGrid([{\r
3945 width: 600\r
3946 }, {\r
3947 width: 600\r
3948 }, {\r
3949 flex: 1\r
3950 }], 1);\r
3951 expectScroll(false, true);\r
3952 expectColumnWidths([600, 600, minColWidth]);\r
3953 colRef[0].setWidth(200);\r
3954 expectScroll(false, false);\r
3955 expectColumnWidths([200, 600, 200]);\r
3956 });\r
3957\r
3958 it("should show a vertical scrollbar if resizing causes overflow", function() {\r
3959 makeScrollGrid([{\r
3960 width: 300\r
3961 }, {\r
3962 flex: 1\r
3963 }], maxRowsBeforeScroll);\r
3964 expectScroll(false, false);\r
3965 expectColumnWidths([300, 700]);\r
3966 colRef[0].setWidth(1200);\r
3967 expectScroll(scrollbarsTakeSpace, true);\r
3968 expectColumnWidths([1200, minColWidth]);\r
3969 });\r
3970\r
3971 it("should not show a vertical scrollbar if resizing causes underflow", function() {\r
3972 makeScrollGrid([{\r
3973 width: 600\r
3974 }, {\r
3975 width: 600\r
3976 }, {\r
3977 flex: 1\r
3978 }], maxRowsBeforeScroll, {\r
3979 height: null\r
3980 });\r
3981 grid.setHeight(grid.getHeight() - 5);\r
3982 expectScroll(true, true);\r
3983 expectColumnWidths([600, 600, minColWidth]);\r
3984 colRef[0].setWidth(200);\r
3985 view.el.setDisplayed(false);\r
3986 waits(1);\r
3987\r
3988 // Allow the reflow before showing and then measuring.\r
3989 runs(function() {\r
3990 view.el.setDisplayed(true);\r
3991 expectScroll(!scrollbarsTakeSpace, false);\r
3992 expectColumnWidths([200, 600, 200]);\r
3993 });\r
3994 });\r
3995 });\r
3996 });\r
3997\r
3998 describe("adding", function() {\r
3999 function addCol(col) {\r
4000 gridRef.headerCt.add(col);\r
4001 }\r
4002 describe("fixed width columns", function() {\r
4003 it("should show a horizontal scrollbar if adding causes overflow", function() {\r
4004 makeScrollGrid([{\r
4005 width: 100\r
4006 }, {\r
4007 width: 300\r
4008 }], 1);\r
4009 expectScroll(false, false);\r
4010 addCol({\r
4011 width: 700\r
4012 });\r
4013 expectScroll(false, true);\r
4014 });\r
4015\r
4016 it("should not show a horizontal scrollbar if adding does not cause overflow", function() {\r
4017 makeScrollGrid([{\r
4018 width: 100\r
4019 }, {\r
4020 width: 300\r
4021 }], 1);\r
4022 expectScroll(false, false);\r
4023 addCol({\r
4024 width: 300\r
4025 });\r
4026 expectScroll(false, false);\r
4027 });\r
4028\r
4029 it("should show a vertical scrollbar if adding causes overflow", function() {\r
4030 makeScrollGrid([{\r
4031 width: 600\r
4032 }, {\r
4033 width: 300\r
4034 }], maxRowsBeforeScroll);\r
4035 expectScroll(false, false);\r
4036 addCol({\r
4037 width: 200\r
4038 });\r
4039 expectScroll(scrollbarsTakeSpace, true);\r
4040 });\r
4041\r
4042 describe("with variableRowHeight", function() {\r
4043 visibleScrollbarsIt("should show a vertical scrollbar if adding causes overflow", function() {\r
4044 var data = makeRows(maxRowsBeforeScroll);\r
4045 data[0].field3 = makeRowDiv(2);\r
4046 makeScrollGrid([{\r
4047 width: 100\r
4048 }, {\r
4049 width: 300\r
4050 }], data);\r
4051 expectScroll(false, false);\r
4052 addCol({\r
4053 width: 200,\r
4054 variableRowHeight: true,\r
4055 dataIndex: 'field3'\r
4056 });\r
4057 expectScroll(true, false);\r
4058 });\r
4059\r
4060 visibleScrollbarsIt("should show a horizontal scrollbar if adding triggered a vertical scrollbar", function() {\r
4061 var data = makeRows(maxRowsBeforeScroll);\r
4062 data[0].field3 = makeRowDiv(2);\r
4063 makeScrollGrid([{\r
4064 width: 330\r
4065 }, {\r
4066 width: 330\r
4067 }], data);\r
4068 expectScroll(false, false);\r
4069 addCol({\r
4070 width: 330,\r
4071 variableRowHeight: true,\r
4072 dataIndex: 'field3'\r
4073 });\r
4074 expectScroll(true, true);\r
4075 });\r
4076 });\r
4077 });\r
4078\r
4079 // Intentionally leaving out flex only\r
4080 \r
4081 describe("fixed width + flexed columns", function() {\r
4082 it("should show a horizontal scrollbar if adding causes overflow", function() {\r
4083 makeScrollGrid([{\r
4084 width: 300\r
4085 }, {\r
4086 flex: 1\r
4087 }], 1);\r
4088 expectScroll(false, false);\r
4089 expectColumnWidths([300, 700]);\r
4090 addCol({\r
4091 width: 800\r
4092 });\r
4093 expectScroll(false, true);\r
4094 expectColumnWidths([300, minColWidth, 800]);\r
4095 });\r
4096\r
4097 it("should not show a horizontal scrollbar if adding does not cause overflow", function() {\r
4098 makeScrollGrid([{\r
4099 width: 300\r
4100 }, {\r
4101 flex: 1\r
4102 }], 1);\r
4103 expectScroll(false, false);\r
4104 expectColumnWidths([300, 700]);\r
4105 addCol({\r
4106 width: 300\r
4107 });\r
4108 expectScroll(false, false);\r
4109 expectColumnWidths([300, 400, 300]);\r
4110 });\r
4111\r
4112 it("should show a vertical scrollbar if adding causes overflow", function() {\r
4113 makeScrollGrid([{\r
4114 width: 300\r
4115 }, {\r
4116 flex: 1\r
4117 }], maxRowsBeforeScroll);\r
4118 expectScroll(false, false);\r
4119 expectColumnWidths([300, 700]);\r
4120 addCol({\r
4121 width: 800\r
4122 });\r
4123 expectScroll(scrollbarsTakeSpace, true);\r
4124 expectColumnWidths([300, minColWidth, 800]);\r
4125 });\r
4126\r
4127 describe("with variableRowHeight", function() {\r
4128 it("should show a vertical scrollbar if adding causes overflow", function() {\r
4129 var data = makeRows(maxRowsBeforeScroll);\r
4130 data[0].field3 = makeRowDiv(2);\r
4131 makeScrollGrid([{\r
4132 width: 300\r
4133 }, {\r
4134 flex: 1\r
4135 }], data);\r
4136 expectScroll(false, false);\r
4137 expectColumnWidths([300, 700]);\r
4138 addCol({\r
4139 width: 200,\r
4140 variableRowHeight: true,\r
4141 dataIndex: 'field3'\r
4142 });\r
4143 expectScroll(true, false);\r
4144 expectColumnWidths([300, scrollbarsTakeSpace ? 480 : 500, 200]);\r
4145 });\r
4146 });\r
4147 });\r
4148 });\r
4149\r
4150 describe("showing", function() {\r
4151 describe("fixed width columns", function() {\r
4152 it("should show a horizontal scrollbar if adding causes overflow", function() {\r
4153 makeScrollGrid([{\r
4154 width: 100\r
4155 }, {\r
4156 width: 700,\r
4157 hidden: true\r
4158 }, {\r
4159 width: 300\r
4160 }], 1);\r
4161 expectScroll(false, false);\r
4162 colRef[1].show();\r
4163 expectScroll(false, true);\r
4164 });\r
4165\r
4166 it("should not show a horizontal scrollbar if adding does not cause overflow", function() {\r
4167 makeScrollGrid([{\r
4168 width: 100\r
4169 }, {\r
4170 width: 300,\r
4171 hidden: true\r
4172 }, {\r
4173 width: 300\r
4174 }], 1);\r
4175 expectScroll(false, false);\r
4176 colRef[1].show();\r
4177 expectScroll(false, false);\r
4178 });\r
4179\r
4180 it("should show a vertical scrollbar if adding causes overflow", function() {\r
4181 makeScrollGrid([{\r
4182 width: 600\r
4183 }, {\r
4184 width: 200,\r
4185 hidden: true\r
4186 }, {\r
4187 width: 300\r
4188 }], maxRowsBeforeScroll);\r
4189 expectScroll(false, false);\r
4190 colRef[1].show();\r
4191 expectScroll(scrollbarsTakeSpace, true);\r
4192 });\r
4193\r
4194 describe("with variableRowHeight", function() {\r
4195 visibleScrollbarsIt("should show a vertical scrollbar if showing causes overflow", function() {\r
4196 var data = makeRows(maxRowsBeforeScroll);\r
4197 data[0].field3 = makeRowDiv(2);\r
4198 makeScrollGrid([{\r
4199 width: 100\r
4200 }, {\r
4201 width: 300\r
4202 }, {\r
4203 width: 200,\r
4204 variableRowHeight: true,\r
4205 hidden: true\r
4206 }], data);\r
4207 expectScroll(false, false);\r
4208 colRef[2].show();\r
4209 expectScroll(true, false);\r
4210 });\r
4211\r
4212 visibleScrollbarsIt("should show a horizontal scrollbar if showing triggered a vertical scrollbar", function() {\r
4213 var data = makeRows(maxRowsBeforeScroll);\r
4214 data[0].field3 = makeRowDiv(2);\r
4215 makeScrollGrid([{\r
4216 width: 330\r
4217 }, {\r
4218 width: 330\r
4219 }, {\r
4220 width: 330,\r
4221 variableRowHeight: true,\r
4222 hidden: true\r
4223 }], data);\r
4224 expectScroll(false, false);\r
4225 colRef[2].show();\r
4226 expectScroll(true, true);\r
4227 });\r
4228 });\r
4229 });\r
4230\r
4231 // Intentionally leaving out flex only\r
4232 \r
4233 describe("fixed width + flexed columns", function() {\r
4234 it("should show a horizontal scrollbar if adding causes overflow", function() {\r
4235 makeScrollGrid([{\r
4236 width: 300\r
4237 }, {\r
4238 width: 800,\r
4239 hidden: true\r
4240 }, {\r
4241 flex: 1\r
4242 }], 1);\r
4243 expectScroll(false, false);\r
4244 expectColumnWidths([300, 700]);\r
4245 colRef[1].show();\r
4246 expectScroll(false, true);\r
4247 expectColumnWidths([300, 800, minColWidth]);\r
4248 });\r
4249\r
4250 it("should not show a horizontal scrollbar if adding does not cause overflow", function() {\r
4251 makeScrollGrid([{\r
4252 width: 300\r
4253 }, {\r
4254 width: 300,\r
4255 hidden: true\r
4256 }, {\r
4257 flex: 1\r
4258 }], 1);\r
4259 expectScroll(false, false);\r
4260 expectColumnWidths([300, 700]);\r
4261 colRef[1].show();\r
4262 expectScroll(false, false);\r
4263 expectColumnWidths([300, 300, 400]);\r
4264 });\r
4265\r
4266 it("should show a vertical scrollbar if adding causes overflow", function() {\r
4267 makeScrollGrid([{\r
4268 width: 300\r
4269 }, {\r
4270 width: 800,\r
4271 hidden: true\r
4272 }, {\r
4273 flex: 1\r
4274 }], maxRowsBeforeScroll);\r
4275 expectScroll(false, false);\r
4276 expectColumnWidths([300, 700]);\r
4277 colRef[1].show();\r
4278 expectScroll(scrollbarsTakeSpace, true);\r
4279 expectColumnWidths([300, 800, minColWidth]);\r
4280 });\r
4281\r
4282 describe("with variableRowHeight", function() {\r
4283 it("should show a vertical scrollbar if showing causes overflow", function() {\r
4284 var data = makeRows(maxRowsBeforeScroll);\r
4285 data[0].field3 = makeRowDiv(2);\r
4286 makeScrollGrid([{\r
4287 width: 300\r
4288 }, {\r
4289 flex: 1\r
4290 }, {\r
4291 width: 200,\r
4292 variableRowHeight: true,\r
4293 hidden: true\r
4294 }], data);\r
4295 expectScroll(false, false);\r
4296 expectColumnWidths([300, 700]);\r
4297 colRef[2].show();\r
4298 expectScroll(true, false);\r
4299 expectColumnWidths([300, scrollbarsTakeSpace ? 480 : 500, 200]);\r
4300 });\r
4301 });\r
4302 });\r
4303 });\r
4304\r
4305 describe("removing", function() {\r
4306 describe("fixed width columns", function() {\r
4307 it("should not show a horizontal scrollbar if removing causes underflow", function() {\r
4308 makeScrollGrid([{\r
4309 width: 100\r
4310 }, {\r
4311 width: 300\r
4312 }, {\r
4313 width: 700\r
4314 }], 1);\r
4315 expectScroll(false, true);\r
4316 colRef[2].destroy();\r
4317 expectScroll(false, false);\r
4318 });\r
4319\r
4320 it("should retain a horizontal scrollbar if removing does not cause underflow", function() {\r
4321 makeScrollGrid([{\r
4322 width: 600\r
4323 }, {\r
4324 width: 600\r
4325 }, {\r
4326 width: 600\r
4327 }], 1);\r
4328 expectScroll(false, true);\r
4329 colRef[2].destroy();\r
4330 expectScroll(false, true);\r
4331 });\r
4332\r
4333 it("should not show a vertical scrollbar if removing causes underflow", function() {\r
4334 makeScrollGrid([{\r
4335 width: 600\r
4336 }, {\r
4337 width: 300\r
4338 }, {\r
4339 width: 200\r
4340 }], maxRowsBeforeScroll);\r
4341 expectScroll(scrollbarsTakeSpace, true);\r
4342 colRef[2].destroy();\r
4343 expectScroll(false, false);\r
4344 });\r
4345\r
4346 describe("with variableRowHeight", function() {\r
4347 it("should not show a vertical scrollbar if removing causes underflow", function() {\r
4348 var data = makeRows(maxRowsBeforeScroll);\r
4349 data[0].field3 = makeRowDiv(2);\r
4350 makeScrollGrid([{\r
4351 width: 100\r
4352 }, {\r
4353 width: 300\r
4354 }, {\r
4355 width: 200,\r
4356 variableRowHeight: true\r
4357 }], data);\r
4358 expectScroll(true, false);\r
4359 colRef[2].destroy();\r
4360 expectScroll(false, false);\r
4361 });\r
4362\r
4363 visibleScrollbarsIt("should not show a horizontal scrollbar if removing triggered a vertical scrollbar removal", function() {\r
4364 var data = makeRows(maxRowsBeforeScroll);\r
4365 data[0].field3 = makeRowDiv(2);\r
4366 makeScrollGrid([{\r
4367 width: 330\r
4368 }, {\r
4369 width: 330\r
4370 }, {\r
4371 width: 330,\r
4372 variableRowHeight: true\r
4373 }], data);\r
4374 expectScroll(true, true);\r
4375 colRef[2].destroy();\r
4376 expectScroll(false, false);\r
4377 });\r
4378 });\r
4379 });\r
4380\r
4381 // Intentionally leaving out flex only\r
4382 \r
4383 describe("fixed width + flexed columns", function() {\r
4384 it("should not show a horizontal scrollbar if removing causes underflow", function() {\r
4385 makeScrollGrid([{\r
4386 width: 300\r
4387 }, {\r
4388 flex: 1\r
4389 }, {\r
4390 width: 800\r
4391 }], 1);\r
4392 expectScroll(false, true);\r
4393 expectColumnWidths([300, minColWidth, 800]);\r
4394 colRef[2].destroy();\r
4395 expectScroll(false, false);\r
4396 expectColumnWidths([300, 700]);\r
4397 });\r
4398\r
4399 it("should show a horizontal scrollbar if removing does not cause underflow", function() {\r
4400 makeScrollGrid([{\r
4401 width: 600\r
4402 }, {\r
4403 width: 600\r
4404 }, {\r
4405 flex: 1\r
4406 }, {\r
4407 width: 600\r
4408 }], 1);\r
4409 expectScroll(false, true);\r
4410 expectColumnWidths([600, 600, minColWidth, 600]);\r
4411 colRef[3].destroy();\r
4412 expectScroll(false, true);\r
4413 expectColumnWidths([600, 600, minColWidth]);\r
4414 });\r
4415\r
4416 it("should not show a vertical scrollbar if removing causes underflow", function() {\r
4417 makeScrollGrid([{\r
4418 width: 300\r
4419 }, {\r
4420 flex: 1\r
4421 }, {\r
4422 width: 800\r
4423 }], maxRowsBeforeScroll);\r
4424 expectScroll(scrollbarsTakeSpace, true);\r
4425 expectColumnWidths([300, minColWidth, 800]);\r
4426 colRef[2].destroy();\r
4427 view.el.setDisplayed(false);\r
4428 waits(1);\r
4429\r
4430 // Allow the reflow before showing and then measuring.\r
4431 runs(function() {\r
4432 view.el.setDisplayed(true);\r
4433 expectScroll(false, false);\r
4434 expectColumnWidths([300, 700]);\r
4435 });\r
4436 });\r
4437\r
4438 describe("with variableRowHeight", function() {\r
4439 it("should not show a vertical scrollbar if removing causes underflow", function() {\r
4440 var data = makeRows(maxRowsBeforeScroll);\r
4441 data[0].field3 = makeRowDiv(2);\r
4442 makeScrollGrid([{\r
4443 width: 300\r
4444 }, {\r
4445 flex: 1\r
4446 }, {\r
4447 width: 200,\r
4448 variableRowHeight: true\r
4449 }], data);\r
4450 expectScroll(true, false);\r
4451 expectColumnWidths([300, scrollbarsTakeSpace ? 480 : 500, 200]);\r
4452 colRef[2].destroy();\r
4453 expectScroll(false, false);\r
4454 expectColumnWidths([300, 700]);\r
4455 });\r
4456 });\r
4457 });\r
4458 });\r
4459\r
4460 describe("hiding", function() {\r
4461 describe("fixed width columns", function() {\r
4462 it("should not show a horizontal scrollbar if hiding causes underflow", function() {\r
4463 makeScrollGrid([{\r
4464 width: 100\r
4465 }, {\r
4466 width: 300\r
4467 }, {\r
4468 width: 700\r
4469 }], 1);\r
4470 expectScroll(false, true);\r
4471 colRef[2].hide();\r
4472 expectScroll(false, false);\r
4473 });\r
4474\r
4475 it("should retain a horizontal scrollbar if hiding does not cause underflow", function() {\r
4476 makeScrollGrid([{\r
4477 width: 600\r
4478 }, {\r
4479 width: 600\r
4480 }, {\r
4481 width: 600\r
4482 }], 1);\r
4483 expectScroll(false, true);\r
4484 colRef[2].hide();\r
4485 expectScroll(false, true);\r
4486 });\r
4487\r
4488 it("should not show a vertical scrollbar if hiding causes underflow", function() {\r
4489 makeScrollGrid([{\r
4490 width: 600\r
4491 }, {\r
4492 width: 300\r
4493 }, {\r
4494 width: 200\r
4495 }], maxRowsBeforeScroll);\r
4496 expectScroll(scrollbarsTakeSpace, true);\r
4497 colRef[2].hide();\r
4498 view.el.setDisplayed(false);\r
4499 waits(1);\r
4500\r
4501 // Allow the reflow before showing and then measuring.\r
4502 runs(function() {\r
4503 view.el.setDisplayed(true);\r
4504 expectScroll(false, false);\r
4505 });\r
4506 });\r
4507\r
4508 describe("with variableRowHeight", function() {\r
4509 it("should not show a vertical scrollbar if hiding causes underflow", function() {\r
4510 var data = makeRows(maxRowsBeforeScroll);\r
4511 data[0].field3 = makeRowDiv(2);\r
4512 makeScrollGrid([{\r
4513 width: 100\r
4514 }, {\r
4515 width: 300\r
4516 }, {\r
4517 width: 200,\r
4518 variableRowHeight: true\r
4519 }], data);\r
4520 expectScroll(true, false);\r
4521 colRef[2].hide();\r
4522 view.el.setDisplayed(false);\r
4523 waits(1);\r
4524\r
4525 // Allow the reflow before showing and then measuring.\r
4526 runs(function() {\r
4527 view.el.setDisplayed(true);\r
4528 expectScroll(false, false);\r
4529 });\r
4530 });\r
4531\r
4532 visibleScrollbarsIt("should not show a horizontal scrollbar if hiding triggered a vertical scrollbar removal", function() {\r
4533 var data = makeRows(maxRowsBeforeScroll);\r
4534 data[0].field3 = makeRowDiv(2);\r
4535 makeScrollGrid([{\r
4536 width: 330\r
4537 }, {\r
4538 width: 330\r
4539 }, {\r
4540 width: 330,\r
4541 variableRowHeight: true\r
4542 }], data);\r
4543 expectScroll(true, true);\r
4544 colRef[2].hide();\r
4545 expectScroll(false, false);\r
4546 });\r
4547 });\r
4548 });\r
4549\r
4550 // Intentionally leaving out flex only\r
4551 \r
4552 describe("fixed width + flexed columns", function() {\r
4553 it("should not show a horizontal scrollbar if hiding causes underflow", function() {\r
4554 makeScrollGrid([{\r
4555 width: 300\r
4556 }, {\r
4557 flex: 1\r
4558 }, {\r
4559 width: 800\r
4560 }], 1);\r
4561 expectScroll(false, true);\r
4562 expectColumnWidths([300, minColWidth, 800]);\r
4563 colRef[2].hide();\r
4564 expectScroll(false, false);\r
4565 expectColumnWidths([300, 700]);\r
4566 });\r
4567\r
4568 it("should show a horizontal scrollbar if hiding does not cause underflow", function() {\r
4569 makeScrollGrid([{\r
4570 width: 600\r
4571 }, {\r
4572 width: 600\r
4573 }, {\r
4574 flex: 1\r
4575 }, {\r
4576 width: 600\r
4577 }], 1);\r
4578 expectScroll(false, true);\r
4579 expectColumnWidths([600, 600, minColWidth, 600]);\r
4580 colRef[3].hide();\r
4581 expectScroll(false, true);\r
4582 expectColumnWidths([600, 600, minColWidth]);\r
4583 });\r
4584\r
4585 it("should not show a vertical scrollbar if hiding causes underflow", function() {\r
4586 makeScrollGrid([{\r
4587 width: 300\r
4588 }, {\r
4589 flex: 1\r
4590 }, {\r
4591 width: 800\r
4592 }], maxRowsBeforeScroll);\r
4593 expectScroll(scrollbarsTakeSpace, true);\r
4594 expectColumnWidths([300, minColWidth, 800]);\r
4595 colRef[2].hide();\r
4596 view.el.setDisplayed(false);\r
4597 waits(1);\r
4598\r
4599 // Allow the reflow before showing and then measuring.\r
4600 runs(function() {\r
4601 view.el.setDisplayed(true);\r
4602 expectScroll(false, false);\r
4603 expectColumnWidths([300, 700]);\r
4604 });\r
4605 });\r
4606\r
4607 describe("with variableRowHeight", function() {\r
4608 it("should not show a vertical scrollbar if hiding causes underflow", function() {\r
4609 var data = makeRows(maxRowsBeforeScroll);\r
4610 data[0].field3 = makeRowDiv(2);\r
4611 makeScrollGrid([{\r
4612 width: 300\r
4613 }, {\r
4614 flex: 1\r
4615 }, {\r
4616 width: 200,\r
4617 variableRowHeight: true\r
4618 }], data);\r
4619 expectScroll(true, false);\r
4620 expectColumnWidths([300, scrollbarsTakeSpace ? 480 : 500, 200]);\r
4621 colRef[2].hide();\r
4622 view.el.setDisplayed(false);\r
4623 waits(1);\r
4624\r
4625 // Allow the reflow before showing and then measuring.\r
4626 runs(function() {\r
4627 view.el.setDisplayed(true);\r
4628 expectScroll(false, false);\r
4629 expectColumnWidths([300, 700]);\r
4630 });\r
4631 });\r
4632 });\r
4633 });\r
4634 });\r
4635 });\r
4636\r
4637 describe("store operations", function() {\r
4638 describe("adding records", function() {\r
4639 describe("fixed width columns", function() {\r
4640 it("should not show a vertical scrollbar if adding does not cause overflow", function() {\r
4641 makeScrollGrid([{\r
4642 width: 100\r
4643 }, {\r
4644 width: 300\r
4645 }], 1);\r
4646 expectScroll(false, false);\r
4647 store.add({});\r
4648 expectScroll(false, false);\r
4649 });\r
4650\r
4651 it("should retain a vertical scrollbar if overflow exists", function() {\r
4652 makeScrollGrid([{\r
4653 width: 100\r
4654 }, {\r
4655 width: 300\r
4656 }], scrollRowSize);\r
4657 expectScroll(true, false);\r
4658 store.add({});\r
4659 expectScroll(true, false);\r
4660 });\r
4661\r
4662 it("should show a vertical scrollbar if adding causes an overflow", function() {\r
4663 makeScrollGrid([{\r
4664 width: 100\r
4665 }, {\r
4666 width: 300\r
4667 }], maxRowsBeforeScroll);\r
4668 expectScroll(false, false);\r
4669 store.add({});\r
4670 expectScroll(true, false);\r
4671 });\r
4672\r
4673 visibleScrollbarsIt("should show a vertical scrollbar if triggered by a horizontal scrollbar", function() {\r
4674 makeScrollGrid([{\r
4675 width: 600\r
4676 }, {\r
4677 width: 600\r
4678 }], maxRowsBeforeScrollWithHorizontalScrollBar, {\r
4679 height: null\r
4680 });\r
4681 // Make the grid just height enough so that there's a horizontal scrollbar, but no vertical\r
4682 grid.setHeight(grid.getHeight() + 5);\r
4683 expectScroll(false, true);\r
4684 store.add({});\r
4685 expectScroll(true, true);\r
4686 });\r
4687\r
4688 visibleScrollbarsIt("should show a horizontal scrollbar if triggered by a vertical scrollbar", function() {\r
4689 makeScrollGrid([{\r
4690 width: 495\r
4691 }, {\r
4692 width: 495\r
4693 }], maxRowsBeforeScroll);\r
4694 expectScroll(false, false);\r
4695 store.add({});\r
4696 expectScroll(true, true);\r
4697 });\r
4698 });\r
4699\r
4700 describe("flexed columns", function() {\r
4701 it("should not show a vertical scrollbar if adding does not cause overflow", function() {\r
4702 makeScrollGrid([{\r
4703 flex: 1\r
4704 }, {\r
4705 flex: 1\r
4706 }], 1);\r
4707 expectScroll(false, false);\r
4708 expectColumnWidths([500, 500]);\r
4709 store.add({});\r
4710 expectScroll(false, false);\r
4711 expectColumnWidths([500, 500]);\r
4712 });\r
4713\r
4714 it("should retain a vertical scrollbar if overflow exists", function() {\r
4715 makeScrollGrid([{\r
4716 flex: 1\r
4717 }, {\r
4718 flex: 1\r
4719 }], scrollRowSize);\r
4720 expectScroll(true, false);\r
4721 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
4722 store.add({});\r
4723 expectScroll(true, false);\r
4724 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
4725 });\r
4726\r
4727 it("should show a vertical scrollbar if adding causes an overflow", function() {\r
4728 makeScrollGrid([{\r
4729 flex: 1\r
4730 }, {\r
4731 flex: 1\r
4732 }], maxRowsBeforeScroll);\r
4733 expectScroll(false, false);\r
4734 expectColumnWidths([500, 500]);\r
4735 store.add({});\r
4736 expectScroll(true, false);\r
4737 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
4738 });\r
4739 });\r
4740\r
4741 describe("fixed width + flexed columns", function() {\r
4742 it("should not show a vertical scrollbar if adding does not cause overflow", function() {\r
4743 makeScrollGrid([{\r
4744 width: 300\r
4745 }, {\r
4746 flex: 1\r
4747 }], 1);\r
4748 expectScroll(false, false);\r
4749 expectColumnWidths([300, 700]);\r
4750 store.add({});\r
4751 expectScroll(false, false);\r
4752 expectColumnWidths([300, 700]);\r
4753 });\r
4754\r
4755 it("should retain a vertical scrollbar if overflow exists", function() {\r
4756 makeScrollGrid([{\r
4757 width: 300\r
4758 }, {\r
4759 flex: 1\r
4760 }], scrollRowSize);\r
4761 expectScroll(true, false);\r
4762 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
4763 store.add({});\r
4764 expectScroll(true, false);\r
4765 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
4766 });\r
4767\r
4768 it("should show a vertical scrollbar if adding causes an overflow", function() {\r
4769 makeScrollGrid([{\r
4770 width: 300\r
4771 }, {\r
4772 flex: 1\r
4773 }], maxRowsBeforeScroll);\r
4774 expectScroll(false, false);\r
4775 expectColumnWidths([300, 700]);\r
4776 store.add({});\r
4777 expectScroll(true, false);\r
4778 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
4779 });\r
4780 });\r
4781 });\r
4782\r
4783 describe("removing records", function() {\r
4784 describe("fixed width columns", function() {\r
4785 it("should not show a vertical scrollbar if there is no overflow", function() {\r
4786 makeScrollGrid([{\r
4787 width: 100\r
4788 }, {\r
4789 width: 300\r
4790 }], 2);\r
4791 expectScroll(false, false);\r
4792 store.removeAt(0);\r
4793 expectScroll(false, false);\r
4794 });\r
4795\r
4796 it("should retain a vertical scrollbar if overflow exists", function() {\r
4797 makeScrollGrid([{\r
4798 width: 100\r
4799 }, {\r
4800 width: 300\r
4801 }], scrollRowSize);\r
4802 expectScroll(true, false);\r
4803 store.removeAt(0);\r
4804 expectScroll(true, false);\r
4805 });\r
4806\r
4807 it("should not show a vertical scrollbar if removing causes underflow", function() {\r
4808 makeScrollGrid([{\r
4809 width: 100\r
4810 }, {\r
4811 width: 300\r
4812 }], maxRowsBeforeScroll + 1);\r
4813 expectScroll(true, false);\r
4814 store.removeAt(0);\r
4815 expectScroll(false, false);\r
4816 });\r
4817\r
4818 visibleScrollbarsIt("should not show a vertical scrollbar if triggered by a horizontal scrollbar", function() {\r
4819 makeScrollGrid([{\r
4820 width: 600\r
4821 }, {\r
4822 width: 600\r
4823 }], maxRowsBeforeScrollWithHorizontalScrollBar + 1, {\r
4824 height: null\r
4825 });\r
4826 grid.setHeight(grid.getHeight() - 5);\r
4827 expectScroll(true, true);\r
4828 store.removeAt(0);\r
4829 view.el.setDisplayed(false);\r
4830 waits(1);\r
4831\r
4832 // Allow the reflow before showing and then measuring.\r
4833 runs(function() {\r
4834 view.el.setDisplayed(true);\r
4835 expectScroll(false, true);\r
4836 });\r
4837 });\r
4838\r
4839 // EXTJS-1578\r
4840 xit("should not show a horizontal scrollbar if triggered by a vertical scrollbar", function() {\r
4841 makeScrollGrid([{\r
4842 width: 495\r
4843 }, {\r
4844 width: 495\r
4845 }], maxRowsBeforeScroll + 1);\r
4846 expectScroll(true, true);\r
4847 store.removeAt(0);\r
4848 expectScroll(false, false);\r
4849 });\r
4850 });\r
4851\r
4852 describe("flexed columns", function() {\r
4853 it("should not show a vertical scrollbar if there is no overflow", function() {\r
4854 makeScrollGrid([{\r
4855 flex: 1\r
4856 }, {\r
4857 flex: 1\r
4858 }], 2);\r
4859 expectScroll(false, false);\r
4860 expectColumnWidths([500, 500]);\r
4861 store.removeAt(0);\r
4862 expectScroll(false, false);\r
4863 expectColumnWidths([500, 500]);\r
4864 });\r
4865\r
4866 it("should retain a vertical scrollbar if overflow exists", function() {\r
4867 makeScrollGrid([{\r
4868 flex: 1\r
4869 }, {\r
4870 flex: 1\r
4871 }], scrollRowSize);\r
4872 expectScroll(true, false);\r
4873 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
4874 store.removeAt(0);\r
4875 expectScroll(true, false);\r
4876 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
4877 });\r
4878\r
4879 it("should not show a vertical scrollbar if removing causes underflow", function() {\r
4880 makeScrollGrid([{\r
4881 flex: 1\r
4882 }, {\r
4883 flex: 1\r
4884 }], maxRowsBeforeScroll + 1, {\r
4885 height: null\r
4886 });\r
4887 // Make the grid just height enough so that there is a vertical scrollbar\r
4888 grid.setHeight(grid.getHeight() - 5);\r
4889 expectScroll(true, false);\r
4890 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
4891 store.removeAt(0);\r
4892\r
4893 // Layout resulting from remove which recalculates column widths runs on idle, so allow that to happen\r
4894 waits(1);\r
4895 runs(function() {\r
4896 expectScroll(false, false);\r
4897 expectColumnWidths([500, 500]);\r
4898 });\r
4899 });\r
4900 });\r
4901\r
4902 describe("fixed width + flexed columns", function() {\r
4903 it("should not show a vertical scrollbar if there is no overflow", function() {\r
4904 makeScrollGrid([{\r
4905 width: 400\r
4906 }, {\r
4907 flex: 1\r
4908 }], 2);\r
4909 expectScroll(false, false);\r
4910 expectColumnWidths([400, 600]);\r
4911 store.removeAt(0);\r
4912 expectScroll(false, false);\r
4913 expectColumnWidths([400, 600]);\r
4914 });\r
4915\r
4916 it("should retain a vertical scrollbar if overflow exists", function() {\r
4917 makeScrollGrid([{\r
4918 width: 400\r
4919 }, {\r
4920 flex: 1\r
4921 }], scrollRowSize);\r
4922 expectScroll(true, false);\r
4923 expectColumnWidths(scrollbarsTakeSpace ? [400, 580] : [400, 600]);\r
4924 store.removeAt(0);\r
4925 expectScroll(true, false);\r
4926 expectColumnWidths(scrollbarsTakeSpace ? [400, 580] : [400, 600]);\r
4927 });\r
4928\r
4929 it("should not show a vertical scrollbar if removing causes underflow", function() {\r
4930 makeScrollGrid([{\r
4931 width: 300\r
4932 }, {\r
4933 flex: 1\r
4934 }], maxRowsBeforeScroll + 1, {\r
4935 height: null\r
4936 });\r
4937 // Make the grid just height enough so that there is a vertical scrollbar\r
4938 grid.setHeight(grid.getHeight() - 5);\r
4939 expectScroll(true, false);\r
4940 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
4941 store.removeAt(0);\r
4942 expectScroll(false, false);\r
4943 expectColumnWidths([300, 700]);\r
4944 });\r
4945 });\r
4946 });\r
4947\r
4948 describe("updating records with variableRowHeight", function() {\r
4949 describe("fixed width columns", function() {\r
4950 it("should not show a vertical scrollbar if there is no overflow", function() {\r
4951 makeScrollGrid([{\r
4952 width: 100,\r
4953 variableRowHeight: true\r
4954 }, {\r
4955 width: 300\r
4956 }], 1);\r
4957 expectScroll(false, false);\r
4958 store.first().set('field1', makeRowDiv(2));\r
4959 expectScroll(false, false);\r
4960 });\r
4961\r
4962 it("should retain a vertical scrollbar if overflow exists", function() {\r
4963 makeScrollGrid([{\r
4964 width: 100,\r
4965 variableRowHeight: true\r
4966 }, {\r
4967 width: 300\r
4968 }], scrollRowSize);\r
4969 expectScroll(true, false);\r
4970 store.first().set('field1', makeRowDiv(2));\r
4971 expectScroll(true, false);\r
4972 });\r
4973\r
4974 describe("making content larger", function() {\r
4975 it("should show a vertical scrollbar if the update causes an overflow", function() {\r
4976 makeScrollGrid([{\r
4977 width: 100,\r
4978 variableRowHeight: true\r
4979 }, {\r
4980 width: 300\r
4981 }], maxRowsBeforeScroll);\r
4982 expectScroll(false, false);\r
4983 store.first().set('field1', makeRowDiv(2));\r
4984 expectScroll(true, false);\r
4985 });\r
4986\r
4987 visibleScrollbarsIt("should show a vertical scrollbar if triggered by a horizontal scrollbar", function() {\r
4988 makeScrollGrid([{\r
4989 width: 600,\r
4990 variableRowHeight: true\r
4991 }, {\r
4992 width: 600\r
4993 }], maxRowsBeforeScrollWithHorizontalScrollBar, {\r
4994 height: null\r
4995 });\r
4996 // Make the grid just height enough so that there's a horizontal scrollbar, but no vertical\r
4997 grid.setHeight(grid.getHeight() + 5);\r
4998 expectScroll(false, true);\r
4999 store.first().set('field1', makeRowDiv(2));\r
5000 expectScroll(true, true);\r
5001 });\r
5002\r
5003 visibleScrollbarsIt("should show a horizontal scrollbar if triggered by a vertical scrollbar", function() {\r
5004 makeScrollGrid([{\r
5005 width: 495\r
5006 }, {\r
5007 width: 495\r
5008 }], maxRowsBeforeScroll);\r
5009 expectScroll(false, false);\r
5010 store.first().set('field1', makeRowDiv(2));\r
5011 expectScroll(true, true);\r
5012 });\r
5013 });\r
5014\r
5015 describe("making content smaller", function() {\r
5016 it("should not show a vertical scrollbar if the update causes an underflow", function() {\r
5017 var data = makeRows(maxRowsBeforeScroll);\r
5018 data[0].field1 = makeRowDiv(3);\r
5019 makeScrollGrid([{\r
5020 width: 100,\r
5021 variableRowHeight: true\r
5022 }, {\r
5023 width: 300\r
5024 }], data);\r
5025 expectScroll(true, false);\r
5026 store.first().set('field1', '1.1');\r
5027 expectScroll(false, false);\r
5028 });\r
5029\r
5030 visibleScrollbarsIt("should not show a vertical scrollbar if triggered by a horizontal scrollbar", function() {\r
5031 makeScrollGrid([{\r
5032 width: 600,\r
5033 variableRowHeight: true\r
5034 }, {\r
5035 width: 600\r
5036 }], maxRowsBeforeScroll, {\r
5037 height: null\r
5038 });\r
5039 grid.setHeight(grid.getHeight());\r
5040 expectScroll(false, true);\r
5041 store.first().set('field1', makeRowDiv(3));\r
5042 expectScroll(true, true);\r
5043 store.first().set('field1', '1.1');\r
5044 expectScroll(false, true);\r
5045 });\r
5046\r
5047 visibleScrollbarsIt("should not show a horizontal scrollbar if triggered by a vertical scrollbar", function() {\r
5048 var data = makeRows(maxRowsBeforeScrollWithHorizontalScrollBar);\r
5049 data[0].field1 = makeRowDiv(3);\r
5050 makeScrollGrid([{\r
5051 width: 495\r
5052 }, {\r
5053 width: 495\r
5054 }], maxRowsBeforeScroll, {\r
5055 height: null\r
5056 });\r
5057 grid.setHeight(grid.getHeight() + 5);\r
5058 store.first().set('field1', makeRowDiv(3));\r
5059 expectScroll(true, true);\r
5060 store.first().set('field1', '1.1');\r
5061 view.el.setDisplayed(false);\r
5062 waits(1);\r
5063\r
5064 // Allow the reflow before showing and then measuring.\r
5065 runs(function() {\r
5066 view.el.setDisplayed(true);\r
5067 expectScroll(false, false);\r
5068 });\r
5069 });\r
5070 });\r
5071 });\r
5072\r
5073 describe("flexed columns", function() {\r
5074 it("should not show a vertical scrollbar if there is no overflow", function() {\r
5075 makeScrollGrid([{\r
5076 flex: 1,\r
5077 variableRowHeight: true\r
5078 }, {\r
5079 flex: 1\r
5080 }], 1);\r
5081 expectScroll(false, false);\r
5082 expectColumnWidths([500, 500]);\r
5083 store.first().set('field1', makeRowDiv(2));\r
5084 expectScroll(false, false);\r
5085 });\r
5086\r
5087 it("should retain a vertical scrollbar if overflow exists", function() {\r
5088 makeScrollGrid([{\r
5089 flex: 1,\r
5090 variableRowHeight: true\r
5091 }, {\r
5092 flex: 1\r
5093 }], scrollRowSize);\r
5094 expectScroll(true, false);\r
5095 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
5096 store.first().set('field1', makeRowDiv(2));\r
5097 expectScroll(true, false);\r
5098 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
5099 });\r
5100\r
5101 it("should show a vertical scrollbar if the update causes an overflow", function() {\r
5102 makeScrollGrid([{\r
5103 flex: 1,\r
5104 variableRowHeight: true\r
5105 }, {\r
5106 flex: 1\r
5107 }], maxRowsBeforeScroll, {\r
5108 height: null\r
5109 });\r
5110 grid.setHeight(grid.getHeight() + 5);\r
5111 expectScroll(false, false);\r
5112 expectColumnWidths([500, 500]);\r
5113 store.first().set('field1', makeRowDiv(2));\r
5114 expectScroll(true, false);\r
5115 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
5116 });\r
5117\r
5118 it("should not show a vertical scrollbar if the update causes an underflow", function() {\r
5119 makeScrollGrid([{\r
5120 flex: 1,\r
5121 variableRowHeight: true\r
5122 }, {\r
5123 flex: 1\r
5124 }], maxRowsBeforeScroll, {\r
5125 height: null\r
5126 });\r
5127 grid.setHeight(grid.getHeight() + 5);\r
5128 store.first().set('field1', makeRowDiv(2));\r
5129 expectScroll(true, false);\r
5130 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
5131 store.first().set('field1', '1.1');\r
5132 expectScroll(false, false);\r
5133 expectColumnWidths([500, 500]);\r
5134 });\r
5135 });\r
5136\r
5137 describe("fixed width + flexed columns", function() {\r
5138 it("should not show a vertical scrollbar if there is no overflow", function() {\r
5139 makeScrollGrid([{\r
5140 width: 300,\r
5141 variableRowHeight: true\r
5142 }, {\r
5143 flex: 1\r
5144 }], 1);\r
5145 expectScroll(false, false);\r
5146 expectColumnWidths([300, 700]);\r
5147 store.first().set('field1', makeRowDiv(2));\r
5148 expectScroll(false, false);\r
5149 });\r
5150\r
5151 it("should retain a vertical scrollbar if overflow exists", function() {\r
5152 makeScrollGrid([{\r
5153 width: 300,\r
5154 variableRowHeight: true\r
5155 }, {\r
5156 flex: 1\r
5157 }], scrollRowSize);\r
5158 expectScroll(true, false);\r
5159 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
5160 store.first().set('field1', makeRowDiv(2));\r
5161 expectScroll(true, false);\r
5162 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
5163 });\r
5164\r
5165 it("should show a vertical scrollbar if the update causes an overflow", function() {\r
5166 makeScrollGrid([{\r
5167 width: 300,\r
5168 variableRowHeight: true\r
5169 }, {\r
5170 flex: 1\r
5171 }], maxRowsBeforeScroll, {\r
5172 height: null\r
5173 });\r
5174 grid.setHeight(grid.getHeight() + 5);\r
5175 expectScroll(false, false);\r
5176 expectColumnWidths([300, 700]);\r
5177 store.first().set('field1', makeRowDiv(2));\r
5178 expectScroll(true, false);\r
5179 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
5180 });\r
5181\r
5182 it("should not show a vertical scrollbar if the update causes an underflow", function() {\r
5183 makeScrollGrid([{\r
5184 width: 300,\r
5185 variableRowHeight: true\r
5186 }, {\r
5187 flex: 1\r
5188 }], maxRowsBeforeScroll, {\r
5189 height: null\r
5190 });\r
5191 grid.setHeight(grid.getHeight() + 5);\r
5192 store.first().set('field1', makeRowDiv(2));\r
5193 expectScroll(true, false);\r
5194 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
5195 store.first().set('field1', '1.1');\r
5196 expectScroll(false, false);\r
5197 expectColumnWidths([300, 700]);\r
5198 });\r
5199 });\r
5200 });\r
5201\r
5202 describe("loading new content", function() {\r
5203 describe("fixed width columns", function() {\r
5204 it("should not show a vertical scrollbar if there is no overflow", function() {\r
5205 makeScrollGrid([{\r
5206 width: 100\r
5207 }, {\r
5208 width: 300\r
5209 }], 1);\r
5210 expectScroll(false, false);\r
5211 store.loadData(makeRows(2));\r
5212 expect(false, false);\r
5213 });\r
5214\r
5215 it("should retain a vertical scrollbar if overflow exists", function() {\r
5216 makeScrollGrid([{\r
5217 width: 100\r
5218 }, {\r
5219 width: 300\r
5220 }], scrollRowSize);\r
5221 expectScroll(true, false);\r
5222 store.loadData(makeRows(scrollRowSize + 20));\r
5223 expect(true, false);\r
5224 });\r
5225\r
5226 it("should not show a vertical scrollbar if the new content does not require it", function() {\r
5227 makeScrollGrid([{\r
5228 width: 100\r
5229 }, {\r
5230 width: 300\r
5231 }], scrollRowSize);\r
5232 expectScroll(true, false);\r
5233 store.loadData(makeRows(1));\r
5234 expectScroll(false, false);\r
5235 });\r
5236\r
5237 it("should not show a horizontal and vertical scrollbar if the new content does not require it", function() {\r
5238 makeScrollGrid([{\r
5239 width: 495\r
5240 }, {\r
5241 width: 495\r
5242 }], maxRowsBeforeScroll - 1);\r
5243 expectScroll(false, false);\r
5244 store.loadData(makeRows(1));\r
5245 expectScroll(false, false);\r
5246 });\r
5247\r
5248 it("should show a vertical scrollbar if the old content did not require it", function() {\r
5249 makeScrollGrid([{\r
5250 width: 100\r
5251 }, {\r
5252 width: 300\r
5253 }], 1);\r
5254 expectScroll(false, false);\r
5255 store.loadData(makeRows(scrollRowSize));\r
5256 expectScroll(true, false);\r
5257 });\r
5258\r
5259 it("should show a horizontal and vertical scrollbar if the old content did not require it", function() {\r
5260 makeScrollGrid([{\r
5261 width: 495\r
5262 }, {\r
5263 width: 495\r
5264 }], 1);\r
5265 expectScroll(false, false);\r
5266 store.loadData(makeRows(scrollRowSize + 1));\r
5267 // Horizontal overflow does not happen unless the vertical scrollbar took up the remaining 10px\r
5268 expectScroll(true, scrollbarsTakeSpace);\r
5269 });\r
5270 });\r
5271\r
5272 describe("flexed columns", function() {\r
5273 it("should not show a vertical scrollbar if there is no overflow", function() {\r
5274 makeScrollGrid([{\r
5275 flex: 1\r
5276 }, {\r
5277 flex: 1\r
5278 }], 1);\r
5279 expectScroll(false, false);\r
5280 expectColumnWidths([500, 500]);\r
5281 store.loadData(makeRows(2));\r
5282 expect(false, false);\r
5283 expectColumnWidths([500, 500]);\r
5284 });\r
5285\r
5286 it("should retain a vertical scrollbar if overflow exists", function() {\r
5287 makeScrollGrid([{\r
5288 flex: 1\r
5289 }, {\r
5290 flex: 1\r
5291 }], scrollRowSize);\r
5292 expectScroll(true, false);\r
5293 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
5294 store.loadData(makeRows(scrollRowSize + 20));\r
5295 expect(true, false);\r
5296 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
5297 });\r
5298\r
5299 it("should not show a vertical scrollbar if the new content does not require it", function() {\r
5300 makeScrollGrid([{\r
5301 flex: 1\r
5302 }, {\r
5303 flex: 1\r
5304 }], scrollRowSize);\r
5305 expectScroll(true, false);\r
5306 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
5307 store.loadData(makeRows(1));\r
5308 expectScroll(false, false);\r
5309 expectColumnWidths([500, 500]);\r
5310 });\r
5311\r
5312 it("should show a vertical scrollbar if the old content did not require it", function() {\r
5313 makeScrollGrid([{\r
5314 flex: 1\r
5315 }, {\r
5316 flex: 1\r
5317 }], 1);\r
5318 expectScroll(false, false);\r
5319 expectColumnWidths([500, 500]);\r
5320 store.loadData(makeRows(scrollRowSize));\r
5321 expectScroll(true, false);\r
5322 expectColumnWidths(scrollbarsTakeSpace ? [490, 490] : [500, 500]);\r
5323 });\r
5324 });\r
5325\r
5326 describe("fixed width + flexed columns", function() {\r
5327 it("should not show a vertical scrollbar if there is no overflow", function() {\r
5328 makeScrollGrid([{\r
5329 width: 300\r
5330 }, {\r
5331 flex: 1\r
5332 }], 1);\r
5333 expectScroll(false, false);\r
5334 expectColumnWidths([300, 700]);\r
5335 store.loadData(makeRows(2));\r
5336 expect(false, false);\r
5337 expectColumnWidths([300, 700]);\r
5338 });\r
5339\r
5340 it("should retain a vertical scrollbar if overflow exists", function() {\r
5341 makeScrollGrid([{\r
5342 width: 300\r
5343 }, {\r
5344 flex: 1\r
5345 }], scrollRowSize);\r
5346 expectScroll(true, false);\r
5347 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
5348 store.loadData(makeRows(scrollRowSize + 20));\r
5349 expect(true, false);\r
5350 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
5351 });\r
5352\r
5353 it("should not show a vertical scrollbar if the new content does not require it", function() {\r
5354 makeScrollGrid([{\r
5355 width: 300\r
5356 }, {\r
5357 flex: 1\r
5358 }], scrollRowSize);\r
5359 expectScroll(true, false);\r
5360 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
5361 store.loadData(makeRows(1));\r
5362 expectScroll(false, false);\r
5363 expectColumnWidths([300, 700]);\r
5364 });\r
5365\r
5366 it("should show a vertical scrollbar if the old content did not require it", function() {\r
5367 makeScrollGrid([{\r
5368 width: 300\r
5369 }, {\r
5370 flex: 1\r
5371 }], 1);\r
5372 expectScroll(false, false);\r
5373 expectColumnWidths([300, 700]);\r
5374 store.loadData(makeRows(scrollRowSize));\r
5375 expectScroll(true, false);\r
5376 expectColumnWidths(scrollbarsTakeSpace ? [300, 680] : [300, 700]);\r
5377 });\r
5378 });\r
5379 });\r
5380 });\r
5381\r
5382 describe("header sizing", function() {\r
5383 function expectHeaderWidth(width) {\r
5384 expect(gridRef.headerCt.getLayout().innerCt.getWidth()).toBe(width);\r
5385 }\r
5386\r
5387 describe("with no vertical and no horizontal scroll", function() {\r
5388 visibleScrollbarsIt("should stretch to the grid size", function() {\r
5389 makeScrollGrid([{\r
5390 width: 300\r
5391 }], 1);\r
5392 expectHeaderWidth(1000);\r
5393 });\r
5394 });\r
5395\r
5396 describe("with no vertical and horizontal scroll", function() {\r
5397 visibleScrollbarsIt("it should stretch to the full column size", function() {\r
5398 makeScrollGrid([{\r
5399 width: 600\r
5400 }, {\r
5401 width: 600\r
5402 }], 1);\r
5403 expectHeaderWidth(1200);\r
5404 });\r
5405 });\r
5406\r
5407 describe("with vertical and no horizontal scroll", function() {\r
5408 visibleScrollbarsIt("should stretch to the grid size", function() {\r
5409 makeScrollGrid([{\r
5410 width: 300\r
5411 }], 100);\r
5412 expectHeaderWidth(1000);\r
5413 });\r
5414 });\r
5415\r
5416 describe("with vertical and horizontal scroll", function() {\r
5417 visibleScrollbarsIt("should account for the vertical scrollbar", function() {\r
5418 makeScrollGrid([{\r
5419 width: 600\r
5420 }, {\r
5421 width: 600\r
5422 }], 100);\r
5423 expectHeaderWidth(1220);\r
5424 });\r
5425\r
5426 // EXTJS-15789\r
5427 xdescribe("when the vertical scroll is caused by a horizontal scrollbar", function() {\r
5428 visibleScrollbarsIt("should account for the vertical scrollbar", function() {\r
5429 makeScrollGrid([{\r
5430 width: 600\r
5431 }, {\r
5432 width: 600\r
5433 }], maxRowsBeforeScroll);\r
5434 expectHeaderWidth(1220);\r
5435 });\r
5436 });\r
5437\r
5438 describe("when the horizontal scroll is caused by a vertical scrollbar", function() {\r
5439 visibleScrollbarsIt("should account for the vertical scrollbar", function() {\r
5440 makeScrollGrid([{\r
5441 width: 495\r
5442 }, {\r
5443 width: 495\r
5444 }], scrollRowSize);\r
5445 expectHeaderWidth(1010);\r
5446 });\r
5447 });\r
5448 });\r
5449 });\r
5450\r
5451 if (withLocking) {\r
5452 describe("locked side horizontal scroll place holder", function() {\r
5453 function expectLockedScroll(scroll) {\r
5454 var overflowX = grid.lockedGrid.getView().getScrollable().getX();\r
5455\r
5456 expect(overflowX).toBe(scroll ? 'scroll' : true);\r
5457 }\r
5458\r
5459 it("should show the placeholder when the normal side overflows", function() {\r
5460 makeScrollGrid([{\r
5461 width: 600\r
5462 }, {\r
5463 width: 600\r
5464 }], 1);\r
5465 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5466 expectLockedScroll(scrollbarsTakeSpace);\r
5467 });\r
5468\r
5469 it("should not show the placeholder when the normal side does not overflow", function() {\r
5470 makeScrollGrid([{\r
5471 width: 100\r
5472 }, {\r
5473 width: 300\r
5474 }], 1);\r
5475 expectLockedScroll(false);\r
5476 });\r
5477\r
5478 it("should show the placeholder when a resize causes an overflow", function() {\r
5479 makeScrollGrid([{\r
5480 width: 400\r
5481 }, {\r
5482 width: 400\r
5483 }], 1);\r
5484 expectLockedScroll(false);\r
5485 grid.setWidth(grid.getWidth() - 400);\r
5486 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5487 expectLockedScroll(scrollbarsTakeSpace);\r
5488 });\r
5489\r
5490 it("should not show the placeholder when a resize causes an underflow", function() {\r
5491 makeScrollGrid([{\r
5492 width: 600\r
5493 }, {\r
5494 width: 600\r
5495 }], 1);\r
5496 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5497 expectLockedScroll(scrollbarsTakeSpace);\r
5498 grid.setWidth(grid.getWidth() + 400);\r
5499 expectLockedScroll(false);\r
5500 });\r
5501\r
5502 describe("column operations", function() {\r
5503 it("should show the placeholder when an add causes an overflow", function() {\r
5504 makeScrollGrid([{\r
5505 width: 400\r
5506 }, {\r
5507 width: 400\r
5508 }], 1);\r
5509 expectLockedScroll(false);\r
5510 grid.normalGrid.headerCt.add({\r
5511 width: 400,\r
5512 dataIndex: 'field3'\r
5513 });\r
5514 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5515 expectLockedScroll(scrollbarsTakeSpace);\r
5516 });\r
5517\r
5518 it("should show the placeholder when a show causes an overflow", function() {\r
5519 makeScrollGrid([{\r
5520 width: 400\r
5521 }, {\r
5522 width: 400\r
5523 }, {\r
5524 width: 400,\r
5525 hidden: true\r
5526 }], 1);\r
5527 expectLockedScroll(false);\r
5528 colRef[2].show();\r
5529 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5530 expectLockedScroll(scrollbarsTakeSpace);\r
5531 });\r
5532\r
5533 it("should not show the placeholder when a remove causes an underflow", function() {\r
5534 makeScrollGrid([{\r
5535 width: 400\r
5536 }, {\r
5537 width: 400\r
5538 }, {\r
5539 width: 400\r
5540 }], 1);\r
5541 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5542 expectLockedScroll(scrollbarsTakeSpace);\r
5543 colRef[2].destroy();\r
5544 expectLockedScroll(false);\r
5545 });\r
5546\r
5547 it("should show the placeholder when a hide causes an underflow", function() {\r
5548 makeScrollGrid([{\r
5549 width: 400\r
5550 }, {\r
5551 width: 400\r
5552 }, {\r
5553 width: 400\r
5554 }], 1);\r
5555 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5556 expectLockedScroll(scrollbarsTakeSpace);\r
5557 colRef[2].hide();\r
5558 expectLockedScroll(false);\r
5559 });\r
5560 });\r
5561\r
5562 describe("store operation", function() {\r
5563 describe("adding", function() {\r
5564 it("should not show the placeholder when the add does not trigger an overflow", function() {\r
5565 makeScrollGrid([{\r
5566 width: 495\r
5567 }, {\r
5568 width: 495\r
5569 }], 1);\r
5570 expectLockedScroll(false);\r
5571 store.add({});\r
5572 expectLockedScroll(false);\r
5573 });\r
5574\r
5575 it("should retain the placeholder when the add does not trigger an underflow", function() {\r
5576 makeScrollGrid([{\r
5577 width: 495\r
5578 }, {\r
5579 width: 495\r
5580 }], scrollRowSize);\r
5581 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5582 expectLockedScroll(scrollbarsTakeSpace);\r
5583 store.add({});\r
5584 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5585 expectLockedScroll(scrollbarsTakeSpace);\r
5586 });\r
5587\r
5588 it("should show the placeholder when an add causes an overflow via a vertical scrollbar", function() {\r
5589 makeScrollGrid([{\r
5590 width: 495\r
5591 }, {\r
5592 width: 495\r
5593 }], maxRowsBeforeScroll);\r
5594 expectLockedScroll(false);\r
5595 store.add({});\r
5596 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5597 expectLockedScroll(scrollbarsTakeSpace);\r
5598 });\r
5599 });\r
5600\r
5601 describe("removing", function() {\r
5602 it("should not show the placeholder when there is no overflow", function() {\r
5603 makeScrollGrid([{\r
5604 width: 495\r
5605 }, {\r
5606 width: 495\r
5607 }], maxRowsBeforeScroll);\r
5608 expectLockedScroll(false);\r
5609 store.removeAt(0);\r
5610 expectLockedScroll(false);\r
5611 });\r
5612\r
5613 it("should retain the placeholder when the remove does not trigger an underflow", function() {\r
5614 makeScrollGrid([{\r
5615 width: 495\r
5616 }, {\r
5617 width: 495\r
5618 }], scrollRowSize);\r
5619 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5620 expectLockedScroll(scrollbarsTakeSpace);\r
5621 store.removeAt(0);\r
5622 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5623 expectLockedScroll(scrollbarsTakeSpace);\r
5624 });\r
5625\r
5626 it("should not show the placeholder when a remove causes an underflow via a vertical scrollbar", function() {\r
5627 makeScrollGrid([{\r
5628 width: 495\r
5629 }, {\r
5630 width: 495\r
5631 }], maxRowsBeforeScroll + 1);\r
5632 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5633 expectLockedScroll(scrollbarsTakeSpace);\r
5634 store.removeAt(0);\r
5635 expectLockedScroll(false);\r
5636 });\r
5637 });\r
5638\r
5639 describe("update via variableRowHeight", function() {\r
5640 it("should not show the placeholder when there is no overflow", function() {\r
5641 makeScrollGrid([{\r
5642 width: 495\r
5643 }, {\r
5644 width: 495\r
5645 }], 1);\r
5646 expectLockedScroll(false);\r
5647 store.first().set('field1', makeRowDiv(2));\r
5648 expectLockedScroll(false);\r
5649 });\r
5650\r
5651 it("should retain the placeholder when the update does not cause an overflow", function() {\r
5652 makeScrollGrid([{\r
5653 width: 495\r
5654 }, {\r
5655 width: 495\r
5656 }], maxRowsBeforeScroll, {\r
5657 height: null,\r
5658 viewConfig: {\r
5659 variableRowHeight: true\r
5660 }\r
5661 });\r
5662 grid.setHeight(grid.getHeight() + 5);\r
5663 store.first().set('field1', makeRowDiv(2));\r
5664 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5665 expectLockedScroll(scrollbarsTakeSpace);\r
5666 store.first().set('field1', '1.1');\r
5667 expectLockedScroll(false);\r
5668 });\r
5669\r
5670 it("should show the placeholder when an update causes an overflow via a vertical scrollbar", function() {\r
5671 makeScrollGrid([{\r
5672 width: 495\r
5673 }, {\r
5674 width: 495\r
5675 }], maxRowsBeforeScroll, {\r
5676 height: null,\r
5677 viewConfig: {\r
5678 variableRowHeight: true\r
5679 }\r
5680 });\r
5681 grid.setHeight(grid.getHeight() + 5);\r
5682 expectLockedScroll(false);\r
5683 store.first().set('field1', makeRowDiv(2));\r
5684 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5685 expectLockedScroll(scrollbarsTakeSpace);\r
5686 });\r
5687\r
5688 it("should not show the placeholder when an update causes an underflow via a vertical scrollbar", function() {\r
5689 var data = makeRows(maxRowsBeforeScroll);\r
5690 data[0].field1 = makeRowDiv(2);\r
5691 makeScrollGrid([{\r
5692 width: 495\r
5693 }, {\r
5694 width: 495\r
5695 }], maxRowsBeforeScroll, {\r
5696 height: null,\r
5697 viewConfig: {\r
5698 variableRowHeight: true\r
5699 }\r
5700 });\r
5701 grid.setHeight(grid.getHeight() + 5);\r
5702 store.first().set('field1', makeRowDiv(2));\r
5703 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5704 expectLockedScroll(scrollbarsTakeSpace);\r
5705 store.first().set('field1', '1.1');\r
5706 expectLockedScroll(false);\r
5707 });\r
5708 });\r
5709\r
5710 describe("loading new content", function() {\r
5711 it("should not show the placeholder if there is no overflow", function() {\r
5712 makeScrollGrid([{\r
5713 width: 495\r
5714 }, {\r
5715 width: 495\r
5716 }], 1);\r
5717 expectLockedScroll(false);\r
5718 store.loadData(makeRows(2));\r
5719 expectLockedScroll(false);\r
5720 });\r
5721\r
5722 it("should retain the placeholder if there is no underflow", function() {\r
5723 makeScrollGrid([{\r
5724 width: 495\r
5725 }, {\r
5726 width: 495\r
5727 }], scrollRowSize);\r
5728 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5729 expectLockedScroll(scrollbarsTakeSpace);\r
5730 store.loadData(makeRows(scrollRowSize + 10));\r
5731 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5732 expectLockedScroll(scrollbarsTakeSpace);\r
5733 });\r
5734\r
5735 it("should not show the placeholder when load causes an underflow", function() {\r
5736 makeScrollGrid([{\r
5737 width: 495\r
5738 }, {\r
5739 width: 495\r
5740 }], scrollRowSize);\r
5741 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5742 expectLockedScroll(scrollbarsTakeSpace);\r
5743 store.loadData(makeRows(1));\r
5744 expectLockedScroll(false);\r
5745 });\r
5746\r
5747 it("should show the placeholder when load causes an overflow", function() {\r
5748 makeScrollGrid([{\r
5749 width: 495\r
5750 }, {\r
5751 width: 495\r
5752 }], 1);\r
5753 expectLockedScroll(false);\r
5754 store.loadData(makeRows(scrollRowSize));\r
5755 // Will only turn the locked side's overflowX to 'scroll' if it has to match a space-taking scrollbar on the normal side\r
5756 expectLockedScroll(scrollbarsTakeSpace);\r
5757 });\r
5758 });\r
5759 });\r
5760 });\r
5761\r
5762 describe("scrollbars caused by height synchronization", function() {\r
5763 beforeEach(function() {\r
5764 lockedIsVariable = true;\r
5765 });\r
5766\r
5767 it("should show a vertical scrollbar if the locked content cause overflow", function() {\r
5768 var data = makeRows(maxRowsBeforeScroll);\r
5769 data[0].field10 = makeRowDiv(2);\r
5770 makeScrollGrid([{\r
5771 width: 100\r
5772 }, {\r
5773 width: 300\r
5774 }], data);\r
5775 expectScroll(true, false);\r
5776 });\r
5777\r
5778 it("should show a vertical scrollbar if adding causes overflow", function() {\r
5779 makeScrollGrid([{\r
5780 width: 100\r
5781 }, {\r
5782 width: 300\r
5783 }], maxRowsBeforeScroll - 1);\r
5784 expectScroll(false, false);\r
5785 store.add({\r
5786 field10: makeRowDiv(2)\r
5787 });\r
5788 expectScroll(true, false);\r
5789 });\r
5790\r
5791 it("should not show a vertical scrollbar if remving causes underflow", function() {\r
5792 var data = makeRows(maxRowsBeforeScroll);\r
5793 data[0].field10 = makeRowDiv(2);\r
5794 makeScrollGrid([{\r
5795 width: 100\r
5796 }, {\r
5797 width: 300\r
5798 }], data);\r
5799 expectScroll(true, false);\r
5800 store.removeAt(0);\r
5801 expectScroll(false, false);\r
5802 });\r
5803\r
5804 it("should show a vertical scrollbar if update causes an overflow", function() {\r
5805 makeScrollGrid([{\r
5806 width: 100\r
5807 }, {\r
5808 width: 300\r
5809 }], maxRowsBeforeScroll);\r
5810 expectScroll(false, false);\r
5811 store.first().set('field10', makeRowDiv(2));\r
5812 expectScroll(true, false);\r
5813 });\r
5814\r
5815 it("should not show a vertical scrollbar if update causes an underflow", function() {\r
5816 var data = makeRows(maxRowsBeforeScroll);\r
5817 data[0].field10 = makeRowDiv(2);\r
5818 makeScrollGrid([{\r
5819 width: 100\r
5820 }, {\r
5821 width: 300\r
5822 }], data);\r
5823 expectScroll(true, false);\r
5824 store.first().set('field10', '1.1');\r
5825 expectScroll(false, false);\r
5826 });\r
5827 });\r
5828 }\r
5829 });\r
5830 }\r
5831 makeScrollSuite(false);\r
5832 makeScrollSuite(true);\r
5833 });\r
5834\r
5835 describe('disable/enable grids', function() {\r
5836 it('should disable single grids', function() {\r
5837 makeGrid();\r
5838 grid.disable();\r
5839\r
5840 expect(grid.isMasked()).toBe(true);\r
5841 expect(grid.headerCt.disabled).toBe(true);\r
5842 expect(grid.headerCt.isMasked()).toBeFalsy();\r
5843 expect(grid.headerCt.el.dom.getAttribute('tabIndex')).toBe('-1');\r
5844 \r
5845 grid.enable();\r
5846 expect(grid.isMasked()).toBeFalsy();\r
5847 expect(grid.headerCt.disabled).toBe(false);\r
5848 expect(grid.headerCt.isMasked()).toBeFalsy();\r
5849 expect(grid.headerCt.el.dom.getAttribute('tabIndex')).toBe('0');\r
5850 });\r
5851 \r
5852 it('should disable locking grids', function() {\r
5853 makeGrid(null, undefined, null, null, true);\r
5854 grid.disable();\r
5855\r
5856 // Outermost grid should be masked\r
5857 expect(grid.isMasked()).toBe(true);\r
5858\r
5859 // Locked side\r
5860 expect(grid.lockedGrid.isMasked()).toBeFalsy();\r
5861 expect(grid.lockedGrid.headerCt.disabled).toBe(true);\r
5862 expect(grid.lockedGrid.headerCt.isMasked()).toBeFalsy();\r
5863 expect(grid.lockedGrid.headerCt.el.dom.getAttribute('tabIndex')).toBe('-1');\r
5864\r
5865 // Normal side\r
5866 expect(grid.normalGrid.isMasked()).toBeFalsy();\r
5867 expect(grid.normalGrid.headerCt.disabled).toBe(true);\r
5868 expect(grid.normalGrid.headerCt.isMasked()).toBeFalsy();\r
5869 expect(grid.normalGrid.headerCt.el.dom.getAttribute('tabIndex')).toBe('-1');\r
5870 \r
5871 grid.enable();\r
5872\r
5873 // Outermost grid should not be masked\r
5874 expect(grid.isMasked()).toBeFalsy();\r
5875\r
5876 // Locked side\r
5877 expect(grid.lockedGrid.isMasked()).toBeFalsy();\r
5878 expect(grid.lockedGrid.headerCt.disabled).toBe(false);\r
5879 expect(grid.lockedGrid.headerCt.isMasked()).toBeFalsy();\r
5880 expect(grid.lockedGrid.headerCt.el.dom.getAttribute('tabIndex')).toBe('0');\r
5881\r
5882 // Normal side\r
5883 expect(grid.normalGrid.isMasked()).toBeFalsy();\r
5884 expect(grid.normalGrid.headerCt.disabled).toBe(false);\r
5885 expect(grid.normalGrid.headerCt.isMasked()).toBeFalsy();\r
5886 expect(grid.normalGrid.headerCt.el.dom.getAttribute('tabIndex')).toBe('0');\r
5887 });\r
5888 });\r
5889\r
5890 describe('disable/enable grid views', function() {\r
5891 it('should only disable the view when view.disable is called', function() {\r
5892 makeGrid();\r
5893 grid.view.disable();\r
5894\r
5895 expect(grid.disabled).toBe(false);\r
5896 expect(grid.isMasked()).toBeFalsy();\r
5897 expect(grid.view.disabled).toBe(true);\r
5898 expect(grid.view.isMasked()).toBe(true);\r
5899\r
5900 grid.view.enable();\r
5901\r
5902 expect(grid.disabled).toBe(false);\r
5903 expect(grid.isMasked()).toBeFalsy();\r
5904 expect(grid.view.disabled).toBe(false);\r
5905 expect(grid.view.isMasked()).toBeFalsy();\r
5906 });\r
5907\r
5908 it('should disable both views in a locking grid when view.disable is alled on a locking grid', function() {\r
5909 makeGrid(null, undefined, null, null, true);\r
5910 grid.view.disable();\r
5911 \r
5912 expect(grid.disabled).toBe(false);\r
5913 expect(grid.isMasked()).toBeFalsy();\r
5914\r
5915 expect(grid.normalGrid.disabled).toBe(false);\r
5916 expect(grid.normalGrid.isMasked()).toBeFalsy();\r
5917 expect(grid.normalGrid.headerCt.disabled).toBe(false);\r
5918 expect(grid.normalGrid.headerCt.isMasked()).toBeFalsy();\r
5919\r
5920 expect(grid.lockedGrid.disabled).toBe(false);\r
5921 expect(grid.lockedGrid.isMasked()).toBeFalsy();\r
5922 expect(grid.lockedGrid.headerCt.disabled).toBe(false);\r
5923 expect(grid.lockedGrid.headerCt.isMasked()).toBeFalsy();\r
5924 \r
5925 expect(grid.normalGrid.view.disabled).toBe(true);\r
5926 expect(grid.normalGrid.view.isMasked()).toBeTruthy();\r
5927 expect(grid.lockedGrid.view.disabled).toBe(true);\r
5928 expect(grid.lockedGrid.view.isMasked()).toBeTruthy();\r
5929\r
5930 grid.view.enable();\r
5931 \r
5932 expect(grid.disabled).toBe(false);\r
5933 expect(grid.isMasked()).toBeFalsy();\r
5934\r
5935 expect(grid.normalGrid.disabled).toBe(false);\r
5936 expect(grid.normalGrid.isMasked()).toBeFalsy();\r
5937 expect(grid.normalGrid.headerCt.disabled).toBe(false);\r
5938 expect(grid.normalGrid.headerCt.isMasked()).toBeFalsy();\r
5939\r
5940 expect(grid.lockedGrid.disabled).toBe(false);\r
5941 expect(grid.lockedGrid.isMasked()).toBeFalsy();\r
5942 expect(grid.lockedGrid.headerCt.disabled).toBe(false);\r
5943 expect(grid.lockedGrid.headerCt.isMasked()).toBeFalsy();\r
5944 \r
5945 expect(grid.normalGrid.view.disabled).toBe(false);\r
5946 expect(grid.normalGrid.view.isMasked()).toBeFalsy();\r
5947 expect(grid.lockedGrid.view.disabled).toBe(false);\r
5948 expect(grid.lockedGrid.view.isMasked()).toBeFalsy();\r
5949 });\r
5950 });\r
5951 });\r
5952 \r
5953 if (buffered) {\r
5954 describe('cellWrap: true column width changing halfway down buffer rendered large dataset', function() {\r
5955 var i,\r
5956 data = [],\r
5957 lorem = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.",\r
5958 loremLen = lorem.length,\r
5959 minLen = loremLen - 100,\r
5960 store,\r
5961 grid,\r
5962 view,\r
5963 bufferedRenderer,\r
5964 rrSpy;\r
5965\r
5966 for (i = 0; i < 500; i++) {\r
5967 data.push(['Row ' + (i + 1), lorem.substr(0, Ext.Number.randomInt(minLen, loremLen))]);\r
5968 }\r
5969 afterEach(function() {\r
5970 Ext.destroy(store, grid);\r
5971 });\r
5972\r
5973 it('should adjust view body position if column width change causes body to move out of view', function() {\r
5974 store = new Ext.data.ArrayStore({\r
5975 data: data,\r
5976 fields: ['row', 'lorem']\r
5977 });\r
5978\r
5979 grid = new Ext.grid.Panel({\r
5980 height: 300,\r
5981 width: 400,\r
5982 title: 'Test',\r
5983 store: store,\r
5984 buffered: true,\r
5985 columns: [{\r
5986 text: 'Row',\r
5987 dataIndex: 'row',\r
5988 width: 50\r
5989 }, {\r
5990 text: 'Lorem',\r
5991 dataIndex: 'lorem',\r
5992 flex: 1,\r
5993 cellWrap: true\r
5994 }],\r
5995 renderTo: document.body\r
5996 });\r
5997 view = grid.view;\r
5998 bufferedRenderer = view.bufferedRenderer;\r
5999 bufferedRenderer.scrollTo(100);\r
6000\r
6001 rrSpy = spyOn(bufferedRenderer, "renderRange").andCallThrough();\r
6002\r
6003 // Widen and then shrink that first column\r
6004 grid.getVisibleColumnManager().getColumns()[0].setWidth(150);\r
6005 grid.getVisibleColumnManager().getColumns()[0].setWidth(50);\r
6006\r
6007 // BufferedRenderer#setViewSize just adds/remove records\r
6008 expect(rrSpy.callCount).toBe(0);\r
6009\r
6010 // Body top must be above the top of the viewport\r
6011 expect(bufferedRenderer.bodyTop).toBeLessThan(bufferedRenderer.scrollTop);\r
6012\r
6013 // The body bottom must be below the bottom of the viewport\r
6014 expect(bufferedRenderer.bodyTop + view.body.dom.offsetHeight).toBeGreaterThan(bufferedRenderer.scrollTop + view.el.dom.clientHeight);\r
6015\r
6016 // Remove all but the last record\r
6017 store.removeAt(0, 498);\r
6018\r
6019 // BufferedRenderer#setViewSize just adds/remove records\r
6020 expect(rrSpy.callCount).toBe(0);\r
6021\r
6022 // Should move the rendered range to top if the viewSize >= storeCount\r
6023 expect(bufferedRenderer.bodyTop).toBe(0);\r
6024 });\r
6025 \r
6026 it("should not refresh if the rendered view is positioned at the start", function() {\r
6027 store = new Ext.data.ArrayStore({\r
6028 data: data,\r
6029 fields: ['row', 'lorem']\r
6030 });\r
6031\r
6032 grid = new Ext.grid.Panel({\r
6033 height: 300,\r
6034 width: 400,\r
6035 title: 'Test',\r
6036 store: store,\r
6037 buffered: true,\r
6038 columns: [{\r
6039 text: 'Row',\r
6040 dataIndex: 'row',\r
6041 width: 50\r
6042 }, {\r
6043 text: 'Lorem',\r
6044 dataIndex: 'lorem',\r
6045 flex: 1,\r
6046 cellWrap: true\r
6047 }],\r
6048 renderTo: document.body\r
6049 });\r
6050 view = grid.view;\r
6051 bufferedRenderer = view.bufferedRenderer;\r
6052 rrSpy = spyOn(bufferedRenderer, "renderRange").andCallThrough();\r
6053\r
6054 // Widen and then shrink that first column\r
6055 grid.getVisibleColumnManager().getColumns()[0].setWidth(150);\r
6056 grid.getVisibleColumnManager().getColumns()[0].setWidth(50);\r
6057\r
6058 // Nothing happened\r
6059 expect(bufferedRenderer.bodyTop).toBe(0);\r
6060 expect(rrSpy.callCount).toBe(0);\r
6061 });\r
6062 });\r
6063 }\r
6064 }\r
6065 createSuite(false);\r
6066 createSuite(true);\r
6067\r
6068 describe('Locking configuration', function () {\r
6069 var store;\r
6070\r
6071 function createGrid(cfg) {\r
6072 grid = new Ext.grid.Panel(Ext.apply({\r
6073 title: 'Test',\r
6074 height: 300,\r
6075 width: 400,\r
6076 renderTo: document.body,\r
6077 store: store,\r
6078 columns: [{\r
6079 text: 'Row',\r
6080 dataIndex: 'row',\r
6081 locked: true,\r
6082 width: 50\r
6083 }, {\r
6084 text: 'Lorem',\r
6085 dataIndex: 'lorem'\r
6086 }]\r
6087 }, cfg));\r
6088 }\r
6089\r
6090 beforeEach(function () {\r
6091 store = new Ext.data.ArrayStore({\r
6092 data: [\r
6093 [ 1, 'Lorem'],\r
6094 [ 2, 'Ipsum'],\r
6095 [ 3, 'Dolor']\r
6096 ],\r
6097 fields: ['row', 'lorem']\r
6098 })\r
6099 });\r
6100\r
6101 describe('on init', function () {\r
6102 beforeEach(function () {\r
6103 createGrid({\r
6104 enableColumnHide: true,\r
6105 rowLines: true,\r
6106 enableColumnMove: false,\r
6107 normalGridConfig: {\r
6108 enableColumnHide: false\r
6109 },\r
6110 lockedGridConfig: {\r
6111 rowLines: false\r
6112 }\r
6113 });\r
6114 });\r
6115\r
6116 it('should pass down configs to normalGrid', function () {\r
6117 expect(grid.enableColumnMove).toBe(false);\r
6118 expect(grid.normalGrid.enableColumnMove).toBe(false);\r
6119 });\r
6120\r
6121 it('should pass down configs to lockedGrid', function () {\r
6122 expect(grid.enableColumnMove).toBe(false);\r
6123 expect(grid.lockedGrid.enableColumnMove).toBe(false);\r
6124 });\r
6125\r
6126 it('should not pass down configs specified in normalGridConfig', function () {\r
6127 expect(grid.enableColumnHide).toBe(true);\r
6128 expect(grid.normalGrid.enableColumnHide).toBe(false);\r
6129 });\r
6130\r
6131 it('should not pass down configs specified in lockedGridConfig', function () {\r
6132 expect(grid.rowLines).toBe(true);\r
6133 expect(grid.lockedGrid.rowLines).toBe(false);\r
6134 });\r
6135 });\r
6136\r
6137 describe('when stateful', function () {\r
6138 afterEach(function () {\r
6139 Ext.state.Manager.set(grid.getStateId(), null);\r
6140 });\r
6141\r
6142 describe('retaining state across page loads', function () {\r
6143 function makeGrid(stateId) {\r
6144 createGrid({\r
6145 columns: [{\r
6146 text: 'Row',\r
6147 dataIndex: 'row',\r
6148 locked: true,\r
6149 width: 50\r
6150 }, {\r
6151 text: 'Lorem',\r
6152 stateId: stateId || null,\r
6153 dataIndex: 'lorem'\r
6154 }],\r
6155 stateful: true,\r
6156 stateId: 'foo'\r
6157 });\r
6158 }\r
6159\r
6160 function saveAndRecreate(stateId) {\r
6161 grid.saveState();\r
6162 Ext.destroy(grid);\r
6163\r
6164 // After page refresh.\r
6165 makeGrid(stateId);\r
6166 }\r
6167\r
6168 function testStateId(stateId) {\r
6169 var maybe = !!stateId ? '' : 'not';\r
6170\r
6171 describe('when columns are ' + maybe + ' configured with a stateId', function () {\r
6172 function testLockingPartner(which) {\r
6173 describe(which + ' locking partner', function () {\r
6174 var partner = which + 'Grid';\r
6175\r
6176 beforeEach(function () {\r
6177 makeGrid(stateId);\r
6178 });\r
6179\r
6180 it('should retain column width', function () {\r
6181 grid[partner].columnManager.getColumns()[0].setWidth(250);\r
6182 saveAndRecreate(stateId);\r
6183\r
6184 expect(grid[partner].columnManager.getColumns()[0].getWidth()).toBe(250);\r
6185 });\r
6186\r
6187 it('should retain column visibility', function () {\r
6188 grid[partner].columnManager.getColumns()[0].hide();\r
6189 saveAndRecreate(stateId);\r
6190\r
6191 expect(grid[partner].columnManager.getColumns()[0].hidden).toBe(true);\r
6192 });\r
6193\r
6194 it('should retain the column sort', function () {\r
6195 var column = grid[partner].columnManager.getColumns()[0];\r
6196\r
6197 column.sort();\r
6198 expect(column.sortState).toBe('ASC');\r
6199\r
6200 // Let's sort again.\r
6201 column.sort();\r
6202\r
6203 saveAndRecreate(stateId);\r
6204\r
6205 expect(grid[partner].columnManager.getColumns()[0].sortState).toBe('DESC');\r
6206 });\r
6207 });\r
6208 }\r
6209\r
6210 testLockingPartner('locked');\r
6211 testLockingPartner('normal');\r
6212 });\r
6213 }\r
6214\r
6215 testStateId('theOwlHouse');\r
6216 testStateId(null);\r
6217 });\r
6218 });\r
6219 });\r
6220\r
6221 describe('BufferedStore asynchronous loading timing with rendering and preserveScrollOnReload: true', function() {\r
6222 var view,\r
6223 bufferedRenderer,\r
6224 scroller,\r
6225 scrollSize,\r
6226 scrollEventCount,\r
6227 scrollRequestCount,\r
6228 TestModel = Ext.define(null, {\r
6229 extend: 'Ext.data.Model',\r
6230 fields: [\r
6231 'title', 'forumtitle', 'forumid', 'username', {\r
6232 name: 'replycount',\r
6233 type: 'int'\r
6234 }, {\r
6235 name: 'lastpost',\r
6236 mapping: 'lastpost',\r
6237 type: 'date',\r
6238 dateFormat: 'timestamp'\r
6239 },\r
6240 'lastposter', 'excerpt', 'threadid'\r
6241 ],\r
6242 idProperty: 'threadid'\r
6243 });\r
6244\r
6245 function getData(start, limit) {\r
6246 var end = start + limit,\r
6247 recs = [],\r
6248 i;\r
6249\r
6250 for (i = start; i < end; ++i) {\r
6251 recs.push({\r
6252 threadid: i,\r
6253 title: 'Title' + i\r
6254 });\r
6255 }\r
6256 return recs;\r
6257 }\r
6258\r
6259 function satisfyRequests(total) {\r
6260 var requests = Ext.Ajax.mockGetAllRequests(),\r
6261 request, params, data;\r
6262\r
6263 while (requests.length) {\r
6264 request = requests[0];\r
6265\r
6266 params = request.options.params;\r
6267 data = getData(params.start, params.limit);\r
6268\r
6269 Ext.Ajax.mockComplete({\r
6270 status: 200,\r
6271 responseText: Ext.encode({\r
6272 total: total || 5000,\r
6273 data: data\r
6274 })\r
6275 });\r
6276\r
6277 requests = Ext.Ajax.mockGetAllRequests();\r
6278 }\r
6279 }\r
6280\r
6281 function satisfyRequestsForPages(pages, total) {\r
6282 var requests = Ext.Ajax.mockGetAllRequests(),\r
6283 i, len, request, params, data;\r
6284\r
6285 for (i = 0, len = requests.length; i < len; i++) {\r
6286 request = requests[i];\r
6287 params = request.options.params;\r
6288 \r
6289 if (Ext.Array.contains(pages, params.page)) {\r
6290 data = getData(params.start, params.limit);\r
6291\r
6292 Ext.Ajax.mockComplete({\r
6293 status: 200,\r
6294 responseText: Ext.encode({\r
6295 total: total || 5000,\r
6296 data: data\r
6297 })\r
6298 }, request.id);\r
6299 }\r
6300 }\r
6301 }\r
6302\r
6303 beforeEach(function() {\r
6304 MockAjaxManager.addMethods();\r
6305\r
6306 store = new Ext.data.BufferedStore({\r
6307 model: TestModel,\r
6308 pageSize: 50,\r
6309 trailingBufferZone: 50,\r
6310 leadingBufferZone: 50,\r
6311 proxy: {\r
6312 type: 'ajax',\r
6313 url: 'fakeUrl',\r
6314 reader: {\r
6315 type: 'json',\r
6316 rootProperty: 'data'\r
6317 }\r
6318 }\r
6319 });\r
6320 store.loadPage(1);\r
6321 satisfyRequests();\r
6322\r
6323 scrollEventCount = 0;\r
6324 grid = new Ext.grid.Panel({\r
6325 columns: [{\r
6326 text: 'Title',\r
6327 dataIndex: 'title'\r
6328 }],\r
6329 store: store,\r
6330 width: 600,\r
6331 height: 300,\r
6332 border: false,\r
6333 viewConfig: {\r
6334 preserveScrollOnReload: true,\r
6335 mouseOverOutBuffer: 0,\r
6336 listeners: {\r
6337 scroll: function() {\r
6338 scrollEventCount++;\r
6339 }\r
6340 }\r
6341 },\r
6342 renderTo: document.body,\r
6343 selModel: {\r
6344 pruneRemoved: false\r
6345 }\r
6346 });\r
6347 view = grid.getView();\r
6348 bufferedRenderer = view.bufferedRenderer;\r
6349 scroller = view.getScrollable();\r
6350 scrollSize = (bufferedRenderer.viewSize * 2 + store.leadingBufferZone + store.trailingBufferZone) * bufferedRenderer.rowHeight;\r
6351\r
6352 // Load inline in the scroll event\r
6353 bufferedRenderer.scrollToLoadBuffer = 0;\r
6354 \r
6355 scrollRequestCount = 0;\r
6356 });\r
6357\r
6358 afterEach(function() {\r
6359 MockAjaxManager.removeMethods();\r
6360 });\r
6361\r
6362 it('should render maintain selection when returning to a page with a previously selected record in it', function() {\r
6363\r
6364 // Select record 0.\r
6365 // We plan to evict this page, but maintain that record as selected.\r
6366 view.getSelectionModel().select(0);\r
6367\r
6368 // It should tolerate the focused record being evicted from the page cache.\r
6369 view.getNavigationModel().setPosition(0, 0);\r
6370\r
6371 // Scroll to new areas of dataset.\r
6372 // Satisfy page requests as they arrive so that\r
6373 // old pages are evicted.\r
6374 waitsFor(function() {\r
6375 satisfyRequests();\r
6376\r
6377 if (scrollEventCount === scrollRequestCount) {\r
6378 // Scroll, until page 1 has been evicted\r
6379 if (!store.data.peekPage(1)) {\r
6380 return true;\r
6381 }\r
6382 view.scrollBy(null, 100);\r
6383 scrollRequestCount++;\r
6384 }\r
6385 }, 'Page one to have been purged from the PageCache', 20000);\r
6386\r
6387 runs(function() {\r
6388 scrollEventCount = 0;\r
6389 scroller.scrollTo(0, 0);\r
6390 });\r
6391 \r
6392 waitsFor(function() {\r
6393 return scrollEventCount === 1;\r
6394 }, 'A scroll event to fire', 20000);\r
6395 runs(function() {\r
6396 satisfyRequests();\r
6397\r
6398 // First record still selected\r
6399 expect(view.all.item(0).hasCls(Ext.baseCSSPrefix + 'grid-item-selected')).toBe(true);\r
6400 });\r
6401 });\r
6402\r
6403 it('should render page 1, and page 1 should still be in the page cache when returning to page 1 after scrolling down', function() {\r
6404 // Scroll to new areas of dataset.\r
6405 // Will queue a lot of page requests which we will satisfy in a while\r
6406 waitsFor(function() {\r
6407 // Scroll until we have 20 page requests outstanding\r
6408 if (Ext.Ajax.mockGetAllRequests().length > 20) {\r
6409 return true;\r
6410 }\r
6411\r
6412 if (scrollEventCount === scrollRequestCount) {\r
6413 view.scrollBy(null, scrollSize);\r
6414 scrollRequestCount++;\r
6415 }\r
6416 });\r
6417\r
6418 runs(function() {\r
6419 scrollEventCount = 0;\r
6420 scroller.scrollTo(0, 0);\r
6421 });\r
6422 \r
6423 waitsFor(function() {\r
6424 return scrollEventCount === 1;\r
6425 });\r
6426 runs(function() {\r
6427 satisfyRequests();\r
6428\r
6429 // Page 1 should be rendered at position zero since we scrolled back to the top\r
6430 expect(getViewTop(view.body)).toBe(0);\r
6431\r
6432 // Page 1 should still be in the page map, NOT purged out by the arrival of all\r
6433 // the other pages from the visited areas of the dataset.\r
6434 expect(store.data.hasPage(1)).toBe(true);\r
6435 });\r
6436 });\r
6437\r
6438 it('Page 1 should still be rendered, and page 1 should still be in the page cache when returning to page 1 after scrolling down with only buffer zone pages loaded into store during scroll', function() {\r
6439 // Scroll to new areas of dataset.\r
6440 // Will queue a lot of page requests which we will satisfy in a while\r
6441 waitsFor(function() {\r
6442 // Scroll until we have 20 page requests outstanding\r
6443 if (Ext.Ajax.mockGetAllRequests().length > 20) {\r
6444 return true;\r
6445 }\r
6446\r
6447 if (scrollEventCount === scrollRequestCount) {\r
6448 view.scrollBy(null, scrollSize);\r
6449 scrollRequestCount++;\r
6450 }\r
6451 });\r
6452\r
6453 runs(function() {\r
6454 scrollEventCount = 0;\r
6455 scroller.scrollTo(0, 0);\r
6456 });\r
6457 \r
6458 waitsFor(function() {\r
6459 return scrollEventCount === 1;\r
6460 });\r
6461 runs(function() {\r
6462 // Only satisfy requests for non-rendered buffer zone pages so that no rendering is done and\r
6463 // page 1 is left undisturbed in the rendered block.\r
6464 satisfyRequestsForPages([3, 6, 7, 10, 11, 13, 14, 17, 18, 21, 22, 25]);\r
6465\r
6466 // Page 1 should be rendered at position zero since we scrolled back to the top\r
6467 expect(getViewTop(view.body)).toBe(0);\r
6468\r
6469 // Page 1 should still be in the page map, NOT purged out by the arrival of all\r
6470 // the other pages from the visited areas of the dataset.\r
6471 expect(store.data.hasPage(1)).toBe(true);\r
6472 });\r
6473 });\r
6474\r
6475 it('should refresh the same rendered block on buffered store reload with preserveScrollOnReload: true', function() {\r
6476 var scrollDone,\r
6477 refreshed,\r
6478 startRow, endRow;\r
6479\r
6480 expect(view.refreshCounter).toBe(1);\r
6481\r
6482 bufferedRenderer.scrollTo(1000, {\r
6483 select: true,\r
6484 focus: true,\r
6485 callback: function() {\r
6486 scrollDone = true;\r
6487 }\r
6488 });\r
6489\r
6490 waitsFor(function() {\r
6491 satisfyRequests();\r
6492 return scrollDone;\r
6493 }, 'scroll to finish');\r
6494\r
6495 runs(function() {\r
6496 startRow = view.all.startIndex;\r
6497 endRow = view.all.endIndex;\r
6498 store.on({\r
6499 refresh: function() {\r
6500 refreshed = true;\r
6501 },\r
6502 single: true\r
6503 });\r
6504 store.reload();\r
6505 });\r
6506\r
6507 waitsFor(function() {\r
6508 satisfyRequests();\r
6509 return refreshed;\r
6510 }, 'store to reload');\r
6511\r
6512 runs(function() {\r
6513 expect(view.refreshCounter).toBe(2);\r
6514 expect(view.all.startIndex).toBe(startRow);\r
6515 expect(view.all.endIndex).toBe(endRow);\r
6516 });\r
6517 });\r
6518 });\r
6519\r
6520 describe('BufferedStore asynchronous loading timing with rendering and preserveScrollOnReload: false', function() {\r
6521 var view,\r
6522 bufferedRenderer,\r
6523 scroller,\r
6524 scrollSize,\r
6525 scrollEventCount,\r
6526 scrollRequestCount,\r
6527 TestModel = Ext.define(null, {\r
6528 extend: 'Ext.data.Model',\r
6529 fields: [\r
6530 'title', 'forumtitle', 'forumid', 'username', {\r
6531 name: 'replycount',\r
6532 type: 'int'\r
6533 }, {\r
6534 name: 'lastpost',\r
6535 mapping: 'lastpost',\r
6536 type: 'date',\r
6537 dateFormat: 'timestamp'\r
6538 },\r
6539 'lastposter', 'excerpt', 'threadid'\r
6540 ],\r
6541 idProperty: 'threadid'\r
6542 });\r
6543\r
6544 function getData(start, limit) {\r
6545 var end = start + limit,\r
6546 recs = [],\r
6547 i;\r
6548\r
6549 for (i = start; i < end; ++i) {\r
6550 recs.push({\r
6551 threadid: i,\r
6552 title: 'Title' + i\r
6553 });\r
6554 }\r
6555 return recs;\r
6556 }\r
6557\r
6558 function satisfyRequests(total) {\r
6559 var requests = Ext.Ajax.mockGetAllRequests(),\r
6560 request, params, data;\r
6561\r
6562 while (requests.length) {\r
6563 request = requests[0];\r
6564\r
6565 params = request.options.params;\r
6566 data = getData(params.start, params.limit);\r
6567\r
6568 Ext.Ajax.mockComplete({\r
6569 status: 200,\r
6570 responseText: Ext.encode({\r
6571 total: total || 5000,\r
6572 data: data\r
6573 })\r
6574 });\r
6575\r
6576 requests = Ext.Ajax.mockGetAllRequests();\r
6577 }\r
6578 }\r
6579\r
6580 function satisfyRequestsForPages(pages, total) {\r
6581 var requests = Ext.Ajax.mockGetAllRequests(),\r
6582 i, len, request, params, data;\r
6583\r
6584 for (i = 0, len = requests.length; i < len; i++) {\r
6585 request = requests[i];\r
6586 params = request.options.params;\r
6587 \r
6588 if (Ext.Array.contains(pages, params.page)) {\r
6589 data = getData(params.start, params.limit);\r
6590\r
6591 Ext.Ajax.mockComplete({\r
6592 status: 200,\r
6593 responseText: Ext.encode({\r
6594 total: total || 5000,\r
6595 data: data\r
6596 })\r
6597 }, request.id);\r
6598 }\r
6599 }\r
6600 }\r
6601\r
6602 beforeEach(function() {\r
6603 MockAjaxManager.addMethods();\r
6604\r
6605 store = new Ext.data.BufferedStore({\r
6606 model: TestModel,\r
6607 pageSize: 50,\r
6608 trailingBufferZone: 50,\r
6609 leadingBufferZone: 50,\r
6610 proxy: {\r
6611 type: 'ajax',\r
6612 url: 'fakeUrl',\r
6613 reader: {\r
6614 type: 'json',\r
6615 rootProperty: 'data'\r
6616 }\r
6617 }\r
6618 });\r
6619 store.loadPage(1);\r
6620 satisfyRequests();\r
6621\r
6622 scrollEventCount = 0;\r
6623 grid = new Ext.grid.Panel({\r
6624 columns: [{\r
6625 text: 'Title',\r
6626 dataIndex: 'title'\r
6627 }],\r
6628 store: store,\r
6629 width: 600,\r
6630 height: 300,\r
6631 border: false,\r
6632 viewConfig: {\r
6633 preserveScrollOnReload: false,\r
6634 mouseOverOutBuffer: 0,\r
6635 listeners: {\r
6636 scroll: function() {\r
6637 scrollEventCount++;\r
6638 }\r
6639 }\r
6640 },\r
6641 renderTo: document.body,\r
6642 selModel: {\r
6643 pruneRemoved: false\r
6644 }\r
6645 });\r
6646 view = grid.getView();\r
6647 bufferedRenderer = view.bufferedRenderer;\r
6648 scroller = view.getScrollable();\r
6649 scrollSize = (bufferedRenderer.viewSize * 2 + store.leadingBufferZone + store.trailingBufferZone) * bufferedRenderer.rowHeight;\r
6650\r
6651 // Load inline in the scroll event\r
6652 bufferedRenderer.scrollToLoadBuffer = 0;\r
6653 \r
6654 scrollRequestCount = 0;\r
6655 });\r
6656\r
6657 afterEach(function() {\r
6658 MockAjaxManager.removeMethods();\r
6659 });\r
6660\r
6661 it('should refresh from page 1 on buffered store reload with preserveScrollOnReload: false', function() {\r
6662 var scrollDone,\r
6663 refreshed,\r
6664 startRow, endRow;\r
6665\r
6666 expect(view.refreshCounter).toBe(1);\r
6667\r
6668 bufferedRenderer.scrollTo(1000, {\r
6669 select: true,\r
6670 focus: true,\r
6671 callback: function() {\r
6672 scrollDone = true;\r
6673 }\r
6674 });\r
6675\r
6676 waitsFor(function() {\r
6677 satisfyRequests();\r
6678 return scrollDone;\r
6679 }, 'scroll to finish');\r
6680\r
6681 runs(function() {\r
6682 startRow = view.all.startIndex;\r
6683 endRow = view.all.endIndex;\r
6684 store.on({\r
6685 refresh: function() {\r
6686 refreshed = true;\r
6687 },\r
6688 single: true\r
6689 });\r
6690 store.reload();\r
6691 });\r
6692\r
6693 waitsFor(function() {\r
6694 satisfyRequests();\r
6695 return refreshed;\r
6696 }, 'store to reload');\r
6697\r
6698 runs(function() {\r
6699 expect(view.refreshCounter).toBe(2);\r
6700 expect(view.all.startIndex).toBe(0);\r
6701 expect(view.all.endIndex).toBe(bufferedRenderer.viewSize - 1);\r
6702 });\r
6703 });\r
6704 });\r
6705\r
6706 describe('paging grid with buffered renderer', function() {\r
6707 var grid;\r
6708\r
6709 afterEach(function() {\r
6710 grid.destroy();\r
6711 });\r
6712\r
6713 it('should refresh the view on each page change', function() {\r
6714 var store, ptoolbar;\r
6715 \r
6716 runs(function() {\r
6717 function getRandomDate() {\r
6718 var from = new Date(1900, 0, 1).getTime();\r
6719 var to = new Date().getTime();\r
6720 return new Date(from + Math.random() * (to - from));\r
6721 }\r
6722\r
6723 function createFakeData(count) {\r
6724 var firstNames = ['Ed', 'Tommy', 'Aaron', 'Abe'];\r
6725 var lastNames = ['Spencer', 'Maintz', 'Conran', 'Elias'];\r
6726\r
6727 var data = [];\r
6728 for (var i = 0; i < count ; i++) {\r
6729 var dob = getRandomDate(); \r
6730 var firstNameId = Math.floor(Math.random() * firstNames.length);\r
6731 var lastNameId = Math.floor(Math.random() * lastNames.length);\r
6732 var name = Ext.String.format("{0} {1}", firstNames[firstNameId], lastNames[lastNameId]);\r
6733\r
6734 data.push([name, dob]);\r
6735 }\r
6736 return data;\r
6737 }\r
6738\r
6739 // create the Data Store\r
6740 store = Ext.create('Ext.data.Store', {\r
6741 fields: [\r
6742 'Name', 'dob'\r
6743 ],\r
6744 autoLoad: true,\r
6745 proxy: {\r
6746 type: 'memory',\r
6747 enablePaging: true,\r
6748 data: createFakeData(100),\r
6749 reader: {\r
6750 type: 'array'\r
6751 }\r
6752 },\r
6753 pageSize: 20\r
6754 });\r
6755\r
6756 grid = Ext.create('Ext.grid.Panel', {\r
6757 store: store,\r
6758 columns: [\r
6759 {text: "Name", width:120, dataIndex: 'Name'},\r
6760 {text: "dob", flex: 1, dataIndex: 'dob'}\r
6761 ], \r
6762 dockedItems: [\r
6763 ptoolbar = Ext.create('Ext.toolbar.Paging', {\r
6764 dock: 'bottom',\r
6765 store: store\r
6766 })\r
6767 ],\r
6768 renderTo: document.body,\r
6769 width: 500,\r
6770 height: 200,\r
6771 plugins: [{\r
6772 ptype: 'bufferedrenderer'\r
6773 }]\r
6774 });\r
6775 });\r
6776\r
6777 // Wait for first refresh.\r
6778 waitsFor(function() {\r
6779 return grid.view.all.getCount() === 20;\r
6780 });\r
6781 \r
6782 runs(function() {\r
6783 var refreshCount = grid.view.refreshCounter;\r
6784\r
6785 grid.view.scrollTo(0,100);\r
6786\r
6787 // Wait for the scroll event to get into the BufferedRenderer \r
6788 waitsFor(function() {\r
6789 return grid.view.bufferedRenderer.scrollTop === 100;\r
6790 });\r
6791\r
6792 runs(function() {\r
6793 jasmine.fireMouseEvent(ptoolbar.down('#next').el, 'click');\r
6794\r
6795 // Should be one more page refresh\r
6796 expect(grid.view.refreshCounter).toBe(refreshCount + 1);\r
6797\r
6798 // A new full page of 20 records should be there\r
6799 expect(grid.view.all.getCount()).toBe(20);\r
6800\r
6801 // Should have scrolled to top on view refresh\r
6802 expect(grid.view.getScrollY()).toBe(0);\r
6803 });\r
6804 });\r
6805 });\r
6806 });\r
6807\r
6808 describe('Locking a column when grid configured with enableLocking, but no locked columns', function() {\r
6809 it('should not throw an error, and should maintain scroll position', function() {\r
6810 var scrollY;\r
6811\r
6812 grid = new Ext.grid.Panel({\r
6813 renderTo: Ext.getBody(),\r
6814 width: 400,\r
6815 height: 400,\r
6816 title: 'Lock a column',\r
6817 columns: [{\r
6818 dataIndex: 'name',\r
6819 text: 'Name'\r
6820 }, {\r
6821 dataIndex: 'age',\r
6822 text: 'Age'\r
6823 }],\r
6824\r
6825 enableLocking: true,\r
6826\r
6827 store: {\r
6828 fields: [{\r
6829 name: 'name',\r
6830 type: 'string'\r
6831 }, {\r
6832 name: 'age',\r
6833 type: 'int'\r
6834 }],\r
6835 data: (function() {\r
6836 var data = [];\r
6837 var len = 44; // <-- 43 records does not trigger error\r
6838 while (len--) {\r
6839 data.unshift({\r
6840 name: 'User ' + len,\r
6841 age: Ext.Number.randomInt(0, 100)\r
6842 });\r
6843 }\r
6844 return data;\r
6845 })()\r
6846 },\r
6847 bbar: ['->', Ext.versions.extjs.version]\r
6848 });\r
6849\r
6850 // Scroll to end (ensureVisible sanitzes the inputs)\r
6851 grid.ensureVisible(100);\r
6852\r
6853 // Locked grid is hidden because there are no locked columns\r
6854 expect(grid.lockedGrid.isVisible()).toBe(false);\r
6855\r
6856 // Cache vertical scroll pos\r
6857 scrollY = grid.normalGrid.view.getScrollY();\r
6858\r
6859 grid.lock(grid.getVisibleColumnManager().getColumns()[1]);\r
6860\r
6861 // Should result in showing the locked grid\r
6862 expect(grid.lockedGrid.isVisible()).toBe(true);\r
6863\r
6864 // Scroll position should be preserved\r
6865 expect(grid.lockedGrid.view.getScrollY()).toBe(scrollY);\r
6866 });\r
6867 });\r
6868});\r