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

Invisible columns affect mesh column span width count with flex

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Normal Normal
    • 8.6.0
    • 8.5.2, 8.5.1.2
    • None
    • Security Level: Jimmy
    • None
    • ZK 8.6.0 S1

      Steps to Reproduce

      Run fiddle:
      http://zkfiddle.org/sample/2f70hon/3-span-flex-with-mesh-break-width-if-header-not-visible

      Click on invisible to hide the first column.
      Click on the remove button to delete the first column and the first cell

      Current Result

      When hiding the first column:

      Since the column is visible:hidden, but not display:none; the isVisible() call during MeshWidget._adjSpanWd returns "true" even if the column element is hidden.
      Since the isVisible returns true, the hidden column is calculated as part of the span width.

      When removing the first column:
      Sizes are calculated as expected.
      Column width are different that when using hidden column

      Expected Result

      hidden column and removed column should produce the same widths for the remaining columns in the mesh component

      Debug Info

      The first column still counts as visible when calculating header width during MeshWidget._adjSpanWd (called during onSize with span / flex="min" to calculate span widths)
      https://github.com/zkoss/zk/blob/cb68179664830f4e66aff97da415369e6994856c/zul/src/archive/web/js/zul/mesh/MeshWidget.js#L1444

      isVisible() on the column header hidden element only checks for display:none (since isVisible is not called with the strict parameter)
      https://github.com/zkoss/zk/blob/be15d1d0cbd2eccd811dbfad57a9cba5fa204df9/zk/src/archive/web/js/zk/dom.js#L618

      Root Cause

      Workaround

      ZK 8.5.1.2 and 8.5.2

      <script><![CDATA[
      	zk.afterLoad('zul.mesh', function() {
      		var xMeshWidget = {};
      		zk.override(zul.mesh.MeshWidget.prototype, xMeshWidget ,{
      			_adjSpanWd: function () { //used in HeadWidgets
      				if (!this._isAllWidths() || !this.isSpan())
      					return;
      				var hdfaker = this.ehdfaker,
      					bdfaker = this.ebdfaker,
      					ftfaker = this.eftfaker;
      				if (!hdfaker || !bdfaker)
      					return;
      	
      				var head = this.head.$n();
      				if (!head)
      					return;
      				this._calcMinWds();
      				var wd,
      					wds = [],
      					width = 0,
      					hdcol = hdfaker.firstChild,
      					bdcol = bdfaker.firstChild,
      					_minwds = this._minWd.wds,
      					hdlen = this.head.nChildren;
      	
      				for (var temphdcol = hdcol, w = this.head.firstChild, i = 0; w; w = w.nextSibling, i++) {
      					if (zk(temphdcol).isVisible(true)) {
      						var wdh = w._width;
      	
      						if (w._hflex == 'min')
      							wd = wds[i] = _minwds[i];
      						else if (wdh && wdh.endsWith('px'))
      							wd = wds[i] = zk.parseInt(wdh);
      						else
      							wd = wds[i] = _minwds[i];
      	
      						width += wd;
      					}
      					temphdcol = temphdcol.nextSibling;
      				}
      	
      				var	ftcol = ftfaker ? ftfaker.firstChild : null,
      					total = this.ebody.clientWidth,
      					extSum = total - width,
      					count = total,
      					visj = -1,
      					tblWidth = 0; //refix B70-ZK-2394: should sync colgroup width with table width
      	
      				 //span to all columns
      				if (this._nspan < 0) {
      	
      	
      					var hasFrozenScrolled = this.frozen && this.frozen.getStart();
      					for (var i = 0; hdcol && i < hdlen; hdcol = hdcol.nextSibling, i++) {
      						// ZK-2222: should check visibility
      						if (!zk(hdcol).isVisible(true)) {
      							bdcol = bdcol.nextSibling;
      							if (ftcol)
      								ftcol = ftcol.nextSibling;
      							continue;
      						} else {
      	
      							// for bug ZK-2772, we don't span it when frozen column has scrolled.
      		                    // Instead, we use its faker width.
      							if (hasFrozenScrolled) {
      								if (extSum <= 0) {
      									wds[i] = wd = wds[i];
      								} else {
      									if (hdcol.style.width) {
      										wds[i] = wd = zk.parseInt(hdcol.style.width);
      									} else {
      										wds[i] = wd = Math.round(((wds[i] * total / width) + 0.5) || 0);
      									}
      								}
      							} else {
      								wds[i] = wd = extSum <= 0 ? wds[i] : Math.round(((wds[i] * total / width) + 0.5) || 0);
      							}
      							var stylew = jq.px0(wd);
      							count -= wd;
      							visj = i;
      	
      							hdcol.style.width = stylew;
      							bdcol.style.width = stylew;
      							tblWidth += wd; //refix B70-ZK-2394: store each col's width
      							bdcol = bdcol.nextSibling;
      	
      							if (ftcol) {
      								ftcol.style.width = stylew;
      								ftcol = ftcol.nextSibling;
      							}
      						}
      					}
      					//compensate calc error but excluding scrolled frozen column
      					if (extSum > 0 && count != 0 && visj >= 0) {
      						tblWidth -= wd; //refix B70-ZK-2394: subtract the last wd (visj is the last)
      						wd = wds[visj] + count;
      						var stylew = jq.px0(wd);
      	
      						tblWidth += wd; //refix B70-ZK-2394: and add new wd
      	
      						if (!hasFrozenScrolled) {
      							bdfaker.childNodes[visj].style.width = stylew;
      							hdfaker.childNodes[visj].style.width = stylew;
      	
      							if (ftfaker)
      								ftfaker.childNodes[visj].style.width = stylew;
      						}
      					}
      				} else { //feature#3184415: span to a specific column
      					visj = this._nspan - 1;
      					for (var i = 0; hdcol && i < hdlen; hdcol = hdcol.nextSibling, i++) {
      						if (!zk(hdcol).isVisible()) {
      							bdcol = bdcol.nextSibling;
      							if (ftcol)
      								ftcol = ftcol.nextSibling;
      							continue;
      						} else {
      							wd = visj == i && extSum > 0 ? (wds[visj] + extSum) : wds[i];
      							var stylew = jq.px0(wd);
      							hdcol.style.width = stylew;
      							bdcol.style.width = stylew;
      							tblWidth += wd; //refix B70-ZK-2394: store each col's width
      							bdcol = bdcol.nextSibling;
      							if (ftcol) {
      								ftcol.style.width = stylew;
      								ftcol = ftcol.nextSibling;
      							}
      						}
      					}
      				}
      	
      				//refix B70-ZK-2394: sync colgroup width with (head, body, foot)table width
      				var allWidths = this._isAllWidths();
      				if (allWidths) {
      					var hdtbl = this.eheadtbl,
      						bdtbl = this.ebodytbl,
      						fttbl = this.efoottbl;
      	
      					if (hdtbl) {
      						hdtbl.style.width = tblWidth + 'px';
      						if (bdtbl)
      							bdtbl.style.width = tblWidth + 'px';
      						if (fttbl)
      							fttbl.style.width = tblWidth + 'px';
      					}
      				}
      	
      				//bug 3188738: Opera only. Grid/Listbox/Tree span="x" not working
      				if (zk.opera)
      					zk(this.$n()).redoCSS();
      			}
      		});//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 - 4 hours
                4h
                Remaining:
                Time Spent - 2 hours Remaining Estimate - 2 hours
                2h
                Logged:
                Time Spent - 2 hours Remaining Estimate - 2 hours
                2h