Why nested ng-grid height does not work?
Asked Answered
R

2

8

I have a nested ng grid.

var faculty = angular.module('faculty', ['ngGrid']);

faculty.controller('facultycontroller', function facultycontroller($scope, $http, $window)
{

$scope.facdata = [{

    examname: 'test'       
  },{

    examname: 'test2'
  }];

  $scope.gridOptions = {

    data: 'facdata',

    plugins: [new ngGridFlexibleHeightPlugin()],

    columnDefs: [
      {field: 'examname',displayName: 'Exam Name'},
      {field: '', displayName: 'Subjects' , cellTemplate: '<div  ng-grid="gridOptions1"  ></div>'
    }]
  };
$scope.fac1data = [{
    abc: 'value',
    def: 'value2'
  }, {

    abc: 'value3',
    def: 'value4'
  }, {
    abc: 'value1',
    def: 'value4'
  }, {
    abc: 'value2',
    def: 'value4'
  }, {
    abc: 'value34',
    def: 'value4'
  }, {

    abc: 'value34',
    def: 'value4'
  }, {
    abc: 'value23',
    def: 'value14'
  }, {
    abc: 'value433',
    def: 'value5554'
  }, {

    abc: 'value3555',
    def: 'value4878'
  }
  ];
$scope.gridOptions1 = {

   plugins: [new ngGridFlexibleHeightPlugin()],

    data: 'fac1data',

    columnDefs: [

      {  field: 'abc',displayName: 'abc'},

      { field: 'def',displayName: 'def'}]
  }
});

See the Plunker I need to show all of the nested data grid at a glance. I need to show child ng-grid data at a glance(without Vertical scroll). But nested grid height does not work . My desire grid is like below....

Mater Detail Grid/Nested Grid

Ribosome answered 8/8, 2014 at 14:33 Comment(2)
I see what you want to do, but it's simply not supported. It HAS been requested: github.com/angular-ui/ng-grid/issues/883Refinement
The suggested solution is "setting the row height to be large enough" github.com/angular-ui/ng-grid/issues/343Refinement
R
5

ng-grid was not designed for nested grids: Or even dynamic height cell by cell

If you look ng-grid's template ui-grid.html you see that the size is fixed in pixels:

  height: {{ grid.options.rowHeight }}px;

see github

This CSS class is embedded in the template, leaving no room to over-write to "auto". Since grids are built with Div's rather than Tables, tabular relationships between rows and columns is difficult if every cell-div is free to decide it's own behavior. So nested grids are quite the challenge.


You CAN get the affect you want with a hack that resembles nested grids:

see plnkr

Collapsed Grid enter image description here

note: The caret's have been added to show that parent rows are expandable. I have'nt added logic to hide carets for parent rows that have no children.

Expanded Grid enter image description here

see plnkr


Alter your JSon to include a column for Test, Name, andd Score. Use columns for either Test names or Student Names/Scores. use parent id for children and give id's to parents:

$scope.facdata  = [{test: "Basic Physics Test", parentId:0,id:1,expanded:true},
                 {name: "NAME", Score: "SCORE",parentId:1,expanded:false},
                 {name: "John", Score: 77,parentId:1,expanded:false},
                 {name: "Jacob", Score: 66,parentId:1,expanded:false},
                 {name: "Jenny", Score: 94,parentId:1,expanded:false},
                 {test: "Advanced Physics Test",id:2, parentId:0,expanded:true},
                 {name: "NAME", Score: "SCORE",parentId:2,expanded:false},
                 {name: "Freddy", Score: 94,parentId:2,expanded:false},
                 {name: "Samantha", Score: 38,parentId:2,expanded:false},
                 {name: "Judy", Score: 100,parentId:2,expanded:false}
                 ];

In Grid Options set rowTemplate to use ng-show directive on the children against the expanded field

$scope.gridOptions = { 
    data: 'facdata',
    columnDefs: [{field: 'id',displayName:'',width:20,
    cellTemplate:'<div ng-show="row.getProperty(\'id\')" ng-click="toggleExpansion(row.getProperty(col.field))"><i class="fa fa-caret-right"></i></div>'},
                {field: 'test', displayName: ''},
                {field: 'name', displayName:''},
                 {field:'Score', displayName:'', 
                 cellTemplate: '<div class="ngCellText">{{row.getProperty(col.field)}}</div>'}],
    rowTemplate:'<div style="width: 600px" ng-show="row.getProperty(\'expanded\')"><div ng-repeat="col in renderedColumns" class="ngCell ">' +
                       '<div ng-cell></div> </div></div>'

Add a ToggleSubReport function to manage showing the embedded data

$scope.ToggleSubReport  = function(id) {
  for (var i=0;i<$scope.facdata.length;++i){
    if ($scope.facdata [i].parentId ===id){
      $scope.facdata [i].expanded = !$scope.facdata [i].expanded;
    }
  }
}

see plnkr

:

:


Followup for Amin Uddin (Original Poster)

1) Nested Grids are not possible: This was your main question and aim. This is what you put a bounty on. But as you can see from github sourcefor grid-row height (defined in pixels) and responses from ng-grid contributors, this is not an option yet they even envision. NG-Grid's cell height is not truly dynamic because ng-grid is designed around matching sized divs rows rather than a table (which can more naturally re-size rows and row-cells).

2) A Sub-Grid of the kind I showed you really can accomodate sophisticated master-child relationships: You can merge arrays before serializing them (or parse JSON strings to arrays, then merge them). You must redefine the fields I used for master-detail from the unimaginative id/parentid I used to the PK/FK of the 2 lists.

Refinement answered 14/8, 2014 at 1:5 Comment(6)
Thanks, your answer is right for sub grid. But my object is more complex. So I need to implement master detail grid/nested grid concept. My object like this... public class Order { public string OrderNO(get; set;) public DateTime OrderDate(get; set;) public List<OrderDetail> OrderDetailList {get; set;} } public class OrderDetail { public string ProductName{get; set;} public decimal Price{get;set;} public int Quantity{get;set;} }Ribosome
@AminUddin, the ONLY way to deal with that is to create JSON that blends the lists.Refinement
@AminUddin, you really have 2 options. 1) if you insist on using ng-grid, create a json object that reflects your data and relationships. 2) The better way is not to use ng-grid at all. You should just use ng-repeat and custom directives. You're trying to build a house with a screw-driver.Refinement
@AminUddin, I worked hard to give you an accurate answer and what I feel is a reasonable alternative. Do you disagree with my answer or simply not like the result?Refinement
Thanks your co-operation. I am trying to avoid ng-grid. Because most of the of my developing software object are complex. In web I could not find any js grid which support such type of features.Your comments is right (You're trying to build a house with a screw-driver. )Ribosome
@ Dave A, You have already gain 25. You were directly answer by subgrid which was not correct. And your answer does not solve my problem. I knew that nested grid does not supported in ng-grid. But I posted such problem in stackoverflow in order to aware ng-grid author or contributors. Else I wanted to get ans. from community if some one solved it already(in another way).Ribosome
G
0

It's just hack the example for each row have same sub rowcount.

<body ng-controller="facultycontroller">
  <h1>Hello Plunker!</h1>
  <div ng-grid="gridOptions" ></div>
</body>
var faculty = angular.module('faculty', ['ngGrid']);

faculty.controller('facultycontroller', function facultycontroller($scope, $http, $window) {
  $scope.facdata = [{
    examname: 'test' 
  },{
    examname: 'test2'
  }];

  $scope.rowHeight = 30;

  $scope.updateGrid = function() {
      $scope.gridOptions = {
      data: 'facdata',
      rowHeight: $scope.fac1data.length * $scope.rowHeight,
      columnDefs: [
        {field: 'examname',displayName: 'Exam Name'},
        {field: '', displayName: 'Subjects' , cellTemplate: '<div  ng-grid="gridOptions1"  ></div>'
      }]
    };
  }

  $scope.fac1data = [{
    abc: 'value',
    def: 'value2'
  }, {
    abc: 'value3',
    def: 'value4'
  }, {
    abc: 'value1',
    def: 'value4'
  }, {
    abc: 'value2',
    def: 'value4'
  }, {
    abc: 'value34',
    def: 'value4'
  }, {
    abc: 'value34',
    def: 'value4'
  }, {
    abc: 'value23',
    def: 'value14'
  }, {
    abc: 'value433',
    def: 'value5554'
  }, {
    abc: 'value3555',
    def: 'value4878'
  }
  ];

  $scope.gridOptions1 = {
   headerRowHeight: 0,
    data: 'fac1data',
    rowHeight: $scope.rowHeight,
    columnDefs: [
      {  field: 'abc',    displayName: 'abc'    },
      { field: 'def',      displayName: 'def'   }]
  }

  $scope.updateGrid();

  $scope.fac1data = [{
    abc: 'value2',
    def: 'value4'
  }, {
    abc: 'value34',
    def: 'value4'
  }, {
    abc: 'value34',
    def: 'value4'
  }, {
    abc: 'value23',
    def: 'value14'
  }, {
    abc: 'value433',
    def: 'value5554'
  }, {
    abc: 'value3555',
    def: 'value4878'
  }
  ];

  $scope.updateGrid();

});

Plunker

Edit : If main row have different sub row count, it not work. I only have idea. Must be fork ui-grid, and redesign it to auto height. The official ui-grid is design fixed height at gridTemplate.html and use absolute top position.

Gambrill answered 13/8, 2014 at 17:5 Comment(10)
Please don't include mysterious shortened URLs. They're scary.Finstad
I post plunker or fiddle link, it can't be send, I try use 'code' button, it's not work.Gambrill
Code is indented with 4 spaces.Finstad
I get it, I can't just post a plunker or fiddle link, it need some code. Thank for your help.Gambrill
Then post some code? I edited your question and copy-pasted the code from your Plunker.Finstad
Yes, I don't know must be 'some code' in post. If i only have link, it can't be send.Gambrill
It's forced. The idea is embeded data and re-sizing. You've provided an example that works for very limited situations. It requires that data neatly fit within a fixed space. What if theres 1 row or 200?Refinement
Thanks, The above answer is correct for fixed length. But my object structure like this...Ribosome
Thanks, The above answer is correct for fixed length. But my object structure like this... public class Order { public string OrderNO(get; set;) public DateTime OrderDate(get; set;) public List<OrderDetail> OrderDetailList {get; set;} } public class OrderDetail { public string ProductName{get; set;} public decimal Price{get;set;} public int Quantity{get;set;} } In this case I do not get same detail record length all time.Ribosome
Yes. If main row have different sub row count, it not work. I only have idea. Must be fork ui-grid, and redesign it to auto height. The official ui-grid is design fixed height at gridTemplate.html and use absolute top position.Gambrill

© 2022 - 2024 — McMap. All rights reserved.