ng2-table icon indicating copy to clipboard operation
ng2-table copied to clipboard

How to add a button to a column

Open cagataycivici opened this issue 9 years ago • 49 comments

Is it possible to add custom content like a button to a column instead of data field?

cagataycivici avatar Feb 15 '16 12:02 cagataycivici

Hi! Do you want to have a button in table's cell instead of just a data?

rychkog avatar Feb 15 '16 12:02 rychkog

@rychkog Exactly, or an image, or two buttons like edit, delete. Basically custom content that I can define instead of data.

cagataycivici avatar Feb 15 '16 13:02 cagataycivici

@cagataycivici, currently you'll get only a string instead of html if you push it into cell. But your usecase is quite common I think. Soon, we plan to change a bit ng2-table and the way it works with data. Will take into account that it should support html as the cell's content as well.

For now as a workaround I would propose you to assemble custom build of ng2-table. Inside of NgTable class you can change template from

...
<td *ngFor="#column of columns">{{row[column.name]}}</td>
...

to

...
<td *ngFor="#column of columns" [innerHtml]="row[column.name]"></td>
...

rychkog avatar Feb 15 '16 13:02 rychkog

I forked the project and I added that functionality. I also pulled request but it is still pending. Have a look in my repository (I modified the demo explaining how to make editable rows) https://github.com/jdelgadoalfonso/ng2-table

jdelgadoalfonso avatar Feb 15 '16 15:02 jdelgadoalfonso

Hi @jdelgadoalfonso! The reason your PRs are still pending is that we are going to redesign a bit ng2-table, so it would be more flexible and lightweight in terms of usage. We really appreciate your participation and as soon as we come up with an appropriate design - all the PRs that are currently in a queue will be reviewed and answered.

rychkog avatar Feb 15 '16 22:02 rychkog

Like @jdelgadoalfonso I've forked the repo and added this ability, but with some differences to how it's done in his fork. https://github.com/oherman1/ng2-table

papayaglobal avatar Feb 22 '16 19:02 papayaglobal

@rychkog and how does one would fire a (click) event inside innerHtml?

zcsongor avatar Feb 23 '16 10:02 zcsongor

@oherman1 after viewing your fork, you just answered to my question, nice work!

zcsongor avatar Feb 23 '16 10:02 zcsongor

Any updates?

davidstellini avatar Jun 10 '16 13:06 davidstellini

I've managed to do it using TemplateRef and ViewContainerRef for PrimeNG DataTable.

http://www.primefaces.org/primeng/#/datatabletemplating

Hope this helps as I guess same solution could be done here as well.

cagataycivici avatar Jun 14 '16 15:06 cagataycivici

@rychkog any updates on adding html to cells yet?

laurima avatar Jul 13 '16 07:07 laurima

+1, would love html in cells without weird workarounds

paolomaffei avatar Aug 11 '16 11:08 paolomaffei

+1, It's a basic today (If I find a solution I will comment here).

Caballerog avatar Aug 12 '16 12:08 Caballerog

+1, would be very useful for me to have img tags for thumbnails in cells.

shamgang avatar Sep 14 '16 20:09 shamgang

Any progress on this?

ghost avatar Oct 10 '16 20:10 ghost

+1, it's very important feature

upmauro avatar Nov 11 '16 17:11 upmauro

+1

previousdeveloper avatar Nov 14 '16 06:11 previousdeveloper

It appears since 1.2.0 (809da05279f7595334a48967402280958cf04d21) data is loaded into cells as innerHtml rather than as standard div content. Now I can get an image into a cell using a variable containing an HTML string ('<img...').

However, this supports pure HTML only and not Angular markup (innerHtml isn't compiled/bound), so I can't bind the contents of my table to any logic. I made it work with this hack: Put empty buttons in each row as HTML strings with some unique CSS class. Wait for the table to change the buttons to render after changing the model using a setInterval and getElementsByClassName. Attach listeners to the buttons that call Angular code onclick. Nasty, right?

Is there a plan to make ng2-table content fully Angularized, each cell being a component? Does anyone know a way to make this happen right now without changes in the library? I've looked into dynamic component creation using ComponentFactory and I heard something about $compile in Angular 1, but haven't fully digested how this would all work. Any advice would be highly appreciated.

shamgang avatar Nov 14 '16 21:11 shamgang

I ended up adding a column with 3 buttons, 'view', 'edit', 'delete' which is only shown when either of the view/edit/delete inputs are set.

ng-table.html

...
<td *ngIf="view || edit || delete" >
  <div>
    <button *ngIf="view"
            type="button"
            class="btn btn-xs btn-default"
            (click)="viewClick(row)">
            <i class="fa fa-eye"></i> View
     </button>

     <button *ngIf="edit"
             type="button"
             class="btn btn-xs btn-default"
             (click)="editClick(row)">
             <i class="fa fa-edit"></i> Edit
      </button>

      <button *ngIf="delete"
            type="button"
            class="btn btn-xs btn-default"
            (click)="deleteClick(row)">
            <i class="fa fa-trash-o"></i> Delete
      </button>
  </div>
</td>
...

ng-table.component

...
@Input() delete: boolean;
@Input() edit: boolean;
@Input() view: boolean;

public editClick(row: any) {
    this.eventService.editRow(row);
}

public viewClick(row: any) {
    this.eventService.viewRow(row);
}

public linkClick(row: any, col: any) {
    this.eventService.linkClick(row);
}
...

The click events are sent to an event service:

ng-table-event.service.

...
deleteRow(row:any) {
    this.deleteRowSource.next(row);
  }

  editRow(row:any) {
    this.editRowSource.next(row);
  }

  viewRow(row:any) {
    this.viewRowSource.next(row);
  }
...

The list component's event service subscribes to the click events:

list-event.service.ts

...
// notification from ng-table to delete a row
onDeleteRowRequest() {
    this.deleteSub = this.tableEventService.deleteRow$
      .subscribe((row:any) => {
        console.log('[deleteRow$] event in licence-event.service ');

        // do delete
      });
  }

  // notification from ng-table to edit a row
  onEditRowRequest() {
    this.editSub = this.tableEventService.editRow$
      .subscribe((row:any) => {
        console.log('[editRow$] event in licence-event.service');

        // do edit
      });
  }

  // notification from ng-table to view a row
  onViewRowRequest() {
    this.viewSub = this.tableEventService.viewRow$
      .subscribe((row:any) => {
        console.log('[viewRow$] event in licence-event.service');

        // do view
      });
  }
...

I'm sure there are more elegant solutions but this is working for me.

ghost avatar Nov 16 '16 07:11 ghost

@charliebrink Could eloborate a bit more? I am interested in implementing as you did, however the overall construct is yet not clear to me. Do you have maybe a complete code sample?

Cheers!

KevKo1990 avatar Dec 03 '16 12:12 KevKo1990

and additionally - need this feature... ;) +1

KevKo1990 avatar Dec 03 '16 12:12 KevKo1990

@KevKo1990 I'll send some details tonight. The project is rather large and still in dev so I'll try explain my solution a bit better.

ghost avatar Dec 06 '16 11:12 ghost

@KevKo1990 I’ve added 3 buttons to ng-table.html and only show them when their @Input is set in ng-table.component. This allows you to show/hide them from your parent that’s hosting the table.

When the user click on any of the buttons ie 'view', 'edit' or 'delete', the ng-table component notifies any subscribers of the click event, a user list component in this example. It does this by means of an ‘event service’. The event service also sends the selected row as parameter. Think of the event service as a communication method between the (list) parent component and the ng-table component and it's just relaying the click events.

The list component that subscribed to the event will then be notified of the click event and can then act accordingly i.e. view, edit or delete.

I hope it makes sense.

ghost avatar Dec 07 '16 12:12 ghost

Hi @charliebrink ,

thank you for your feedback. I just had today the chance to look at it.

I understand the overall process / config, however I run into understanding problems where the buttons will actually be shown. I expected to have buttons in every list entry, however they are just attached below the table. Reasonable because I have my ng2-table and just attach below the buttons...

ng-table component in ng-table.component.html <ng-table [config]="config" (tableChanged)="onChangeTable(config)" (cellClicked)="onCellClick($event)" [rows]="rows" [columns]="columns"> </ng-table>

I added your button code below ng-table in ng-table.component.html

Where did you put your buttons code to receive for every row buttons?

Thank you!!!

KevKo1990 avatar Dec 24 '16 10:12 KevKo1990

Ok, I solved it now differently, I just added additional rows mit glyphicons and reduced the click event of my table on these columns...

KevKo1990 avatar Jan 01 '17 18:01 KevKo1990

hi , I tried to display what you told but the view also is not displayed when i put this code

<td *ngIf="view || edit || delete" >
  <div>
    <button *ngIf="view"
            type="button"
            class="btn btn-xs btn-default"
            (click)="viewClick(row)">
            <i class="fa fa-eye"></i> View
     </button>

     <button *ngIf="edit"
             type="button"
             class="btn btn-xs btn-default"
             (click)="editClick(row)">
             <i class="fa fa-edit"></i> Edit
      </button>

      <button *ngIf="delete"
            type="button"
            class="btn btn-xs btn-default"
            (click)="deleteClick(row)">
            <i class="fa fa-trash-o"></i> Delete
      </button>
  </div>
</td>

sureshhustle avatar Jan 03 '17 05:01 sureshhustle

Hi, could somebody told me what is the simplest workaround for this problem?

pepgonzalez avatar Jan 25 '17 21:01 pepgonzalez

Yeah, please

tomzi8 avatar Feb 07 '17 18:02 tomzi8

+1

atierant avatar Feb 14 '17 13:02 atierant

+1

cipchk avatar Feb 16 '17 08:02 cipchk