Ngx-datatable: Horizontal scroll not resumed after filter all rows, then unfilter.

Created on 15 May 2017  路  7Comments  路  Source: swimlane/ngx-datatable








I'm submitting a ... (check one with "x")

[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, post on Stackoverflow or Gitter

Current behavior

Using the Horizontal scrolling demo, add buttons to show empty rows and then resume original rows. (I'll post code in a comment)
http://localhost:9999/#horz-vert-scrolling

  1. Horizontal scroll to right
  2. Click Empty Rows
  3. Click Show Rows

Columns will still be scrolled to right, but body scroll will be reset to beginning.

Expected behavior

Either:
A. Column and Body scroll should be reset to 0
B. Column and Body scroll should resume the last horizontal scrolled position before 0 rows displayed.

Reproduction of the problem

import { Component } from '@angular/core';

@Component({
  selector: 'horz-vert-scrolling-demo',
  template: `
    <div>
      <h3>
        Horizontal and Vertical Scrolling
        <small>
          <a href="https://github.com/swimlane/ngx-datatable/blob/master/demo/basic/scrolling.component.ts" target="_blank">
            Source
          </a>
        </small>
      </h3>
      <div>
        <button (click)="showEmptyRows()">Empty Rows</button>
        <button (click)="showOriginalRows()">Show Rows</button>
      </div>
      <ngx-datatable
        class="material"
        [rows]="rows"
        columnMode="force"
        [headerHeight]="50"
        [footerHeight]="0"
        [rowHeight]="50"
        [scrollbarV]="true"
        [scrollbarH]="true">
        <ngx-datatable-column name="Name" [width]="300"></ngx-datatable-column>
        <ngx-datatable-column name="Gender"></ngx-datatable-column>
        <ngx-datatable-column name="Age"></ngx-datatable-column>
        <ngx-datatable-column name="City" [width]="300" prop="address.city"></ngx-datatable-column>
        <ngx-datatable-column name="State" [width]="300" prop="address.state"></ngx-datatable-column>
      </ngx-datatable>
    </div>
  `
})
export class HorzVertScrolling {

  rows = [];

  originalRows: any[];

  constructor() {
    this.fetch((data) => {
      this.rows = data;
      this.originalRows = data;
    });
  }

  fetch(cb) {
    const req = new XMLHttpRequest();
    req.open('GET', `assets/data/100k.json`);

    req.onload = () => {
      cb(JSON.parse(req.response));
    };

    req.send();
  }

  showEmptyRows() {
    this.rows = [];
  }

  showOriginalRows() {
    this.rows = this.originalRows;
  }

}

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

Many users of ngx-datatable probably have large horizontally scrolled tables that have filter UI. Users often briefly display empty rows as they adjust their table filters and will encounter this bug.

Please tell us about your environment:

Reproduced in ngx-datatable#master demo 42364cc91b29003bde1a146d23e6fa855a5a0176

  • Table version: 9.1.0

  • Angular version: 4.0.2

  • Browser: all

  • Language: all

Investigate

Most helpful comment

@bheda91 All I know, is that for me, calling recalculateColumns() fixed the header horizontal scroll being offset from the table body horizontal scroll. But you may have to call it within a timeout. You could also try triggering ChangeDetection if that doesn't work.

However, in my case, I wanted the horizontal scroll to resume where it was instead of at 0, so that's the reason for the scrollLeft code.

All 7 comments

To reset scroll at 0, recalculateColumns() needs to be called after going from empty rows to displayed rows.

However, my vote is for resuming the scrolled position. I already implemented this in my project.

Capture scroll events (scroll)="onTableScroll($event)"

Store last offsetX

  onTableScroll(scroll: any) {
    const offsetX = scroll.offsetX;
    // can be undefined sometimes
    if (offsetX != null) {
      this.offsetX = offsetX;
    }
  }

After rows are updated, resume the offsetX

    setTimeout(() => {
      this.scrollX(this.offsetX);
    }, 1);

  scrollX(offsetX: number) {
    this.datatableBodyElement.scrollLeft = offsetX;
  }

Let me know if you want me to work on creating a PR or not.

I fancy resetting it to 0. I thought we were doing this...

I am using 6.3.0 version
If we added both rowHeight=auto and scrollbars =true { i.e [scrollbarV]="true" [scrollbarH]="true"} getting error like
Row Height cache initialization failed. Please ensure that 'rowHeight' is a
valid number value: (auto) when 'scrollbarV' is enabled.

if we mention row height with numeric value some rows are missing

@arlowhite @amcdnl The given solution is not working.

Can you please suggest any other solution?

Table version: 9.0.0

Angular version: 4.1.0

Browser: all

Language: all

@MorlaRamakrishna Sounds like a different issue; you should upgrade to the latest ngx-datatable version first and see if you still have the problem.

@bheda91 All I know, is that for me, calling recalculateColumns() fixed the header horizontal scroll being offset from the table body horizontal scroll. But you may have to call it within a timeout. You could also try triggering ChangeDetection if that doesn't work.

However, in my case, I wanted the horizontal scroll to resume where it was instead of at 0, so that's the reason for the scrollLeft code.

The workaround here didn't work for me. I'm using ngx-datatable version 11.3.2 (using Angular 5) and the closest I came to it working is calling this.datatable._offsetX.next(offsetX), but I have a pinned left column that gets laid out wrong when I do this. I realize this is an old ticket, but any suggestions are welcome.

Was this page helpful?
0 / 5 - 0 ratings