Any better approaches in achieving multi-column grouping in UI-Grid header?

血红的双手。 提交于 2019-12-06 03:14:32

问题


I've tried to achieve the multi column grouping at column header level for UI-Grid with the below approach.

Steps I've followed:

  1. Include the below header cell template, of the UI grid, with another "UI Grid row":

    <div class="ui-grid-header custom-ui-grid-header">
        <div class="ui-grid-top-panel">
            <div class="ui-grid-header-viewport">
                <div class="ui-grid-header-canvas">
                    <div class="ui-grid-header-cell-wrapper" ng-style="colContainer.headerCellWrapperStyle()">
                        <div class="ui-grid-header-cell-row">
                            <div class="ui-grid-header-cell" ng-repeat="superCol in grid.options.superColDefs track by $index" col-name="{{superCol.name}}">
                                <div class="ui-grid-cell-contents" data-ng-bind="superCol.displayName">
                                </div>
                            </div>
                        </div>
                        <div class="ui-grid-header-cell-row">
                            <div class="ui-grid-header-cell ui-grid-clearfix" ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" ui-grid-header-cell super-col-width-update col="col" render-index="$index">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div ui-grid-menu></div>
        </div>
    </div>
    
  2. Add references to your column definition object of the grid with Super Column data:

    $scope.gridOptions = {
        headerTemplate: 'views/header-template.html',
        superColDefs: [{
            name: 'group1',
            displayName: 'Group 1'
        }, {
            name: 'group2',
            displayName: 'Group 2'
        }],
        columnDefs: [{
            name: 'name',
            displayName: 'Name',
            superCol: 'group1'
        }, {
            name: 'title',
            displayName: 'Title',
            superCol: 'group1'
        }, {
            name: 'age',
            displayName: 'Age',
            superCol: 'group2'
        }],
        data: [{
            name: 'Bob',
            title: 'CEO',
            age: '31'
        }, {
            name: 'Frank',
            title: 'Lowly Developer',
            age: '33'
        }]
    };
    
  3. Calculate the width of each header column, and add it to its Super Column's width, to make each relevant Super cell to span across its child cells. This can be achieved with a directive that will be placed on every child header cell.

Directive:

.directive('superColWidthUpdate', ['$timeout', function ($timeout) {
    return {
        'restrict': 'A',
            'link': function (scope, element) {
            var _colId = scope.col.colDef.superCol,
                _el = jQuery(element);
            _el.on('resize', function () {
                _updateSuperColWidth();
            });
            var _updateSuperColWidth = function () {
                $timeout(function () {
                    var _parentCol = jQuery('.ui-grid-header-cell[col-name="' + _colId + '"]');
                    var _parentWidth = _parentCol.outerWidth(),
                        _width = _el.outerWidth();
                    _parentWidth = ((_parentWidth === 1) ? 0 : _parentWidth) + _width + 'px';
                    _parentCol.css({
                        'min-width': _parentWidth,
                        'max-width': _parentWidth
                    });
                }, 0);
            };
            _updateSuperColWidth();
        }
    };
}]);

In the above approach, the solution has been achieved by manipulating the DOM to render a new header row and new header cells, which sit on top of the usual header row, but within the Header viewport.

However, I am looking for any better approach, may be by using the UI-Grid's internal services or directives. Any help here is much appreciated!


回答1:


There is a much simpler solution. Write a customTreeAggregationFn that just calculates the identity of the row you wish to include in the grouping row:

var customTreeAggregationFn = function(aggregation, fieldValue, value, row) {
    // calculates the average of the squares of the values
    if (typeof(aggregation.count) === 'undefined') {
        aggregation.count = 0;
    }
    aggregation.count++;
    aggregation.value = value;
}

Then use this function and filter out non-header rows in the cellTemplate:

{
        name: 'EDM Id',
        displayName: 'EDM Id',
        field: 'Entity__r.EDM_ID__c',
        enableColumnMenu: false,
        customTreeAggregationFinalizerFn: function(aggregation) {
            aggregation.rendered = aggregation.value;
        },
        cellTemplate: '<div><div class="ui-grid-cell-contents" ng-if="row.groupHeader" title="TOOLTIP">{{COL_FIELD CUSTOM_FILTERS}}</div></div>',
        customTreeAggregationFn: customTreeAggregationFn

    }




回答2:


Multi-column grouping isn't something the grid currently does, one of the barriers is the interaction with column moving and resizing.

Having said that, we'd like to have it, and looking at what you've done I reckon you could help to write that feature in ui-grid.

I'm not entirely sure how column grouping would work with column moving - perhaps it would always force the entire group to move, not just an individual column. With resizing basically the group column needs to have a width that equals the total of the sub columns.

That's basically what you've done already, the only trick is to fit it into the feature structure.

If you want to drop onto the gitter channel sometime https://gitter.im/angular-ui/ng-grid you'd probably find people would give you a hand with that PR (probably @c0bra would be best placed to help)



来源:https://stackoverflow.com/questions/29564283/any-better-approaches-in-achieving-multi-column-grouping-in-ui-grid-header

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!