Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slickgrid: Final column autosize to use all remaining space

I'm using SlickGrid and struggling to find an elegant solution to the following:

  1. All columns must have a specific initial width when first rendered but be resizable afterwards
  2. The final column should auto fill the remaining column space when the window is resized

I've seen:

Make one column fill remaining space in SlickGrid without messing up explicit width columns
resizing of grid when resizing browser window
How do I autosize the column in SlickGrid?

But these don't seem to quite do what I need. If I use the forceFitColumns option, then all columns will autosize (unless I put a maxsize on them). Using resizeCanvas on window.resize works well - but it still only works if forceFitColumns is true.

If I set minWidth=maxWidth - then I can't resize the column.

Any suggestions?

like image 670
Scott Durow Avatar asked Mar 24 '23 09:03

Scott Durow


2 Answers

I'm not sure it would correct all your problem but in my case I do use the forceFitColumns and then depending how I want my column to react in size I will use a combination of minWidth and width, and in some cases the ones that will never exceed a certain width, I would then use a maxWidth as well. Now the problem you have is when setting the minWidth to be the same with as maxWidth this of course will make it unresizable, well think about it you set a minimum and a maximum, SlickGrid is respecting it by now being able to size it afterwards. I also have my grid which takes 95% width of my screen so I have a little padding on the side and with it I use a auto-resize using jQuery.

Here is my code:

// HTML Grid Container
<div id="myGridContainer" style="width:95%;">
    <div class="grid-header" style="width:100%">
        <label>ECO: Log / Slickgrid</label>
        <span style="float:right" class="ui-icon ui-icon-search" title="Toggle search panel" onclick="toggleFilterRow1()"></span>
    </div>
    <div id="myGrid" style="width:100%;height:600px;"></div>
    <div id="myPager"></div>
</div>

// My SlickGrid Options
var options = {
    enableCellNavigation: true,
    forceFitColumns: true
};

// The browser auto-resize 
$(window).resize(function () {
    $("#myGrid").width($("myGridContainer").width());
    $(".slick-viewport").width($("#myGrid").width());
    grid.resizeCanvas();
});


EDIT
I also was annoyed by the fact that using all of these together is blocking you from resizing the width of the column. I came up with a different solution, much later after, which makes the fields to expand (take available width) and does not block you afterwards on resizing the width. So this new solution I believe is giving you exactly what you are looking for... First of all remove the maxWidth property and only use minWidth and width, actually you could probably use only the width if you wanted. Now I had to unfortunately, modify 1 of the core file slick.grid.js with the following code:

//-- slick.grid.js --//

// on line 69 insert this code
autoExpandColumns: false,

// on line 1614 PREVIOUS CODE
if (options.forceFitColumns) {
    autosizeColumns();
}

// on line 1614 change to this NEW CODE
if (options.forceFitColumns || options.autoExpandColumns) {
    autosizeColumns();
}

then going back to my grid definition, I replace my previous options with this:

// My NEW SlickGrid Options
var options = {
    enableCellNavigation: true,
    forceFitColumns: false,     // make sure the force fit is false
    autoExpandColumns: true     // <-- our new property is now usable
};

with this new change it has some functionality of the force fit (expanding) but does not restrict you on resizing your columns width afterwards like the force fit does. I also tested it with the columnPicker, if you hide a column it's resizing the others accordingly. I also modified the file slick.columnpicker.js to include a checkbox for that property but that is totally optional...I can add the code for that too if any of you want it as well. Voila!!! :)


EDIT #2
I realized much later that there's no need to modify the core file, we can simply call grid.autosizeColumns() after the grid creation. Like this

var options = { forceFitColumns: false };
grid = new Slick.Grid("#myGrid", data, columns, options);

// will take available space only on first load
grid.autosizeColumns(); 

This will automatically resize the columns to fit the screen on first load but will not give you the restriction of the forceFitcolumns flag.

like image 160
ghiscoding Avatar answered Apr 25 '23 16:04

ghiscoding


I know it's kind late for this reply.

But i've managed to do that without having to change things at slick.grid.js or set min/maxWidth at columns array.

Instead what i did was to iterate through the columns array adding the values of "width" field of each column and then i've did a simple math count to set the last column width as innerWidth - totalColumsWidth + lastColumnWidth.

Code:

function lastColumnWidth(columns)
{
        var widthSum = 0;
        angular.forEach(columns, function(col) {
            if(col.width) { widthSum = col.width + widthSum; }
        });
        if(window.innerWidth > widthSum) {
            columns[columns.length-1].width = columns[columns.length-1].width + (window.innerWidth - widthSum);
        }
        return columns;
}
like image 45
Raphael Koszalka Avatar answered Apr 25 '23 15:04

Raphael Koszalka