valor-software / ng2-table

Simple table extension with sorting, filtering, paging... for Angular2 apps
http://valor-software.github.io/ng2-table/
MIT License
553 stars 335 forks source link

How to change columns eg. you have 2 columns SSN and Name and then you have something like Title, Name, SSN and then you should have again only SSN and Name #570

Open alotnak opened 7 years ago

alotnak commented 7 years ago

We've used ng2-table and bring rows and column(names) from server. The columns (Names, Count and Order can change). How to change columns eg. you have 2 columns SSN and Name and then you have something like Title, Name and SSN in this order and then you should have again only SSN and Name.

In first change: SSN and Name => Title, Name and SSN there is not seen columns as expected, but SSN, Name and Title.

In second change : Title, Name and SSN (seen SSN, Name and Title) => SSN and Name there is not seen columns as expected, but SSN, Name and Title (and all the values in column Title are 'undefined' (yes, we don't bring value for Title, because we don't expect there is column for Title).

There is our code. What else should we do?

  public updateTable(): void {
      this.tableService.getTable(this.mySettings).subscribe(obj => {
         this.config = {
            paging: true,
            sorting: { columns: obj.columns },
            filtering: { filterString: '' },
            className: ['table-striped', 'table-bordered'],
            selectedRowClass: 'selectedRow'
          };
        this.columns =obj.columns;
        this.data = obj.rows;
        this.length = this.data.length;
        this.onChangeTable(this.config);
      }
      );
  }

  public onChangeTable(config: any, page: any = { page: this.page, itemsPerPage: this.itemsPerPage }): any {
    if (config.filtering) {
      Object.assign(this.config.filtering, config.filtering);
    }
    if (config.sorting) {
      Object.assign(this.config.sorting, config.sorting);
    }
    let filteredData = this.changeFilter(this.data, this.config);
    let sortedData = this.changeSort(filteredData, this.config);
    this.rows = page && config.paging ? this.changePage(page, sortedData) : sortedData;
    this.length = sortedData.length;
  }
jdlennoxs commented 6 years ago

I fixed this with changes to the ng-table.component.js Object.defineProperty(NgTableComponent.prototype, "columns", { get: function () { return this._columns; }, set: function (values) { var _this = this; var names = values.map(v => v.name); values.forEach(function (value) { if (value.filtering) { _this.showFilterRow = true; } if (value.className && value.className instanceof Array) { value.className = value.className.join(' '); } if (_this._columns.length) { var difference = _this._columns.filter(x => names.indexOf(x.name) === -1); difference.forEach(function (d) { _this._columns.splice(_this._columns.indexOf(d), 1); }); } var column = _this._columns.find(function (col) { return col.name === value.name; }); if (column) { Object.assign(column, value); } if (!column) { _this._columns.push(value); } }); }, enumerable: true, configurable: true });

A new conditional checks if any of the existing columns are no longer in the update values and removes them from the table.

alotnak commented 6 years ago

Thanks! You made my day :) I'll check, if I can make the same. Newbi with these components... If ng2-table is a part of your application, how do you handle this change? I mean how you overwrite this method and how you keep it in your application so it's not overwritten when your upgrade the component from GitHub?

jdlennoxs commented 6 years ago

I have opened a PR with this fix in it, but if this is like the ng2-charts repo it probably won't get merged. I'm not super sure what to do at this point, I've been making custom fixes to both repositories in the built .js files which works for now, but like you say if they do start pushing changes again they could get over written. One option would be to look at the PR I raised #585 then fork a branch add that and host your own repo for yourself to use. But I haven't got that far yet so you'd need to google the hell out of it or ask some slightly more experienced git-hubbers :P

jdlennoxs commented 6 years ago

Also the change was made in ng2-table->components->table->ng-table.component.js. Replace the whole "columns" property with the code above 👍

alotnak commented 6 years ago

Hi, I can now remove the columns, but if there is SSN and Name and next time there should be Name and SSN, they are not. Did this work for you, I mean, are you able to tell, how it can be fixed?

itsnotme01 commented 6 years ago

Hello,

I'm a bit late but you can fork the repository and modify it then use your repository as source instead of the default one.

For the column change bug, my solution is to rebuild all columns at every Set. So my columns are always the good ones and with the right order.

You just have to be careful by refreshing your sorting configuration after setting new columns.

Here is my column Set method:

@Input()
  public set columns(values:Array<any>) {
    // Column reset added, now we always repopulate de columns instead of recycling, preventing columns refresh bugs
    this._columns = [];
    values.forEach((value:any) => {
      if (value.filtering) {
        this.showFilterRow = true;
      }
      if (value.className && value.className instanceof Array) {
        value.className = value.className.join(' ');
      }

      this._columns.push(value);
    });
  }

And here the component part with the configuration refresh:


//Add LocalIT column for SHOW ALL mode
        this.columns = [
          {title: 'Local IT', name: 'LocalIT', filtering: {filterString: '', placeholder: 'LocalIT'}, sort:'', className: 'groupidColumnWidth'},    
          {title: 'Product Name', name: 'ProductName', filtering: {filterString: '', placeholder: 'Product Filter'}, sort:'', className: 'productColumnWidth'},    
          {title: 'Target', name: 'Target', filtering: {filterString: '', placeholder: 'GID Filter'}, sort: '', className: 'groupidColumnWidth'},    
          {title: 'Status', name: 'Status', filtering: {filterString: '', placeholder: 'Status Filter'}, sort: '', className: 'statusColumnWidth'},    
          {title: 'Creation Date', name: 'CreatedOn', sort: '', className: 'dateColumnWidth'},
          {title: 'Modification Date', name: 'ModifiedOn', sort:'', className: 'dateColumnWidth'},
          {title: 'Requestor', name: 'Requestor', filtering: {filterString: '', placeholder: 'GID Filter'}, sort:'', className: 'groupidColumnWidth'}
        ];

        //Refresh the sorting onfiguration with the ne column and update de table with the new config
        if(this.config){
          this.config.sorting = {columns: this.columns};
        }

        this.onChangeTable(this.config);

I hope it can help someone,

Have a nice day

Sauravsam85 commented 5 years ago

@itsnotme01 your solution worked for me. I changed the set values in ng2-table->components->table->ng-table.component.js.