[SalesForce] Filter LWC DataTable

I am trying to build Alphabet base filter in LWC Datatable. I want to filter opportunity name based on the Alphabet pressed by the user i.e if letter 'A' is pressed then I should see only those opportunities where opportunity name starts with letter 'A' .This is where i am not able to find a solution how to filter the datatable based on the action of the user , I want to do this filter in js file as I already have the data which needs to be filtered. if somebody has implemented the same kind of functionality and can share the knowledge that will be helpful.

JS code snippet

handleLetterFilter(event){
    this.allProducts = [...this.products];
    let letter = event.target.text;
    console.log('This is the letter ',letter);
    if(letter != 'ALL'){

    } else {
        console.log('This is the length',this.allProducts.length);
    }
}

HTML code Snippet

 <ul class="slds-list_horizontal slds-has-block-links_space">
    <li><a onclick={handleLetterFilter}>A</a></li>
    <li><a>B</a></li>
    <li><a>C</a></li>
    <li><a>D</a></li>
    <li><a>E</a></li>
    <li><a>F</a></li>
    <li><a>G</a></li>
    <li><a>H</a></li>
    <li><a>I</a></li>
    <li><a>J</a></li>
    <li><a>K</a></li>
    <li><a>L</a></li>
    <li><a>M</a></li>
    <li><a>N</a></li>
    <li><a>O</a></li>
    <li><a>P</a></li>
    <li><a>Q</a></li>
    <li><a>R</a></li>
    <li><a>S</a></li>
    <li><a>T</a></li>
    <li><a>U</a></li>
    <li><a>V</a></li>
    <li><a>W</a></li>
    <li><a>X</a></li>
    <li><a>Z</a></li>
    <li><a onclick={handleLetterFilter}>ALL</a></li>
  </ul>

Best Answer

You need a separate variable to show the filtered results. I wrote a complete example in this playground.


<template>
    <lightning-card title="Filters">
        <div class="slds-align_absolute-center">
    <template for:each={alphabet} for:item="letter">
        &nbsp;<a onclick={handleFilterChange} key={letter} data-filter={letter}>
            {letter}
        </a>
        &nbsp;|
    </template>
    <a onclick={handleFilterChange} data-filter="">
        ALL
    </a>
        </div>
    <lightning-datatable 
        columns={columns}
        data={currentPage}
        key-field="index">
    </lightning-datatable>
    <div class="slds-align_absolute-center">
    <lightning-button-group>
    <lightning-button label="First" onclick={firstPage}>
    </lightning-button>
    <lightning-button label="Previous" onclick={previousPage}>
    </lightning-button>
    <div class="slds-m-horizontal_medium slds-align_absolute-center">
    {pageNumber} of {maxPageNumber}
    </div>
    <lightning-button label="Next" onclick={nextPage}>
    </lightning-button>
    <lightning-button label="Last" onclick={lastPage}>
    </lightning-button>
    </lightning-button-group>
    </div>
    </lightning-card>
</template>

import { LightningElement } from "lwc";

const NAMES = [
  "Noah", ...
   // Top 2k baby names of 2016 //
];

export default class App extends LightningElement {
  filteredResults = [];
  currentLetter;
  pageNumber = 1;
  pageSize = 10;
  columns = [
      { fieldName: 'name', label: 'Name', type: 'text' }
  ];
  alphabet;
  connectedCallback() {
      this.alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
      this.handleFilterChange();
  }
  nextPage() {
    this.pageNumber = Math.min(
      this.pageNumber + 1,
      this.maxPageNumber
    );
  }
  previousPage() {
    this.pageNumber = Math.max(1, this.pageNumber - 1);
  }
  firstPage() {
    this.pageNumber = 1;
  }
  lastPage() {
    this.pageNumber = this.maxPageNumber;
  }
  get maxPageNumber() {
    return Math.floor(
      (this.filteredResults.length + (this.pageSize - 1)) / this.pageSize
    );
  }
  get currentPage() {
    return this.filteredResults.slice(
      (this.pageNumber - 1) * this.pageSize,
      this.pageNumber * this.pageSize
    ).map((name,index)=>({ key: index, name }));
  }
  handleFilterChange(event) {
    if(event) {
        this.currentLetter = event.target.dataset.filter;
    }
    if (this.currentLetter) {
      this.filteredResults = NAMES.filter((name) =>
        name.startsWith(this.currentLetter)
      );
    } else {
      this.filteredResults = [...NAMES];
    }
    this.filteredResults.sort((a,b)=>a<b?-1:1);
    this.pageNumber = 1;
  }
}