0

Remove grid extra scroll space with frozen columns

asked 2024-03-23 18:34:19 +0800

GiovanniDeMarco gravatar image GiovanniDeMarco
161 4

I'm using a grid with frozen columns.

As stated in the Grid documentation page (https://www.zkoss.org/wiki/ZKComponentReference/Supplementary/Frozen) at section "Scroll to Hide Columns", "By default, Grid will render extra space (larger width) after the last column. So that you can drag to hide all columns except the last one.".

Is there a way or some configuration to remove this extra space? I want to obtain a grid similar to the one in this demo: as you can see no extra space is added after the last column.

Can someone help me? Thanks in advance.

delete flag offensive retag edit

3 Answers

Sort by ยป oldest newest most voted
1

answered 2024-04-06 16:23:16 +0800

GiovanniDeMarco gravatar image GiovanniDeMarco
161 4

Thanks to MDuchemin's advice, I worked on the javascript in "Frozen.js" and I managed to get what I wanted. Instead of overriding the "_doScrollNow" function (that would have been a little bit tricky for me), I worked on the "_onSizeLater" function.

Here I changed the width assigned to the scrolling element in the "frozen" horizontal bar. Instead of calculating the "scrollScale" as the number of the not-frozen columns, I used the number of currently not visible not-frozen columns based on the actual width of the grid. Here is the javascript I changed:

    [...]
    // CUSTOM: given the calculated width, compute how many 
    // non-frozen cols will not be visible
    var nonFrozenColsWidth = 0;
    var notVisibleCols = 0;
    // Start the index from the first not-frozen col
    for(var i = columns; i < cells.length; i++){
        // Skip hidden cols and scrollbar (cols with no width)
        if (cells[i].offsetWidth > 0) {
            // compute the total width the not-frozen cols need
            nonFrozenColsWidth += cells[i].offsetWidth;
            // if this width exceeds the width of the grid, 
            // count this as a not visible column
            if (nonFrozenColsWidth > width){
               notVisibleCols++;
           }
        }
    }

    // CUSTOM: Calculate scrollScale only for exceeding columns
    // var scrollScale = totalcols - columns - 1; // <-- This is the OLD way
    var scrollScale = notVisibleCols ; // <-- This is the CUSTOMIZED way
    var scrollWidth = width + 50 * scrollScale;
    scroll.firstChild.style.width = jq.px0(scrollWidth);
    wgt.syncScroll();

To call the "new" version of "onSizeLater" I had to override the onSize function of the "zul.mesh.Frozen" prototype (no changes made, just overriding as it is... only to call the customized "onSizeLater" function):

zk.afterLoad('zul.mesh', function() { //specify zk widget package name
    var exWidget = {};
    zk.override(zul.mesh.Frozen.prototype, exWidget, { //specify zk full widget name
        onSize: function () {
            if (!this._columns)
                    return;
            var self = this;
            self._syncFrozen(); // B65-ZK-1470

            //B70-ZK-2129: prevent height changed by scrolling
            var p = this.parent,
                    phead = p.head,
                    firstHdcell, fhcs;
            if (p._nativebar && phead) {
                    //B70-ZK-2558: frozen will onSize before other columns,
                    //so there might be no any column in the beginning
                    var n = phead.$n();
                    firstHdcell = n ? (n.cells ? n.cells[0] : null) : null;
                    //B70-ZK-2463: if firstHdcell is not undefined
                    if (firstHdcell) {
                            fhcs = firstHdcell.style;
                            if (!fhcs.height)
                                    fhcs.height = firstHdcell.offsetHeight + 'px';
                    }
            }

            // Bug 3218078, to do the sizing after the 'setAttr' command
            setTimeout(function () {
                    _onSizeLater(self);
                    self._syncFrozenNow();
            });
        }
    });
});

Surely this is not the best way, but it was the fastest/easieast for me!

Hope this could be useful for someone else.

link publish delete flag offensive edit

Comments

nice! I recommend you make that answer the accepted answer, to mark it as useful if someone else search for this topic.

MDuchemin ( 2024-04-22 09:59:08 +0800 )edit
1

answered 2024-03-28 18:24:27 +0800

MDuchemin gravatar image MDuchemin
2560 1 6
ZK Team

Regarding the behavior of the CE version:

CE keeps the whitespace by default, but you can customize it with a JS override. https://www.zkoss.org/wiki/ZKClient-sideReference/GeneralControl/WidgetCustomization

See here for the original function in charge of the scroll: https://github.com/zkoss/zk/blob/v9.6.0/zul/src/archive/web/js/zul/mesh/Frozen.js#L301C2-L429C3

The way it "scrolls" in this case is that the position of the scrollbar is retrieved as the "num" argument of the function, with the right-end of the scrollbar being the last column in your component.

Every columns before the target receive a width of 0px (technically 0.001px because old browsers were weird like that)

If you want that last column to end on the right-most side of the control, I think the easiest way to accomplish that would be to do the regular processing, then at the end, correct the previous columns' with going from right to left, based on the remaining available width in the component.

for example, if your grid is 500px wide, you'd check the width used by the last column, and if you have anything remaining after substracting the column with from the available space, you'd get the rightmost hidden column, count how much width it requires, and if there is enough left in the total width, show that one instead of hiding it. Same with the next ones until you run out of total width.

link publish delete flag offensive edit

Comments

Thanks MDuchemin! Very interesting! I'll give it a try!

GiovanniDeMarco ( 2024-03-28 23:14:38 +0800 )edit
0

answered 2024-03-27 15:53:16 +0800

MDuchemin gravatar image MDuchemin
2560 1 6
ZK Team

Hey there,

Good news! just update to any ZK version after 8.5.0

The Frozen feature was reworked in 8.5.0, and no longer adds extra white space after the last column. Here's the tracker entry of the rework: ZK-3525

The demo listed in your question is the default state in the current releases.

link publish delete flag offensive edit

Comments

Forgot to mention, but that's in ZK EE. You can use the eval versions to test it out, if you want to try it in your local environment

MDuchemin ( 2024-03-27 21:06:42 +0800 )edit

Actually i'm using ZK 9.6.0 CE. So, there's no way to disable that extra space in CE version?

GiovanniDeMarco ( 2024-03-28 01:11:57 +0800 )edit
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow
1 follower

RSS

Stats

Asked: 2024-03-23 18:34:19 +0800

Seen: 16 times

Last updated: Apr 06

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More