Ngx-datatable set column width dynamically
Asked Answered
A

6

12

I'm storing the column widths of my ngx-datatable inside a database. I get these values using an AJAX call.

How can I set these values for the datatable?

What I've tried:

  1. setting the [width] property on the <ngx-datatable-column> element
  2. injecting the datatable as @ViewChild(DatatableComponent) table: DatatableComponent; and setting this.table.bodyComponent.columns[0].width = 500;

    I've tried these methods with and without this.table.recalculate();, but nothing seems to work.


EDIT
I'm using datatable-column with header-template and cell-template.

Anemophilous answered 12/1, 2018 at 14:36 Comment(0)
A
2

I got it working, though it was very trivial:

I store the width values of the columns in an object which acts as a dictionary. The problem was that the grid was rendered before my ajax call has finished and could not make the grid to redraw itself.

So I set the initial value of my dictionary object to null and put an *ngIf on the grid: <ngx-datatable *ngIf="colSizes">

This way the rendering happens only after the values of the dictionary are ready to be used.

Anemophilous answered 15/1, 2018 at 13:31 Comment(1)
I use ngIf approach like this: *ngIf="gridData$ | async" - the grid is not rendered untill row data received. The problem is that the grid is not displayed (including progressbar and headers) till data is loaded. And it does not look nice.Photon
W
10

If you use the solution of Hoang Duc Nguyen, you can also store the width in the columns:

 columns = [
    { name: 'Name', prop: 'name', width: 250},
    { name: 'Gender', prop: 'gender'},
    { name: 'Company', prop: 'company', sortable: false }
  ];
Wilbanks answered 30/7, 2018 at 13:44 Comment(0)
U
8

You need to set column width along with [columnMode]="force", like this:

app.component.html

<ngx-datatable
  class="material"
  [rows]="rows"
  [loadingIndicator]="loadingIndicator"
  [columns]="columns"
  [headerHeight]="50"
  [footerHeight]="50"
  [rowHeight]="'auto'"
  [reorderable]="reorderable"
  columnMode="force">
</ngx-datatable>

app.component.ts

  columns = [
    { name: 'Name', prop: 'name'},
    { name: 'Gender', prop: 'gender'},
    { name: 'Company', prop: 'company', sortable: false }
  ];

  rows = [
    {name: "A", gender: "male", company: "abc"},
    {name: "B", gender: "female", company: "abc"},
    {name: "C", gender: "male", company: "abc"}
  ];

  columnWidths = [
    {column: "name", width: 50},
    {column: "gender", width: 100},
    {column: "company", width: 150}
  ]

  ngOnInit() {
    this.columns.forEach((col: any) => {
      const colWidth = this.columnWidths.find(colWidth => colWidth.column === col.prop);
      if (colWidth) {
        col.width = colWidth.width;
      }
    });
  }
Usurp answered 12/1, 2018 at 16:8 Comment(1)
Thanks for the tip! But I'm using ngx-datatable-column with header-template and cell-template, and it just won't work.Anemophilous
R
5

You can create custom ngx-datatable-column templates and use [width] prop like:

<ngx-datatable-column name="Name" prop="name" [width]="200">
    <ng-template let-name="value" ngx-datatable-cell-template>
        {{name}}
    </ng-template>
</ngx-datatable-column>


<ngx-datatable-column name="Gender" prop="gender" [width]="100">
    <ng-template let-gender="value" ngx-datatable-cell-template>
        {{gender}}
    </ng-template>
</ngx-datatable-column>


<ngx-datatable-column name="Company" prop="company" [width]="300">
    <ng-template let-company="value" ngx-datatable-cell-template>
        {{company}}
    </ng-template>
</ngx-datatable-column>
Reganregard answered 26/1, 2021 at 23:30 Comment(0)
C
3

You can set your desired width for column in your table column definition. for exmaple:

  providersColumns = [
            { prop: 'id', name: 'ID', sortable: true, width: -100 },
            { prop: 'name', name: 'Name', sortable: true },
            { prop: 'email', name: 'Email', sortable: true ,width:50}

Btw there is a tricky point here !!! Ngx-datatable set a fixed width for every column if you want to increase that width you should set a positive number that this number will add to the Ngx-datatable width i mean if you set 50 as width ,50 will add to Ngx-datatable fixed width : 50 + x ( Im not sure but i think it was 130 PX for every column)

so final width for email column will be 50+130 =180 PX

or if you want to decrease that width you should set a negative number that this number will add to the Ngx-datatable width i mean if you set -100 as width ,-100 will minus Ngx-datatable fixed width : -100 + x

final width for id column will be -100+130 =30 PX

Coolant answered 11/2, 2019 at 11:16 Comment(0)
A
2

I got it working, though it was very trivial:

I store the width values of the columns in an object which acts as a dictionary. The problem was that the grid was rendered before my ajax call has finished and could not make the grid to redraw itself.

So I set the initial value of my dictionary object to null and put an *ngIf on the grid: <ngx-datatable *ngIf="colSizes">

This way the rendering happens only after the values of the dictionary are ready to be used.

Anemophilous answered 15/1, 2018 at 13:31 Comment(1)
I use ngIf approach like this: *ngIf="gridData$ | async" - the grid is not rendered untill row data received. The problem is that the grid is not displayed (including progressbar and headers) till data is loaded. And it does not look nice.Photon
J
1

I wanna share my solution, I was able to assign percentage values ​​to the columns, I hope work for you:

TEMPLATE:

 <ngx-datatable
        id="datatablele"
        #tablePedidos
        class="bootstrap expandable virtualized"
        rowHeight="auto"
        [rows]="pedidos"
        [columnMode]="innerWidth > 1250 ? columnMode.flex : columnMode.force"
        [loadingIndicator]="cargandoDatos"
        [headerHeight]="50"
        [footerHeight]="50"
>
...
</ngx-datatable>

TS:

import ResizeObserver from 'resize-observer-polyfill';

export class MyComponent implements OnInit {

initialSize = 0;
columnSize  = [ 20, 20, 23, 25, 25, 12 ];


ngOnInit(): void {
    const item = document.getElementById('datatablele');
    this.initialSize = item.offsetWidth;
    new ResizeObserver((event: any) => {
      this.escucharResizeDiv(event);
    }).observe(item);
  }


escucharResizeDiv(event) {
    const item = document.getElementById('datatablele');

    if (item.offsetWidth !== this.initialSize) {
      // HEADER
      const headerDatatable  = event[0].target.children[0].children[0];
      headerDatatable.style.width = '100%';
      headerDatatable.children[0].style.width = '100%';
      const rowHeader = headerDatatable.children[0].children[1];
      rowHeader.style.width = '100%';
      const headerColumns = Array.from( rowHeader.children );
      // BODY
      const bodyDatatable  = event[0].target.children[0].children[1].children[0].children[0];
      bodyDatatable.style.width = '100%';
      const rowsIterables = Array.from( bodyDatatable.children );
      // ============ CICLOS ==========================
      headerColumns.forEach( (column: any, index: number) => {
        column.style.width = `${this.columnSize[index]}%`;
      });

      // BODY - Recorremos las filas del datatable
      rowsIterables.forEach((row: any) => {
        row.children[0].style.width = '100%';
        const columns = Array.from( row.children[0].children[1].children );

        if ( columns.length ) {
          // const cantidadSize = diferenciaSize / columns.length;
          row.children[0].children[1].style.width = '100%';
          // Recorremos cada columna del datatable
          columns.forEach( (column: any, index: number) => {
            column.style.width = `${this.columnSize[index]}%`;
          });
        }

      });

      // Obtenemos el nuevo ancho del div
      this.initialSize = item.offsetWidth;
    }

  }
}
Jacqui answered 22/7, 2021 at 15:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.