Topic: Datatables Search Issue

Dave Moniz priority asked 2 years ago


Expected behavior

Datatable search feature filters on <td> only

Actual behavior

Appears to be filtering on <td> and <th> meaning if a value in a <td> overlaps with a value in <th>, all records remain

Resources (screenshots, code snippets etc.)

Example below shows search term of "user" but that is a substring of the [mdbTableSortHeader]="'Username'" therefore all records remain... altering the search term to "tuser" (substring of testuser) limits the records to just testuser, as it should.

enter image description here


Arkadiusz Idzikowski staff commented 2 years ago

@Dave Moniz I think this is not the cause of the problem. We only search for the data in dataSource, the heading names should not affect search results in any way. Can you edit your post and provide a simple HTML/TS code to help us reproduce the problem?


Dave Moniz priority commented 2 years ago

I do think this is the problem - but I'm eager to be proved wrong. Below I've provided some HTML and TS to prove my theory. Not only does it function exactly as I've described, there's the additional issue that I've been ignoring: the search feature doesn't like capital letters: ie - searching for 'tiger' works but 'Tiger' doesn't.


Arkadiusz Idzikowski staff answered 2 years ago


Thank you. I think we found the bug in the filter function. Please try to replace it with this custom method until this is fixed on our end.

HTML:

      <table
        class="table datatable-table"
        mdbTable
        [filterFn]="customFilter"
      >...</table>

TS:

  customFilter(data: Person, searchTerm: string): boolean {
    return Object.keys(data).some((key: any) => {
      if (data[key]) {
        return data[key].toString().toLowerCase().includes(searchTerm.toLowerCase());
      }
    });
  }

Dave Moniz priority answered 2 years ago


This is more or less copy paste from the documentation. Use the word 'office' as an example of the problem because Jena Gaines is an "Office Manager" but "Office" is also a column header.

HTML

<div class="container mt-4">
    <mdb-form-control>
        <input mdbInput type="text" class="form-control" id="search-input" (keyup)="search($event)" />
        <label mdbLabel class="form-label" for="search-input">Search</label>
    </mdb-form-control>
    <div class="datatable">
        <table class="table datatable-table" mdbTable mdbTableSort #table="mdbTable" #sort="mdbTableSort"
            [dataSource]="dataSource" [pagination]="pagination" [sort]="sort">
            <thead class="datatable-header">
                <tr>
                    <th *ngFor="let header of headers" [mdbTableSortHeader]="header" scope="col">
                        {{ header | titlecase }}
                    </th>
                </tr>
            </thead>
            <tbody class="datatable-body">
                <tr *ngFor="let data of table.data" scope="row">
                    <td>
                        {{ data.name }}
                    </td>
                    <td>
                        {{ data.position }}
                    </td>
                    <td>
                        {{ data.office }}
                    </td>
                    <td>
                        {{ data.age }}
                    </td>
                    <td>
                        {{ data.startDate }}
                    </td>
                    <td>
                        {{ data.salary }}
                    </td>
                </tr>
            </tbody>
        </table>
        <mdb-table-pagination #pagination></mdb-table-pagination>
    </div>
</div>

TS

import { Component, ViewChild } from '@angular/core';
import { MdbTableDirective } from 'mdb-angular-ui-kit/table';

export interface Person {
    name: string;
    position: string;
    office: string;
    age: number;
    startDate: string;
    salary: string;
}

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss']
})
export class AppComponent {
    @ViewChild('table') searchTable: MdbTableDirective<Person>;

    title = 'mdb-angular-ui-kit-pro-essential';
    constructor() { }

    headers = ['Name', 'Position', 'Office', 'Age', 'Start Date', 'Salary'];

    dataSource: Person[] = [
        {
            name: 'Tiger Nixon',
            position: 'System Architect',
            office: 'Edinburgh',
            age: 61,
            startDate: '2011/04/25',
            salary: '$320,800',
        },
        {
            name: 'Sonya Frost',
            position: 'Software Engineer',
            office: 'Edinburgh',
            age: 23,
            startDate: '2008/12/13',
            salary: '$103,600',
        },
        {
            name: 'Jena Gaines',
            position: 'Office Manager',
            office: 'London',
            age: 30,
            startDate: '2008/12/19',
            salary: '$90,560',
        },
        {
            name: 'Quinn Flynn',
            position: 'Support Lead',
            office: 'Edinburgh',
            age: 22,
            startDate: '2013/03/03',
            salary: '$342,000',
        },
        {
            name: 'Charde Marshall',
            position: 'Regional Director',
            office: 'San Francisco',
            age: 36,
            startDate: '2008/10/16',
            salary: '$470,600',
        },

    ];

    search(event: Event): void {
        const searchTerm = (event.target as HTMLInputElement).value;
        this.searchTable.search(searchTerm);
    }
}


Please insert min. 20 characters.

FREE CONSULTATION

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

Status

Answered

Specification of the issue

  • ForumUser: Priority
  • Premium support: Yes
  • Technology: MDB Angular
  • MDB Version: MDB5 1.0.0-beta5
  • Device: PC
  • Browser: Google Chrome
  • OS: Arch Linux
  • Provided sample code: Yes
  • Provided link: No