swimlane / ngx-datatable

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

Multiple prop for single column #1195

Open nishantc19 opened 6 years ago

nishantc19 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, 'prop' property supports only three ways of mentioning column value - deep value ("a.b.c": 123), shallow value (obj["prop"]) and numerals.

Expected behavior I want to define multiple column properties in single column, something like this: {{obj.prop1}} {{obj.prop2}}. It is possible to do so when we use ng-template, but not possible when mentioning columns using array of objects.

New declaration could look like: columns = [{"name": "name1", "prop": arrayOfProps}]

Reproduction of the problem

What is the motivation / use case for changing the behavior? In my case, I am trying to write a wrapper component for ngx-datatable because there are numerous tables in my project. And that is why I am bound to define columns in ts rather than in html.

Please tell us about your environment: Table version: 10.4.0 Angular version: 4.4.6 Browser: [all] Language: [TypeScript 2.6]

nishantc19 commented 6 years ago

Any update on this one?

fgscaglioni commented 6 years ago

@nishantc19 I have used this approach and it worked for me, take a look https://stackoverflow.com/questions/45295031/angular-ngx-datatable-multiple-data-in-one-column Instead of using the 'let-value' property, you can use the 'let-row' property. For example:

<ng-template let-row="row" ngx-datatable-cell-template>
     {{row | json}}
</ng-template>
nishantc19 commented 6 years ago

I'm already using the way you mentioned. But the problem is, we are using template. I have several tables and wanted to customize and generalize the ngx-datatable into one component so that I can use that component every where. Usage of template restricts that and I ended up writing ng-template for all of them.

mumvock commented 5 years ago

Any update on this one?

asmith2306 commented 5 years ago

I'd like to have this feature too. I have an Address Column that is made from an object containing a couple of fields e.g. state, city. An array such as prop: ['address.city', [', '], 'address.state'] would be ideal. Just concat all the values in the array for the prop to display.

Edit: I think I have a workaround for this:

I have a generic "custom-datatable" component which has it's rows and columns as an input, and also a templateRef declaration for columns requiring split properties:

export interface ExtendedTableColumn extends TableColumn {
  splitProps?: Array<string>;
}
@Component({
  selector: 'app-custom-datatable',
  templateUrl: './custom-datatable.component.html',
  styleUrls: ['./custom-datatable.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class CustomDatatableComponent implements OnInit {

  @Input()
  rows = [];

  @Input()
  columnDefinitions = Array<ExtendedTableColumn>();

  // Split template
  @ViewChild('splitTmpl', {static: true}) splitTmpl: TemplateRef<any>;

In the custom-datatable.component.html file (where ngx-datatable is declared) I have this template:

<ngx-datatable [rows]="rows" [columns]="columnDefinitions" ...other attributes excluded for brevity...>
  <!-- Split template -->
  <ng-template #splitTmpl let-row="row" let-value="value" let-column="column">
    <div>{{value[column.splitProps[0]]}}, {{value[column.splitProps[1]]}}</div>
  </ng-template>
</ngx-datatable>

I have a component that uses the above custom-datatable:

<app-custom-datatable [rows]="allPeople" [columnDefinitions]="columnDefinitions">
 </app-custom-datatable>

Note: the allPeople data passed into the rows input is just the data from https://github.com/swimlane/ngx-datatable/blob/master/src/assets/data/100k.json

The columnDefinitions that I'm passing into the custom component is as follows:

this.columnDefinitions = [
      {
        name: 'Id',
        flexGrow: 0.25,
        resizeable: false
      },
      {
        name: 'Name',
        flexGrow: 0.8,
        resizeable: false
      },
      {
        name: 'Gender',
        flexGrow: 0.5,
        resizeable: false
      },
      {
        name: 'Address',
        flexGrow: 1,
        resizeable: false,
        splitProps: ['city', 'state']
      },
      {
        name: 'Age',
        flexGrow: 0.5,
        resizeable: false,
        prop: 'age'
}];

Notice the 'splitProps' field. When the custom-datatable component receives this array as input, in it's onInit method simply loop through the columnDefinitions and if 'splitProps' is declared for a column then set the columns 'cellTemplate' to 'splitTmpl' which you can see above.

this.columnDefinitions.forEach(column => {
      console.log(column);
      if (column.splitProps) {
        column.cellTemplate = this.splitTmpl;
      }
 });

Obviously this example only supports using two values but it's a start.