SDSMTKyzer
SDSMTKyzer

Reputation: 112

AngularJS ui-grid grouping not grouping all the way

I am having a problem with the angular UI grid grouping functionality and have spent the better part of a day searching for an answer on both SO and online and cannot find an answer. What I've seen relates to grid 3.1.1 which I was using but I have since updated to grid 4.0.4. All the answers I could find insisted that it had something to do with externalSorting and I do not ever turn that on. I am wondering if there is just something super stupidly simple that I'm missing.

The following is my grid:

    (function() {
    angular.module("app").controller("reportController", ["$http", "$scope", "stats", "uiGridConstants", "uiGridGroupingConstants", "$rootScope", "$timeout",
        function ($http, $scope, stats, uiGridConstants, uiGridGroupingConstants, $rootScope, $timeout) {
            $scope.reportData = [];
            $scope.parameters = "";
            $scope.reportGrid = {
                data: "reportData",
                columnDefs: [{field: " "}],
                enableColumnResizing: true,
                enableGridMenu: true,
                enableSorting: true,
                enableSelectAll: true,
                infiniteScrollRowsFromEnd: 40,
                infiniteScrollUp: true,
                infiniteScrollDown: true,
                enableFiltering: true,
                fastWatch: true,
                flatEntityAccess: true,
                showGridFooter: true,
                exporterCsvFilename: "data.csv",
                exporterPdfDefaultStyle: { fontSize: 8 },
                exporterPdfTableStyle: { margin: [5, 5, 5, 5] },
                exporterPdfTableHeaderStyle: { fontSize: 8, bold: true, italics: true, color: "red"},
                exporterPdfHeader: { text: "Data", style: "headerStyle"},
                exporterPdfFooter: function(currentPage, pageCount) {
                    return { text: currentPage.toString() + " of " + pageCount.toString(), style: "footerStyle" };
                },
                exporterPdfCustomFormatter: function(docDefinition) {
                    docDefinition.styles.headerStyle = { fontSize: 22, bold: true };
                    docDefinition.styles.footerStyle = { fontSize: 10, bold: true };
                    docDefinition.content = $scope.parameters.concat(docDefinition.content);
                    return docDefinition;
                },
                exporterPdfOrientation: "landscape",
                exporterPdfPageSize: "LETTER",
                exporterPdfMaxGridWidth: 500,
                exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")),
                enableGroupHeaderSelection: true,
                enableGrouping: true,
                treeCustomAggregations: {
                    uniqueCount: { label: "Unique Count: ", menuTitle:"Agg: Unique", aggregationFn: stats.aggregator.uniqueCount, finalizerFn: stats.finalizer.uniqueCount }
                },
                onRegisterApi: function(gridApi) {
                    $scope.gridApi = gridApi;
                    $scope.gridApi.selection.on.rowSelectionChanged($scope, function (rowChanged) {
                        console.log($scope.reportGrid.columnDefs);
                        if (typeof rowChanged.treeLevel !== "undefined" && rowChanged.treeLevel > -1) {
                            // this is a group header
                            children = $scope.gridApi.treeBase.getRowChildren(rowChanged);
                            children.forEach(function(child) {
                                if (rowChanged.isSelected) {
                                    $scope.gridApi.selection.selectRow(child.entity);
                                } else {
                                    $scope.gridApi.selection.unSelectRow(child.entity);
                                }
                            });
                        }
                    });
                }
            };

            $scope.setGridState = function () {
                if ($scope.state) {
                    $scope.gridApi.saveState.restore($scope, $scope.state);
                }
            };

            $rootScope.$on("resetGridData", function() {
                $scope.reportData = [];
                $scope.gridApi.grouping.clearGrouping();
                $scope.gridApi.grid.clearAllFilters();
                $scope.state = {};
            });

            $rootScope.$on("getGridState", function () {
                $scope.state = $scope.gridApi.saveState.save();
                $rootScope.$emit("sendGridState", $scope.state);
            });

            $rootScope.$on("restoreGridState", function (event, state) {
                $scope.state = JSON.parse(state);
            });

            $rootScope.$on("populateReportGrid", function (event, args) {
                $scope.reportData = args.reportData.data;
                console.log($scope.reportData);
                for (var i = 0; i < $scope.reportData.length; i++) {
                    console.log($scope.reportData[i].$$hashKey);
                }
                $timeout(function () { $scope.setGridState(); }, 0);
                $scope.reportGrid.columnDefs = args.reportData.coldefs;
                $scope.reportGrid.exporterCsvFilename = args.headerInformation.ReportName + ".csv";
                $scope.reportGrid.exporterPdfFilename = args.headerInformation.ReportName + ".pdf";
                $scope.reportGrid.exporterPdfHeader.text = args.headerInformation.ReportName;
                $scope.parameters = [args.headerInformation.FromDate + " to " + args.headerInformation.ToDate + "\n" + 
                    "Teams: " + args.headerInformation.Teams + "\n" +
                    "Customers: " + args.headerInformation.Customers + "\n" +
                    "Systems: " + args.headerInformation.Systems + "\n" +
                    "Accounts" + args.headerInformation.BillingIds + "\n" +    
                    "Statuses: " + args.headerInformation.Statuses + "\n" +
                    "Project Numbers: " + args.headerInformation.Projects];
            });
        }])
        .service("stats", function () {

            var initAggregation = function (aggregation) {
                /* To be used in conjunction with the cleanup finalizer */
                if (angular.isUndefined(aggregation.stats)) {
                    aggregation.stats = { sum: 0 };
                }
            };
              var coreAccumulate = function(aggregation, value){
                initAggregation(aggregation);
                if ( angular.isUndefined(aggregation.stats.accumulator) ){
                  aggregation.stats.accumulator = [];
                }
                if ( !isNaN(value) ){
                  aggregation.stats.accumulator.push(value);
                }
              };

              var increment = function(obj, prop){
                /* if the property on obj is undefined, sets to 1, otherwise increments by one */
                if ( angular.isUndefined(obj[prop])){
                  obj[prop] = 1;
                }
                else {
                  obj[prop]++;
                }
              };

              var service = {
                aggregator: {
                  accumulate: {
                    /* This is to be used with the uiGrid customTreeAggregationFn definition,
                     * to accumulate all of the data into an array for sorting or other operations by customTreeAggregationFinalizerFn
                     * In general this strategy is not the most efficient way to generate grouped statistics, but
                     * sometime is the only way.
                     */
                    numValue: function (aggregation, fieldValue, numValue) {
                      return coreAccumulate(aggregation, numValue);
                    },
                    fieldValue: function (aggregation, fieldValue) {
                      return coreAccumulate(aggregation, fieldValue);
                    }
                  },
                  uniqueCount: function(aggregation, fieldValue, numValue){
                    initAggregation(aggregation);
                    var thisValue = fieldValue;
                      if (aggregation.stats.accumulator === undefined || aggregation.stats.accumulator.indexOf(thisValue) === -1) {
                          service.aggregator.accumulate.numValue(aggregation, fieldValue, numValue);
                      }
                      aggregation.value = aggregation.stats.accumulator.length;                    
                  }
                },
                finalizer: {
                  cleanup: function (aggregation) {
                    delete aggregation.stats;
                    if ( angular.isUndefined(aggregation.rendered) ){
                      aggregation.rendered = aggregation.value;
                    }
                  }
                }
              };

              return service;
            });
})();

Expected result:

enter image description here

Actual result:

enter image description here

Upvotes: 1

Views: 946

Answers (1)

SDSMTKyzer
SDSMTKyzer

Reputation: 112

I have a workaround for this. It was pointed out to me that there are two columns with the expandable things which led me to look at the HTML closer.

We had the directives for both the group and the tree view version of the grid included and while this had been somehow working for a while some recent changes I added in the controller appeared to have broken it. Here is the snippet of my new HTML:

 <div id="reportBody" ng-controller="reportController">
    <div id="reportGrid" ui-grid="reportGrid" ui-grid-grouping  ui-grid-exporter ui-grid-infinite-scroll ui-grid-move-columns
            ui-grid-selection ui-grid-resize-columns ui-grid-save-state class="reportgrid"> <!--ui-grid-tree-view took this out because it was doing duplicates for unknown reason--> 
        <div id="loadingOverlay">
            <i id="loadingOverlayIcon"></i>
        </div>
    </div>
</div>

Upvotes: 1

Related Questions