Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is variable rowheight a possibility in SlickGrid?

I would like to provide variable row height depending upon the content size. is it possible in Slickgrid?

Can you point me towards any examples?

like image 684
sandie Avatar asked May 10 '10 17:05

sandie


4 Answers

This is possible but it's not trivial and you will likely take a performance penalty. The way SlickGrid works, it needs to be able to answer the following two questions rapidly:

  • For a given row X, what is the top offset for that row?
  • For a given offset Y, what row is at that offset?

When you use a static row height, answering these questions is trivial; however, with dynamic row height, you'll need to maintain a couple of extra data structures.

Here's roughly what I changed in Slick.Grid.js

  • Add a new array to track row sizes. Initialize all rows to the default size
  • Remove the css rules in createCssRules which set the cell height
  • Add some code at the end of renderRows which checks the rendered height of each cell in the row and then sets the height of all cells to the maximum (and stores the height in the row size array). You also need to adjust the top offset based on the sum of heights of rows above the current one.
  • Add code to the end of render to resize the canvas to the sum of all row heights.
  • Update getViewport to return the top and bottom rows based on the sums of row heights.
  • There are a handful of other places where options.rowHeight is used. You can ignore some of them but at the very least, anywhere the canvas is resized needs to be changed.

To make this practical (performant), you'll also need a cache of row top offsets (a cache of sums of row size). This will enable quick computation for the first question and will allow for binary search to answer the second.

I hope that helps.

like image 56
Codure Avatar answered Nov 15 '22 10:11

Codure


I have implemented this in my project, with the help of @Stephen Robinson 's answer here.
If anyone is interested they can check:
https://github.com/vihari/Seaview/blob/version3.0/SlickGrid-master/slick.grid.js.
It can be enabled with the file above if you set options.enableWrap to true.
Thank you.

like image 27
Vihari Piratla Avatar answered Nov 15 '22 10:11

Vihari Piratla


I know this doesn't meet the heart of the question, but decided upon a simple solution for now that is minimal effort and meets my requirements at the moment. So, this is just in case others were looking for a simple solution as well.

I started with an input box, where changing the value would resize the row. However, I've now settled on using a slider. As a matter of fact, since I have such little data in my grid (guaranteed to be small amounts of data, and very few rows), I dynamically resize the grid as the slider slides. Now, I know many will say this is a terrible idea because it can be horribly slow, but again, I'm using a very small amount of data.

The key is that I recreate the grid again with the new rowHeight value set in the options.

  1. Include jQuery UI:
  2. Create elements for the slider and the value
  3. Be sure your grid is set up and initialized for when the page loads.
  4. Add the code to handle the slider and recreating the grid (alternatively, you could move what I have in the "slide" function to the "stop" function if you don't want to redraw on every sliding tick):

    $j( "#resizeRowSlider" ).slider({
          range:"min"
        , min: 50
        , max: 200
        , value: 50
        , create: function( even, ui ) {
            $j("rowResizeValue").html( "50" );
        }
        , slide: function( event, ui ) {
            $j( "rowResizeValue" ).html( ui.value );
    
            options.rowHeight = ui.value;
    
            // I do a manual resize; you could use autoHeight:true in grid options
            resizeGrid();
    
            grid = new Slick.Grid("#" + gridElemId, json, columns , options);
            grid.setSelectionModel(new Slick.RowSelectionModel() );
    
            refreshGrid(); // Handle invalidate, resizeCanvas
        }
        , stop: function( event, ui ) {
        }
    });
    

Also, I should note that this is not on a per row basis, but again, it fits my needs for now. It's not ideal, but it works. Additionally, if you really need to render the grid the first time without any overflow, you can create a hidden div whenever you get the text in question and add display:table-cell, then get the div height and set that value the grid options for rowHeight. Then, create (or recreate) the grid.

like image 44
thephatp Avatar answered Nov 15 '22 10:11

thephatp


Plain and simple, this is not supported in SlickGrid and likely will never be. Sorry.

like image 40
Tin Avatar answered Nov 15 '22 10:11

Tin