SlickGrid的行高可以动态改变吗?

时间:2012-05-10 13:36:14

标签: slickgrid

我们正在实施用户首选项(立即)在网格上显示“更多”或“更少”的数据。 “更多”应该增加行高(每行具有相同的增加高度)。

当用户切换时,我们更新DataView,并使用更新的rowHeight值调用网格上的setOptions。然后我们调用invalidate()和render()。

但行高未更新。 :(

有人可以建议解决方案吗?我们应该直接通过CSS改变高度吗?如果是这样,有关这方面的任何提示吗?

3 个答案:

答案 0 :(得分:15)

实际上 可以根据用户交互动态更新行高。 Slickgrid API提供了我们所需要的一切。

由于:

  1. 我们可以动态添加/删除行;
  2. 我们可以在第一行和第二行动态应用自定义css细胞水平。

  3. 这是一个简单的演示来开始:

    ////////////////////////////////////////////////////////////////////////////////
    //example codez re trying to create a grid with rows of dynamic height to
    //cater for folks that wanna bung loads of stuff in a field & see it all...
    //by violet313@gmail.com ~ visit: www.violet313.org/slickgrids
    //have all the fun with it  ;) vxx.
    ////////////////////////////////////////////////////////////////////////////////
    modSlickgridSimple=(
    function()
    {
        var _dataView=null;
        var _grid=null;
        var _data=[];
    
    
        //////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////
        var getPaddingItem=function(parent , offset)
        {
            var item={};
    
            for (var prop in _data[0]) item[prop]=null;
            item.id=parent.id+"."+offset;
    
            //additional hidden padding metadata fields
            item._collapsed=     true;
            item._isPadding=     true;
    
            return item;
        }
    
        //////////////////////////////////////////////////////////////
        //this just builds our expand collapse button
        //////////////////////////////////////////////////////////////
        var onRenderIDCell=function(row, cell, value, columnDef, item)
        {
            if (item._isPadding==true); //render nothing
            else if (item._collapsed) return "<div class='toggle expand'></div>";
            else
            {
                var html=[];
                var rowHeight=_grid.getOptions().rowHeight;
    
                //V313HAX:
                //putting in an extra closing div after the closing toggle div and ommiting a
                //final closing div for the detail ctr div causes the slickgrid renderer to
                //insert our detail div as a new column ;) ~since it wraps whatever we provide
                //in a generic div column container. so our detail becomes a child directly of
                //the row not the cell. nice =)  ~no need to apply a css change to the parent
                //slick-cell to escape the cell overflow clipping.
    
                //sneaky extra </div> inserted here-----------------v
                html.push("<div class='toggle collapse'></div></div>");
    
                html.push("<div class='dynamic-cell-detail' ");   //apply custom css to detail
                html.push("style='height:", item._height, "px;"); //set total height of padding
                html.push("top:", rowHeight, "px'>");             //shift detail below 1st row
                html.push("<div>",item._detailContent,"</div>");  //sub ctr for custom styling
                //&omit a final closing detail container </div> that would come next
    
                return html.join("");
            }
        }
    
        //////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////
        var onRowClick=function(e, args)
        {
            _dataView.beginUpdate();
    
            if ($(e.target).hasClass("toggle"))
            {
                var item=_dataView.getItem(args.row);
    
                if (item)
                {
                    if (!item._collapsed)
                    {
                        item._collapsed=true;
                        for (var idx=1; idx<=item._sizePadding; idx++)
                            _dataView.deleteItem(item.id+"."+idx);
                        item._sizePadding=0;
                    }
                    else
                    {
                        item._collapsed=false;
                        kookupDynamicContent(item);
                        var idxParent=_dataView.getIdxById(item.id);
                        for (var idx=1; idx<=item._sizePadding; idx++)
                            _dataView.insertItem(idxParent+idx, getPaddingItem(item,idx));
                    }
                    _dataView.updateItem(item.id, item);
                }
                e.stopImmediatePropagation();
            }
    
            _dataView.endUpdate();
        }
    
        //////////////////////////////////////////////////////////////
        var gridOptions={ enableColumnReorder:  true };
    
        //////////////////////////////////////////////////////////////
        var _gridColumns=
        [
            {
                id:         "id",
                name:       "",
                field:      "id",
                resizable:  false,
                width:      20,
                formatter:  onRenderIDCell,
            },
            {id: "title",        name: "Title",         field: "title",        resizable: true},
            {id: "duration",     name: "Duration",      field: "duration",     resizable: true},
            {id: "pcComplete",   name: "% Complete",    field: "pcComplete",   resizable: true},
            {id: "start",        name: "Start",         field: "start",        resizable: true},
            {id: "finish",       name: "Finish",        field: "finish",       resizable: true},
            {id: "effortDriven", name: "Effort Driven", field: "effortDriven", resizable: true},
        ];
    
        //////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////
        var kookupTestData=(function()
        {
            for (var i = 0; i < 100; i++)
                _data[i] =
                {
                    id:               i,
                    title:            "Task " + i,
                    duration:         "5 days",
                    pcComplete:       Math.round(Math.random() * 100),
                    start:            "01/01/2009",
                    finish:           "01/05/2009",
                    effortDriven:     (i % 5 == 0),
    
                    //additional hidden metadata fields
                    _collapsed:       true,
                    _sizePadding:     0,     //the required number of pading rows
                    _height:          0,     //the actual height in pixels of the detail field
                    _isPadding:       false,
                };
        })();
    
        //////////////////////////////////////////////////////////////
        //create the detail ctr node. this belongs to the dev & can be custom-styled as per
        //////////////////////////////////////////////////////////////
        var kookupDynamicContent=function(item)
        {
            //add some random oooks as fake detail content
            var oookContent=[];
            var oookCount=Math.round(Math.random() * 12)+1;
            for (var next=0; next<oookCount; next++)
                oookContent.push("<div><span>oook</span></div>");
            item._detailContent=oookContent.join("");
    
            //calculate padding requirements based on detail-content..
            //ie. worst-case: create an invisible dom node now &find it's height.
            var lineHeight=13; //we know cuz we wrote the custom css innit ;)
            item._sizePadding=Math.ceil((oookCount*lineHeight) / _grid.getOptions().rowHeight);
            item._height=(item._sizePadding * _grid.getOptions().rowHeight);
        }
    
        //////////////////////////////////////////////////////////////
        //jquery onDocumentLoad
        //////////////////////////////////////////////////////////////
        $(function()
        {
            //initialise the data-model
            _dataView=new Slick.Data.DataView();
            _dataView.beginUpdate();
            _dataView.setItems(_data);
            _dataView.endUpdate();
    
            //initialise the grid
            _grid=new Slick.Grid("#grid-simple", _dataView, _gridColumns);
            _grid.onClick.subscribe(onRowClick);
    
            //wire up model events to drive the grid per DataView requirements
            _dataView.onRowCountChanged.subscribe
                (function(){ _grid.updateRowCount();_grid.render(); });
    
            _dataView.onRowsChanged.subscribe
                (function(e, a){ _grid.invalidateRows(a.rows);_grid.render(); });
    
            $(window).resize(function() {_grid.resizeCanvas()});
        });
    }
    )();
    //////////////////////////////////////////////////////////////
    //done ;)
    ::-webkit-scrollbar       
    { 
        width:              12px; 
        background-color:   #B9BACC; 
    }
    ::-webkit-scrollbar-track 
    { 
        color:              #fff; 
        -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); 
        border-radius:      10px;  
    }
    ::-webkit-scrollbar-thumb 
    { 
        color:              #96A9BB; 
        border-radius:      10px;  
        -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); 
    }
    
    body
    {
        font-family:        Arial, Helvetica, sans-serif;
        background-color:   #131313;
        position:           absolute;
        top:                5px;
        bottom:             5px;
        left:               5px;
        right:              5px;
    }
    
    #grid-simple
    {
        position:         absolute;
        top:              0px;
        left:             0px;
        right:            0px;    
        bottom:           0px;
        margin:           auto;
        font-size:        12px;
        background-color: #ECEEE9;
    }
    
    .toggle
    {
        height:           16px;
        width:            16px;
        display:          inline-block;
    }
    .toggle.expand
    {
        background: url(http://tinyurl.com/k9ejb3a/expand.gif) no-repeat center center;
    }
    
    .toggle.collapse
    {
        background: url(http://tinyurl.com/k9ejb3a/collapse.gif) no-repeat center center;
    }
    
    
    /*--- generic slickgrid padding pollyfill  ----------------------*/
     
    .dynamic-cell-detail
    {
        z-index:            10000;
        position:           absolute;
        background-color:   #F4DFFA;
        margin:             0;
        padding:            0;
        width:              100%;
        display:            table;
    }
    
    .dynamic-cell-detail > :first-child
    {
        display:            table-cell;
        vertical-align:     middle;
        text-align:         center;
        font-size:          12px;
        line-height:        13px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
    <script type="text/javascript" src="https://cdn.rawgit.com/Celebio/SlickGrid/master/lib/jquery.event.drag-2.2.js"></script>
    <script type="text/javascript" src="https://cdn.rawgit.com/Celebio/SlickGrid/master/slick.core.js"></script>
    <script type="text/javascript" src="https://cdn.rawgit.com/Celebio/SlickGrid/master/slick.grid.js"></script>
    <script type="text/javascript" src="https://cdn.rawgit.com/Celebio/SlickGrid/master/slick.dataview.js"></script>
    <link rel="stylesheet" type="text/css" href="https://cdn.rawgit.com/Celebio/SlickGrid/master/slick.grid.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.rawgit.com/Celebio/SlickGrid/master/slick-default-theme.css">
    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/themes/base/jquery-ui.css">
    
    
    <div id="grid-simple"></div>

    不到200行代码。
    fiddle with it!

    顺便说一句,这种方法也非常出色Datatables通过它的API本身提供(几乎)。 &amp; imo它是正确的模式; &安培;我如何选择使用Slickgrid实现我自己的东西。但它涉及轻微破解,并且在任何情况下*都不完全符合OP要求;我声称是可能的。


    要进行动态行高 per-cell ,我们采用了类似的技巧,但我们还必须处理一些副作用:〜

    样式化行分区

    我们必须:

    1. 转义 per-cell 溢出剪辑
    2. 删除不需要的行stipeyness
    3. 删除行边框
    4. Slickgrid API通过Grid.getItemMetadata回调界面提供基于行的样式。在下一个小提琴中,在第107行上,请参阅此接口的onRenderRow实现:
      fiddle with it!

      另请注意第148-150行,我调用Slickgrid Grid.setCellCssStyles API添加自定义dynamic-cell css类来设置overflowvisible,以便消除每个单元格溢出剪辑。

      列调整大小

      如果详细内容是静态的,则列大小调整是一种限制。

      响应以更改列宽(流动文本或wotnot)的详细内容需要一些工作。填充行需要动态添加和删除。请参阅(来自第66行)下一个小提琴中的addPaddingtrimPadding函数:
      fiddle with it!

      分选

      这里还有一些工作要做。我们需要确保无论我们是向上还是向下排序,填充都保持在父级下方连续。请参阅下一个小提琴中的第136行上的comparer
      fiddle with it!

      过滤

      几乎是一个单行:如果是填充,则将比较委托给父。任务完成。请参阅下一个小提琴中第192行上的pcFilter
      fiddle with it!

      耶!这是调整大小,排序和&amp;过滤500行相当清晰,自由评论的自定义javascripts ..我实际上已经看到某些花哨的input-range-slider pollyfill有更多的代码行;)
      ACU


      注意事项

      我只介绍了基础知识。整个可选择/可编辑的方面到Slickgrid,〜超出了我当前的要求(sry)。
      另外:

      • 仅限示例代码;没准备好生产。 你被警告等等 =)
      • 示例似乎适用于大多数现代浏览器;我有没有/尝试过iE;版本&gt; = 11可能没问题..

      更多信息

      除了可以合理地将其引入SO答案之外,还有更多要说的内容 - 尽管没有参考政策指南。任何有兴趣了解所有这些内容的人都可以here where i go into a fair bit more detail

      最后一个例子

      这是最后一个有趣的例子。它使用了上述所有功能,但可以看出,我已经放弃了 expando-rows ,并且有两个动态内容字段。此外,fyi,此示例使用MutationObservers生成onPostRender事件作为{em>替代Slickgrid本机 asyncPostRender column option回调:
      fiddle with it!

      我们有它。 - 通往DataView-like Slickgrid extension-mod的方式; &安培;所有这些都不需要在可爱的Slickgrid代码上使用可怕的hax。 yippee;)

答案 1 :(得分:5)

你可以通过css这样做。 查看slick.grid.css文件,然后在那里进行所需的更改。

看看

.slick-row.ui-widget-content.slick-row.ui-state-active

OR

您可以使用SlickGrid的rowHeight属性

看一下网格选项

https://github.com/mleibman/SlickGrid/wiki/Grid-Options

答案 2 :(得分:2)

我将一个函数附加到我的网格,这使我能够扩展行高:

var normalHeight = 25;
var expandedHeight = 100;
var columns = [
    {id: "col1", name: "Column 1", field: "col1", expanded: false},
    {id: "col2", name: "Column 2", field: "col2"}
];
var options = {
    rowHeight: normalHeight
};
var dataView = new Slick.Data.DataView();
var grid = new Slick.Grid(element, dataView, columns, options);
grid.updateOptions = function(expanded){
    var columns = grid.getColumns();
    if(!expanded){
        options['rowHeight'] = normalHeight;
        columns[0]['expanded'] = false;
    }else{
        options['rowHeight'] = expandedHeight;
        columns[0]['expanded'] = true;
    }
    grid.setOptions(options);
    grid.setColumns(columns);
    grid.invalidate();
    grid.render();
}

它似乎工作得很好,希望这对某人有帮助。