]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | describe('Ext.grid.plugin.BufferedRenderer', function () {\r |
2 | var store, grid, tree, view, plugin,\r | |
3 | synchronousLoad = true,\r | |
4 | proxyStoreLoad = Ext.data.ProxyStore.prototype.load,\r | |
5 | loadStore,\r | |
6 | treeStoreLoad = Ext.data.TreeStore.prototype.load,\r | |
7 | loadTreeStore,\r | |
8 | itIE10p = Ext.isIE9m ? xit : it;\r | |
9 | \r | |
10 | function createData(total, variableRowHeight, asymmetricRowHeight) {\r | |
11 | var data = [],\r | |
12 | i, len, n;\r | |
13 | \r | |
14 | for (i = 0, len = total || 100; i < len; i++) {\r | |
15 | n = i + 1;\r | |
16 | \r | |
17 | data.push({\r | |
18 | field1: variableRowHeight ? ('<div style="height:' + Ext.Number.randomInt(20, 40)+ 'px">' + n + '</div>') : asymmetricRowHeight ? 40 : n,\r | |
19 | field2: n,\r | |
20 | field3: n,\r | |
21 | field4: n,\r | |
22 | field5: n\r | |
23 | });\r | |
24 | }\r | |
25 | \r | |
26 | return data;\r | |
27 | }\r | |
28 | \r | |
29 | function makeData(n, start) {\r | |
30 | start = start || 1;\r | |
31 | \r | |
32 | var data = [],\r | |
33 | limit = start + n,\r | |
34 | i;\r | |
35 | \r | |
36 | for (i = start; i < limit; ++i) {\r | |
37 | data.push({\r | |
38 | id: i,\r | |
39 | name: 'name' + i\r | |
40 | });\r | |
41 | }\r | |
42 | return data;\r | |
43 | }\r | |
44 | \r | |
45 | function getData(start, limit) {\r | |
46 | var end = start + limit,\r | |
47 | recs = [],\r | |
48 | i;\r | |
49 | \r | |
50 | for (i = start; i < end; ++i) {\r | |
51 | recs.push({\r | |
52 | id: i,\r | |
53 | namee: 'name' + i\r | |
54 | });\r | |
55 | }\r | |
56 | return recs;\r | |
57 | }\r | |
58 | \r | |
59 | function satisfyRequests(total) {\r | |
60 | var requests = Ext.Ajax.mockGetAllRequests(),\r | |
61 | empty = total === 0,\r | |
62 | request, params, data;\r | |
63 | \r | |
64 | while (requests.length) {\r | |
65 | request = requests[0];\r | |
66 | \r | |
67 | params = request.options.params;\r | |
68 | data = getData(empty ? 0 : params.start, empty ? 0 : params.limit);\r | |
69 | \r | |
70 | Ext.Ajax.mockComplete({\r | |
71 | status: 200,\r | |
72 | responseText: Ext.encode({\r | |
73 | total: (total || empty) ? total : 5000,\r | |
74 | data: data\r | |
75 | })\r | |
76 | });\r | |
77 | \r | |
78 | requests = Ext.Ajax.mockGetAllRequests();\r | |
79 | }\r | |
80 | }\r | |
81 | \r | |
82 | function makeGrid(gridCfg, storeCfg) {\r | |
83 | if (!storeCfg || !storeCfg.store) {\r | |
84 | store = new Ext.data.Store(Ext.apply({\r | |
85 | fields: ['name', 'email', 'phone'],\r | |
86 | groupField: 'name',\r | |
87 | data: [\r | |
88 | {'name': 'Lisa', 'email': 'lisa@simpsons.com', 'phone': '555-111-1224', 'age': 14},\r | |
89 | {'name': 'Lisa', 'email': 'aunt_lisa@simpsons.com', 'phone': '555-111-1274', 'age': 34},\r | |
90 | {'name': 'Bart', 'email': 'bart@simpsons.com', 'phone': '555-222-1234', 'age': 12},\r | |
91 | {'name': 'Homer', 'email': 'homer@simpsons.com', 'phone': '555-222-1244', 'age': 44},\r | |
92 | {'name': 'Marge', 'email': 'marge@simpsons.com', 'phone': '555-222-1254', 'age': 41}\r | |
93 | ],\r | |
94 | autoDestroy: true\r | |
95 | }, storeCfg));\r | |
96 | } else {\r | |
97 | store = storeCfg.store;\r | |
98 | }\r | |
99 | \r | |
100 | grid = new Ext.grid.Panel(Ext.apply({\r | |
101 | columns: [\r | |
102 | {header: 'Name', dataIndex: 'name', editor: 'textfield'},\r | |
103 | {header: 'Email', dataIndex: 'email', flex:1,\r | |
104 | editor: {\r | |
105 | xtype: 'textfield',\r | |
106 | allowBlank: false\r | |
107 | }\r | |
108 | },\r | |
109 | {header: 'Phone', dataIndex: 'phone', editor: 'textfield'},\r | |
110 | {header: 'Age', dataIndex: 'age', editor: 'textfield'}\r | |
111 | ],\r | |
112 | store: store,\r | |
113 | width: 200,\r | |
114 | height: 400,\r | |
115 | renderTo: Ext.getBody()\r | |
116 | }, gridCfg));\r | |
117 | \r | |
118 | view = grid.view;\r | |
119 | \r | |
120 | // Extract the buffered renderer from a real TableView, the topmost one might be a Locking pseudo view\r | |
121 | plugin = grid.down('tableview').bufferedRenderer;\r | |
122 | }\r | |
123 | \r | |
124 | function createTreeData(count) {\r | |
125 | var i = 0,\r | |
126 | j = 0,\r | |
127 | children = [],\r | |
128 | grandKids;\r | |
129 | \r | |
130 | for (; i < count; i++) {\r | |
131 | grandKids = [];\r | |
132 | \r | |
133 | for (j = 1; j < 7; j++) {\r | |
134 | grandKids.push({\r | |
135 | treeData: 'Child of ' + i + ', number ' + j,\r | |
136 | leaf: true\r | |
137 | });\r | |
138 | }\r | |
139 | \r | |
140 | children.push({\r | |
141 | treeData: i,\r | |
142 | children: grandKids\r | |
143 | });\r | |
144 | }\r | |
145 | \r | |
146 | return {\r | |
147 | children: children\r | |
148 | };\r | |
149 | }\r | |
150 | \r | |
151 | function makeTree(treeCfg, count) {\r | |
152 | store = new Ext.data.TreeStore({\r | |
153 | fields: ['treeData'],\r | |
154 | root: createTreeData(count || 20)\r | |
155 | });\r | |
156 | \r | |
157 | tree = new Ext.tree.Panel(Ext.apply({\r | |
158 | columns: [{\r | |
159 | xtype: 'treecolumn',\r | |
160 | text: 'Tree Column',\r | |
161 | width: 300,\r | |
162 | dataIndex: 'treeData'\r | |
163 | }],\r | |
164 | height: 800,\r | |
165 | width: 500,\r | |
166 | store: store,\r | |
167 | rootVisible: false,\r | |
168 | animate: false,\r | |
169 | renderTo: Ext.getBody()\r | |
170 | }, treeCfg || {}));\r | |
171 | \r | |
172 | view = tree.view;\r | |
173 | }\r | |
174 | \r | |
175 | function completeWithData(data) {\r | |
176 | Ext.Ajax.mockComplete({\r | |
177 | status: 200,\r | |
178 | responseText: Ext.JSON.encode(data)\r | |
179 | });\r | |
180 | }\r | |
181 | \r | |
182 | beforeEach(function () {\r | |
183 | // Override so that we can control asynchronous loading\r | |
184 | loadStore = Ext.data.ProxyStore.prototype.load = function() {\r | |
185 | proxyStoreLoad.apply(this, arguments);\r | |
186 | if (synchronousLoad) {\r | |
187 | this.flushLoad.apply(this, arguments);\r | |
188 | }\r | |
189 | return this;\r | |
190 | };\r | |
191 | loadTreeStore = Ext.data.TreeStore.prototype.load = function() {\r | |
192 | treeStoreLoad.apply(this, arguments);\r | |
193 | if (synchronousLoad) {\r | |
194 | this.flushLoad.apply(this, arguments);\r | |
195 | }\r | |
196 | return this;\r | |
197 | };\r | |
198 | \r | |
199 | MockAjaxManager.addMethods();\r | |
200 | });\r | |
201 | \r | |
202 | afterEach(function () {\r | |
203 | // Undo the overrides.\r | |
204 | Ext.data.ProxyStore.prototype.load = proxyStoreLoad;\r | |
205 | Ext.data.TreeStore.prototype.load = treeStoreLoad;\r | |
206 | \r | |
207 | MockAjaxManager.removeMethods();\r | |
208 | \r | |
209 | if (grid) {\r | |
210 | Ext.destroy(grid);\r | |
211 | }\r | |
212 | \r | |
213 | if (tree) {\r | |
214 | Ext.destroy(tree);\r | |
215 | }\r | |
216 | \r | |
217 | store = grid = tree = view = plugin = null;\r | |
218 | });\r | |
219 | \r | |
220 | describe('updateing scroller when changing width', function() {\r | |
221 | it('should update the horizontal scroll range', function() {\r | |
222 | makeGrid();\r | |
223 | var scroller = view.getScrollable(),\r | |
224 | maxX = scroller.getMaxPosition().x;\r | |
225 | \r | |
226 | grid.setWidth(grid.getWidth() - 100);\r | |
227 | \r | |
228 | // The scroll range should have increased\r | |
229 | expect(scroller.getMaxPosition().x).toBe(maxX + 100);\r | |
230 | });\r | |
231 | });\r | |
232 | \r | |
233 | describe('autogenerating the plugin', function () {\r | |
234 | var BR = Ext.grid.plugin.BufferedRenderer;\r | |
235 | \r | |
236 | it('should create an instance by default', function () {\r | |
237 | makeGrid();\r | |
238 | \r | |
239 | expect(plugin instanceof BR).toBe(true);\r | |
240 | });\r | |
241 | \r | |
242 | it('should not create an instance when turned off', function () {\r | |
243 | makeGrid({\r | |
244 | bufferedRenderer: false\r | |
245 | });\r | |
246 | \r | |
247 | expect(plugin instanceof BR).toBe(false);\r | |
248 | expect(plugin).toBeUndefined();\r | |
249 | });\r | |
250 | \r | |
251 | describe('locking grids', function () {\r | |
252 | var normal, locked;\r | |
253 | \r | |
254 | afterEach(function () {\r | |
255 | normal = locked = null;\r | |
256 | });\r | |
257 | \r | |
258 | describe('init', function () {\r | |
259 | function runTests(useBR) {\r | |
260 | var not = useBR ? 'not' : '';\r | |
261 | \r | |
262 | describe('buffered rendering = ' + useBR, function () {\r | |
263 | beforeEach(function () {\r | |
264 | makeGrid({\r | |
265 | bufferedRenderer: useBR,\r | |
266 | columns: [\r | |
267 | {header: 'Name', dataIndex: 'name', editor: 'textfield'},\r | |
268 | {header: 'Phone', dataIndex: 'phone', editor: 'textfield', locked: true},\r | |
269 | {header: 'Age', dataIndex: 'age', editor: 'textfield'}\r | |
270 | ]\r | |
271 | });\r | |
272 | \r | |
273 | normal = grid.normalGrid.bufferedRenderer;\r | |
274 | locked = grid.lockedGrid.bufferedRenderer;\r | |
275 | });\r | |
276 | \r | |
277 | it('should ' + not + ' create an instance on the ownerGrid for locking grids', function () {\r | |
278 | plugin = grid.bufferedRenderer;\r | |
279 | expect(plugin instanceof BR).toBe(false);\r | |
280 | });\r | |
281 | \r | |
282 | it('should ' + not + ' create an instance by default on each child grid for locking grids', function () {\r | |
283 | expect(normal instanceof BR).toBe(useBR);\r | |
284 | expect(locked instanceof BR).toBe(useBR);\r | |
285 | });\r | |
286 | });\r | |
287 | }\r | |
288 | \r | |
289 | runTests(true);\r | |
290 | runTests(false);\r | |
291 | });\r | |
292 | \r | |
293 | describe('syncing locking partners when scrolling', function () {\r | |
294 | beforeEach(function () {\r | |
295 | makeGrid({\r | |
296 | columns: [\r | |
297 | {header: 'Name', dataIndex: 'name', editor: 'textfield', locked: true},\r | |
298 | {header: 'Email', dataIndex: 'email', flex:1,\r | |
299 | editor: {\r | |
300 | xtype: 'textfield',\r | |
301 | allowBlank: false\r | |
302 | }\r | |
303 | },\r | |
304 | {header: 'Phone', dataIndex: 'phone', editor: 'textfield'},\r | |
305 | {header: 'Age', dataIndex: 'age', editor: 'textfield'}\r | |
306 | ]\r | |
307 | }, {\r | |
308 | data: makeData(1000)\r | |
309 | });\r | |
310 | \r | |
311 | normal = grid.normalGrid.bufferedRenderer;\r | |
312 | locked = grid.lockedGrid.bufferedRenderer;\r | |
313 | });\r | |
314 | \r | |
315 | it('should fetch the range', function () {\r | |
316 | spyOn(normal, 'onRangeFetched').andCallThrough();\r | |
317 | spyOn(locked, 'onRangeFetched').andCallThrough();\r | |
318 | \r | |
319 | normal.scrollTo(500);\r | |
320 | \r | |
321 | expect(normal.onRangeFetched).toHaveBeenCalled();\r | |
322 | expect(locked.onRangeFetched).toHaveBeenCalled();\r | |
323 | });\r | |
324 | \r | |
325 | it('should sync the view els', function () {\r | |
326 | normal.scrollTo(500);\r | |
327 | \r | |
328 | expect(normal.bodyTop).toBe(locked.bodyTop);\r | |
329 | });\r | |
330 | });\r | |
331 | \r | |
332 | describe('Load requests during scrolling', function () {\r | |
333 | var scrollToLoadBufferValue,\r | |
334 | scrollTimer,\r | |
335 | Person = Ext.define(null, {\r | |
336 | extend: 'Ext.data.Model',\r | |
337 | fields: ['name'],\r | |
338 | proxy: {\r | |
339 | type: 'ajax',\r | |
340 | url: '/foo',\r | |
341 | reader: {\r | |
342 | rootProperty: 'data'\r | |
343 | }\r | |
344 | }\r | |
345 | });\r | |
346 | \r | |
347 | function scrollTheGrid() {\r | |
348 | // Scroll incrementally until the correct starting point is found\r | |
349 | if (view && !view.destroyed) {\r | |
350 | view.scrollBy(null, 100);\r | |
351 | }\r | |
352 | scrollTimer = 0;\r | |
353 | }\r | |
354 | \r | |
355 | beforeEach(function () {\r | |
356 | scrollToLoadBufferValue = Ext.grid.plugin.BufferedRenderer.prototype.scrollToLoadBuffer;\r | |
357 | \r | |
358 | // Make the timeout from attemptLoad call to the doAttemptLoad ten seconds\r | |
359 | // The doAttemptLoad DelayedTask should not fire between scroll events which take place\r | |
360 | // every 50 milliseconds\r | |
361 | Ext.grid.plugin.BufferedRenderer.prototype.scrollToLoadBuffer = 10000;\r | |
362 | makeGrid({\r | |
363 | columns: [\r | |
364 | {header: 'Name', dataIndex: 'name', editor: 'textfield'},\r | |
365 | {header: 'Phone', dataIndex: 'phone', editor: 'textfield', locked: true},\r | |
366 | {header: 'Age', dataIndex: 'age', editor: 'textfield'}\r | |
367 | ]\r | |
368 | }, {\r | |
369 | store: new Ext.data.BufferedStore({\r | |
370 | model: Person,\r | |
371 | leadingBufferZone: 300,\r | |
372 | pageSize: 100\r | |
373 | })\r | |
374 | });\r | |
375 | \r | |
376 | // Tell the BufferedRenderer that there are 1000 rows.\r | |
377 | // We plan not to satisfy any requests from now on so that\r | |
378 | // on scroll, an attemptLoad call will be made.\r | |
379 | // the timeout to doAttemptLoad should not expire during the scroll operation\r | |
380 | store.load();\r | |
381 | completeWithData({\r | |
382 | total: 1000,\r | |
383 | data: makeData(100)\r | |
384 | });\r | |
385 | completeWithData({\r | |
386 | total: 1000,\r | |
387 | data: makeData(100, 101)\r | |
388 | });\r | |
389 | completeWithData({\r | |
390 | total: 1000,\r | |
391 | data: makeData(100, 201)\r | |
392 | });\r | |
393 | completeWithData({\r | |
394 | total: 1000,\r | |
395 | data: makeData(100, 301)\r | |
396 | });\r | |
397 | });\r | |
398 | afterEach(function() {\r | |
399 | Ext.grid.plugin.BufferedRenderer.prototype.scrollToLoadBuffer = scrollToLoadBufferValue;\r | |
400 | });\r | |
401 | it('should not have time between scroll events to fire off any requests', function() {\r | |
402 | spyOn(plugin, 'doAttemptLoad');\r | |
403 | \r | |
404 | // Scroll to close enough to the end in a slow manner, 50ms between each scroll.\r | |
405 | // The doAttemptLoad timer should not timeout and fire off a page request between each scroll.\r | |
406 | waitsFor(function() {\r | |
407 | if (plugin.getLastVisibleRowIndex() <= 995) {\r | |
408 | if (!scrollTimer) {\r | |
409 | scrollTimer = setTimeout(scrollTheGrid, 50);\r | |
410 | }\r | |
411 | } else {\r | |
412 | return true;\r | |
413 | }\r | |
414 | }, 'grid to scroll to end', Ext.isIE ? 40000 : 20000);\r | |
415 | \r | |
416 | // The atteptLoad timer must never have fired during the scroll.\r | |
417 | runs(function() {\r | |
418 | expect(plugin.doAttemptLoad.callCount).toBe(0);\r | |
419 | });\r | |
420 | });\r | |
421 | });\r | |
422 | });\r | |
423 | });\r | |
424 | \r | |
425 | describe("Less data than the computed view size", function() {\r | |
426 | it("should add new rows at top while scrolled to bottom", function() {\r | |
427 | var Person = Ext.define(null, {\r | |
428 | extend: 'Ext.data.Model',\r | |
429 | fields: ['name'],\r | |
430 | proxy: {\r | |
431 | type: 'ajax',\r | |
432 | url: '/foo',\r | |
433 | reader: {\r | |
434 | rootProperty: 'data'\r | |
435 | }\r | |
436 | }\r | |
437 | });\r | |
438 | \r | |
439 | store = new Ext.data.Store({\r | |
440 | model: Person,\r | |
441 | data: makeData(12)\r | |
442 | });\r | |
443 | \r | |
444 | grid = new Ext.grid.Panel({\r | |
445 | width: 600,\r | |
446 | height: 305,\r | |
447 | store: store,\r | |
448 | deferRowRender: false,\r | |
449 | columns: [{\r | |
450 | dataIndex: 'id',\r | |
451 | renderer: function(v) {\r | |
452 | return '<span style="line-height:25px">' + v + '</span>';\r | |
453 | },\r | |
454 | producesHTML: true\r | |
455 | }, {\r | |
456 | dataIndex: 'name'\r | |
457 | }],\r | |
458 | renderTo: Ext.getBody()\r | |
459 | });\r | |
460 | view = grid.getView();\r | |
461 | \r | |
462 | // Wait until known correct condition is met.\r | |
463 | // Timeout === test failure.\r | |
464 | waitsFor(function() {\r | |
465 | if (view.all.endIndex === store.getCount() - 1) {\r | |
466 | return true;\r | |
467 | }\r | |
468 | else {\r | |
469 | // Scroll incrementally until the correct starting point is found\r | |
470 | view.scrollBy(null, 10);\r | |
471 | }\r | |
472 | }, 'view is scrolled to the last record');\r | |
473 | \r | |
474 | runs(function() {\r | |
475 | store.insert(0, {id: 666, name: 'Old Nick'});\r | |
476 | view.scrollTo(0, 0);\r | |
477 | \r | |
478 | var r0 = view.all.item(0, true);\r | |
479 | \r | |
480 | // Must have been rendered\r | |
481 | expect(r0).not.toBeNull();\r | |
482 | \r | |
483 | // The new row zero must have been rendered.\r | |
484 | expect((r0.innerText || r0.textContent).replace(/\n/g,'').replace(/\r/g,'')).toBe("666Old Nick");\r | |
485 | });\r | |
486 | });\r | |
487 | });\r | |
488 | \r | |
489 | describe("basic functionality with a buffered store", function() {\r | |
490 | it("should render rows in order", function() {\r | |
491 | var Person = Ext.define(null, {\r | |
492 | extend: 'Ext.data.Model',\r | |
493 | fields: ['name'],\r | |
494 | proxy: {\r | |
495 | type: 'ajax',\r | |
496 | url: '/foo',\r | |
497 | reader: {\r | |
498 | rootProperty: 'data'\r | |
499 | }\r | |
500 | }\r | |
501 | });\r | |
502 | \r | |
503 | store = new Ext.data.BufferedStore({\r | |
504 | model: Person,\r | |
505 | leadingBufferZone: 300,\r | |
506 | pageSize: 100\r | |
507 | });\r | |
508 | \r | |
509 | grid = new Ext.grid.Panel({\r | |
510 | width: 800,\r | |
511 | height: 500,\r | |
512 | store: store,\r | |
513 | deferRowRender: false,\r | |
514 | columns: [{\r | |
515 | dataIndex: 'id'\r | |
516 | }, {\r | |
517 | dataIndex: 'name'\r | |
518 | }],\r | |
519 | renderTo: Ext.getBody()\r | |
520 | });\r | |
521 | store.load();\r | |
522 | completeWithData({\r | |
523 | total: 5000,\r | |
524 | data: makeData(100)\r | |
525 | });\r | |
526 | completeWithData({\r | |
527 | total: 5000,\r | |
528 | data: makeData(100, 101)\r | |
529 | });\r | |
530 | completeWithData({\r | |
531 | total: 5000,\r | |
532 | data: makeData(100, 201)\r | |
533 | });\r | |
534 | completeWithData({\r | |
535 | total: 5000,\r | |
536 | data: makeData(100, 301)\r | |
537 | });\r | |
538 | var view = grid.getView(),\r | |
539 | rows = view.all;\r | |
540 | \r | |
541 | // Wait until known correct condition is met.\r | |
542 | // Timeout === test failure.\r | |
543 | waitsFor(function() {\r | |
544 | if (rows.startIndex <= 100 && rows.endIndex >= 100) {\r | |
545 | return true;\r | |
546 | }\r | |
547 | else {\r | |
548 | // Scroll incrementally until the correct starting point is found\r | |
549 | view.scrollBy(null, 10);\r | |
550 | }\r | |
551 | }, 'View to scroll record id 100 into the rendered block', 20000);\r | |
552 | \r | |
553 | runs(function() {\r | |
554 | var nodes = view.getNodes(),\r | |
555 | len = nodes.length,\r | |
556 | offset = rows.startIndex + 1,\r | |
557 | i, rec;\r | |
558 | \r | |
559 | expect(len).toBe(view.bufferedRenderer.viewSize);\r | |
560 | for (i = 0; i < len; ++i) {\r | |
561 | rec = view.getRecord(nodes[i]);\r | |
562 | expect(rec.getId()).toBe(i + offset);\r | |
563 | }\r | |
564 | \r | |
565 | });\r | |
566 | });\r | |
567 | \r | |
568 | // EXTJS-16140\r | |
569 | it("should scroll to the bottom of a locking grid with no error", function() {\r | |
570 | var Person = Ext.define(null, {\r | |
571 | extend: 'Ext.data.Model',\r | |
572 | fields: ['name'],\r | |
573 | proxy: {\r | |
574 | type: 'ajax',\r | |
575 | url: '/foo',\r | |
576 | reader: {\r | |
577 | rootProperty: 'data'\r | |
578 | }\r | |
579 | }\r | |
580 | }),\r | |
581 | lockedView,\r | |
582 | normalView,\r | |
583 | maxScroll;\r | |
584 | \r | |
585 | store = new Ext.data.BufferedStore({\r | |
586 | model: Person,\r | |
587 | leadingBufferZone: 300,\r | |
588 | pageSize: 100\r | |
589 | });\r | |
590 | \r | |
591 | grid = new Ext.grid.Panel({\r | |
592 | width: 800,\r | |
593 | height: 500,\r | |
594 | store: store,\r | |
595 | deferRowRender: false,\r | |
596 | columns: [{\r | |
597 | dataIndex: 'id',\r | |
598 | locked: true\r | |
599 | }, {\r | |
600 | dataIndex: 'name'\r | |
601 | }],\r | |
602 | renderTo: Ext.getBody()\r | |
603 | });\r | |
604 | lockedView = grid.lockedGrid.view;\r | |
605 | normalView = grid.normalGrid.view;\r | |
606 | \r | |
607 | // Make the buffered renderers respond IMMEDIATELY to the scroll event, so that\r | |
608 | // the waits(100) will be enough to wait for the newly scrolled-to region to be rendered.\r | |
609 | lockedView.bufferedRenderer.scrollToLoadBuffer = normalView.bufferedRenderer.scrollToLoadBuffer = 0;\r | |
610 | \r | |
611 | store.load();\r | |
612 | completeWithData({\r | |
613 | total: 5000,\r | |
614 | data: makeData(100)\r | |
615 | });\r | |
616 | \r | |
617 | maxScroll = normalView.getScrollable().getMaxPosition().y;\r | |
618 | normalView.setScrollY(maxScroll);\r | |
619 | \r | |
620 | // Important: Simulate Ajax delay before returning data\r | |
621 | waits(100);\r | |
622 | runs(function() {\r | |
623 | satisfyRequests();\r | |
624 | });\r | |
625 | \r | |
626 | // Both views must render up to the last row with no error thrown\r | |
627 | waitsFor(function() {\r | |
628 | return lockedView.all.endIndex === 4999 && normalView.all.endIndex === 4999;\r | |
629 | });\r | |
630 | });\r | |
631 | \r | |
632 | // EXTJS-17053\r | |
633 | it('should maintain synchronization when scrolling locked, variable row height grid with keyboard', function() {\r | |
634 | store = Ext.create('Ext.data.Store', {\r | |
635 | idProperty: 'index',\r | |
636 | fields: ['index', 'name', 'email', 'phone', 'isActive', 'eyeColor', 'company', 'gender'],\r | |
637 | autoLoad: true,\r | |
638 | data: [{\r | |
639 | "_id": "54ff69d95aa43325cc4eee9f",\r | |
640 | "index": 0,\r | |
641 | "guid": "48c42a75-09a7-4671-86a1-e9a486bee6ab",\r | |
642 | "isActive": true,\r | |
643 | "balance": "$3,457.90",\r | |
644 | "age": 20,\r | |
645 | "eyeColor": "brown",\r | |
646 | "name": "Louella Morrison",\r | |
647 | "gender": "female",\r | |
648 | "company": "ZBOO",\r | |
649 | "email": "louellamorrison@zboo.com",\r | |
650 | "phone": "+1 (803) 483-2686"\r | |
651 | }, {\r | |
652 | "_id": "54ff69d918616dbc093ca6cd",\r | |
653 | "index": 1,\r | |
654 | "guid": "17b3f923-96b5-40c9-b3c1-721485e5bf80",\r | |
655 | "isActive": true,\r | |
656 | "balance": "$1,377.85",\r | |
657 | "age": 20,\r | |
658 | "eyeColor": "brown",\r | |
659 | "name": "Madden Coffey",\r | |
660 | "gender": "male",\r | |
661 | "company": "COMDOM",\r | |
662 | "email": "maddencoffey@comdom.com",\r | |
663 | "phone": "+1 (850) 534-2345"\r | |
664 | }, {\r | |
665 | "_id": "54ff69d91a4917f9643178b0",\r | |
666 | "index": 2,\r | |
667 | "guid": "f62da049-ab17-49fd-9f4c-3439d33cbb93",\r | |
668 | "isActive": false,\r | |
669 | "balance": "$3,798.71",\r | |
670 | "age": 22,\r | |
671 | "eyeColor": "blue",\r | |
672 | "name": "Chase Crawford",\r | |
673 | "gender": "male",\r | |
674 | "company": "PYRAMAX",\r | |
675 | "email": "chasecrawford@pyramax.com",\r | |
676 | "phone": "+1 (944) 494-2920"\r | |
677 | }, {\r | |
678 | "_id": "54ff69d9a63b6103f9e1530f",\r | |
679 | "index": 3,\r | |
680 | "guid": "3640c402-f878-4f97-bbda-564de91d2dde",\r | |
681 | "isActive": true,\r | |
682 | "balance": "$2,480.02",\r | |
683 | "age": 39,\r | |
684 | "eyeColor": "blue",\r | |
685 | "name": "Johanna Pollard",\r | |
686 | "gender": "female",\r | |
687 | "company": "ZEROLOGY",\r | |
688 | "email": "johannapollard@zerology.com",\r | |
689 | "phone": "+1 (813) 512-3311"\r | |
690 | }, {\r | |
691 | "_id": "54ff69d9048722389ffde4bb",\r | |
692 | "index": 4,\r | |
693 | "guid": "361089ba-e6dc-4701-b316-c7e977b21cb2",\r | |
694 | "isActive": true,\r | |
695 | "balance": "$3,973.38",\r | |
696 | "age": 20,\r | |
697 | "eyeColor": "brown",\r | |
698 | "name": "Malone Bentley",\r | |
699 | "gender": "male",\r | |
700 | "company": "DIGIPRINT",\r | |
701 | "email": "malonebentley@digiprint.com",\r | |
702 | "phone": "+1 (905) 435-2056"\r | |
703 | }, {\r | |
704 | "_id": "54ff69d9f75a66fb8e08b335",\r | |
705 | "index": 5,\r | |
706 | "guid": "4cec529a-232a-4d5f-bedc-6141adc9f2fa",\r | |
707 | "isActive": true,\r | |
708 | "balance": "$3,956.60",\r | |
709 | "age": 21,\r | |
710 | "eyeColor": "green",\r | |
711 | "name": "Jennings Rodgers",\r | |
712 | "gender": "male",\r | |
713 | "company": "LUDAK",\r | |
714 | "email": "jenningsrodgers@ludak.com",\r | |
715 | "phone": "+1 (833) 543-2230"\r | |
716 | }, {\r | |
717 | "_id": "54ff69d974c1757e026721cb",\r | |
718 | "index": 6,\r | |
719 | "guid": "6ce0c1e1-adc6-4cd0-b9c9-e2214e63aa8f",\r | |
720 | "isActive": true,\r | |
721 | "balance": "$2,874.71",\r | |
722 | "age": 40,\r | |
723 | "eyeColor": "green",\r | |
724 | "name": "Mosley Mcgowan",\r | |
725 | "gender": "male",\r | |
726 | "company": "AMTAP",\r | |
727 | "email": "mosleymcgowan@amtap.com",\r | |
728 | "phone": "+1 (990) 486-3229"\r | |
729 | }, {\r | |
730 | "_id": "54ff69d949a3873336e2e446",\r | |
731 | "index": 7,\r | |
732 | "guid": "0f88d544-4aa0-4a05-a236-363c64b40988",\r | |
733 | "isActive": false,\r | |
734 | "balance": "$3,277.11",\r | |
735 | "age": 28,\r | |
736 | "eyeColor": "green",\r | |
737 | "name": "Patton Whitaker",\r | |
738 | "gender": "male",\r | |
739 | "company": "IMMUNICS",\r | |
740 | "email": "pattonwhitaker@immunics.com",\r | |
741 | "phone": "+1 (944) 557-2615"\r | |
742 | }, {\r | |
743 | "_id": "54ff69d917f9642ab989e999",\r | |
744 | "index": 8,\r | |
745 | "guid": "6577bb0c-f7ed-495f-a3db-7f7d35f6fe49",\r | |
746 | "isActive": false,\r | |
747 | "balance": "$1,091.47",\r | |
748 | "age": 35,\r | |
749 | "eyeColor": "green",\r | |
750 | "name": "Neal Rivera",\r | |
751 | "gender": "male",\r | |
752 | "company": "NETILITY",\r | |
753 | "email": "nealrivera@netility.com",\r | |
754 | "phone": "+1 (816) 590-2358"\r | |
755 | }, {\r | |
756 | "_id": "54ff69d94573c1c04f0a9940",\r | |
757 | "index": 9,\r | |
758 | "guid": "29be9274-d3cb-461f-a565-2374768689df",\r | |
759 | "isActive": false,\r | |
760 | "balance": "$1,885.75",\r | |
761 | "age": 25,\r | |
762 | "eyeColor": "brown",\r | |
763 | "name": "May Barron",\r | |
764 | "gender": "male",\r | |
765 | "company": "TELEPARK",\r | |
766 | "email": "maybarron@telepark.com",\r | |
767 | "phone": "+1 (958) 486-2915"\r | |
768 | }, {\r | |
769 | "_id": "54ff69d9c0e2f4aee9180984",\r | |
770 | "index": 10,\r | |
771 | "guid": "479320d7-70ef-4f55-99b9-f3ef3a76b72e",\r | |
772 | "isActive": false,\r | |
773 | "balance": "$2,031.57",\r | |
774 | "age": 36,\r | |
775 | "eyeColor": "brown",\r | |
776 | "name": "Janna Howell",\r | |
777 | "gender": "female",\r | |
778 | "company": "PYRAMIS",\r | |
779 | "email": "jannahowell@pyramis.com",\r | |
780 | "phone": "+1 (823) 423-2342"\r | |
781 | }, {\r | |
782 | "_id": "54ff69d96e7f08b674de7cb9",\r | |
783 | "index": 11,\r | |
784 | "guid": "9f6df0e4-b92c-4272-ad75-981305e9bb09",\r | |
785 | "isActive": true,\r | |
786 | "balance": "$2,279.79",\r | |
787 | "age": 33,\r | |
788 | "eyeColor": "green",\r | |
789 | "name": "Nieves Short",\r | |
790 | "gender": "male",\r | |
791 | "company": "PETICULAR",\r | |
792 | "email": "nievesshort@peticular.com",\r | |
793 | "phone": "+1 (904) 556-3401"\r | |
794 | }, {\r | |
795 | "_id": "54ff69d9fb987df7ecf3d8ab",\r | |
796 | "index": 12,\r | |
797 | "guid": "32c80cfd-d880-48a6-a3b0-e687c1e52b30",\r | |
798 | "isActive": false,\r | |
799 | "balance": "$3,830.03",\r | |
800 | "age": 26,\r | |
801 | "eyeColor": "green",\r | |
802 | "name": "Tania Gillespie",\r | |
803 | "gender": "female",\r | |
804 | "company": "AUSTEX",\r | |
805 | "email": "taniagillespie@austex.com",\r | |
806 | "phone": "+1 (969) 527-3521"\r | |
807 | }, {\r | |
808 | "_id": "54ff69d9f586c6e7e9a08b4b",\r | |
809 | "index": 13,\r | |
810 | "guid": "e6a006c4-1d5e-4a09-9dd6-496426fc4982",\r | |
811 | "isActive": false,\r | |
812 | "balance": "$3,411.76",\r | |
813 | "age": 32,\r | |
814 | "eyeColor": "blue",\r | |
815 | "name": "Joyner Suarez",\r | |
816 | "gender": "male",\r | |
817 | "company": "GEOFARM",\r | |
818 | "email": "joynersuarez@geofarm.com",\r | |
819 | "phone": "+1 (879) 571-3671"\r | |
820 | }, {\r | |
821 | "_id": "54ff69d94eaa44d993966048",\r | |
822 | "index": 14,\r | |
823 | "guid": "00927bfa-dfd7-4850-bfd7-a2c25c476327",\r | |
824 | "isActive": true,\r | |
825 | "balance": "$2,402.44",\r | |
826 | "age": 35,\r | |
827 | "eyeColor": "brown",\r | |
828 | "name": "Hull Cooley",\r | |
829 | "gender": "male",\r | |
830 | "company": "ENERVATE",\r | |
831 | "email": "hullcooley@enervate.com",\r | |
832 | "phone": "+1 (910) 476-3577"\r | |
833 | }, {\r | |
834 | "_id": "54ff69d9b341bfef697e75ac",\r | |
835 | "index": 15,\r | |
836 | "guid": "cd6a241c-35a4-4038-ae01-d32640719dc7",\r | |
837 | "isActive": false,\r | |
838 | "balance": "$2,889.76",\r | |
839 | "age": 28,\r | |
840 | "eyeColor": "green",\r | |
841 | "name": "Cortez Fleming",\r | |
842 | "gender": "male",\r | |
843 | "company": "CIPROMOX",\r | |
844 | "email": "cortezfleming@cipromox.com",\r | |
845 | "phone": "+1 (964) 460-3159"\r | |
846 | }, {\r | |
847 | "_id": "54ff69d9a1f835d92cb8a017",\r | |
848 | "index": 16,\r | |
849 | "guid": "45ad04ed-c154-4f16-a60b-d091e2ab8c13",\r | |
850 | "isActive": true,\r | |
851 | "balance": "$1,994.50",\r | |
852 | "age": 21,\r | |
853 | "eyeColor": "green",\r | |
854 | "name": "Hazel Rodriguez",\r | |
855 | "gender": "female",\r | |
856 | "company": "SILODYNE",\r | |
857 | "email": "hazelrodriguez@silodyne.com",\r | |
858 | "phone": "+1 (962) 492-3107"\r | |
859 | }, {\r | |
860 | "_id": "54ff69d93989153e00dc5f02",\r | |
861 | "index": 17,\r | |
862 | "guid": "b2a702d1-b47e-4f2b-98f2-4ab2e70b126f",\r | |
863 | "isActive": true,\r | |
864 | "balance": "$2,826.88",\r | |
865 | "age": 30,\r | |
866 | "eyeColor": "green",\r | |
867 | "name": "Keri Pearson",\r | |
868 | "gender": "female",\r | |
869 | "company": "CENTICE",\r | |
870 | "email": "keripearson@centice.com",\r | |
871 | "phone": "+1 (858) 417-3541"\r | |
872 | }, {\r | |
873 | "_id": "54ff69d9377beb85134e2761",\r | |
874 | "index": 18,\r | |
875 | "guid": "9bbb9bd7-d517-4bbb-a9b6-76f4fab0e5ab",\r | |
876 | "isActive": false,\r | |
877 | "balance": "$1,119.17",\r | |
878 | "age": 24,\r | |
879 | "eyeColor": "brown",\r | |
880 | "name": "Daisy Mcconnell",\r | |
881 | "gender": "female",\r | |
882 | "company": "MONDICIL",\r | |
883 | "email": "daisymcconnell@mondicil.com",\r | |
884 | "phone": "+1 (836) 470-3995"\r | |
885 | }, {\r | |
886 | "_id": "54ff69d999e3637d8287287f",\r | |
887 | "index": 19,\r | |
888 | "guid": "c2dbece0-7554-4666-9378-805a625789db",\r | |
889 | "isActive": false,\r | |
890 | "balance": "$3,855.83",\r | |
891 | "age": 30,\r | |
892 | "eyeColor": "blue",\r | |
893 | "name": "Michelle Espinoza",\r | |
894 | "gender": "female",\r | |
895 | "company": "STEELFAB",\r | |
896 | "email": "michelleespinoza@steelfab.com",\r | |
897 | "phone": "+1 (882) 508-2376"\r | |
898 | }, {\r | |
899 | "_id": "54ff69d93826cfb24af88797",\r | |
900 | "index": 20,\r | |
901 | "guid": "20be5f38-dc45-4a2f-8889-e9ba5ade8bed",\r | |
902 | "isActive": false,\r | |
903 | "balance": "$1,366.06",\r | |
904 | "age": 39,\r | |
905 | "eyeColor": "blue",\r | |
906 | "name": "Wall Sears",\r | |
907 | "gender": "male",\r | |
908 | "company": "PLAYCE",\r | |
909 | "email": "wallsears@playce.com",\r | |
910 | "phone": "+1 (846) 505-3782"\r | |
911 | }, {\r | |
912 | "_id": "54ff69d97f6a23afdd06849c",\r | |
913 | "index": 21,\r | |
914 | "guid": "66fc61ba-38ef-4d49-862d-eb7d5fa68245",\r | |
915 | "isActive": false,\r | |
916 | "balance": "$2,379.73",\r | |
917 | "age": 20,\r | |
918 | "eyeColor": "green",\r | |
919 | "name": "Caldwell Cain",\r | |
920 | "gender": "male",\r | |
921 | "company": "ORBIXTAR",\r | |
922 | "email": "caldwellcain@orbixtar.com",\r | |
923 | "phone": "+1 (831) 456-3297"\r | |
924 | }, {\r | |
925 | "_id": "54ff69d970154f7ac17b1438",\r | |
926 | "index": 22,\r | |
927 | "guid": "85b6d275-3bff-4475-8c42-0c4f8ec2d385",\r | |
928 | "isActive": true,\r | |
929 | "balance": "$2,572.21",\r | |
930 | "age": 20,\r | |
931 | "eyeColor": "green",\r | |
932 | "name": "Viola Mckay",\r | |
933 | "gender": "female",\r | |
934 | "company": "SPRINGBEE",\r | |
935 | "email": "violamckay@springbee.com",\r | |
936 | "phone": "+1 (901) 412-3479"\r | |
937 | }, {\r | |
938 | "_id": "54ff69d98ac67b26bce2d4a8",\r | |
939 | "index": 23,\r | |
940 | "guid": "1d7460af-09a7-479a-8476-c3187a85ba8d",\r | |
941 | "isActive": false,\r | |
942 | "balance": "$2,467.39",\r | |
943 | "age": 40,\r | |
944 | "eyeColor": "blue",\r | |
945 | "name": "Gutierrez Conway",\r | |
946 | "gender": "male",\r | |
947 | "company": "ULTRASURE",\r | |
948 | "email": "gutierrezconway@ultrasure.com",\r | |
949 | "phone": "+1 (939) 438-3340"\r | |
950 | }, {\r | |
951 | "_id": "54ff69d93a9b81bdb7af6473",\r | |
952 | "index": 24,\r | |
953 | "guid": "2da97cff-a16c-47a2-b9b0-d05d7ce8655d",\r | |
954 | "isActive": false,\r | |
955 | "balance": "$2,496.66",\r | |
956 | "age": 20,\r | |
957 | "eyeColor": "brown",\r | |
958 | "name": "Chandler Schmidt",\r | |
959 | "gender": "male",\r | |
960 | "company": "ZANITY",\r | |
961 | "email": "chandlerschmidt@zanity.com",\r | |
962 | "phone": "+1 (822) 461-2247"\r | |
963 | }, {\r | |
964 | "_id": "54ff69d99e5b0a9b8db8da2b",\r | |
965 | "index": 26,\r | |
966 | "guid": "b8081e85-d0a9-4575-9fdd-83baa0cfe79b",\r | |
967 | "isActive": false,\r | |
968 | "balance": "$3,044.12",\r | |
969 | "age": 21,\r | |
970 | "eyeColor": "brown",\r | |
971 | "name": "Bradshaw Ware",\r | |
972 | "gender": "male",\r | |
973 | "company": "BEDDER",\r | |
974 | "email": "bradshawware@bedder.com",\r | |
975 | "phone": "+1 (932) 496-3718"\r | |
976 | }, {\r | |
977 | "_id": "54ff69d9a9827e6a14480e37",\r | |
978 | "index": 27,\r | |
979 | "guid": "f0d49a25-fa17-4319-9f6a-9e88bb974755",\r | |
980 | "isActive": true,\r | |
981 | "balance": "$1,799.46",\r | |
982 | "age": 38,\r | |
983 | "eyeColor": "green",\r | |
984 | "name": "Krystal Bush",\r | |
985 | "gender": "female",\r | |
986 | "company": "ZOLAREX",\r | |
987 | "email": "krystalbush@zolarex.com",\r | |
988 | "phone": "+1 (928) 577-3693"\r | |
989 | }, {\r | |
990 | "_id": "54ff69d97e57e2cab6272464",\r | |
991 | "index": 28,\r | |
992 | "guid": "40860305-ba5a-44ec-9783-21d4a1a4927b",\r | |
993 | "isActive": true,\r | |
994 | "balance": "$1,856.24",\r | |
995 | "age": 20,\r | |
996 | "eyeColor": "green",\r | |
997 | "name": "Madeline Grant",\r | |
998 | "gender": "female",\r | |
999 | "company": "APEXIA",\r | |
1000 | "email": "madelinegrant@apexia.com",\r | |
1001 | "phone": "+1 (895) 521-2877"\r | |
1002 | }, {\r | |
1003 | "_id": "54ff69d9431984c9fdb6f25a",\r | |
1004 | "index": 29,\r | |
1005 | "guid": "36d78b3f-a9dd-4180-bb66-c12a1147e92d",\r | |
1006 | "isActive": true,\r | |
1007 | "balance": "$3,971.70",\r | |
1008 | "age": 40,\r | |
1009 | "eyeColor": "brown",\r | |
1010 | "name": "Flora Ortiz",\r | |
1011 | "gender": "female",\r | |
1012 | "company": "ACCUSAGE",\r | |
1013 | "email": "floraortiz@accusage.com",\r | |
1014 | "phone": "+1 (992) 561-2107"\r | |
1015 | }, {\r | |
1016 | "_id": "54ff69d9c7c52140a4572361",\r | |
1017 | "index": 30,\r | |
1018 | "guid": "ba91387f-cab7-4487-a650-1bd94a650306",\r | |
1019 | "isActive": false,\r | |
1020 | "balance": "$1,408.31",\r | |
1021 | "age": 37,\r | |
1022 | "eyeColor": "brown",\r | |
1023 | "name": "Bobbie Atkins",\r | |
1024 | "gender": "female",\r | |
1025 | "company": "GRAINSPOT",\r | |
1026 | "email": "bobbieatkins@grainspot.com",\r | |
1027 | "phone": "+1 (840) 497-2564"\r | |
1028 | }, {\r | |
1029 | "_id": "54ff69d982ac77cad23cb28d",\r | |
1030 | "index": 31,\r | |
1031 | "guid": "7068b1b5-cb81-4127-b252-ccc3ff8d3b5a",\r | |
1032 | "isActive": true,\r | |
1033 | "balance": "$3,375.36",\r | |
1034 | "age": 39,\r | |
1035 | "eyeColor": "brown",\r | |
1036 | "name": "Mayer Osborne",\r | |
1037 | "gender": "male",\r | |
1038 | "company": "DEEPENDS",\r | |
1039 | "email": "mayerosborne@deepends.com",\r | |
1040 | "phone": "+1 (952) 498-3050"\r | |
1041 | }, {\r | |
1042 | "_id": "54ff69d99aefdc9cdd70a0df",\r | |
1043 | "index": 32,\r | |
1044 | "guid": "087771d5-4f39-46aa-bad7-7a051e807770",\r | |
1045 | "isActive": true,\r | |
1046 | "balance": "$3,345.55",\r | |
1047 | "age": 38,\r | |
1048 | "eyeColor": "blue",\r | |
1049 | "name": "Sullivan Gibson",\r | |
1050 | "gender": "male",\r | |
1051 | "company": "AQUASURE",\r | |
1052 | "email": "sullivangibson@aquasure.com",\r | |
1053 | "phone": "+1 (833) 463-3464"\r | |
1054 | }, {\r | |
1055 | "_id": "54ff69d970a46678753362fc",\r | |
1056 | "index": 33,\r | |
1057 | "guid": "23e28ddc-a102-4f7c-b53b-4e3b8e45c64e",\r | |
1058 | "isActive": false,\r | |
1059 | "balance": "$2,521.22",\r | |
1060 | "age": 28,\r | |
1061 | "eyeColor": "green",\r | |
1062 | "name": "Nikki Whitley",\r | |
1063 | "gender": "female",\r | |
1064 | "company": "FUTURIS",\r | |
1065 | "email": "nikkiwhitley@futuris.com",\r | |
1066 | "phone": "+1 (883) 561-2974"\r | |
1067 | }, {\r | |
1068 | "_id": "54ff69d9f7ca2fa585ecbac6",\r | |
1069 | "index": 34,\r | |
1070 | "guid": "b711bd69-e672-48f5-8138-d3120bbedb40",\r | |
1071 | "isActive": true,\r | |
1072 | "balance": "$2,388.02",\r | |
1073 | "age": 21,\r | |
1074 | "eyeColor": "green",\r | |
1075 | "name": "Juana Doyle",\r | |
1076 | "gender": "female",\r | |
1077 | "company": "HOUSEDOWN",\r | |
1078 | "email": "juanadoyle@housedown.com",\r | |
1079 | "phone": "+1 (847) 428-3271"\r | |
1080 | }, {\r | |
1081 | "_id": "54ff69d9295e29d7b81a31be",\r | |
1082 | "index": 35,\r | |
1083 | "guid": "d393a87f-0789-4762-8ab8-d0fb66fc0fcb",\r | |
1084 | "isActive": true,\r | |
1085 | "balance": "$1,126.53",\r | |
1086 | "age": 32,\r | |
1087 | "eyeColor": "green",\r | |
1088 | "name": "Marci Shaffer",\r | |
1089 | "gender": "female",\r | |
1090 | "company": "TRASOLA",\r | |
1091 | "email": "marcishaffer@trasola.com",\r | |
1092 | "phone": "+1 (929) 502-2533"\r | |
1093 | }, {\r | |
1094 | "_id": "54ff69d9d8f81e674722a7d5",\r | |
1095 | "index": 36,\r | |
1096 | "guid": "281bbeea-5bef-4c37-8e2a-22481c9616c3",\r | |
1097 | "isActive": false,\r | |
1098 | "balance": "$2,616.22",\r | |
1099 | "age": 26,\r | |
1100 | "eyeColor": "green",\r | |
1101 | "name": "Maynard Watts",\r | |
1102 | "gender": "male",\r | |
1103 | "company": "AEORA",\r | |
1104 | "email": "maynardwatts@aeora.com",\r | |
1105 | "phone": "+1 (896) 418-3281"\r | |
1106 | }, {\r | |
1107 | "_id": "54ff69d98f504a9e6c63dedb",\r | |
1108 | "index": 37,\r | |
1109 | "guid": "48698e76-8996-40d2-9abe-3fdd8fe98cf7",\r | |
1110 | "isActive": true,\r | |
1111 | "balance": "$3,441.08",\r | |
1112 | "age": 21,\r | |
1113 | "eyeColor": "brown",\r | |
1114 | "name": "Ollie Mooney",\r | |
1115 | "gender": "female",\r | |
1116 | "company": "ACCUPRINT",\r | |
1117 | "email": "olliemooney@accuprint.com",\r | |
1118 | "phone": "+1 (811) 512-3357"\r | |
1119 | }, {\r | |
1120 | "_id": "54ff69d9fc55f5cd34359bf9",\r | |
1121 | "index": 38,\r | |
1122 | "guid": "495c9d9e-95d8-48a2-83b4-c0f314f7aa26",\r | |
1123 | "isActive": true,\r | |
1124 | "balance": "$1,134.21",\r | |
1125 | "age": 30,\r | |
1126 | "eyeColor": "green",\r | |
1127 | "name": "Mattie Collins",\r | |
1128 | "gender": "female",\r | |
1129 | "company": "EARGO",\r | |
1130 | "email": "mattiecollins@eargo.com",\r | |
1131 | "phone": "+1 (800) 463-2474"\r | |
1132 | }, {\r | |
1133 | "_id": "54ff69d94692077fe1587d2b",\r | |
1134 | "index": 39,\r | |
1135 | "guid": "9c259004-63be-4056-b291-7989cd582d41",\r | |
1136 | "isActive": true,\r | |
1137 | "balance": "$1,429.64",\r | |
1138 | "age": 23,\r | |
1139 | "eyeColor": "brown",\r | |
1140 | "name": "Weeks Mcdowell",\r | |
1141 | "gender": "male",\r | |
1142 | "company": "ORBAXTER",\r | |
1143 | "email": "weeksmcdowell@orbaxter.com",\r | |
1144 | "phone": "+1 (913) 562-2677"\r | |
1145 | }, {\r | |
1146 | "_id": "54ff69d95c44a1cefcb13a58",\r | |
1147 | "index": 40,\r | |
1148 | "guid": "44fa1564-9ef2-4503-b887-5f0f282b1bd3",\r | |
1149 | "isActive": false,\r | |
1150 | "balance": "$1,340.36",\r | |
1151 | "age": 30,\r | |
1152 | "eyeColor": "brown",\r | |
1153 | "name": "Hammond Valencia",\r | |
1154 | "gender": "male",\r | |
1155 | "company": "IZZBY",\r | |
1156 | "email": "hammondvalencia@izzby.com",\r | |
1157 | "phone": "+1 (899) 577-2537"\r | |
1158 | }, {\r | |
1159 | "_id": "54ff69d9c513f5b3c8ba15d7",\r | |
1160 | "index": 41,\r | |
1161 | "guid": "70c237d2-4a51-4b41-a5e2-e3bc1def56c5",\r | |
1162 | "isActive": true,\r | |
1163 | "balance": "$2,979.67",\r | |
1164 | "age": 39,\r | |
1165 | "eyeColor": "brown",\r | |
1166 | "name": "Ramona Fitzgerald",\r | |
1167 | "gender": "female",\r | |
1168 | "company": "GOLISTIC",\r | |
1169 | "email": "ramonafitzgerald@golistic.com",\r | |
1170 | "phone": "+1 (965) 432-2851"\r | |
1171 | }, {\r | |
1172 | "_id": "54ff69d9affa1d1749cd11d5",\r | |
1173 | "index": 42,\r | |
1174 | "guid": "80ef3c8e-b6ca-4048-9920-e651fa2a11b0",\r | |
1175 | "isActive": false,\r | |
1176 | "balance": "$3,671.11",\r | |
1177 | "age": 27,\r | |
1178 | "eyeColor": "blue",\r | |
1179 | "name": "Hyde Alford",\r | |
1180 | "gender": "male",\r | |
1181 | "company": "COFINE",\r | |
1182 | "email": "hydealford@cofine.com",\r | |
1183 | "phone": "+1 (806) 588-3800"\r | |
1184 | }, {\r | |
1185 | "_id": "54ff69d9bd4f8a5bc1e34937",\r | |
1186 | "index": 43,\r | |
1187 | "guid": "3d5ed46a-0b40-4e2d-8438-ada9007f4d49",\r | |
1188 | "isActive": true,\r | |
1189 | "balance": "$1,051.71",\r | |
1190 | "age": 36,\r | |
1191 | "eyeColor": "brown",\r | |
1192 | "name": "Sonia Salazar",\r | |
1193 | "gender": "female",\r | |
1194 | "company": "RENOVIZE",\r | |
1195 | "email": "soniasalazar@renovize.com",\r | |
1196 | "phone": "+1 (855) 547-2046"\r | |
1197 | }, {\r | |
1198 | "_id": "54ff69d9c59ba53ca1b15c7f",\r | |
1199 | "index": 44,\r | |
1200 | "guid": "fe908aad-5474-4767-baf4-66a4e9fcf106",\r | |
1201 | "isActive": true,\r | |
1202 | "balance": "$3,531.45",\r | |
1203 | "age": 21,\r | |
1204 | "eyeColor": "blue",\r | |
1205 | "name": "Johnston Nolan",\r | |
1206 | "gender": "male",\r | |
1207 | "company": "VELOS",\r | |
1208 | "email": "johnstonnolan@velos.com",\r | |
1209 | "phone": "+1 (950) 510-3191"\r | |
1210 | }, {\r | |
1211 | "_id": "54ff69d96252c760ec1787a4",\r | |
1212 | "index": 45,\r | |
1213 | "guid": "efd7b2aa-804b-4463-a1e4-7931bcac6a18",\r | |
1214 | "isActive": true,\r | |
1215 | "balance": "$2,238.60",\r | |
1216 | "age": 40,\r | |
1217 | "eyeColor": "green",\r | |
1218 | "name": "Salazar Walters",\r | |
1219 | "gender": "male",\r | |
1220 | "company": "GEEKNET",\r | |
1221 | "email": "salazarwalters@geeknet.com",\r | |
1222 | "phone": "+1 (834) 510-2779"\r | |
1223 | }, {\r | |
1224 | "_id": "54ff69d9672f19a45f583e87",\r | |
1225 | "index": 46,\r | |
1226 | "guid": "25d3dddd-3983-49ae-b7f4-224e73bdacd9",\r | |
1227 | "isActive": true,\r | |
1228 | "balance": "$2,092.02",\r | |
1229 | "age": 21,\r | |
1230 | "eyeColor": "brown",\r | |
1231 | "name": "Emma Mcfarland",\r | |
1232 | "gender": "female",\r | |
1233 | "company": "COWTOWN",\r | |
1234 | "email": "emmamcfarland@cowtown.com",\r | |
1235 | "phone": "+1 (858) 410-3273"\r | |
1236 | }, {\r | |
1237 | "_id": "54ff69d902facac3a9fc9fbf",\r | |
1238 | "index": 47,\r | |
1239 | "guid": "e22f488c-a5ad-49d3-b9ec-f3dd9f287318",\r | |
1240 | "isActive": false,\r | |
1241 | "balance": "$1,199.34",\r | |
1242 | "age": 39,\r | |
1243 | "eyeColor": "blue",\r | |
1244 | "name": "Lisa Sutton",\r | |
1245 | "gender": "female",\r | |
1246 | "company": "EXTRAGEN",\r | |
1247 | "email": "lisasutton@extragen.com",\r | |
1248 | "phone": "+1 (815) 583-2428"\r | |
1249 | }, {\r | |
1250 | "_id": "54ff69d958481e8cde608526",\r | |
1251 | "index": 48,\r | |
1252 | "guid": "aa976349-e7dc-4a38-aae7-e497c986c288",\r | |
1253 | "isActive": true,\r | |
1254 | "balance": "$3,680.82",\r | |
1255 | "age": 37,\r | |
1256 | "eyeColor": "blue",\r | |
1257 | "name": "Blackburn Ingram",\r | |
1258 | "gender": "male",\r | |
1259 | "company": "EXTREMO",\r | |
1260 | "email": "blackburningram@extremo.com",\r | |
1261 | "phone": "+1 (800) 407-3564"\r | |
1262 | }, {\r | |
1263 | "_id": "54ff69d9e28a5207c6ce32f2",\r | |
1264 | "index": 49,\r | |
1265 | "guid": "e95d0949-d9e5-4665-bee0-29697d6b6e61",\r | |
1266 | "isActive": true,\r | |
1267 | "balance": "$3,399.52",\r | |
1268 | "age": 24,\r | |
1269 | "eyeColor": "blue",\r | |
1270 | "name": "Preston Hardy",\r | |
1271 | "gender": "male",\r | |
1272 | "company": "PROXSOFT",\r | |
1273 | "email": "prestonhardy@proxsoft.com",\r | |
1274 | "phone": "+1 (960) 444-3169"\r | |
1275 | }, {\r | |
1276 | "_id": "54ff69d92e96909171f3e1b1",\r | |
1277 | "index": 50,\r | |
1278 | "guid": "0d6b5e73-7b1d-4c96-9a16-d73d0e74c364",\r | |
1279 | "isActive": false,\r | |
1280 | "balance": "$2,920.49",\r | |
1281 | "age": 21,\r | |
1282 | "eyeColor": "green",\r | |
1283 | "name": "Mia Mcgee",\r | |
1284 | "gender": "female",\r | |
1285 | "company": "GEEKOLOGY",\r | |
1286 | "email": "miamcgee@geekology.com",\r | |
1287 | "phone": "+1 (921) 464-2944"\r | |
1288 | }, {\r | |
1289 | "_id": "54ff69d94e56363d2f4110cb",\r | |
1290 | "index": 51,\r | |
1291 | "guid": "c355ad3a-a137-4dc4-9eeb-2ef6c5385076",\r | |
1292 | "isActive": true,\r | |
1293 | "balance": "$2,738.07",\r | |
1294 | "age": 36,\r | |
1295 | "eyeColor": "brown",\r | |
1296 | "name": "Doris Mccullough",\r | |
1297 | "gender": "female",\r | |
1298 | "company": "PRIMORDIA",\r | |
1299 | "email": "dorismccullough@primordia.com",\r | |
1300 | "phone": "+1 (823) 470-2961"\r | |
1301 | }, {\r | |
1302 | "_id": "54ff69d99d447d751c48fefc",\r | |
1303 | "index": 52,\r | |
1304 | "guid": "564a646d-4bd9-4e4b-bb64-522eea292751",\r | |
1305 | "isActive": false,\r | |
1306 | "balance": "$1,966.01",\r | |
1307 | "age": 30,\r | |
1308 | "eyeColor": "brown",\r | |
1309 | "name": "Fernandez Shepard",\r | |
1310 | "gender": "male",\r | |
1311 | "company": "PAWNAGRA",\r | |
1312 | "email": "fernandezshepard@pawnagra.com",\r | |
1313 | "phone": "+1 (903) 453-3876"\r | |
1314 | }, {\r | |
1315 | "_id": "54ff69d949dfc5b655d10e58",\r | |
1316 | "index": 53,\r | |
1317 | "guid": "4b07ab75-7a20-4515-9561-10323a712c37",\r | |
1318 | "isActive": false,\r | |
1319 | "balance": "$3,447.93",\r | |
1320 | "age": 38,\r | |
1321 | "eyeColor": "green",\r | |
1322 | "name": "Yvette Caldwell",\r | |
1323 | "gender": "female",\r | |
1324 | "company": "OLUCORE",\r | |
1325 | "email": "yvettecaldwell@olucore.com",\r | |
1326 | "phone": "+1 (861) 417-2291"\r | |
1327 | }, {\r | |
1328 | "_id": "54ff69d9e7ab8c4e8029f2d6",\r | |
1329 | "index": 54,\r | |
1330 | "guid": "73917fc2-53d6-4331-8ac9-ec65943d8e75",\r | |
1331 | "isActive": false,\r | |
1332 | "balance": "$1,949.14",\r | |
1333 | "age": 25,\r | |
1334 | "eyeColor": "green",\r | |
1335 | "name": "Gibson Molina",\r | |
1336 | "gender": "male",\r | |
1337 | "company": "STREZZO",\r | |
1338 | "email": "gibsonmolina@strezzo.com",\r | |
1339 | "phone": "+1 (809) 485-2161"\r | |
1340 | }, {\r | |
1341 | "_id": "54ff69d958fcd9a733351136",\r | |
1342 | "index": 55,\r | |
1343 | "guid": "ad310b11-965c-480e-9088-4d65c27d6d04",\r | |
1344 | "isActive": false,\r | |
1345 | "balance": "$2,512.16",\r | |
1346 | "age": 40,\r | |
1347 | "eyeColor": "brown",\r | |
1348 | "name": "Hicks Ferguson",\r | |
1349 | "gender": "male",\r | |
1350 | "company": "COMTEXT",\r | |
1351 | "email": "hicksferguson@comtext.com",\r | |
1352 | "phone": "+1 (897) 565-2845"\r | |
1353 | }, {\r | |
1354 | "_id": "54ff69d94a48d9b5a556f495",\r | |
1355 | "index": 56,\r | |
1356 | "guid": "17bca210-7a7f-4236-badd-4d52abc4d73f",\r | |
1357 | "isActive": false,\r | |
1358 | "balance": "$3,950.51",\r | |
1359 | "age": 28,\r | |
1360 | "eyeColor": "brown",\r | |
1361 | "name": "Dale Stephens",\r | |
1362 | "gender": "female",\r | |
1363 | "company": "ZENSOR",\r | |
1364 | "email": "dalestephens@zensor.com",\r | |
1365 | "phone": "+1 (867) 474-3050"\r | |
1366 | }, {\r | |
1367 | "_id": "54ff69d94f91296292db728e",\r | |
1368 | "index": 57,\r | |
1369 | "guid": "1cd712d4-b477-496d-aea6-d8b75f0aebcc",\r | |
1370 | "isActive": false,\r | |
1371 | "balance": "$1,385.99",\r | |
1372 | "age": 37,\r | |
1373 | "eyeColor": "brown",\r | |
1374 | "name": "Burris Nash",\r | |
1375 | "gender": "male",\r | |
1376 | "company": "BRAINCLIP",\r | |
1377 | "email": "burrisnash@brainclip.com",\r | |
1378 | "phone": "+1 (873) 533-2943"\r | |
1379 | }, {\r | |
1380 | "_id": "54ff69d9b8edd89a22d08814",\r | |
1381 | "index": 58,\r | |
1382 | "guid": "3cab0ec2-bece-43a2-b49f-1213cbd8bbb0",\r | |
1383 | "isActive": false,\r | |
1384 | "balance": "$3,652.39",\r | |
1385 | "age": 37,\r | |
1386 | "eyeColor": "brown",\r | |
1387 | "name": "Janie Harrington",\r | |
1388 | "gender": "female",\r | |
1389 | "company": "ZISIS",\r | |
1390 | "email": "janieharrington@zisis.com",\r | |
1391 | "phone": "+1 (920) 441-3329"\r | |
1392 | }, {\r | |
1393 | "_id": "54ff69d90550f9ffe4676013",\r | |
1394 | "index": 59,\r | |
1395 | "guid": "536e1f5f-474f-412e-a4ad-258a20a7cb77",\r | |
1396 | "isActive": false,\r | |
1397 | "balance": "$3,937.99",\r | |
1398 | "age": 24,\r | |
1399 | "eyeColor": "brown",\r | |
1400 | "name": "Beulah Burch",\r | |
1401 | "gender": "female",\r | |
1402 | "company": "PLASTO",\r | |
1403 | "email": "beulahburch@plasto.com",\r | |
1404 | "phone": "+1 (904) 452-2143"\r | |
1405 | }, {\r | |
1406 | "_id": "54ff69d920a5eed9e3d2cb29",\r | |
1407 | "index": 60,\r | |
1408 | "guid": "54a44fee-8614-492f-a1bd-c4a6248fce48",\r | |
1409 | "isActive": true,\r | |
1410 | "balance": "$3,024.67",\r | |
1411 | "age": 25,\r | |
1412 | "eyeColor": "green",\r | |
1413 | "name": "Osborne Carter",\r | |
1414 | "gender": "male",\r | |
1415 | "company": "ARTIQ",\r | |
1416 | "email": "osbornecarter@artiq.com",\r | |
1417 | "phone": "+1 (937) 431-2440"\r | |
1418 | }, {\r | |
1419 | "_id": "54ff69d921ee90fcb998a583",\r | |
1420 | "index": 61,\r | |
1421 | "guid": "6e899cc3-f935-405d-995c-43635d3ed121",\r | |
1422 | "isActive": true,\r | |
1423 | "balance": "$3,189.34",\r | |
1424 | "age": 37,\r | |
1425 | "eyeColor": "green",\r | |
1426 | "name": "Rice Mcclain",\r | |
1427 | "gender": "male",\r | |
1428 | "company": "EVENTIX",\r | |
1429 | "email": "ricemcclain@eventix.com",\r | |
1430 | "phone": "+1 (924) 448-3107"\r | |
1431 | }, {\r | |
1432 | "_id": "54ff69d9c70b2ae884142f6f",\r | |
1433 | "index": 62,\r | |
1434 | "guid": "0e62a562-ced9-4922-9985-8c813a647d87",\r | |
1435 | "isActive": false,\r | |
1436 | "balance": "$2,135.22",\r | |
1437 | "age": 34,\r | |
1438 | "eyeColor": "green",\r | |
1439 | "name": "Jerri Knowles",\r | |
1440 | "gender": "female",\r | |
1441 | "company": "VANTAGE",\r | |
1442 | "email": "jerriknowles@vantage.com",\r | |
1443 | "phone": "+1 (926) 566-3957"\r | |
1444 | }, {\r | |
1445 | "_id": "54ff69d950ea8f13f7e0adc3",\r | |
1446 | "index": 63,\r | |
1447 | "guid": "70e8cbfa-9f24-4e58-b827-9d683765e383",\r | |
1448 | "isActive": false,\r | |
1449 | "balance": "$1,360.09",\r | |
1450 | "age": 24,\r | |
1451 | "eyeColor": "blue",\r | |
1452 | "name": "Rose Chapman",\r | |
1453 | "gender": "male",\r | |
1454 | "company": "STEELTAB",\r | |
1455 | "email": "rosechapman@steeltab.com",\r | |
1456 | "phone": "+1 (922) 514-3065"\r | |
1457 | }, {\r | |
1458 | "_id": "54ff69d939f6877321458bf6",\r | |
1459 | "index": 64,\r | |
1460 | "guid": "ddb4264b-de31-464b-89ff-dc7b89c120c5",\r | |
1461 | "isActive": true,\r | |
1462 | "balance": "$1,331.51",\r | |
1463 | "age": 32,\r | |
1464 | "eyeColor": "green",\r | |
1465 | "name": "Larson Baxter",\r | |
1466 | "gender": "male",\r | |
1467 | "company": "HALAP",\r | |
1468 | "email": "larsonbaxter@halap.com",\r | |
1469 | "phone": "+1 (968) 451-2570"\r | |
1470 | }, {\r | |
1471 | "_id": "54ff69d9e8c4ac69c408d5a5",\r | |
1472 | "index": 65,\r | |
1473 | "guid": "92f7f97e-469f-4e61-93ba-58d440f9bdee",\r | |
1474 | "isActive": false,\r | |
1475 | "balance": "$3,771.47",\r | |
1476 | "age": 28,\r | |
1477 | "eyeColor": "green",\r | |
1478 | "name": "Sweeney Shepherd",\r | |
1479 | "gender": "male",\r | |
1480 | "company": "OVOLO",\r | |
1481 | "email": "sweeneyshepherd@ovolo.com",\r | |
1482 | "phone": "+1 (963) 413-2263"\r | |
1483 | }, {\r | |
1484 | "_id": "54ff69d97caf29d7106b9a22",\r | |
1485 | "index": 66,\r | |
1486 | "guid": "ccff96f2-0dea-4d72-ae9b-5f2c5e1bccf8",\r | |
1487 | "isActive": false,\r | |
1488 | "balance": "$3,022.08",\r | |
1489 | "age": 35,\r | |
1490 | "eyeColor": "blue",\r | |
1491 | "name": "Maribel Henry",\r | |
1492 | "gender": "female",\r | |
1493 | "company": "CHILLIUM",\r | |
1494 | "email": "maribelhenry@chillium.com",\r | |
1495 | "phone": "+1 (814) 489-2410"\r | |
1496 | }, {\r | |
1497 | "_id": "54ff69d9ea34002e4fc91d67",\r | |
1498 | "index": 67,\r | |
1499 | "guid": "133b0c0a-1517-487c-84b9-b0eb1fc8bfd1",\r | |
1500 | "isActive": false,\r | |
1501 | "balance": "$1,995.00",\r | |
1502 | "age": 20,\r | |
1503 | "eyeColor": "brown",\r | |
1504 | "name": "Deann Bray",\r | |
1505 | "gender": "female",\r | |
1506 | "company": "VERTON",\r | |
1507 | "email": "deannbray@verton.com",\r | |
1508 | "phone": "+1 (847) 540-2423"\r | |
1509 | }, {\r | |
1510 | "_id": "54ff69d9837c8279be6854e0",\r | |
1511 | "index": 68,\r | |
1512 | "guid": "d562f05e-b605-475e-b7ea-e38cf8c6b32f",\r | |
1513 | "isActive": true,\r | |
1514 | "balance": "$1,035.74",\r | |
1515 | "age": 35,\r | |
1516 | "eyeColor": "brown",\r | |
1517 | "name": "Hart Dillon",\r | |
1518 | "gender": "male",\r | |
1519 | "company": "SOLAREN",\r | |
1520 | "email": "hartdillon@solaren.com",\r | |
1521 | "phone": "+1 (885) 540-3322"\r | |
1522 | }, {\r | |
1523 | "_id": "54ff69d975a0df7615047dda",\r | |
1524 | "index": 69,\r | |
1525 | "guid": "7ec2a46e-9d61-42ad-9aa0-d06596232252",\r | |
1526 | "isActive": false,\r | |
1527 | "balance": "$1,317.78",\r | |
1528 | "age": 40,\r | |
1529 | "eyeColor": "green",\r | |
1530 | "name": "Daphne Mercado",\r | |
1531 | "gender": "female",\r | |
1532 | "company": "TERRASYS",\r | |
1533 | "email": "daphnemercado@terrasys.com",\r | |
1534 | "phone": "+1 (915) 491-2470"\r | |
1535 | }, {\r | |
1536 | "_id": "54ff69d9a6aafdf53cf7899d",\r | |
1537 | "index": 70,\r | |
1538 | "guid": "99c23548-6731-4236-a6b1-0455172d931b",\r | |
1539 | "isActive": false,\r | |
1540 | "balance": "$3,395.05",\r | |
1541 | "age": 22,\r | |
1542 | "eyeColor": "blue",\r | |
1543 | "name": "Aguilar Ramsey",\r | |
1544 | "gender": "male",\r | |
1545 | "company": "SONIQUE",\r | |
1546 | "email": "aguilarramsey@sonique.com",\r | |
1547 | "phone": "+1 (918) 407-2528"\r | |
1548 | }, {\r | |
1549 | "_id": "54ff69d98368d84760f7ffb4",\r | |
1550 | "index": 71,\r | |
1551 | "guid": "919aa130-2a9a-4c18-9f82-a4cc5fa9d18f",\r | |
1552 | "isActive": true,\r | |
1553 | "balance": "$3,961.57",\r | |
1554 | "age": 23,\r | |
1555 | "eyeColor": "blue",\r | |
1556 | "name": "Alyssa Garrett",\r | |
1557 | "gender": "female",\r | |
1558 | "company": "ZORK",\r | |
1559 | "email": "alyssagarrett@zork.com",\r | |
1560 | "phone": "+1 (816) 467-3019"\r | |
1561 | }, {\r | |
1562 | "_id": "54ff69d97100f98d64a49826",\r | |
1563 | "index": 72,\r | |
1564 | "guid": "32301d04-6bd8-4db2-a1d0-b98ae4a53877",\r | |
1565 | "isActive": true,\r | |
1566 | "balance": "$2,245.64",\r | |
1567 | "age": 27,\r | |
1568 | "eyeColor": "blue",\r | |
1569 | "name": "Vickie Castro",\r | |
1570 | "gender": "female",\r | |
1571 | "company": "QUOTEZART",\r | |
1572 | "email": "vickiecastro@quotezart.com",\r | |
1573 | "phone": "+1 (894) 530-3406"\r | |
1574 | }, {\r | |
1575 | "_id": "54ff69d944ae1efb286accdf",\r | |
1576 | "index": 73,\r | |
1577 | "guid": "a15615f1-2077-4d7f-800c-f19aad0cf45a",\r | |
1578 | "isActive": false,\r | |
1579 | "balance": "$3,610.39",\r | |
1580 | "age": 26,\r | |
1581 | "eyeColor": "brown",\r | |
1582 | "name": "Sheryl Cherry",\r | |
1583 | "gender": "female",\r | |
1584 | "company": "TOYLETRY",\r | |
1585 | "email": "sherylcherry@toyletry.com",\r | |
1586 | "phone": "+1 (883) 527-2393"\r | |
1587 | }]\r | |
1588 | });\r | |
1589 | \r | |
1590 | grid = Ext.create('Ext.grid.Panel', {\r | |
1591 | title: 'Simpsons',\r | |
1592 | store: store,\r | |
1593 | height: 350,\r | |
1594 | width: 600,\r | |
1595 | renderTo: document.body,\r | |
1596 | columns: [{\r | |
1597 | text: 'index',\r | |
1598 | dataIndex: 'index',\r | |
1599 | locked: true\r | |
1600 | }, {\r | |
1601 | text: 'Name',\r | |
1602 | dataIndex: 'name',\r | |
1603 | locked: true,\r | |
1604 | cellWrap: true,\r | |
1605 | width: 75\r | |
1606 | }, {\r | |
1607 | text: 'Email',\r | |
1608 | dataIndex: 'email',\r | |
1609 | flex: 1\r | |
1610 | }, {\r | |
1611 | text: 'Phone',\r | |
1612 | dataIndex: 'phone'\r | |
1613 | }, {\r | |
1614 | text: 'isActive',\r | |
1615 | dataIndex: 'isActive'\r | |
1616 | \r | |
1617 | }, {\r | |
1618 | text: 'eyeColor',\r | |
1619 | dataIndex: 'eyeColor'\r | |
1620 | }, {\r | |
1621 | text: 'company',\r | |
1622 | dataIndex: 'company'\r | |
1623 | }, {\r | |
1624 | text: 'gender',\r | |
1625 | dataIndex: 'gender'\r | |
1626 | }],\r | |
1627 | region: 'center'\r | |
1628 | });\r | |
1629 | \r | |
1630 | var normalView = grid.normalGrid.getView(),\r | |
1631 | lockedView = grid.lockedGrid.getView(),\r | |
1632 | lockedScroller = lockedView.getScrollable(),\r | |
1633 | normalScroller = normalView.getScrollable(),\r | |
1634 | normalRows = normalView.all,\r | |
1635 | lockedRows = lockedView.all,\r | |
1636 | navModel = normalView.getNavigationModel();\r | |
1637 | \r | |
1638 | waitsFor(function() {\r | |
1639 | return normalView.all.getCount();\r | |
1640 | });\r | |
1641 | \r | |
1642 | runs(function() {\r | |
1643 | navModel.setPosition(new Ext.grid.CellContext(lockedView).setPosition(0, 0));\r | |
1644 | });\r | |
1645 | \r | |
1646 | waitsFor(function() {\r | |
1647 | var a = Ext.Element.getActiveElement(),\r | |
1648 | p = navModel.getPosition();\r | |
1649 | \r | |
1650 | if (p) {\r | |
1651 | // Scroll only when the last scroll signal has found both views and caused them to update\r | |
1652 | if (navModel.getCell() && (a === navModel.getCell().dom) && normalRows.startIndex === lockedRows.startIndex && lockedScroller.getPosition().y === normalScroller.getPosition().y) {\r | |
1653 | jasmine.fireKeyEvent(a, 'keydown', Ext.event.Event.PAGE_DOWN);\r | |
1654 | }\r | |
1655 | \r | |
1656 | // Scroll until the end\r | |
1657 | return (navModel.getPosition().rowIdx === store.getCount() - 1);\r | |
1658 | }\r | |
1659 | }, 'down arrow to scroll to the last row. 20 seconds expired', 20000);\r | |
1660 | \r | |
1661 | runs(function() {\r | |
1662 | var i;\r | |
1663 | \r | |
1664 | // Row count must be in sync\r | |
1665 | expect(lockedRows.getCount()).toBe(normalRows.getCount());\r | |
1666 | \r | |
1667 | // view sizes must still be in sync\r | |
1668 | expect(lockedView.bufferedRenderer.viewSize).toBe(normalView.bufferedRenderer.viewSize);\r | |
1669 | \r | |
1670 | // Every row must be the same height\r | |
1671 | for (i = normalRows.startIndex; i <= normalRows.endIndex; i++) {\r | |
1672 | expect(normalRows.item(i).getHeight()).toBe(lockedRows.item(i).getHeight());\r | |
1673 | }\r | |
1674 | });\r | |
1675 | });\r | |
1676 | });\r | |
1677 | \r | |
1678 | describe('gridpanel', function () {\r | |
1679 | describe('locking grid', function () {\r | |
1680 | function doIt(reconfigure) {\r | |
1681 | var columns = [{\r | |
1682 | text: 'Col 1',\r | |
1683 | dataIndex: 'field1',\r | |
1684 | width: 100,\r | |
1685 | locked: true\r | |
1686 | }, {\r | |
1687 | text: 'Col 2',\r | |
1688 | dataIndex: 'field2',\r | |
1689 | width: 100\r | |
1690 | }, {\r | |
1691 | text: 'Col 3',\r | |
1692 | dataIndex: 'field3',\r | |
1693 | width: 100\r | |
1694 | }, {\r | |
1695 | text: 'Col 4',\r | |
1696 | dataIndex: 'field4',\r | |
1697 | width: 100\r | |
1698 | }, {\r | |
1699 | text: 'Col 5',\r | |
1700 | dataIndex: 'field5',\r | |
1701 | height: 25,\r | |
1702 | width: 150,\r | |
1703 | xtype: 'widgetcolumn',\r | |
1704 | widget: {\r | |
1705 | xtype: 'progressbarwidget',\r | |
1706 | height: 25,\r | |
1707 | textTpl: ['{percent:number("0")}% capacity']\r | |
1708 | }\r | |
1709 | }],\r | |
1710 | nodeCache;\r | |
1711 | \r | |
1712 | makeGrid({\r | |
1713 | columns: columns\r | |
1714 | }, {\r | |
1715 | fields: ['field1', 'field2', 'field3', 'field4', 'field5'],\r | |
1716 | data: createData(100)\r | |
1717 | });\r | |
1718 | \r | |
1719 | view = grid.view.normalView;\r | |
1720 | nodeCache = view.all;\r | |
1721 | \r | |
1722 | if (reconfigure) {\r | |
1723 | grid.reconfigure(null, columns);\r | |
1724 | }\r | |
1725 | \r | |
1726 | waitsFor(function () {\r | |
1727 | if (nodeCache.endIndex === 99 && view.bufferedRenderer.getLastVisibleRowIndex() === 99) {\r | |
1728 | return true;\r | |
1729 | }\r | |
1730 | else {\r | |
1731 | // Scroll incrementally until the correct end point is found\r | |
1732 | view.scrollBy(null, 20);\r | |
1733 | }\r | |
1734 | }, 'last node to scroll into view', 10000, 50);\r | |
1735 | \r | |
1736 | runs(function () {\r | |
1737 | expect(view.el.down('.x-grid-item-container').getHeight() === view.lockingPartner.el.down('.x-grid-item-container').getHeight()).toBe(true);\r | |
1738 | });\r | |
1739 | }\r | |
1740 | \r | |
1741 | it('should have the same height for each locking partner when scrolling', function () {\r | |
1742 | doIt(false);\r | |
1743 | });\r | |
1744 | \r | |
1745 | it('should have the same height for each locking partner when scrolling after a reconfigure', function () {\r | |
1746 | doIt(true);\r | |
1747 | });\r | |
1748 | });\r | |
1749 | \r | |
1750 | describe('locking grid with variableRowHeight', function () {\r | |
1751 | itIE10p('should keep the row heights on both sides synchronized', function() {\r | |
1752 | var columns = [{\r | |
1753 | text: 'Col 1',\r | |
1754 | dataIndex: 'field1',\r | |
1755 | width: 100,\r | |
1756 | locked: true,\r | |
1757 | variableRowHeight: true\r | |
1758 | }, {\r | |
1759 | text: 'Col 2',\r | |
1760 | dataIndex: 'field2',\r | |
1761 | width: 100\r | |
1762 | }, {\r | |
1763 | text: 'Col 3',\r | |
1764 | dataIndex: 'field3',\r | |
1765 | width: 100\r | |
1766 | }, {\r | |
1767 | text: 'Col 4',\r | |
1768 | dataIndex: 'field4',\r | |
1769 | width: 100\r | |
1770 | }, {\r | |
1771 | text: 'Col 5',\r | |
1772 | dataIndex: 'field5',\r | |
1773 | height: 25,\r | |
1774 | width: 150,\r | |
1775 | xtype: 'widgetcolumn',\r | |
1776 | widget: {\r | |
1777 | xtype: 'progressbarwidget',\r | |
1778 | height: 25,\r | |
1779 | textTpl: ['{percent:number("0")}% capacity']\r | |
1780 | }\r | |
1781 | }],\r | |
1782 | nodeCache,\r | |
1783 | lockedView,\r | |
1784 | bufferedRendererInvocationCount = 0,\r | |
1785 | onSyncHeights = function() {\r | |
1786 | var lockedItems = lockedView.all.slice(),\r | |
1787 | normalItems = nodeCache.slice(),\r | |
1788 | lockedSize = lockedItems.length,\r | |
1789 | normalSize = normalItems.length,\r | |
1790 | i,\r | |
1791 | allEqual = true;\r | |
1792 | \r | |
1793 | // must be same number of rows\r | |
1794 | expect(lockedSize).toBe(normalSize);\r | |
1795 | \r | |
1796 | for (i = 0; allEqual && i < lockedSize; i++) {\r | |
1797 | allEqual = allEqual && normalItems[i].offsetHeight === lockedItems[i].offsetHeight;\r | |
1798 | }\r | |
1799 | // All rows must be same size\r | |
1800 | expect(allEqual).toBe(true);\r | |
1801 | bufferedRendererInvocationCount++;\r | |
1802 | };\r | |
1803 | \r | |
1804 | // Make grid with small buffer zones.\r | |
1805 | makeGrid({\r | |
1806 | columns: columns,\r | |
1807 | syncRowHeight: true\r | |
1808 | }, {\r | |
1809 | fields: ['field1', 'field2', 'field3', 'field4', 'field5'],\r | |
1810 | data: createData(1000, true)\r | |
1811 | });\r | |
1812 | \r | |
1813 | lockedView = grid.view.lockedView;\r | |
1814 | view = grid.view.normalView;\r | |
1815 | nodeCache = view.all;\r | |
1816 | \r | |
1817 | // Set up a sequence on the buffered renderers to check that all rows are always synced\r | |
1818 | view.bufferedRenderer.syncRowHeights = Ext.Function.createSequence(view.bufferedRenderer.syncRowHeights, onSyncHeights);\r | |
1819 | lockedView.bufferedRenderer.syncRowHeights = Ext.Function.createSequence(view.bufferedRenderer.syncRowHeights, onSyncHeights);\r | |
1820 | \r | |
1821 | waitsFor(function () {\r | |
1822 | var reachedTargetRow = nodeCache.startIndex <= 99 && nodeCache.endIndex >= 99;\r | |
1823 | \r | |
1824 | // If row 99 is in the nodeCache, we're done\r | |
1825 | if (reachedTargetRow) {\r | |
1826 | return view.getScrollY() === lockedView.getScrollY() && nodeCache.startIndex === lockedView.all.startIndex && lockedView.position === view.position && lockedView.bodyTop === view.bodyTop;\r | |
1827 | }\r | |
1828 | else {\r | |
1829 | // Scroll incrementally until the correct end point is found\r | |
1830 | view.scrollBy(null, 20);\r | |
1831 | }\r | |
1832 | }, 'row 99 to be rendered', 20000, 50);\r | |
1833 | \r | |
1834 | // Must have invoked the row syncher and the two body heights must be the same\r | |
1835 | runs(function () {\r | |
1836 | \r | |
1837 | expect(bufferedRendererInvocationCount).toBeGreaterThan(0);\r | |
1838 | expect(view.el.down('.x-grid-item-container', true).offsetHeight === view.lockingPartner.el.down('.x-grid-item-container', true).offsetHeight).toBe(true);\r | |
1839 | bufferedRendererInvocationCount = 0;\r | |
1840 | });\r | |
1841 | \r | |
1842 | // Now teleport down to neat the bottom\r | |
1843 | waitsFor(function () {\r | |
1844 | var reachedTargetRow = view.bufferedRenderer.getLastVisibleRowIndex() > 990;\r | |
1845 | \r | |
1846 | if (reachedTargetRow) {\r | |
1847 | return view.getScrollY() === lockedView.getScrollY() && view.all.startIndex === lockedView.all.startIndex;\r | |
1848 | }\r | |
1849 | else {\r | |
1850 | // Scroll in teleporting chunks until the correct end point is found\r | |
1851 | view.scrollBy(null, 1000);\r | |
1852 | }\r | |
1853 | }, 'row 990 to scroll into view', 30000, 100);\r | |
1854 | \r | |
1855 | // Scrolling is too fast for IE8, need to repaint the grid\r | |
1856 | // so that measurements below will yield correct values\r | |
1857 | if (Ext.isIE8) {\r | |
1858 | runs(function() {\r | |
1859 | grid.hide();\r | |
1860 | grid.show();\r | |
1861 | });\r | |
1862 | }\r | |
1863 | \r | |
1864 | // Must have invoked the row syncher and the two body heights must be the same\r | |
1865 | runs(function () {\r | |
1866 | expect(bufferedRendererInvocationCount).toBeGreaterThan(0);\r | |
1867 | \r | |
1868 | var mainHeight = view.el.down('.x-grid-item-container').getHeight(),\r | |
1869 | partnerHeight = view.lockingPartner.el.down('.x-grid-item-container').getHeight();\r | |
1870 | \r | |
1871 | expect(partnerHeight).toBe(mainHeight);\r | |
1872 | bufferedRendererInvocationCount = 0;\r | |
1873 | });\r | |
1874 | });\r | |
1875 | });\r | |
1876 | \r | |
1877 | describe('locking grid with asymmetricRowHeight', function () {\r | |
1878 | it('should keep the row heights on both sides synchronized', function() {\r | |
1879 | // Note that we do NOT set variableRowHeight. All row heights are the same\r | |
1880 | // even if one side drives the row height, and the sides need syncing.\r | |
1881 | // This means BufferedRenderer can use simple arithmetic to find first/last visible row index.\r | |
1882 | var columns = [{\r | |
1883 | text: 'Col 1',\r | |
1884 | dataIndex: 'field1',\r | |
1885 | width: 100,\r | |
1886 | locked: true\r | |
1887 | }, {\r | |
1888 | text: 'Col 2',\r | |
1889 | dataIndex: 'field2',\r | |
1890 | width: 100\r | |
1891 | }, {\r | |
1892 | text: 'Col 3',\r | |
1893 | dataIndex: 'field3',\r | |
1894 | width: 100\r | |
1895 | }, {\r | |
1896 | text: 'Col 4',\r | |
1897 | dataIndex: 'field4',\r | |
1898 | width: 100\r | |
1899 | }, {\r | |
1900 | text: 'Col 5',\r | |
1901 | dataIndex: 'field5',\r | |
1902 | height: 25,\r | |
1903 | width: 150,\r | |
1904 | xtype: 'widgetcolumn',\r | |
1905 | widget: {\r | |
1906 | xtype: 'progressbarwidget',\r | |
1907 | height: 25,\r | |
1908 | textTpl: ['{percent:number("0")}% capacity']\r | |
1909 | }\r | |
1910 | }],\r | |
1911 | nodeCache,\r | |
1912 | lockedView,\r | |
1913 | bufferedRendererInvocationCount = 0,\r | |
1914 | onSyncHeights = function() {\r | |
1915 | var lockedItems = lockedView.all.slice(),\r | |
1916 | normalItems = nodeCache.slice(),\r | |
1917 | lockedSize = lockedItems.length,\r | |
1918 | normalSize = normalItems.length,\r | |
1919 | i,\r | |
1920 | allEqual = true;\r | |
1921 | \r | |
1922 | // must be same number of rows\r | |
1923 | expect(lockedSize).toBe(normalSize);\r | |
1924 | \r | |
1925 | for (i = 0; allEqual && i < lockedSize; i++) {\r | |
1926 | allEqual = allEqual && normalItems[i].offsetHeight === lockedItems[i].offsetHeight;\r | |
1927 | }\r | |
1928 | // All rows must be same size\r | |
1929 | expect(allEqual).toBe(true);\r | |
1930 | bufferedRendererInvocationCount++;\r | |
1931 | };\r | |
1932 | \r | |
1933 | // Make grid with small buffer zones.\r | |
1934 | makeGrid({\r | |
1935 | columns: columns,\r | |
1936 | syncRowHeight: true\r | |
1937 | }, {\r | |
1938 | fields: ['field1', 'field2', 'field3', 'field4', 'field5'],\r | |
1939 | data: createData(1000, false, true),\r | |
1940 | \r | |
1941 | // Make sure store.isGrouped() returns false\r | |
1942 | // otherwise variableRowHeight will be detected\r | |
1943 | groupField: undefined\r | |
1944 | });\r | |
1945 | \r | |
1946 | lockedView = grid.view.lockedView;\r | |
1947 | view = grid.view.normalView;\r | |
1948 | nodeCache = view.all;\r | |
1949 | \r | |
1950 | // Set up a sequence on the buffered renderers to check that all rows are always synced\r | |
1951 | view.bufferedRenderer.syncRowHeights = Ext.Function.createSequence(view.bufferedRenderer.syncRowHeights, onSyncHeights);\r | |
1952 | lockedView.bufferedRenderer.syncRowHeights = Ext.Function.createSequence(view.bufferedRenderer.syncRowHeights, onSyncHeights);\r | |
1953 | \r | |
1954 | waitsFor(function () {\r | |
1955 | var reachedTargetRow = nodeCache.startIndex <= 99 && nodeCache.endIndex >= 99;\r | |
1956 | \r | |
1957 | // If row 99 is in the nodeCache, we're done\r | |
1958 | if (reachedTargetRow) {\r | |
1959 | return view.getScrollY() === lockedView.getScrollY() && nodeCache.startIndex === lockedView.all.startIndex && lockedView.position === view.position && lockedView.bodyTop === view.bodyTop;\r | |
1960 | }\r | |
1961 | else {\r | |
1962 | // Scroll incrementally until the correct end point is found\r | |
1963 | view.scrollBy(null, 20);\r | |
1964 | }\r | |
1965 | }, 'row 99 to be rendered', 20000, 50);\r | |
1966 | \r | |
1967 | // Must have invoked the row syncher and the two body heights must be the same\r | |
1968 | runs(function () {\r | |
1969 | expect(bufferedRendererInvocationCount).toBeGreaterThan(0);\r | |
1970 | expect(view.el.down('.x-grid-item-container').getHeight() === view.lockingPartner.el.down('.x-grid-item-container').getHeight()).toBe(true);\r | |
1971 | bufferedRendererInvocationCount = 0;\r | |
1972 | });\r | |
1973 | \r | |
1974 | // Now teleport down to neat the bottom\r | |
1975 | waitsFor(function () {\r | |
1976 | var reachedTargetRow = view.bufferedRenderer.getLastVisibleRowIndex() > 990;\r | |
1977 | \r | |
1978 | if (reachedTargetRow) {\r | |
1979 | return view.getScrollY() === lockedView.getScrollY() && view.all.startIndex === lockedView.all.startIndex;\r | |
1980 | }\r | |
1981 | else {\r | |
1982 | // Scroll in teleporting chunks until the correct end point is found\r | |
1983 | view.scrollBy(null, 1000);\r | |
1984 | }\r | |
1985 | }, 'row 990 to scroll into view', 30000, 100);\r | |
1986 | \r | |
1987 | // Scrolling is too fast for IE8, need to repaint the grid\r | |
1988 | // so that measurements below will yield correct values\r | |
1989 | if (Ext.isIE8) {\r | |
1990 | runs(function() {\r | |
1991 | grid.hide();\r | |
1992 | grid.show();\r | |
1993 | });\r | |
1994 | }\r | |
1995 | \r | |
1996 | // Must have invoked the row syncher and the two body heights must be the same\r | |
1997 | runs(function () {\r | |
1998 | expect(bufferedRendererInvocationCount).toBeGreaterThan(0);\r | |
1999 | \r | |
2000 | var mainHeight = view.el.down('.x-grid-item-container').getHeight(),\r | |
2001 | partnerHeight = view.lockingPartner.el.down('.x-grid-item-container').getHeight();\r | |
2002 | \r | |
2003 | expect(partnerHeight).toBe(mainHeight);\r | |
2004 | bufferedRendererInvocationCount = 0;\r | |
2005 | });\r | |
2006 | });\r | |
2007 | });\r | |
2008 | \r | |
2009 | describe('reconfiguring', function () {\r | |
2010 | it('should never return `undefined` records when called in a metachange event', function () {\r | |
2011 | // When reconfigure is called within a metchange event listener, the view is refreshed and\r | |
2012 | // `undefined` is returned when AbstractView.getViewRange() -> PageMap.getRange() is called.\r | |
2013 | // This isn't usually a problem, but if there are data records in the PageMap hash that don't exist\r | |
2014 | // in a current page then `undefined` will be returned when instead an array is expected. This, of\r | |
2015 | // course, will throw an exception when the rows are attempted to be created by the template in\r | |
2016 | // AbstractView.refresh(). See EXTJS-12633.\r | |
2017 | var successData = {\r | |
2018 | success: true,\r | |
2019 | totally: 1000,\r | |
2020 | data: [{\r | |
2021 | first: 'First',\r | |
2022 | last: 'Last'\r | |
2023 | }, {\r | |
2024 | first: 'First',\r | |
2025 | last: 'Last'\r | |
2026 | }],\r | |
2027 | metaData: {\r | |
2028 | root: 'data',\r | |
2029 | totalProperty: 'totally',\r | |
2030 | fields: ['first', 'last'],\r | |
2031 | columns: [{\r | |
2032 | text: 'First',\r | |
2033 | dataIndex: 'first'\r | |
2034 | }, {\r | |
2035 | text: 'Last',\r | |
2036 | dataIndex: 'last'\r | |
2037 | }]\r | |
2038 | }\r | |
2039 | },\r | |
2040 | wasCalled = false;\r | |
2041 | \r | |
2042 | makeGrid(null, {\r | |
2043 | data: null,\r | |
2044 | fields: [],\r | |
2045 | leadingBufferZone: 50,\r | |
2046 | pageSize: 25,\r | |
2047 | proxy: {\r | |
2048 | type: 'ajax',\r | |
2049 | url: 'derp'\r | |
2050 | },\r | |
2051 | listeners: {\r | |
2052 | metachange: function (store, meta) {\r | |
2053 | grid.reconfigure(store, meta.columns);\r | |
2054 | wasCalled = true;\r | |
2055 | }\r | |
2056 | }\r | |
2057 | });\r | |
2058 | \r | |
2059 | // Overriding the PageMap method to return a value > 0 when there isn't a representative\r | |
2060 | // page map will reproduce the bug.\r | |
2061 | spyOn(store.data, 'getCount').andCallFake(function () {\r | |
2062 | store.totalCount = 1000;\r | |
2063 | return 25;\r | |
2064 | });\r | |
2065 | \r | |
2066 | store.load();\r | |
2067 | completeWithData(successData);\r | |
2068 | \r | |
2069 | expect(wasCalled).toBe(true);\r | |
2070 | });\r | |
2071 | \r | |
2072 | describe('with grouping feature', function () {\r | |
2073 | it('reconfiguring should bind the groupStore to the plugin', function () {\r | |
2074 | // This test demonstrates that reconfiguring the grid will properly bind the feature's group\r | |
2075 | // store to the plugin.\r | |
2076 | //\r | |
2077 | // This bug only is reproducible when reconfigure is called on a grid with the buffered\r | |
2078 | // renderer plugin and grouping feature. The bug was that the buffered renderer plugin\r | |
2079 | // would bind the data store to the plugin rather than the group store (created when\r | |
2080 | // there's a grouping feature).\r | |
2081 | //\r | |
2082 | // See EXTJS-11860 and EXTJS-11892.\r | |
2083 | makeGrid({\r | |
2084 | features: [{ftype: 'grouping'}]\r | |
2085 | });\r | |
2086 | \r | |
2087 | grid.reconfigure(store);\r | |
2088 | \r | |
2089 | expect(grid.view.bufferedRenderer.store.isFeatureStore).toBe(true);\r | |
2090 | });\r | |
2091 | });\r | |
2092 | });\r | |
2093 | \r | |
2094 | describe('refreshing the view', function () {\r | |
2095 | describe('filtering out all records', function () {\r | |
2096 | function makeData(len) {\r | |
2097 | var data = [],\r | |
2098 | i, str;\r | |
2099 | \r | |
2100 | len = len || 100;\r | |
2101 | \r | |
2102 | for (i = 0; i < len; i++) {\r | |
2103 | str = 'emp_' + i;\r | |
2104 | \r | |
2105 | data.push({\r | |
2106 | name: str,\r | |
2107 | email: str + '@sencha.com',\r | |
2108 | phone: '1-888-' + i,\r | |
2109 | age: i\r | |
2110 | });\r | |
2111 | }\r | |
2112 | \r | |
2113 | return data;\r | |
2114 | }\r | |
2115 | \r | |
2116 | function runTests(scroll) {\r | |
2117 | describe('scrolled = ' + scroll, function () {\r | |
2118 | it('should trigger a view refresh', function () {\r | |
2119 | var wasCalled = false;\r | |
2120 | \r | |
2121 | makeGrid({\r | |
2122 | viewConfig: {\r | |
2123 | listeners: {\r | |
2124 | refresh: function () {\r | |
2125 | wasCalled = true;\r | |
2126 | }\r | |
2127 | }\r | |
2128 | }\r | |
2129 | });\r | |
2130 | \r | |
2131 | if (scroll) {\r | |
2132 | plugin.scrollTo(50);\r | |
2133 | }\r | |
2134 | \r | |
2135 | // Filter out all data.\r | |
2136 | store.filter('name', '______');\r | |
2137 | \r | |
2138 | expect(wasCalled).toBe(true);\r | |
2139 | });\r | |
2140 | \r | |
2141 | it('should reset the view body', function () {\r | |
2142 | makeGrid(null, {\r | |
2143 | data: makeData(500)\r | |
2144 | });\r | |
2145 | \r | |
2146 | if (scroll) {\r | |
2147 | plugin.scrollTo(50);\r | |
2148 | \r | |
2149 | expect(plugin.bodyTop).toBeGreaterThan(0);\r | |
2150 | expect(plugin.scrollHeight).toBeGreaterThan(0);\r | |
2151 | }\r | |
2152 | \r | |
2153 | // Filter out all data.\r | |
2154 | store.filter('name', '______');\r | |
2155 | \r | |
2156 | expect(plugin.bodyTop).toBe(0);\r | |
2157 | expect(plugin.scrollHeight).toBe(0);\r | |
2158 | });\r | |
2159 | });\r | |
2160 | }\r | |
2161 | \r | |
2162 | runTests(true);\r | |
2163 | runTests(false);\r | |
2164 | });\r | |
2165 | });\r | |
2166 | });\r | |
2167 | \r | |
2168 | describe('treepanel', function () {\r | |
2169 | describe('expanding/collapsing', function () {\r | |
2170 | it('should always render the view nodes when expanding', function () {\r | |
2171 | var nodeCache;\r | |
2172 | \r | |
2173 | makeTree({\r | |
2174 | height: 300\r | |
2175 | }, 100);\r | |
2176 | \r | |
2177 | nodeCache = view.all;\r | |
2178 | \r | |
2179 | // Scroll until the last tree node is the last in the rendered block.\r | |
2180 | waitsFor(function () {\r | |
2181 | if (nodeCache.endIndex === 99 && view.bufferedRenderer.getLastVisibleRowIndex() === 99) {\r | |
2182 | return true;\r | |
2183 | }\r | |
2184 | else {\r | |
2185 | // Scroll incrementally until the correct end point is found\r | |
2186 | view.scrollBy(null, 10);\r | |
2187 | }\r | |
2188 | }, 'last node to scroll into view', 10000, 50);\r | |
2189 | \r | |
2190 | // Expanding that last node should append some child nodes to replenish the leading buffer zone.\r | |
2191 | runs(function () {\r | |
2192 | // Expand node 99\r | |
2193 | store.getAt(99).expand();\r | |
2194 | });\r | |
2195 | \r | |
2196 | // Scroll until the last of those expanded children is the last in the rendered block.\r | |
2197 | waitsFor(function () {\r | |
2198 | if (nodeCache.endIndex === 105) {\r | |
2199 | return true;\r | |
2200 | }\r | |
2201 | else {\r | |
2202 | // Scroll incrementally until the correct end point is found\r | |
2203 | view.scrollBy(null, 10);\r | |
2204 | }\r | |
2205 | }, 'new last leaf node to scroll into view', 10000, 50);\r | |
2206 | \r | |
2207 | // Expanding that last node should append the child nodes to the view even though the buffer rendered block is the correct size already\r | |
2208 | runs(function () {\r | |
2209 | //expect(view.bufferedRenderer.position).toBe(view.el.dom.scrollTop);\r | |
2210 | expect(view.getRecord(view.all.last()).get('treeData')).toBe('Child of 99, number 6');\r | |
2211 | \r | |
2212 | // Now let's collapse the parent node by simulating a click on the elbow node.\r | |
2213 | jasmine.fireMouseEvent(nodeCache.item(99).down('.x-tree-expander'), 'click');\r | |
2214 | });\r | |
2215 | });\r | |
2216 | });\r | |
2217 | \r | |
2218 | describe('loadMask config', function () {\r | |
2219 | it('should create a mask by default if not configured', function () {\r | |
2220 | makeTree({\r | |
2221 | store: {\r | |
2222 | proxy: {\r | |
2223 | type: 'ajax',\r | |
2224 | url: 'foo'\r | |
2225 | }\r | |
2226 | }\r | |
2227 | });\r | |
2228 | expect(view.loadMask instanceof Ext.LoadMask).toBe(true);\r | |
2229 | });\r | |
2230 | \r | |
2231 | it('should honor the value if configured', function () {\r | |
2232 | makeTree({\r | |
2233 | store: {\r | |
2234 | proxy: {\r | |
2235 | type: 'ajax',\r | |
2236 | url: 'foo'\r | |
2237 | }\r | |
2238 | },\r | |
2239 | viewConfig: {\r | |
2240 | loadMask: false\r | |
2241 | }\r | |
2242 | });\r | |
2243 | expect(view.loadMask).toBe(false);\r | |
2244 | });\r | |
2245 | });\r | |
2246 | \r | |
2247 | describe('Measuring row height', function() {\r | |
2248 | it('should measure row height', function() {\r | |
2249 | makeGrid(null, {\r | |
2250 | groupField: null,\r | |
2251 | data: [\r | |
2252 | {'name': '<div style="height:30px">Lisa</div>', 'email': 'lisa@simpsons.com', 'phone': '555-111-1224', 'age': 14},\r | |
2253 | {'name': 'Lisa', 'email': 'aunt_lisa@simpsons.com', 'phone': '555-111-1274', 'age': 34},\r | |
2254 | {'name': 'Bart', 'email': 'bart@simpsons.com', 'phone': '555-222-1234', 'age': 12},\r | |
2255 | {'name': 'Homer', 'email': 'homer@simpsons.com', 'phone': '555-222-1244', 'age': 44},\r | |
2256 | {'name': 'Marge', 'email': 'marge@simpsons.com', 'phone': '555-222-1254', 'age': 41}\r | |
2257 | ]\r | |
2258 | });\r | |
2259 | \r | |
2260 | // Should measure the row height be looking at the first row when we do NOT have variableRowHeight: true\r | |
2261 | // EXTJS-15942 - did not measure, stayed at classic default of 21\r | |
2262 | var row = view.all.first(),\r | |
2263 | rowHeight = row.getHeight();\r | |
2264 | \r | |
2265 | // In IE8 we're adding a bottom border on the rows and shifting the row up\r | |
2266 | // at -border-width to compensate for that\r | |
2267 | if (Ext.isIE8) {\r | |
2268 | rowHeight -= row.getBorderWidth('b');\r | |
2269 | }\r | |
2270 | \r | |
2271 | expect(plugin.rowHeight).toBe(rowHeight);\r | |
2272 | });\r | |
2273 | });\r | |
2274 | });\r | |
2275 | \r | |
2276 | describe('filtering the store', function () {\r | |
2277 | var Hobbit, store;\r | |
2278 | \r | |
2279 | afterEach(function() {\r | |
2280 | Ext.destroy(Hobbit, store);\r | |
2281 | });\r | |
2282 | \r | |
2283 | it('should reset the cached position so the grid-item-container is at the top of the view on filter', function () {\r | |
2284 | Hobbit = Ext.define(null, {\r | |
2285 | extend: 'Ext.data.Model',\r | |
2286 | fields: ['name'],\r | |
2287 | proxy: {\r | |
2288 | type: 'ajax',\r | |
2289 | url: '/foo',\r | |
2290 | reader: {\r | |
2291 | rootProperty: 'data'\r | |
2292 | }\r | |
2293 | }\r | |
2294 | });\r | |
2295 | \r | |
2296 | store = new Ext.data.BufferedStore({\r | |
2297 | model: Hobbit,\r | |
2298 | remoteGroup: true,\r | |
2299 | leadingBufferZone: 300,\r | |
2300 | pageSize: 100,\r | |
2301 | autoDestroy: true\r | |
2302 | });\r | |
2303 | \r | |
2304 | makeGrid({\r | |
2305 | columns: [{\r | |
2306 | dataIndex: 'name',\r | |
2307 | width: 100\r | |
2308 | }]\r | |
2309 | }, {\r | |
2310 | store: store\r | |
2311 | });\r | |
2312 | \r | |
2313 | store.load();\r | |
2314 | \r | |
2315 | completeWithData({\r | |
2316 | total: 5000,\r | |
2317 | data: makeData(100)\r | |
2318 | });\r | |
2319 | \r | |
2320 | completeWithData({\r | |
2321 | total: 5000,\r | |
2322 | data: makeData(100, 101)\r | |
2323 | });\r | |
2324 | \r | |
2325 | completeWithData({\r | |
2326 | total: 5000,\r | |
2327 | data: makeData(100, 201)\r | |
2328 | });\r | |
2329 | \r | |
2330 | completeWithData({\r | |
2331 | total: 5000,\r | |
2332 | data: makeData(100, 301)\r | |
2333 | });\r | |
2334 | \r | |
2335 | waitsFor(function () {\r | |
2336 | view.scrollBy(null, 10);\r | |
2337 | return view.all.startIndex <= 199 && view.all.endIndex >= 199;\r | |
2338 | }, 'row 199 to scroll into the rendered block', 10000);\r | |
2339 | \r | |
2340 | runs(function () {\r | |
2341 | store.addFilter({\r | |
2342 | property: 'name',\r | |
2343 | value: 'name212'\r | |
2344 | });\r | |
2345 | \r | |
2346 | // Unfortunately, we're testing private properties here :(\r | |
2347 | expect(plugin.bodyTop).toBe(0);\r | |
2348 | expect(plugin.position).toBe(0);\r | |
2349 | });\r | |
2350 | });\r | |
2351 | it('should reset the cached position so the grid-item-container is at the top of the view on clearFilter', function () {\r | |
2352 | var selModel;\r | |
2353 | \r | |
2354 | Hobbit = Ext.define(null, {\r | |
2355 | extend: 'Ext.data.Model',\r | |
2356 | fields: ['name'],\r | |
2357 | proxy: {\r | |
2358 | type: 'ajax',\r | |
2359 | url: '/foo',\r | |
2360 | reader: {\r | |
2361 | rootProperty: 'data'\r | |
2362 | }\r | |
2363 | }\r | |
2364 | });\r | |
2365 | \r | |
2366 | store = new Ext.data.Store({\r | |
2367 | model: Hobbit,\r | |
2368 | remoteFilter: false,\r | |
2369 | autoDestroy: true,\r | |
2370 | proxy: {\r | |
2371 | type: 'memory',\r | |
2372 | data: makeData(5000)\r | |
2373 | },\r | |
2374 | autoLoad: true\r | |
2375 | });\r | |
2376 | \r | |
2377 | makeGrid({\r | |
2378 | columns: [{\r | |
2379 | dataIndex: 'name',\r | |
2380 | width: 100\r | |
2381 | }],\r | |
2382 | selModel: {\r | |
2383 | type: 'rowmodel',\r | |
2384 | mode: 'MULTI'\r | |
2385 | }\r | |
2386 | }, {\r | |
2387 | store: store\r | |
2388 | });\r | |
2389 | selModel = grid.selModel;\r | |
2390 | \r | |
2391 | // Wait for first block to be rendered\r | |
2392 | waitsFor(function() {\r | |
2393 | return view.all.startIndex === 0 && view.all.getCount();\r | |
2394 | });\r | |
2395 | \r | |
2396 | runs(function() {\r | |
2397 | \r | |
2398 | // Only show the first 2500\r | |
2399 | store.addFilter({\r | |
2400 | property: 'id',\r | |
2401 | value: 2500,\r | |
2402 | operator: '<='\r | |
2403 | });\r | |
2404 | \r | |
2405 | // We have filtered out the top 2500 IDs: 2501-5000\r | |
2406 | expect(store.getCount()).toBe(2500);\r | |
2407 | \r | |
2408 | // Click to select first row\r | |
2409 | jasmine.fireMouseEvent(view.getCellByPosition({row: 0, column: 0}, true), 'click');\r | |
2410 | expect(view.selModel.getSelection().length).toBe(1);\r | |
2411 | });\r | |
2412 | \r | |
2413 | // Scroll all the way to the end\r | |
2414 | waitsFor(function () {\r | |
2415 | view.scrollBy(null, 100);\r | |
2416 | return view.all.endIndex === 2499;\r | |
2417 | }, 'scroll to end', 10000);\r | |
2418 | \r | |
2419 | runs(function () {\r | |
2420 | // Click to select from start to end.\r | |
2421 | jasmine.fireMouseEvent(view.getCellByPosition({row: 2499, column: 0}, true), 'click', null, null, null, true);\r | |
2422 | expect(view.selModel.getSelection().length).toBe(2500);\r | |
2423 | \r | |
2424 | store.remove(selModel.getSelection());\r | |
2425 | \r | |
2426 | // All records gone. (There are still 2500) filtered out though...\r | |
2427 | expect(store.getCount()).toBe(0);\r | |
2428 | \r | |
2429 | // Should have gone to top\r | |
2430 | expect(view.all.getCount()).toBe(0);\r | |
2431 | expect(view.getScrollY()).toBe(0);\r | |
2432 | \r | |
2433 | // Unfortunately, we're testing private properties here :(\r | |
2434 | expect(plugin.bodyTop).toBe(0);\r | |
2435 | expect(plugin.position).toBe(0);\r | |
2436 | \r | |
2437 | store.clearFilter();\r | |
2438 | \r | |
2439 | // The 2500 filtered out records should jump back in\r | |
2440 | expect(store.getCount()).toBe(2500);\r | |
2441 | \r | |
2442 | // Unfortunately, we're testing private properties here :(\r | |
2443 | expect(plugin.bodyTop).toBe(0);\r | |
2444 | expect(plugin.position).toBe(0);\r | |
2445 | });\r | |
2446 | });\r | |
2447 | });\r | |
2448 | \r | |
2449 | describe("reloading store", function() {\r | |
2450 | describe("from having items to not having items", function() {\r | |
2451 | it("should not cause an error when reloading", function() {\r | |
2452 | var store = new Ext.data.BufferedStore({\r | |
2453 | fields: ['id'],\r | |
2454 | autoDestroy: true,\r | |
2455 | proxy: {\r | |
2456 | type: 'ajax',\r | |
2457 | url: '/foo',\r | |
2458 | reader: {\r | |
2459 | type: 'json',\r | |
2460 | rootProperty: 'data',\r | |
2461 | totalProperty: 'total'\r | |
2462 | }\r | |
2463 | }\r | |
2464 | });\r | |
2465 | \r | |
2466 | makeGrid({\r | |
2467 | columns: [{\r | |
2468 | dataIndex: 'name',\r | |
2469 | width: 100\r | |
2470 | }]\r | |
2471 | }, {\r | |
2472 | store: store\r | |
2473 | });\r | |
2474 | \r | |
2475 | store.load();\r | |
2476 | satisfyRequests();\r | |
2477 | \r | |
2478 | store.reload();\r | |
2479 | satisfyRequests(0);\r | |
2480 | \r | |
2481 | expect(view.getNodes()).toEqual([]);\r | |
2482 | });\r | |
2483 | \r | |
2484 | it("should show emptyText if specified", function() {\r | |
2485 | var store = new Ext.data.BufferedStore({\r | |
2486 | fields: ['id'],\r | |
2487 | autoDestroy: true,\r | |
2488 | proxy: {\r | |
2489 | type: 'ajax',\r | |
2490 | url: '/foo',\r | |
2491 | reader: {\r | |
2492 | type: 'json',\r | |
2493 | rootProperty: 'data',\r | |
2494 | totalProperty: 'total'\r | |
2495 | }\r | |
2496 | }\r | |
2497 | });\r | |
2498 | \r | |
2499 | makeGrid({\r | |
2500 | columns: [{\r | |
2501 | dataIndex: 'name',\r | |
2502 | width: 100\r | |
2503 | }],\r | |
2504 | emptyText: 'Empty'\r | |
2505 | }, {\r | |
2506 | store: store\r | |
2507 | });\r | |
2508 | \r | |
2509 | store.load();\r | |
2510 | satisfyRequests();\r | |
2511 | \r | |
2512 | store.reload();\r | |
2513 | satisfyRequests(0);\r | |
2514 | \r | |
2515 | expect(grid.el.down('.' + grid.emptyCls, true)).hasHTML('Empty');\r | |
2516 | });\r | |
2517 | });\r | |
2518 | \r | |
2519 | describe('loading the bound store', function () {\r | |
2520 | function testLockable(locked) {\r | |
2521 | makeTree({\r | |
2522 | columns: [{\r | |
2523 | xtype: 'treecolumn',\r | |
2524 | text: 'Tree Column',\r | |
2525 | width: 300,\r | |
2526 | locked: locked,\r | |
2527 | dataIndex: 'task'\r | |
2528 | }, {\r | |
2529 | text: 'Task1',\r | |
2530 | dataIndex: 'task1'\r | |
2531 | }, {\r | |
2532 | text: 'Task2',\r | |
2533 | dataIndex: 'task2'\r | |
2534 | }, {\r | |
2535 | text: 'Task3',\r | |
2536 | dataIndex: 'task3'\r | |
2537 | }, {\r | |
2538 | text: 'Task4',\r | |
2539 | dataIndex: 'task4'\r | |
2540 | }, {\r | |
2541 | text: 'Task5',\r | |
2542 | dataIndex: 'task5'\r | |
2543 | }],\r | |
2544 | }, 1000);\r | |
2545 | }\r | |
2546 | \r | |
2547 | it('should not scroll the view, non-locked grid', function () {\r | |
2548 | \r | |
2549 | testLockable(false);\r | |
2550 | \r | |
2551 | expect(view.el.dom.scrollTop).toBe(0);\r | |
2552 | store.load();\r | |
2553 | expect(view.el.dom.scrollTop).toBe(0);\r | |
2554 | });\r | |
2555 | \r | |
2556 | it('should not scroll the view, locked grid', function () {\r | |
2557 | var lockedView, normalView;\r | |
2558 | \r | |
2559 | testLockable(true);\r | |
2560 | lockedViewDom = view.lockedView.el.dom;\r | |
2561 | normalViewDom = view.normalView.el.dom;\r | |
2562 | \r | |
2563 | expect(lockedViewDom.scrollTop).toBe(0);\r | |
2564 | expect(normalViewDom.scrollTop).toBe(0);\r | |
2565 | store.load();\r | |
2566 | expect(lockedViewDom.scrollTop).toBe(0);\r | |
2567 | expect(normalViewDom.scrollTop).toBe(0);\r | |
2568 | });\r | |
2569 | });\r | |
2570 | });\r | |
2571 | \r | |
2572 | describe('Expanding view size', function() {\r | |
2573 | var window;\r | |
2574 | \r | |
2575 | afterEach(function() {\r | |
2576 | window.destroy();\r | |
2577 | });\r | |
2578 | \r | |
2579 | it('should scroll to top when view size expands to encapsulate whole dataset', function() {\r | |
2580 | var Person = Ext.define(null, {\r | |
2581 | extend: 'Ext.data.Model',\r | |
2582 | fields: ['name'],\r | |
2583 | proxy: {\r | |
2584 | type: 'ajax',\r | |
2585 | url: '/foo',\r | |
2586 | reader: {\r | |
2587 | rootProperty: 'data'\r | |
2588 | }\r | |
2589 | }\r | |
2590 | });\r | |
2591 | \r | |
2592 | var store = new Ext.data.Store({\r | |
2593 | model: Person,\r | |
2594 | proxy: {\r | |
2595 | type: 'memory',\r | |
2596 | data: makeData(52)\r | |
2597 | }\r | |
2598 | });\r | |
2599 | store.load();\r | |
2600 | var store1 = new Ext.data.Store({\r | |
2601 | model: Person,\r | |
2602 | proxy: {\r | |
2603 | type: 'memory',\r | |
2604 | data: makeData(52)\r | |
2605 | }\r | |
2606 | });\r | |
2607 | store1.load();\r | |
2608 | \r | |
2609 | var grid = new Ext.grid.Panel({\r | |
2610 | hideMode: 'offsets',\r | |
2611 | title: 'Grid 1',\r | |
2612 | store: store,\r | |
2613 | deferRowRender: false,\r | |
2614 | columns: [{\r | |
2615 | dataIndex: 'id'\r | |
2616 | }, {\r | |
2617 | dataIndex: 'name'\r | |
2618 | }]\r | |
2619 | });\r | |
2620 | var grid1 = new Ext.grid.Panel({\r | |
2621 | hideMode: 'offsets',\r | |
2622 | title: 'Grid 2',\r | |
2623 | store: store1,\r | |
2624 | deferRowRender: false,\r | |
2625 | columns: [{\r | |
2626 | dataIndex: 'id'\r | |
2627 | }, {\r | |
2628 | dataIndex: 'name'\r | |
2629 | }]\r | |
2630 | });\r | |
2631 | \r | |
2632 | window = new Ext.window.Window({\r | |
2633 | title: 'Test',\r | |
2634 | height: 395,\r | |
2635 | width: 800,\r | |
2636 | x: 10,\r | |
2637 | y: 10,\r | |
2638 | autoShow: true,\r | |
2639 | maximizable: true,\r | |
2640 | minimizable: true,\r | |
2641 | constrain: false,\r | |
2642 | layout: 'fit',\r | |
2643 | items: {\r | |
2644 | xtype: 'tabpanel',\r | |
2645 | items: [\r | |
2646 | grid, grid1\r | |
2647 | ]\r | |
2648 | }\r | |
2649 | });\r | |
2650 | var tabPanel = window.child('tabpanel');\r | |
2651 | \r | |
2652 | var view = grid.getView();\r | |
2653 | \r | |
2654 | // Scroll all the way to the end\r | |
2655 | waitsFor(function () {\r | |
2656 | view.scrollBy(null, 100);\r | |
2657 | return view.all.endIndex === view.store.getCount() - 1;\r | |
2658 | }, 'scroll to end', 10000);\r | |
2659 | \r | |
2660 | runs(function() {\r | |
2661 | view.scrollBy(null, 100);\r | |
2662 | \r | |
2663 | tabPanel.setActiveTab(1);\r | |
2664 | \r | |
2665 | // inserting at top\r | |
2666 | grid.store.insert(0,{'title': 'hi',replycount:5});\r | |
2667 | grid.store.insert(0,{'title': 'hi2',replycount:5});\r | |
2668 | \r | |
2669 | grid1.store.insert(0,{'title': 'hi',replycount:5});\r | |
2670 | grid1.store.insert(0,{'title': 'hi2',replycount:5});\r | |
2671 | \r | |
2672 | tabPanel.setActiveTab(0);\r | |
2673 | \r | |
2674 | window.setHeight(940);\r | |
2675 | });\r | |
2676 | \r | |
2677 | // Scroll all the way to the start\r | |
2678 | waitsFor(function () {\r | |
2679 | view.scrollBy(null, -100);\r | |
2680 | return view.getScrollY() === 0;;\r | |
2681 | }, 'scroll to top', 10000);\r | |
2682 | \r | |
2683 | runs(function() {\r | |
2684 | expect(view.bufferedRenderer.bodyTop).toBe(0);\r | |
2685 | });\r | |
2686 | });\r | |
2687 | });\r | |
2688 | \r | |
2689 | describe('ensureVisible', function() {\r | |
2690 | it('should work in a viewready listener', function() {\r | |
2691 | var done,\r | |
2692 | columns = [{\r | |
2693 | text: 'Col 1',\r | |
2694 | dataIndex: 'field1',\r | |
2695 | width: 100\r | |
2696 | }, {\r | |
2697 | text: 'Col 2',\r | |
2698 | dataIndex: 'field2',\r | |
2699 | width: 100\r | |
2700 | }, {\r | |
2701 | text: 'Col 3',\r | |
2702 | dataIndex: 'field3',\r | |
2703 | width: 100\r | |
2704 | }, {\r | |
2705 | text: 'Col 4',\r | |
2706 | dataIndex: 'field4',\r | |
2707 | width: 100\r | |
2708 | }];\r | |
2709 | \r | |
2710 | makeGrid({\r | |
2711 | columns: columns,\r | |
2712 | listeners : {\r | |
2713 | viewready : function(grid) {\r | |
2714 | grid.ensureVisible(grid.getStore().last(), {\r | |
2715 | callback: function() {\r | |
2716 | done = true;\r | |
2717 | }\r | |
2718 | });\r | |
2719 | }\r | |
2720 | }\r | |
2721 | }, {\r | |
2722 | fields: ['field1', 'field2', 'field3', 'field4'],\r | |
2723 | data: createData(1000)\r | |
2724 | });\r | |
2725 | \r | |
2726 | waitsFor(function() {\r | |
2727 | return done;\r | |
2728 | });\r | |
2729 | \r | |
2730 | // Should have scrolled all the way to the end\r | |
2731 | expect(view.all.endIndex).toBe(999);\r | |
2732 | expect(view.bufferedRenderer.getLastVisibleRowIndex()).toBe(999);\r | |
2733 | });\r | |
2734 | });\r | |
2735 | });\r | |
2736 | \r |