question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Horizontal scroll bar is not shown when datatable is empty

See original GitHub issue

I’m submitting a … (check one with “x”)

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, post on Stackoverflow or Gitter

Current behavior

If I am using [scrollbarH]=“true” and if there it is no rows in datatable, the horizontal scroll bar is not shown, and header is cut off and cannot see more header columns in right side.

Expected behavior

Horizontal scroll bar shows on page and user should be able to see header columns even datatable is empty.

Reproduction of the problem

in demo HorzVertScrolling, comment out this code snippet: /* this.fetch((data) => { this.rows = data; }); */

you can find there is no horizontal scrolling bar and state column on right side is hidden.

screen shot 2018-04-10 at 16 32 07

What is the motivation / use case for changing the behavior?

This is not a user friendly experience when the table is empty.

Please tell us about your environment:

  • Table version: 0.8.x

swimlane/ngx-datatable: “11.2.0”,

  • Angular version: 2.0.x

angular/common: “^4.1.3”

  • 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

  • Language: [all | TypeScript X.X | ES6/7 | ES5] typescript: “2.5.3”,

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:6
  • Comments:11

github_iconTop GitHub Comments

1reaction
renuverma03commented, Jun 1, 2018

I had same issue, but doing lots of R&D , I did some custom code, it solve my problem. I created a common method and call from component when data not available.

like : setEmptyMessage() { let msg = ‘No data to display.’; if (!this.tableData.length) { this.tableData = [{ ‘message’: msg }]; } else { delete this.tableData[0][‘message’]; msg = ‘’; } this.setEmptyMessageDataTable(msg); }

// create a common method like this setEmptyMessageDataTable(msg) { const hideClass = document.querySelector(‘datatable-body-row’); const divelm = document.querySelector(‘#noMsg’); if (msg) { if (hideClass) { hideClass.setAttribute(‘style’, ‘display:none;’); }

        if (divelm) {
            document.querySelector('#noMsg').remove();
        }
        // Create a new element
        const element = document.createElement('p');
        element.id = 'noMsg';
        element.innerHTML = msg;
        document.querySelector('datatable-row-wrapper').appendChild(element);
    } else {
        if (divelm) {
            document.querySelector('#noMsg').remove();
        }
        if (hideClass) {
            hideClass.removeAttribute('style');
        }

    }

}

// use setEmptyMessage() where you are fetching dataTable data

this.yourApi.method(req).subscribe( results => { this.setEmptyMessage(); }, error => { } )

0reactions
jusemoncommented, Dec 21, 2022

A more improved version of the fix, instead of using scrollLeft, use the transformers that the data table uses internally, I made this improvement because we found some inconsistencies when the table has one row, the user scroll to the right and finally add another filter to remove the row, in that scenario the header scroll messed up.

// https://github.com/swimlane/ngx-datatable/issues/1367#issuecomment-511893170
import {
  Directive,
  Renderer2,
  ElementRef,
  AfterViewInit,
  AfterViewChecked,
} from '@angular/core';

/**
 * Directive to add an empty row to `ngx-datatable components that do not have any data.
 * This fixes a bug with ngx-datatable in which empty tables do not have a scrollable header.
 */
@Directive({
  selector: '[appEmptyRow]',
})
export class EmptyRowDirective implements AfterViewInit, AfterViewChecked {
  private datatableBodyEl!: HTMLElement;
  private datatableEmptyRowEl!: HTMLElement;
  private datatableRowCenterEl!: HTMLElement;
  private prevNumberOfRows!: number;
  constructor(private renderer: Renderer2, private hostElRef: ElementRef) { }

  public ngAfterViewInit() {
    this.setUpElementReferences();
    if (this.shouldApplyHack) {
      this.hackEmptyCellWidth();
      this.setUpHeaderScrollListener();
    }
  }

  public ngAfterViewChecked() {
    if (this.shouldApplyHack) {
      this.hackEmptyCellWidth();
    }
    this.restartScrollingOnRowChanges();
  }

  private restartScrollingOnRowChanges() {
    if (this.prevNumberOfRows !== this.numberOfRows) {
      this.prevNumberOfRows = this.numberOfRows;
      this.datatableBodyEl.scrollTo(1, 0);
      this.renderer.setStyle(this.datatableRowCenterEl, 'transform', 'translate3d(0px, 0px, 0px)');
    }
  }

  private setUpHeaderScrollListener() {
    this.renderer.listen(this.datatableBodyEl, 'scroll', (event: any) => {
      if (this.shouldApplyHack) {
        this.renderer.setStyle(this.datatableRowCenterEl, 'transform', `translate3d(-${event.srcElement.scrollLeft}px, 0px, 0px)`)
      }
    });
  }

  private hackEmptyCellWidth() {
    const newWidth = this.datatableRowCenterEl.style.width;
    this.renderer.setStyle(this.datatableEmptyRowEl, 'width', newWidth);
  }

  private setUpElementReferences() {
    const hostEl = this.hostElRef.nativeElement;
    this.datatableBodyEl = hostEl.getElementsByClassName('datatable-body')[0];
    this.datatableEmptyRowEl = hostEl.getElementsByClassName('empty-row')[0];
    this.datatableRowCenterEl = hostEl.getElementsByClassName('datatable-row-center')[0];
  }

  private get shouldApplyHack(): boolean {
    const hostEl = this.hostElRef.nativeElement;
    this.datatableEmptyRowEl = hostEl.getElementsByClassName('empty-row')[0];
    return !!this.datatableEmptyRowEl;
  }

  private get numberOfRows(): number {
    const hostEl = this.hostElRef.nativeElement;
    return hostEl.getElementsByClassName('datatable-body-row').length;
  }
}


Read more comments on GitHub >

github_iconTop Results From Across the Web

Datagrid Horizontal scroll bar not get visible when binded to ...
Hi. I have an scenario to display empty rows with more than 25 columns in display. In this case Horizontal scrollbar not get...
Read more >
Datatable horizontal scroll bar when no data - Stack Overflow
Workaround is to have ngx-datatable inside a div with predefined width, height and scroll bar ie. overflow - auto (defined in css class...
Read more >
Scroll - horizontal - DataTables example
DataTables has the ability to show tables with horizontal scrolling, which is very useful for when you have a wide table, but want...
Read more >
horizontal scroll bars missing from datatable - Webix Forum
Hi, I've noticed that occasionally the horizontal scroll bars don't show up in a datatable, especially if the columns are fixed.
Read more >
DataGrid - The horizontal scrollbar is not shown even if ...
I am using a DevExtreme DataGrid and the data I have does not fit within the horizontal dimensions of the screen. I expected...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found