Dynamic columns table


Topic: Dynamic columns table

JackZeled0n pro asked 6 years ago

It is possible to generate columns dynamically with mdbTable ?, I want to create a component where can dynamically generate the columns that are in the tbody tag from the data the data that I send, something similar to this angular material image. Thank you very much in advance!!

enter image description here


Damian Gemza staff answered 6 years ago

Dear @JackZeled0n

There's no built-in feature from our tables to add new column.

But you can use Angular Renderer2 class to create dynamic elements.

Please take a look at the below code:

.html:

<div class="container my-5">
  <table mdbTable>
    <thead>
    <tr>
      <th *ngFor="let head of headElements" scope="col">{{head}} </th>
    </tr>
    </thead>
    <tbody>
    <tr mdbTableCol *ngFor="let el of elements" #tablerow>
      <th scope="row">{{el.id}}</th>
      <td>{{el.first}}</td>
      <td>{{el.last}}</td>
      <td>{{el.handle}}</td>
    </tr>
    </tbody>
  </table>
</div>

<button mdbBtn color="primary" (click)="addRow()">Add new row</button>

.ts:

@ViewChildren('tablerow') tableRow: QueryList<ElementRef>;
  elements: any = [
    {id: 1, first: 'Mark', last: 'Otto', handle: '@mdo'},
    {id: 2, first: 'Jacob', last: 'Thornton', handle: '@fat'},
    {id: 3, first: 'Larry', last: 'the Bird', handle: '@twitter'},
  ];

  headElements = ['ID', 'First', 'Last', 'Handle'];

  constructor(private el: ElementRef, private renderer: Renderer2) {

  }

  addRow() {
    this.tableRow.toArray().forEach((elem: any) => {
      const el = this.renderer.createElement('td');
      const text = this.renderer.createText('Dynamic element');
      this.renderer.appendChild(el, text);
      this.renderer.appendChild(elem.nativeElement, el);
    })
  }

Best Regards,

Damian


Damian Gemza staff answered 6 years ago

Dear @JackZeled0n

I don't think that using pagination on dynamic elements is possible but you could try to use the following scenario:

1) Add elements dynamically,

2) Use the pagination button

3) If table row fill logical requirement:

"i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex"

remove the d-none class, else add d-none class

I don't know if this scenario will work for you, but you may try.

Best Regards,

Damian


JackZeled0n pro answered 6 years ago

Thank you very much for your prompt response, I did the tests with a table and it worked to a certain extent (for what I want to do), then I came up with the following question, is it possible to use the pagination with the implementation you suggested?

Following the code you gave me, I made this implementation that appears in the image, with test data, but I have no idea how to add the pagination.

My ultimate goal is to create datatables in a dynamic way, with all its functions of ordering, searching, page, etc.

.ts

@ViewChild(MdbTableDirective) mdbTable: MdbTableDirective;
@ViewChild(MdbTablePaginationComponent) mdbTablePagination: MdbTablePaginationComponent;
@ViewChildren("tablerow") tableRow: QueryList<ElementRef>;
elements: any = [
    { id: 1, first: "Mark", last: "Otto", handle: "@mdo" },
    { id: 2, first: "Jacob", last: "Thornton", handle: "@fat" },
    { id: 3, first: "Larry", last: "the Bird", handle: "@twitter" }
];

headElements = ["Id", "First", "Last", "Handle"];
findText: string = "";
previo: string;

@HostListener("input") oninput() {
    this.mdbTablePagination.searchText = this.findText;
    this.buscarItems();
}

constructor(
    private el: ElementRef,
    private renderer: Renderer2,
    private cdRef: ChangeDetectorRef
) {}

ngOnInit() {
    this.mdbTable.setDataSource(this.elements);
    this.elements = this.mdbTable.getDataSource();
    this.previo = this.mdbTable.getDataSource();
}

ngAfterViewInit(): void {
    this.mdbTablePagination.setMaxVisibleItemsNumberTo(2);

    this.mdbTablePagination.calculateFirstItemIndex();
    this.mdbTablePagination.calculateLastItemIndex();
    this.cdRef.detectChanges();

    this.headElements.forEach((value, index) => {
        let i = 0;
        this.tableRow.toArray().forEach((elem: any) => {
            const el = this.renderer.createElement("td");
            let text;
            if (index === 2) {
                text = this.renderer.createText(String(i));
            } else {
                text = this.renderer.createText(String(i + 2));
            }

            this.renderer.appendChild(el, text);
            this.renderer.appendChild(elem.nativeElement, el);
            i = i + 1;
        });
    });
}

buscarItems() {
    const prev = this.mdbTable.getDataSource();

    if (!this.findText) {
        this.mdbTable.setDataSource(this.previo);
        this.elements = this.mdbTable.getDataSource();
    }

    if (this.findText) {
        this.elements = this.mdbTable.searchLocalDataBy(this.findText);
        this.mdbTable.setDataSource(prev);
    }
}

metodo(value, event): string {
    if (value === "Id") return "id";
    if (value === "First") return "first";
    if (value === "Last") return "last";
    if (value === "Handle") return "handle";
}

.html

<div class="container my-5">
<div class="row">

    <div class="col-12">
        <div class="in input-group md-form form-inline form-sm form-2 pl-0 mt-5">
            <i class="fa fa-search mt-3 black-text" aria-hidden="true"></i>
            <input class="form-control w-75 ml-3" type="search" placeholder="Buscar" aria-label="Buscar"
                   [(ngModel)]="findText" id="search">
        </div>
    </div>

</div>

<table mdbTable #tableEl="mdbTable" hover="true" small="true" bordered="true" striped="true">
    <thead>
    <tr>
        <th [mdbTableSort]="elements" *ngFor="let head of headElements" [sortBy]="metodo(head, th)"  #th scope="col">{{head}} </th>
    </tr>
    </thead>
    <tbody>
    <tr mdbTableCol *ngFor="let el of elements; let i = index" #tablerow>
    </tr>
    </tbody>
    <tfoot class="grey lighten-5 w-100">
    <tr>
        <td colspan="5">
            <mdb-table-pagination [tableEl]="tableEl" paginationAlign="" [searchDataSource]="elements">
            </mdb-table-pagination>
        </td>
    </tr>
    </tfoot>

</table>


JackZeled0n pro answered 6 years ago

Dear Damian,

Thank you very much for the support!

Best Regards,

Jake


Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Resolved

Specification of the issue
  • User: Pro
  • Premium support: No
  • Technology: MDB Angular
  • MDB Version: 7.5.1
  • Device: Laptop
  • Browser: Chrome
  • OS: Windows 10
  • Provided sample code: No
  • Provided link: No