angularangular-slickgrid

Angular SlickGrid Dynamic grid inside md-tab not loading the definitions


Angular slick grid is not loading using the md-tab

In the child component will be created once the md tab is created. Am setting the tab configurations on ngOnInit method of the child component ts.

Am not sure what am missing here.

If the tab is already loaded then am getting the dom doesnot exists error.

Parent.html

<mat-tab-group [selectedIndex]="selected.value"  (selectedTabChange)="tabChanged($event)">
    <mat-tab>
        <ng-template mat-tab-label>
            ...
        </ng-template>
        Content 1
        <div class="container col-12" style="width: 100%; height: 100%;">
            <angular-slickgrid gridId="grid1"
                      [columnDefinitions]="columnDefinitions"
                      [gridOptions]="gridOptions"
                      [dataset]="dataset"
                      (sgOnSelectedRowsChanged)="onSelectedRowsChanged($event.detail.eventData, $event.detail.args)"
                      (sgOnClick)="onCellClicked($event.detail.eventData, $event.detail.args)"
                      >
            </angular-slickgrid>
          </div>
    </mat-tab>
<mat-tab *ngFor="let tab of tabs; let index = index">
    <ng-template mat-tab-label>
        <div class="d-flex">
            <div class="d-flex">
                ...
            </div>
            <div class="d-flex ml-4">
                <a class="" (click)="removeTab(tab)"> 
                    <span class="fa fa-times fa-1x"></span>
                </a>
            </div>
        </div>
    </ng-template>
    Content of {{tab}}
    <div class="container col-12" style="width: 100%; height: 100%;" [id]="tab" >
        Table : {{tab}}
        <child-details [id]="tab" [query]="tab"></child-details> 
      </div>
</mat-tab>
</mat-tab-group>


ParentComponent

export class ParentComponent implements OnInit, OnDestroy {

  columnDefinitions: Column[] = [];
  gridOptions: GridOption = {};
  dataset: any[] = [];
  angularGrid: AngularGridInstance;

  constructor( private angularUtilService: AngularUtilService,private http: HttpClient) { 
    this.prepareGrid()

  }

  ngOnDestroy(): void {
    sessionStorage.setItem("pinnedTabs", this.tabs.join('|'));
  }

  inputValue: string = "";

  tabs = [];
  selected = new FormControl(0);

  ngOnInit(): void {
    if (sessionStorage.getItem('pinnedTabs') !== null && sessionStorage.getItem('pinnedTabs') !== undefined && sessionStorage.getItem('pinnedTabs').trim() !== "") {
      this.tabs = sessionStorage.getItem('pinnedTabs').split('|');
    }

  }

  removeTab(tabName: string) {
    this.tabs.splice(this.tabs.indexOf(tabName), 1);
    sessionStorage.setItem("pinnedTabs", this.tabs.join('|'));
  }

  addNewTab(tabName: string) {
    console.log("Added new tab")
    if (this.tabs.indexOf(tabName) === -1) {
      this.tabs.push(tabName);
    }
    this.selected.setValue(this.tabs.indexOf(tabName) + 1);
    sessionStorage.setItem("pinnedTabs", this.tabs.join('|'));
  }

  getConfigurations() : Observable<JobListConfig[]>{
    return this.http.get<...[]>('...');
  }


  prepareGrid() {
    this.columnDefinitions = [
      {
        "id": "id", "name": "id", "field": "id", "sortable": true, type: FieldType.number, "filterable": true, "filter": { model: Filters.compoundInputNumber }, formatter(rowIndex, cellIndex, value, columnObject, rowObject, grid) {
          return "<label class='pointer' (click)=addNewTab(" + rowObject.id + ")>" + rowObject.jobId + "</label>";
        }
      }
      .....
    ];

    this.gridOptions = {
      enableAutoResize: true,
      enableSorting: true,
      enablePagination: true,
      enableFiltering: true,
      enableCellNavigation: true,
      datasetIdPropertyName: "id",
      createPreHeaderPanel: true,
      showPreHeaderPanel: true,
      alwaysShowVerticalScroll: false,
      //autoHeight: true,
      autoResize: {
        containerId: 'demo-container',
        sidePadding: 15
      },
      
      pagination: {
        pageSize:10,
        pageSizes:[10,15,20]
      },
      enableCheckboxSelector: true,
      enableRowSelection: true,
      rowSelectionOptions: {
        // True (Single Selection), False (Multiple Selections)
        selectActiveRow: false
      },

      //headerRowHeight: 40,
      //rowHeight: 60
   //   preHeaderPanelHeight: 28,
     // colspanCallback: this.renderDifferentColspan,
    };

    // fill the dataset with your data
    this.dataset = this.mockData();
  }

  onSelectedRowsChanged(e, args) {
    // user clicked on the 1st column, multiple checkbox selection
    console.log('multiple row checkbox selected', event, args);
  }

  onCellClicked(e, args) {
    // when clicking on any cell, we will make it the new selected row
    // however, we don't want to interfere with multiple row selection checkbox which is on 1st column cell

    if(args.cell !== 0 && args.grid.getColumns()[args.cell].id==="id"){
      this.addNewTab(args.grid.getData().getItems()[args.row]["id"])
    }
  }

  mockData() {
    // mock a dataset
    const mockDataset = [];
    for (let i = 0; i < 100; i++) {
      mockDataset[i] = {
        "id": i,
        ....
      };
    }

    return mockDataset;
  }

  tabChanged(event) {
    console.log("Tab changed");
    console.log(event);
  }
}

ChildTemplate html

<angular-slickgrid [gridId]="query" [columnDefinitions]="columnDefinitions" [gridOptions]="gridOptions"
   [dataset]="dataset" (onAngularGridCreated)="angularGridReady($event)">
   </angular-slickgrid>
export class ChildCompoent implements OnInit {

  @Input() query: Array<any>;

  private angularGrid: AngularGridInstance;


  ngOnInit(): void {
    console.log("Ng On init")
    console.log(this.query);
    this.prepareGrid();
  }

  constructor(private http: HttpClient) {
   

  }

  columnDefinitions: Column[] = [];
  gridOptions: GridOption = {};
  dataset: any[] = [];

  prepareGrid() {
    this.columnDefinitions = [
      {
        "id": "id", "name": "id", "field": "id", "sortable": true, type: FieldType.number, "filterable": true, "filter": { model: Filters.compoundInputNumber }, formatter(rowIndex, cellIndex, value, columnObject, rowObject, grid) {
          return "<label class='pointer' (click)=addNewTab(" + rowObject.id + ")>" + rowObject.jobId + "</label>";
        }
      }
      ....
      },

    ];

    this.gridOptions = {
      enableAutoResize: true,
      enableSorting: true,
      enablePagination: true,
      enableFiltering: true,
      enableCellNavigation: true,
      datasetIdPropertyName: "id",
      createPreHeaderPanel: true,
      showPreHeaderPanel: true,
      alwaysShowVerticalScroll: false,
      //autoHeight: true,
      autoResize: {
        containerId: 'demo-container',
        sidePadding: 15
      },

      pagination: {
        pageSize: 10,
        pageSizes: [10, 15, 20]
      },
      enableCheckboxSelector: true,
      enableRowSelection: true,
      rowSelectionOptions: {
        // True (Single Selection), False (Multiple Selections)
        selectActiveRow: false
      },

      //headerRowHeight: 40,
      //rowHeight: 60
      //   preHeaderPanelHeight: 28,
      // colspanCallback: this.renderDifferentColspan,
    };

    // fill the dataset with your data
    this.dataset = this.mockData();
  }

  mockData() {
    // mock a dataset
    const mockDataset = [];
    for (let i = 0; i < 100; i++) {

      mockDataset[i] = {
        "id": i,
        ....
      };
    }

    return mockDataset;
  }


  angularGridReady(angularGrid: AngularGridInstance) {
    console.log('slickgrid created');
    this.angularGrid = angularGrid;
  }

  onTabSelected(tab){
    console.log("Tab selected")
    this.angularGrid.resizerService.resizeGrid();
  }
}

Sample screen shot

enter image description here

Thanks in advance.


Solution

  • I have resolved by adding the style to the container as below and wrapped that with <ng-template matTabContent>

        <ng-template matTabContent>
        <child-details class="container col-12" style="width: 100%; height: 100%;" [id]="tab" [query]="tab" ></child-details> 
    </ng-template>