swimlane / ngx-datatable

✨ A feature-rich yet lightweight data-table crafted for Angular
http://swimlane.github.io/ngx-datatable/
MIT License
4.62k stars 1.67k forks source link

Delete button in a column through cell template not working #859

Open Abhishek-Kanitkar opened 6 years ago

Abhishek-Kanitkar commented 6 years ago

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

Current behavior

Currently no demo shows action buttons.

Expected behavior

Atleast one demo should show how action buttons like Edit/Delete can be added to a cell template. Reproduction of the problem

Here is my use case

I have created a Angular 2 component and encapsulated ngx-datagrid into it. I accept json data & column config from parent component.

What is currently happening is

I want to show action buttons in last column. But they don't show up in template.

Following is my code

datagrid-component.html file (reusable component's template)

<i class="search-icon" (click)='updateFilter($event)'>

{{ column.cellTpl }}

feature-component.html(Component for a feature uses grid component)

=================================================

feature-component.ts

import { Component, OnInit } from '@angular/core'; import { Response } from '@angular/http';

@Component({ selector: 'feature', templateUrl: './feature.component.html', styleUrls: ['./feature.component.less'] }) export class FeatureComponent implements OnInit {

_columns: any[]; _defaultSort: any;

constructor( ) { }

ngOnInit() { this._columns = [ { prop: 'column1', name: 'Column 1', flexGrow: 1, cellTpl: <ng-template let-value="value" ngx-datatable-cell-template> <span tooltip="{{value.length > 30 ? value : null}}" placement="bottom" container="body">{{value}}</span> </ng-template> }, { prop: 'column1', name: 'Column 1', flexGrow: 1, cellTpl: `

               </ng-template>`
  }];

====================================================

Like mentioned above, I have _columns property which gets passed down to datagrid component. But in data grid component, cellTpl is not rendered for actions columns.

How to do this ????

Can we have a column which doesn't map to any data/key in response from server ????

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

It's very commonly done

Please tell us about your environment:

Windows 7, Sublime

Abhishek-Kanitkar commented 6 years ago

Can cell template be given through interpolation for actions columns ?

Abhishek-Kanitkar commented 6 years ago

Can anyone please help me ??? @amcdnl

justin1291 commented 6 years ago

@Abhishek-Kanitkar

for example in your feature.component html:

<ng-template #deleteBtn let-row="row"  ngx-datatable-cell-template>
  <div (click)="delete(row.id)" class="d-flex justify-content-center btn btn-sm btn-outline-secondary"><i class="fa fa-trash"></i></div>
</ng-template>

In feature.component.ts: @ViewChild('deleteBtn ') deleteBtn : TemplateRef<any>;

ngOnInit() {
this._columns = [
{
prop: 'column1',
name: 'Column 1',
flexGrow: 1,
cellTemplate: this.deleteBtn
},
{
prop: 'column1',
name: 'Column 1',
flexGrow: 1,
cellTemplate: this.deleteBtn
amcdnl commented 6 years ago

I'm not sure this is possible ATM because of the way Angular reads out viewchildren. :(

bhushangahire commented 6 years ago

Any luck on this?

juliusstoerrle commented 6 years ago

FYI: @ViewChild is populated before the ngAfterViewInit callback is called.

See: https://angular.io/api/core/ViewChild

Marcidius commented 6 years ago

EDIT: I just noticed that you're using cellTpl: as the property on the column to map your columns to but based on the documentation it's supposed to be cellTemplate isn't it?

https://swimlane.gitbooks.io/ngx-datatable/api/column/inputs.html

Original, still applies:

You certainly can do this.

@ViewChild('district') districtTmpl: TemplateRef<any>;
@ViewChild('name') nameTmpl: TemplateRef<any>;
@ViewChild('funds') fundsTmpl: TemplateRef<any>;
@ViewChild('addButton') addButtonTmpl: TemplateRef<any>;
this.columns = [
      { name: 'District', prop: 'ID', cellTemplate: this.districtTmpl, flexGrow: 1 },
      { name: 'Name', prop: 'name', cellTemplate: this.nameTmpl, flexGrow: 2  },
      { name: 'Funds', prop: 'funds', cellTemplate: this.fundsTmpl, flexGrow: 2, sortable: false },
      { name: '', cellTemplate: this.addButtonTmpl, flexGrow: 1, sortable: false}
    ]

HTML template for just the button template:

<ng-template let-value="value" let-rowIndex="rowIndex">
  <button [disabled]="!value || submitting" (click)="saveFunds(rowIndex)" mat-raised-button class="second">Add Funds</button>
</ng-template>

You just need to have the "saveFunds(rowIndex)" function handle the delete of the data in the array you are feeding to the rows property of the datatable. Note, that the data I'm feeding to this table is asynchronous being passed as an input to the component and I'm instantiating the columns for it in the ngOnInit().

ThommyTheThird commented 6 years ago

I'll be honest: I haven't read the whole discussion, but I'd like to drop my implementation as having custom action buttons (optionally, multiple, etc) was one of my needs as well.

I provide an array of a custom class I called DatatableButtons, which basically features an icon and an action callback. In the ngOnInit and other key moments I process these values and provide the ngx-datatable with an array of column definitions that include the "button columns"

for (let db of this.buttons) {
        let buttonColumn = {
        name: '',
        prop: db.id,
        button: db,
        cellTemplate: this.buttonTmpl
    };

    columns.push(buttonColumn);
}

In the html a buttonTmpl template is defined where the button's icon will be rendered, and we can access the row/column/value there to extract the icon (note I put my entire custom button object in the column object, and use this in the html to extract its icon)

<ng-template #buttonTmpl let-row="row" let-value="value" let-button="column.button">
    <span class="glyphicon glyphicon-{{button.icon}}"></span>
</ng-template>

To give you an example of a button implementation:

public buttons: DatatableButton[] = [
      {
          action: this.logYourself.bind(this),
          icon: 'trash'
      }
  ];

Where the logYourself function is in the component using the datatable, and I bind it to this so that I can use the correct this in the function's scope.

image