Uploaded image for project: 'ZK'
  1. ZK
  2. ZK-4172

ROD grid rerender cause scroll jumps and scroll size desync

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Major Major
    • 8.6.1
    • 8.6.1
    • None
    • Security Level: Jimmy
    • None
    • ZK 8.6.1 S1

      Steps to Reproduce

      http://zkfiddle.org/sample/1ant0tl/2-zk-grid-rerender-scroll-issue

      Scroll down untill triggering the ROD load
      (after line 100)

      click on any button
      each trigger grid.rerender() (directly, or through column.setSize > column.updateMesh)

      Current Result

      When rerendering the ROD grid, the scroll position jumps around and resizes incorectly

      Expected Result

      Rerendering a grid or resizing a column shouldn't break layout

      Debug Info

      Root Cause

      Workaround

      For column setWidth specifically:

      	<script><![CDATA[   
      	zk.afterLoad('zul.grid', function() {
      		var xColumn = {};
      		zk.override(zul.grid.Column.prototype, xColumn ,{
      			setWidth : function(w) {
      				this.handleWidth(w);
      			},
      			handleWidth(wd){
      				var wgt = this,
      					mesh = wgt.getMeshWidget(),
      					hdfaker = mesh.ehdfaker,
      					bdfaker = mesh.ebdfaker,
      					ftfaker = mesh.eftfaker,
      					cidx = zk(wgt.$n()).cellIndex();
      
      					if(hdfaker == null){
      						return;
      					}
      				
      				var hdcols = hdfaker.childNodes,
      					bdcols = bdfaker.childNodes,
      					ftcols = ftfaker ? ftfaker.childNodes : null;
      
      				//1. store resized width
      				// B70-ZK-2199: convert percent width to fixed width
      				var wds = [];
      				for (var w = mesh.head.firstChild, i = 0; w; w = w.nextSibling, i++) {
      					var stylew = hdcols[i].style.width,
      						origWd = w._origWd, // ZK-1022: get original width if it is shrinked by Frozen.js#_doScrollNow
      						isFixedWidth = stylew && stylew.indexOf('%') < 0;
      
      					if (origWd) {
      						if (isFixedWidth && zk.parseFloat(stylew) > 1) {
      							origWd = stylew; // use the latest one;
      						}
      						w._width = wds[i] = origWd;
      					} else {
      						wds[i] = isFixedWidth ? stylew : jq.px0(w.$n().offsetWidth);
      						if (w.isVisible()) w._width = wds[i];
      					}
      					if (!isFixedWidth) {
      						hdcols[i].style.width = bdcols[i].style.width = wds[i];
      						if (ftcols) //ZK-2769: Listfooter is not aligned with listhead on changing width
      							ftcols[i].style.width = wds[i];
      					}
      
      					// reset hflex, Bug ZK-2772 - Misaligned Grid columns
      					var wdInt = zk.parseInt(wds[i]);
      					if (w._hflexWidth) {
      						w.setHflex_(null);
      						w._hflexWidth = undefined;
      					}
      					if (mesh._minWd) {
      						mesh._minWd.wds[i] = wdInt;
      					}
      				}
      
      
      				//2. set resized width to colgroup col
      				if (!wgt.origWd)
      					wgt._width = wds[cidx] = wd;
      				hdcols[cidx].style.width = bdcols[cidx].style.width = wd;
      				if (ftcols) //ZK-2769: Listfooter is not aligned with listhead on changing width
      					ftcols[cidx].style.width = wd;
      
      				//3. clear width=100% setting, otherwise it will try to expand to whole width
      				mesh.eheadtbl.width = '';
      				mesh.ebodytbl.width = '';
      				if (mesh.efoottbl)
      					mesh.efoottbl.width = '';
      
      				delete mesh._span; //no span!
      				delete mesh._sizedByContent; //no sizedByContent!
      				for (var w = mesh.head.firstChild; w; w = w.nextSibling)
      					w.setHflex_(null); //has side effect of setting w.$n().style.width of w._width
      
      				wgt.parent.fire('onColSize', zk.copy({
      					index: cidx,
      					column: wgt,
      					width: wd ,
      					widths: wds
      				}, null), null, 0);
      
      				// bug #2799258 in IE, we have to force to recalculate the size.
      				mesh.$n()._lastsz = null;
      
      				// for the test case of B70-ZK-2290.zul, we need to put the width back.
      				if (!zk.webkit) {
      					mesh.eheadtbl.width = '100%';
      					mesh.ebodytbl.width = '100%';
      					if (mesh.efoottbl)
      						mesh.efoottbl.width = '100%';
      				}
      				// bug #2799258
      				zUtl.fireSized(mesh, -1); //no beforeSize
      			}
      		});//zk.override
      	});//zk.afterLoad
      	]]></script>
      

            rudyhuang rudyhuang
            MDuchemin MDuchemin
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:

                Estimated:
                Original Estimate - 1 day
                1d
                Remaining:
                Time Spent - 6 hours Remaining Estimate - 2 hours
                2h
                Logged:
                Time Spent - 6 hours Remaining Estimate - 2 hours
                6h