I'm submitting a ... (check one with "x")
[ ] bug report => search github for a similar issue or PR before submitting
[X ] feature request
[ ] support request => Please do not submit support request here
Current behavior
I have a table with 10 rows, displayed great on my site, but as my site should be mobile friendly I can't get the table to look good when on mobile.
Expected behavior
I would like to have some of my column header text wrap and increass in hight, I would like to set which column will have such behavior. I would like my words to break as well.
In general I would like it to look good.
Reproduction of the problem
Take any of your demo, shrink the browser and see the issue.
What is the motivation / use case for changing the behavior?
Web responsiveness
Please tell us about your environment:
Google chrome, vs code, npm, .net
Angular version: 2.0.x
2.42
Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
Chrome
The table examples at the: demo site do appear to be responsive.

The demo link uses the following configuration for the datatable:
<ngx-datatable
class="material"
[rows]="rows"
[loadingIndicator]="loadingIndicator"
[columns]="columns"
[columnMode]="'force'"
[headerHeight]="50"
[footerHeight]="50"
[rowHeight]="'auto'">
</ngx-datatable>
However, on my local setup with the same configuration, the tables do not change their size at all. Anything I am missing here?
I think you miss datatable-row-wrapper as part of you class... But I still stand for my original call shrink the page to the size of a cell phone, than you see the problem. My table is 10 columns, it must allow to break words and increase header size to make it work.
Edit: It was an issue with my outer div css. Working fine now.
Hmm, I dont think datatable-row-wrapper is causing the issue. Its already applied. I am following the themeing instructions as defined here. I included the following lines in my custom.scss file.
@import '/node_modules/@swimlane/ngx-datatable/release/index.css';
@import '/node_modules/@swimlane/ngx-datatable/release/material.css';
@import '/node_modules/@swimlane/ngx-datatable/release/assets/icons.css';
Can someone point me to which css style is exactly responsible for the responsiveness of the table?
Thanks a lot.



I am seeing similar issues just trying to use the demo site from mobile.
Ya, the demo site is not responsive :( ... not a huge priority right now. open to PRs.
can we make responsive feature like ember-light-table
http://offirgolan.github.io/ember-light-table/#/responsive
any suggestion please share....
When can we expect that ngx-datatable becomes responsive.??
The table is fluid, it depends on your column sizing choice. The demo site is not responsive, haven't had time to improve that yet.
I have 10 columns, I resized my columns especially for mobile but it didn't fit.
I admit I tried to play with the CSS to make my header break the words but it really massed things up.
My current selection was to give up some columns in mobile...
I wonder how to present a large tabular data in mobile in general... The amber link sent here was interesting.
Ya, tubular data views are really not ideal for mobile.
What I did to compliment mobile was to set a horizontal scroller for the table like bootstrap used to.
I really like the library , one way to display in a responsive way would be this one https://rawgit.com/jefersonestevo/angular-smd/master/dist/index.html#/angular-smd/demo-datatable.
The ember mobile size looks great, love to see a mobile-first responsive web design come to this excellent datatable Austin.
My current workaround is to size with standard column and turn on the scroll bar when under 1200 pixels wide (smaller than BS large displays). But the column headers are not part of the scroll. :-(
View snipped: -
<ngx-datatable [columnMode]="'standard'" [scrollbarH]="scrollBarHorizontal"
...
Component snippet
scrollBarHorizontal = (window.innerWidth < 1200);
constructor() {
window.onresize = () => {
this.scrollBarHorizontal = (window.innerWidth < 1200);
};
}
Love this component :-)
Peter
I figured out an elegant way to make the table responsive, but it requires some manual coding. It's not hard and results are beautiful.
Combine the _Row Detail Demo_ (http://swimlane.github.io/ngx-datatable/#row-details' -- https://github.com/swimlane/ngx-datatable/blob/master/demo/basic/row-detail.component.ts) with @media queries that change CSS that will hide columns and show the extra row toggle button. Put whatever information (column content) you'd like into the extra row.
In my case I created a .mobile-hidden class with display: none; and added the class to every column header and column content I want to hide at a certain breakpoint (@media).
If someone is having trouble implementing what I described, please ask specific questions.
@whyboris - Would you mind submitting a PR for a demo? :)
@whyboris Hi whyboris. I'm looking for the solution too. Would you mind submitting a PR for a demo ? thanks in advance ^^
Potential demo ready: https://github.com/swimlane/ngx-datatable/pull/924
Demo is now live. Please see http://swimlane.github.io/ngx-datatable/#responsive' (Responsive link under Rows category). Once demo is loaded, resize the browser to see the effect kick in at the 800px breakpoint.
Here is the source: https://github.com/swimlane/ngx-datatable/blob/master/demo/basic/responsive.component.ts
Notice the added css rules and explicit css classes in row elements.
While I like @whyboris solution, it is not 100% satisfying as "hidden" columns are not neatly hidden. ngx-datatable-header-template and ngx-datatable-cell-template contents are hidden but not their respective wrappers : datatable-header-cell and datatable-body-cell components.
I was looking at how to combine ngx-datatable-column component and fxShow API from @angular/flex-layout by simply listening the style.display changes ..
Something like
@Directive({ selector: 'ngx-datatable-column' })
export class DataTableColumnDirective {
[...]
@HostBinding('style.display')
get isShown(): boolean {
const displayValue: string = this.element.style.display;
return displayValue !== 'none' && displayValue !== 'hidden';
}
element: HTMLElement;
constructor(element: ElementRef) {
this.element = element.nativeElement;
}
}
and then where column width are being calculated, if columns are effectively hidden set a width of 0 and/or hide them.
As I said previously I tried and failed miserably at it as I don't have the chops yet with typescript and angular 4. Just got started on it recently..
Is what I propose silly or something possible ?
Thanks
Hi friends i had a width problem if anyone can give me the solution..

There is now a demo up on the site of how to make the table responsive.
What I would do in this scenario is removing some of the columns in the table when entering mobile width, keeping the most important columns.
I've found a really dumb way of doing, so use at own discretion. This is my journey:
My issue was that using this .mobile-hidden { display: none !important; } and placing it on the headerClass and cellClass attributes <ngx-datatable-column name="test" headerClass="mobile-hidden" cellClass="mobile-hidden"> would cause a massive gap at the end of the table when those columns and cells were hidden, because recalculation would still see the elements in my view.
So first solution was to use https://github.com/swimlane/ngx-datatable/blob/master/demo/columns/column-toggle.component.ts and implement a resizing listener.
This piece of code allows me to make changes to the column array.
<ngx-datatable-column
*ngFor="let col of columns"
[name]="col.name">
</ngx-datatable-column>
So with a bit of tinkering I came up with this:
columns = [
{ name: 'Name' },
{ name: 'Gender' },
{ name: 'Company' }
];
allColumns = [
{ name: 'Name' },
{ name: 'Gender' },
{ name: 'Company' }
];
//resizing listener
@HostListener('window:resize', ['$event'])
onResize(event) {
//if mobile
if (event.target.innerWidth < 1024) {
this.columns = this.columns.filter(x => x.name != 'Gender');
} else {
this.columns = this.allColumns;
}
}
Problem solved? Well not really. This works for simple datatables, but nothing is easy and I'm using custom templates. The original problem existed because those damn datatable columns still persisted in my view causing the recalculation method to include them, which throws everything off. Also another bummer is if you change this.columns by replacing or using any Array.prototype function that causes it to be replaced like this.columns = array.filter(), your nice custom template will be replaced by the default looking one... Life is tough, eh?
Ok, So I added an extra function exist(column) to check if the current datatable column should persist in my view if its still in this.columns.
> VIEW (example of column that should be removed if certain width is reached):
<ngx-datatable-column name="Gender" *ngIf="exist('Gender')">
<ng-template let-column="column" ngx-datatable-header-template>
Some non-binary horse
</ng-template>
<ng-template let-row="row" let-value="value" ngx-datatable-cell-template>
<strong><a class="font-red-haze" [routerLink]="['/gender/of/the/future']">{{value}}</a></strong>
</ng-template>
</ngx-datatable-column>
> CODE (.ts code)
@HostListener('window:resize', ['$event'])
onResize(event) {
this.recalulate(event.target.innerWidth);
}
recalulate(width) {
//if mobile
if (width < 1024) {
if (this.columns.find(x => x.name == 'Gender') != null) {
var index = this.columns.findIndex(x => x.name == 'Gender');
this.columns.splice(index, 1); //in place edit
}
} else {
if (this.columns.find(x => x.name == 'Gender') == null)
this.columns.push({ name: 'Gender' });
}
}
//check if column exists
exist(column) {
if (column == null) return false;
return this.columns.find(x => x.name == column) != null;
}
//this is important, because it needs to recalculate when datatable loads
ngOnInit() {
this.recalculate(window.screen.width);
}
I know this is ugly. And I know the push doesn't insert the original column object back in the array 'properly', but it damn well works. Because it wipes the object, there might be some problems with reordering columns or such, but I don't use those features, so they didn't affect me.
Go mad.
I've been doing something similar to this and came up with a directive that is basically simulating *ngIf on ngx-datatable-column.
<ngx-datatable-column name="Column 1" prop="col1" [flexGrow]="1"></ngx-datatable-column>
<ngx-datatable-column name="Column 2" prop="col2" [flexGrow]="1" *ngxResponsiveColumn="2"></ngx-datatable-column>
<ngx-datatable-column name="Column 3" prop="col3" [flexGrow]="1" *ngxResponsiveColumn="1"></ngx-datatable-column>
And first rough try on directive:
You can specify the thresholds on which the columns should be hidden.
The code needs some polishing but you can get the idea.
import { Directive, AfterContentChecked, TemplateRef, ViewContainerRef, Input } from '@angular/core';
@Directive({ selector: '[ngxResponsiveColumn]' })
export class NgxResponsiveColumnDirective implements AfterContentChecked {
private _visible = false;
@Input('ngxResponsiveColumn') threshold: number;
constructor(private _templateRef: TemplateRef<any>,
private _viewContainer: ViewContainerRef) {
}
ngAfterContentChecked() {
if (window.innerWidth >= 1480) {
this.show();
} else if (window.innerWidth >= 1240 && window.innerWidth <= 1479) {
if (this.threshold === 1) {
this.hide();
} else {
this.show();
}
} else if (window.innerWidth >= 1000 && window.innerWidth <= 1239) {
if (this.threshold <= 2) {
this.hide();
} else {
this.show();
}
} else if (window.innerWidth <= 999) {
if (this.threshold <= 3) {
this.hide();
}
}
}
private show() {
if (this._visible) {
return;
}
this._viewContainer.createEmbeddedView(this._templateRef);
this._visible = true;
}
private hide() {
if (!this._visible) {
return;
}
this._viewContainer.clear();
this._visible = false;
}
}
Hi @alzdrak
Know where you are, I've got the same problem.

(look all this available space on the right side...)
I applied the approach by @whyboris (and I definitely prefer to put all the column configurations in the view as shown below)
<ngx-datatable-column name="Id" [width]="200" [sortable]="true" [resizeable]="false" [canAutoResize]="false"
headerClass="hidden-xs"
cellClass="hidden-xs fcom-selectable fcom-ellipsible">
<ng-template let-po="row" ngx-datatable-cell-template>
<div class="text-right">
{{ po?.legacy?.id || po?._id }}
</div>
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name="Client" [minWidth]="60" [width]="260" [sortable]="true" [resizeable]="true" [canAutoResize]="true"
cellClass="fcom-selectable fcom-ellipsible">
<ng-template let-po="row" ngx-datatable-cell-template>
{{ po?.company?.name }}
</ng-template>
</ngx-datatable-column>
and I'm pretty happy with the result except for this problem.
Just found out an approach using @angular/cdk/layout (see: https://alligator.io/angular/breakpoints-angular-cdk/) I wanted to share with you.
import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';
...
...
class MyComponent implements OnInit {
public readonly LAYOUT = {
XS : 768,
SM : 992,
MD : 1200,
LG : 1600,
XL : 1920,
XXL: 2560,
};
public layout: number = this.LAYOUT.MD;
ngOnInit() {
// Setting up breakpoint mechanism
const breakpoints = Object.keys(this.LAYOUT).map(k => this.LAYOUT[k]);
breakpoints.forEach((maxWidth, index) => {
const minWidth = (index > 0) ? breakpoints[index - 1] : 0;
this.breakpointObserver
.observe([`(min-width: ${ minWidth }px) and (max-width: ${ maxWidth - 1 }px)`])
.subscribe((state: BreakpointState) => {
if (!state.matches) { return; }
this.layout = maxWidth;
console.log('Layout', this.layout);
});
});
With this in place, adding/removing columns based on breakpoints is just a *ngIf away:
<ngx-datatable-column
*ngIf="layout > LAYOUT.XS"
name="Id" [width]="200" [sortable]="true" [resizeable]="false" [canAutoResize]="false"
cellClass="fcom-selectable fcom-ellipsible">
<ng-template let-po="row" ngx-datatable-cell-template>
<div class="text-right">
{{ po?.legacy?.id || po?._id }}
</div>
</ng-template>
</ngx-datatable-column>
I do think it is more legible too.
What do you think?
Once again, I found that it was ruining the controller to have all this layout stuff...
Hence, I wrote my own (and first) class decorator: https://gist.github.com/guillaumegarcia13/402c260249bd5f194f7d76690eac0afc
Much leaner now!
@Component({...)
@MyResponsive()
export class MyComponent implements OnInit { ... }
Disclaimer: not AOT-compatible for the moment, use it at your own trouble!
Please reopen if this is still an issue.
I've been doing something similar to this and came up with a directive that is basically simulating
*ngIfonngx-datatable-column.<ngx-datatable-column name="Column 1" prop="col1" [flexGrow]="1"></ngx-datatable-column> <ngx-datatable-column name="Column 2" prop="col2" [flexGrow]="1" *ngxResponsiveColumn="2"></ngx-datatable-column> <ngx-datatable-column name="Column 3" prop="col3" [flexGrow]="1" *ngxResponsiveColumn="1"></ngx-datatable-column>And first rough try on directive:
You can specify the thresholds on which the columns should be hidden.
The code needs some polishing but you can get the idea.import { Directive, AfterContentChecked, TemplateRef, ViewContainerRef, Input } from '@angular/core'; @Directive({ selector: '[ngxResponsiveColumn]' }) export class NgxResponsiveColumnDirective implements AfterContentChecked { private _visible = false; @Input('ngxResponsiveColumn') threshold: number; constructor(private _templateRef: TemplateRef<any>, private _viewContainer: ViewContainerRef) { } ngAfterContentChecked() { if (window.innerWidth >= 1480) { this.show(); } else if (window.innerWidth >= 1240 && window.innerWidth <= 1479) { if (this.threshold === 1) { this.hide(); } else { this.show(); } } else if (window.innerWidth >= 1000 && window.innerWidth <= 1239) { if (this.threshold <= 2) { this.hide(); } else { this.show(); } } else if (window.innerWidth <= 999) { if (this.threshold <= 3) { this.hide(); } } } private show() { if (this._visible) { return; } this._viewContainer.createEmbeddedView(this._templateRef); this._visible = true; } private hide() { if (!this._visible) { return; } this._viewContainer.clear(); this._visible = false; } }
This worked like a charm! Thank you so much.
can we make responsive feature like ember-light-table
http://offirgolan.github.io/ember-light-table/#/responsiveany suggestion please share....
that's really nice.
Most helpful comment
The ember mobile size looks great, love to see a mobile-first responsive web design come to this excellent datatable Austin.
My current workaround is to size with standard column and turn on the scroll bar when under 1200 pixels wide (smaller than BS large displays). But the column headers are not part of the scroll. :-(
View snipped: -
Component snippet
Love this component :-)
Peter