Svelte DataTables - Flowbite

Use the datatable component to search, sort, filter and paginate table data of rows and columns for your web application.

The datatable component examples from Flowbite are open-source under the MIT License and they are based on the simple-datatables repository from GitHub.

This page provides multiple examples of datatable components where you can search, sort, filter, and paginate table data up to thousands of entries.

All examples are responsive, dark mode and RTL support included and by installing the Flowbite-Svelte-DataTable plugin the custom styles will automatically be applied to the datatable components using Tailwind CSS.

Installation #

  • Svelte
pnpm i -D @flowbite-svelte-plugins/datatable

app.d.ts #

Update app.d.ts as the following:

declare global {
  namespace App {}
}

declare module "simple-datatables" {
  export { DataTable } from "simple-datatables/dist/dts/datatable";
  export { convertCSV, convertJSON } from "simple-datatables/dist/dts/convert";
  export { exportCSV, exportJSON, exportSQL, exportTXT } from "simple-datatables/dist/dts/export";
  export { createElement, isJson, isObject } from "simple-datatables/dist/dts/helpers";
  export { makeEditable } from "simple-datatables/dist/dts/editing";
  export { addColumnFilter } from "simple-datatables/dist/dts/column_filter";

  export type { DataTableOptions, DataTableConfiguration, ColumnOption, cellType, inputCellType, dataRowType, inputRowType, headerCellType, inputHeaderCellType, TableDataType, DataOption, renderType, nodeType, elementNodeType, textNodeType, cellDataType } from "simple-datatables/dist/dts/datatable";

  export interface SelectableDataRow {
    selected?: boolean;
    [key: string]: any;
  }
}

export {};

app.css #

@source "../node_modules/simple-datatables/dist";
@source "../node_modules/@flowbite-svelte-plugins/datatable/dist";

.datatable-pagination .datatable-active a,
.datatable-pagination .datatable-active a:focus,
.datatable-pagination .datatable-active a:hover,
.datatable-pagination .datatable-active button,
.datatable-pagination .datatable-active button:focus,
.datatable-pagination .datatable-active button:hover {
  background-color: #ffe4de;
  cursor: default;
}

.datatable-wrapper .datatable-table tbody tr.selected {
  background-color: #fff1ee !important;
}

Default datatable #

Use this example to show table data with default sorting and pagination functionalities.

Name ReleaseDate NpmDownloads Growth
Flowbite2021/25/0926900049%
React2013/24/05450000024%
Angular2010/20/09280000017%
Vue2014/12/02360000030%
Svelte2016/26/11120000057%
Ember2011/08/1250000044%
Backbone2010/13/103000009%
jQuery2006/28/0160000005%
Bootstrap2011/19/08180000012%
Foundation2011/23/097000008%
Bulma2016/24/105000007%
Next.js2016/25/10230000045%
Nuxt.js2016/16/1090000050%
Meteor2012/17/01100000010%
Aurelia2015/08/0720000020%
Inferno2016/27/0910000035%
Preact2015/16/0860000028%
Lit2018/28/0540000060%
Alpine.js2019/02/1130000070%
Stimulus2018/06/0315000025%
Solid2021/05/0725000080%
  • Svelte
<script lang="ts">
  import { Table } from "@flowbite-svelte-plugins/datatable";
  import items from "./data/sample.json";
</script>

<Table {items} />

Snippets #

Use captionSlot and footerSlot snippets.

Caption

Browse a list of Flowbite products designed to help you work and play, stay organized, get answers, keep in touch, grow your business, and more.

Name ReleaseDate NpmDownloads Growth
Flowbite2021/25/0926900049%
React2013/24/05450000024%
Angular2010/20/09280000017%
Vue2014/12/02360000030%
Svelte2016/26/11120000057%
Ember2011/08/1250000044%
Backbone2010/13/103000009%
jQuery2006/28/0160000005%
Bootstrap2011/19/08180000012%
Foundation2011/23/097000008%
Bulma2016/24/105000007%
Next.js2016/25/10230000045%
Nuxt.js2016/16/1090000050%
Meteor2012/17/01100000010%
Aurelia2015/08/0720000020%
Inferno2016/27/0910000035%
Preact2015/16/0860000028%
Lit2018/28/0540000060%
Alpine.js2019/02/1130000070%
Stimulus2018/06/0315000025%
Solid2021/05/0725000080%
footerSlot: Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias laboriosam placeat eum facilis aliquam, adipisci consequuntur excepturi rerum distinctio illum quibusdam neque magni quaerat dolorum hic labore repellat omnis? Quisquam?
  • Svelte
<script lang="ts">
  import { Table } from "@flowbite-svelte-plugins/datatable";
  import { P, Heading } from "flowbite-svelte";
  import items from "./data/sample.json";
</script>

<Table {items}>
  {#snippet captionSlot()}
    <Heading tag="h5" class="text-primary-700 text-left">Caption</Heading>
    <P>Browse a list of Flowbite products designed to help you work and play, stay organized, get answers, keep in touch, grow your business, and more.</P>
  {/snippet}
  {#snippet footerSlot()}
    <tr>
      <td colspan={4} class="text-left text-base leading-normal font-normal tracking-normal whitespace-normal text-gray-900 dark:text-white">
        <Span highlight="red" class="bold">footerSlot:</Span>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias laboriosam placeat eum facilis aliquam, adipisci consequuntur excepturi rerum distinctio illum quibusdam neque magni quaerat dolorum hic labore repellat omnis? Quisquam?
      </td>
    </tr>
  {/snippet}
</Table>

searchable and sortable #

searchable and sortable options are true as default. You can disable it as the following example.

Name ReleaseDate NpmDownloads Growth
Flowbite2021/25/0926900049%
React2013/24/05450000024%
Angular2010/20/09280000017%
Vue2014/12/02360000030%
Svelte2016/26/11120000057%
Ember2011/08/1250000044%
Backbone2010/13/103000009%
jQuery2006/28/0160000005%
Bootstrap2011/19/08180000012%
Foundation2011/23/097000008%
Bulma2016/24/105000007%
Next.js2016/25/10230000045%
Nuxt.js2016/16/1090000050%
Meteor2012/17/01100000010%
Aurelia2015/08/0720000020%
Inferno2016/27/0910000035%
Preact2015/16/0860000028%
Lit2018/28/0540000060%
Alpine.js2019/02/1130000070%
Stimulus2018/06/0315000025%
Solid2021/05/0725000080%
  • Svelte
<Table {items} dataTableOptions={{ searchable: false, sortable: false }} />

Filtering data #

Use the following example to enable filtering data based on a search query for each column. Enabling search for each individual data column is an advanced way of letting users browse complex data.

Name Category Brand Price Stock TotalSales Status
Apple iMacComputersApple$1,29950200In Stock
Apple iPhoneMobile PhonesApple$999120300In Stock
Samsung GalaxyMobile PhonesSamsung$89980150In Stock
Dell XPS 13ComputersDell$1,09930120In Stock
HP Spectre x360ComputersHP$1,2992580In Stock
Google Pixel 6Mobile PhonesGoogle$799100200In Stock
Sony WH-1000XM4HeadphonesSony$34960150In Stock
Apple AirPods ProHeadphonesApple$249200300In Stock
Asus ROG ZephyrusComputersAsus$1,8991550In Stock
Microsoft Surface Pro 7ComputersMicrosoft$89940100In Stock
Samsung QLED TVTelevisionsSamsung$1,2992570In Stock
LG OLED TVTelevisionsLG$1,4992050In Stock
Canon EOS R5CamerasCanon$3,8991030In Stock
Nikon Z7 IICamerasNikon$3,299825In Stock
Apple Watch Series 7WearablesApple$399150500In Stock
Fitbit Charge 5WearablesFitbit$179100250In Stock
Dyson V11 VacuumHome AppliancesDyson$5993090In Stock
iRobot Roomba i7+Home AppliancesiRobot$7992070In Stock
Bose SoundLink RevolveSpeakersBose$19980200In Stock
Sonos OneSpeakersSonos$21960180In Stock
Apple iPad ProTabletsApple$1,09950150In Stock
Samsung Galaxy Tab S7TabletsSamsung$64970130In Stock
Amazon Echo DotSmart HomeAmazon$49300800In Stock
Google Nest HubSmart HomeGoogle$89150400In Stock
PlayStation 5Gaming ConsolesSony$49910500Out of Stock
Xbox Series XGaming ConsolesMicrosoft$49915450Out of Stock
Nintendo SwitchGaming ConsolesNintendo$29940600In Stock
Apple MacBook ProComputersApple$1,29920100In Stock
  • Svelte
<script lang="ts">
  import { Table } from "@flowbite-svelte-plugins/datatable";
  import products from "./data/products.json";
  import type { DataTableOptions } from "simple-datatables";

  const filterOptions: DataTableOptions = {
    tableRender: (data: any[], table: any, type: string) => {
      if (type === "print") {
        return table;
      }

      const tHead = table.childNodes[0];
      const filterHeaders = {
        nodeName: "TR",
        attributes: {
          class: "search-filtering-row"
        },
        childNodes: tHead.childNodes[0].childNodes.map((_th: any, index: number) => ({
          nodeName: "TH",
          childNodes: [
            {
              nodeName: "INPUT",
              attributes: {
                class: "datatable-input",
                type: "search",
                placeholder: `Filter column ${index + 1}`,
                "data-columns": `[${index}]`
              }
            }
          ]
        }))
      };

      tHead.childNodes.push(filterHeaders);
      return table;
    }
  };
</script>

<Table items={products} dataTableOptions={filterOptions} />

Table pagination #

Pagination is enabled by default for all datatables, however, you can disable it by setting the option paging to false. Use the perPage option to specify how many data rows to show by default.

You can also set the perPageSelect option to set the selection options of the table.

ModelName Developer ReleaseDate Parameters PrimaryApplication
GPT-4OpenAIMarch 20231 trillionNatural Language Processing
BERTGoogleOctober 2018340 millionNatural Language Understanding
DALL-E 2OpenAIApril 20223.5 billionImage Generation
T5GoogleOctober 201911 billionText-to-Text Transfer
GPT-3.5OpenAINovember 2022175 billionNatural Language Processing
CodexOpenAIAugust 202112 billionCode Generation
PaLM 2GoogleMay 2023540 billionMultilingual Understanding
LaMDAGoogleMay 2021137 billionConversational AI
CLIPOpenAIJanuary 2021400 millionImage and Text Understanding
XLNetGoogleJune 2019340 millionNatural Language Processing
MeenaGoogleJanuary 20202.6 billionConversational AI
BigGANGoogleSeptember 2018UnlimitedImage Generation
ElectraGoogleMarch 202014 millionNatural Language Understanding
Swin TransformerMicrosoftApril 202188 millionVision Processing
GPT-NeoX-20BEleutherAIApril 202220 billionNatural Language Processing
Ernie 3.0BaiduJuly 202110 billionNatural Language Processing
Turing-NLGMicrosoftFebruary 202017 billionNatural Language Processing
Wu Dao 2.0Beijing Academy of AIJune 20211.75 trillionMultimodal Processing
JukeboxOpenAIApril 20201.2 billionMusic Generation
StyleGAN2NVIDIAFebruary 2020UnlimitedImage Generation
FLANGoogleDecember 2021137 billionFew-shot Learning
GShardGoogleJune 2020600 billionMultilingual Understanding
AlphaFoldDeepMindDecember 2020UnknownProtein Folding
GPT-JEleutherAIJune 20216 billionNatural Language Processing
M6AlibabaDecember 202010 billionMultimodal Processing
Megatron-Turing NLGNVIDIA & MicrosoftOctober 2021530 billionNatural Language Processing
DeepSpeedMicrosoftFebruary 2020Not disclosedAI Training Optimization
  • Svelte
<script lang="ts">
  import { Table } from "@flowbite-svelte-plugins/datatable";
  import aimodels from "./data/aimodels.json";
  import type { DataTableOptions } from "simple-datatables";

  const paginationOptions: DataTableOptions = {
    paging: true,
    perPage: 5,
    perPageSelect: [5, 10, 15, 20, 25],
    sortable: false
  };
</script>

<Table items={aimodels} dataTableOptions={paginationOptions} />

Selecting rows #

Use this example to enable the selection of rows by clicking anywhere one of the table row elements.

Use selectable true and rowRender option to enable multi selection. Use multiSelect false to make single selection.

Name ReleaseDate NpmDownloads Growth
Flowbite2021/25/0926900049%
React2013/24/05450000024%
Angular2010/20/09280000017%
Vue2014/12/02360000030%
Svelte2016/26/11120000057%
Ember2011/08/1250000044%
Backbone2010/13/103000009%
jQuery2006/28/0160000005%
Bootstrap2011/19/08180000012%
Foundation2011/23/097000008%
Bulma2016/24/105000007%
Next.js2016/25/10230000045%
Nuxt.js2016/16/1090000050%
Meteor2012/17/01100000010%
Aurelia2015/08/0720000020%
Inferno2016/27/0910000035%
Preact2015/16/0860000028%
Lit2018/28/0540000060%
Alpine.js2019/02/1130000070%
Stimulus2018/06/0315000025%
Solid2021/05/0725000080%
  • Svelte
<script lang="ts">
  import { Table } from "@flowbite-svelte-plugins/datatable";
  import items from "./data/sample.json";

  const selectRowsOptions = {
    rowRender: (row: any, tr: any, _index: number) => {
      if (!tr.attributes) {
        tr.attributes = {};
      }
      if (!tr.attributes.class) {
        tr.attributes.class = "";
      }
      if (row.selected) {
        tr.attributes.class += " selected";
      } else {
        tr.attributes.class = tr.attributes.class.replace(" selected", "");
      }
      return tr;
    }
  };
</script>

<Table selectable {items} dataTableOptions={selectRowsOptions} />

Custom Cell Renderer #

  • Svelte
<script lang="ts">
  import { Table } from "@flowbite-svelte-plugins/datatable";
  import type { DataTableOptions } from "simple-datatables";

  // Define types for the render function parameters
  interface CellNode {
    nodeName: string;
    attributes?: Record<string, string | number>;
    childNodes?: (CellNode | TextNode)[];
  }

  interface TextNode {
    nodeName: "#text";
    data: string;
  }

  interface TableCell {
    childNodes: (CellNode | TextNode)[];
    data: any;
  }

  interface TableRow {
    attributes?: Record<string, string>;
    cells: TableCell[];
  }

  // Type the render functions properly
  const renderIcon = function (data: any, _cell: TableCell, _dataIndex: number, _cellIndex: number): string {
    if (data === "Latte") {
      return `${data}`;
    } else if (data === "Green tea") {
      return `🍵 ${data}`;
    }
    return `🌿 ${data}`;
  };

  // Price column cell manipulation
  const renderButton = function (data: any, cell: TableCell, dataIndex: number, _cellIndex: number): void {
    cell.childNodes.push({
      nodeName: "BUTTON",
      attributes: {
        "data-row": dataIndex,
        class: "buy-now"
      },
      childNodes: [
        {
          nodeName: "#text",
          data: "Buy Now!"
        }
      ]
    });
  };

  // Caffeinated column cell manipulation
  const renderYesNo = function (data: any, cell: TableCell, _dataIndex: number, _cellIndex: number): void {
    if ([true, false].includes(data)) {
      cell.childNodes = [
        {
          nodeName: "SPAN",
          attributes: {
            class: data === true ? "caffeinated" : "uncaffeinated"
          },
          childNodes: [
            {
              nodeName: "#text",
              data: data === true ? "Yes" : "No"
            }
          ]
        }
      ];
    }
  };

  // Numbers with styling
  const renderHighLow = function (data: any, cell: TableCell, _dataIndex: number, _cellIndex: number): void {
    const cellTextNode = cell.childNodes[0];
    const currencyNode: CellNode = {
      nodeName: "SPAN",
      attributes: {
        class: "currency "
      },
      childNodes: [cellTextNode]
    };
    cell.childNodes = [currencyNode];

    if (data < 0) {
      currencyNode.attributes!.class += "currency--loss";
    } else if (data > 0) {
      currencyNode.attributes!.class += "currency--profit";
    } else if (data === 0) {
      currencyNode.attributes!.class += "currency--zero";
    }
  };

  const data = {
    headings: ["ID", "Drink", "Price", "Caffeinated", "Profit"],
    data: [
      [574, "Latte", 4.0, false, 0.0],
      [984, "Herbal tea", 3.0, false, 0.56],
      [312, "Green tea", 3.0, true, 1.72],
      [312, "Latte", 3.0, true, -1.21],
      [312, "Green tea", 3.0, false, 0.0],
      [312, "Green tea", 3.0, false, 0.0],
      [312, "Green tea", 3.0, true, 1.72],
      [312, "Latte", 3.0, true, 1.72],
      [312, "Green tea", 3.0, true, -1.21],
      [312, "Green tea", 3.0, false, 0.0],
      [312, "Green tea", 3.0, true, 1.72],
      [312, "Green tea", 3.0, true, 1.72],
      [312, "Latte", 3.0, false, 0.0],
      [312, "Latte", 3.0, true, 1.72],
      [312, "Green tea", 3.0, false, 0.0],
      [312, "Green tea", 3.0, true, 1.72],
      [312, "Latte", 3.0, false, 0.0],
      [312, "Latte", 3.0, true, -1.21],
      [312, "Latte", 3.0, true, 1.72],
      [312, "Latte", 3.0, false, 0.0],
      [312, "Latte", 3.0, false, 0.0],
      [312, "Latte", 3.0, true, 1.72],
      [312, "Green tea", 3.0, true, -1.21],
      [312, "Green tea", 3.0, true, -1.21],
      [312, "Green tea", 3.0, true, -1.21]
    ]
  } as const;

  const cellRendererOptions: DataTableOptions = {
    data,
    rowRender: (row: TableRow, tr: TableRow, _index: number) => {
      if ([true, false].includes(row.cells[3].data)) {
        if (!tr.attributes) {
          tr.attributes = {};
        }
        if (!tr.attributes.class) {
          tr.attributes.class = row.cells[3].data === true ? "yes" : "no";
        } else {
          tr.attributes.class += row.cells[3].data === true ? " yes" : " no";
        }
      }
    },
    columns: [
      {
        select: 0,
        hidden: true,
        type: "number"
      },
      {
        select: 1,
        render: renderIcon,
        type: "string"
      },
      {
        select: 2,
        render: renderButton,
        type: "number"
      },
      {
        select: 3,
        render: renderYesNo,
        type: "boolean"
      },
      {
        select: 4,
        render: renderHighLow,
        type: "number"
      }
    ]
  };
</script>

<Table dataTableOptions={cellRendererOptions} />

Export #

Name ReleaseDate NpmDownloads Growth
Flowbite2021/25/0926900049%
React2013/24/05450000024%
Angular2010/20/09280000017%
Vue2014/12/02360000030%
Svelte2016/26/11120000057%
Ember2011/08/1250000044%
Backbone2010/13/103000009%
jQuery2006/28/0160000005%
Bootstrap2011/19/08180000012%
Foundation2011/23/097000008%
Bulma2016/24/105000007%
Next.js2016/25/10230000045%
Nuxt.js2016/16/1090000050%
Meteor2012/17/01100000010%
Aurelia2015/08/0720000020%
Inferno2016/27/0910000035%
Preact2015/16/0860000028%
Lit2018/28/0540000060%
Alpine.js2019/02/1130000070%
Stimulus2018/06/0315000025%
Solid2021/05/0725000080%
  • Svelte
<script lang="ts">
  import { Table } from "@flowbite-svelte-plugins/datatable";
  import { Button } from "flowbite-svelte";
  import { exportJSON, exportCSV, exportTXT, exportSQL } from "simple-datatables";

  import items from "./data/sample.json";

  let tableComponent: any;

  const handleCSV = () => {
    if (tableComponent?.dataTableInstance) {
      exportCSV(tableComponent.dataTableInstance, {
        download: true,
        lineDelimiter: "\n",
        columnDelimiter: ";"
      });
    }
  };

  const handleSQL = () => {
    if (tableComponent?.dataTableInstance) {
      exportSQL(tableComponent.dataTableInstance, {
        download: true,
        tableName: "export_table"
      });
    }
  };

  const handleTXT = () => {
    if (tableComponent?.dataTableInstance) {
      exportTXT(tableComponent.dataTableInstance, {
        download: true
      });
    }
  };

  const handleJSON = () => {
    if (tableComponent?.dataTableInstance) {
      exportJSON(tableComponent.dataTableInstance, {
        download: true,
        space: 3
      });
    }
  };
</script>

<Table bind:this={tableComponent} {items} />

<div class="mt-4 space-x-2">
  <Button onclick={handleCSV}>Export CSV</Button>
  <Button onclick={handleSQL}>Export SQL</Button>
  <Button onclick={handleTXT}>Export TXT</Button>
  <Button onclick={handleJSON}>Export JSON</Button>
</div>

Scroll Y #

Name Category Brand Price Stock TotalSales Status
Apple iMacComputersApple$1,29950200In Stock
Apple iPhoneMobile PhonesApple$999120300In Stock
Samsung GalaxyMobile PhonesSamsung$89980150In Stock
Dell XPS 13ComputersDell$1,09930120In Stock
HP Spectre x360ComputersHP$1,2992580In Stock
Google Pixel 6Mobile PhonesGoogle$799100200In Stock
Sony WH-1000XM4HeadphonesSony$34960150In Stock
Apple AirPods ProHeadphonesApple$249200300In Stock
Asus ROG ZephyrusComputersAsus$1,8991550In Stock
Microsoft Surface Pro 7ComputersMicrosoft$89940100In Stock
Samsung QLED TVTelevisionsSamsung$1,2992570In Stock
LG OLED TVTelevisionsLG$1,4992050In Stock
Canon EOS R5CamerasCanon$3,8991030In Stock
Nikon Z7 IICamerasNikon$3,299825In Stock
Apple Watch Series 7WearablesApple$399150500In Stock
Fitbit Charge 5WearablesFitbit$179100250In Stock
Dyson V11 VacuumHome AppliancesDyson$5993090In Stock
iRobot Roomba i7+Home AppliancesiRobot$7992070In Stock
Bose SoundLink RevolveSpeakersBose$19980200In Stock
Sonos OneSpeakersSonos$21960180In Stock
Apple iPad ProTabletsApple$1,09950150In Stock
Samsung Galaxy Tab S7TabletsSamsung$64970130In Stock
Amazon Echo DotSmart HomeAmazon$49300800In Stock
Google Nest HubSmart HomeGoogle$89150400In Stock
PlayStation 5Gaming ConsolesSony$49910500Out of Stock
Xbox Series XGaming ConsolesMicrosoft$49915450Out of Stock
Nintendo SwitchGaming ConsolesNintendo$29940600In Stock
Apple MacBook ProComputersApple$1,29920100In Stock
  • Svelte
<script lang="ts">
  import { Table } from "@flowbite-svelte-plugins/datatable";
  import products from "./data/products.json";
  import type { DataTableOptions } from "simple-datatables";

  const scrollyOptions: DataTableOptions = {
    paging: false,
    scrollY: "30vh",
    rowNavigation: true,
    tabIndex: 1
  };
</script>

<Table items={products} dataTableOptions={scrollyOptions} />

AND Search #

Try to search for “blossom 2014” in the two boxes. The OR-search will give you results that contain “2014” OR “Blossom”, while the AND-search will only return results including both “2014” and “Blossom”.

The search item separator for the extension column is ”;” so that searching for “3147;5018” will return no results, but searching for “3147” or “5018” will return the row that contains that value.

Name Id City Date Percentage
Unity Pugh9958Curicó2005/02/1137%
Theodore Duran8971Dhanbad1999/04/0797%
Kylie Bishop3147;5018Norman2005/09/0863%
Willow Gilliam3497;4067Amqui2009/29/1130%
Blossom Dickerson5018Kempten2007/11/0917%
Elliott Snyder3925;4050Enines2006/03/0857%
Castor Pugh9488Neath2014/23/1293%
Pearl Carlson6231Cobourg2014/31/08100%
Deirdre Bridges1579Eberswalde-Finow2014/26/0844%
Daniel Baldwin6095Moircy2000/11/0133%
Phelan Kane9519Germersheim1999/16/0477%
Quentin Salas1339Los Andes2011/26/0149%
Armand Suarez6583Funtua1999/06/119%
Gretchen Rogers5393Moxhe1998/26/1024%
Harding Thompson2824Abeokuta2008/06/0810%
Mira Rocha4393Port Harcourt2002/04/1014%
Drew Phillips2931Goes2011/18/1058%
Emerald Warner6205Chiavari2002/08/0458%
Colin Burch7457Anamur2004/02/0134%
Russell Haynes8916Frascati2015/28/0418%
Brennan Brooks9011;7563Olmué2000/18/042%
Kane Anthony8075LaSalle2006/21/0593%
Scarlett Hurst1019Brampton2015/07/0194%
James Scott3008Meux2007/30/0555%
Desiree Ferguson9054Gojra2009/15/0281%
Elaine Bishop9160Petrópolis2008/23/1248%
Hilda Nelson6307Posina2004/23/0576%
Evangeline Beasley3820Caplan2009/12/0362%
Wyatt Riley5694Cavaion Veronese2012/19/0267%
Blossom Mccarthy3547Patan2014/23/069%
Cairo Rice6273Ostra Vetere2016/27/0213%
Sylvia Peters6829Arrah2015/03/0213%
Kasper Craig5515Firenze2015/26/0456%
Leigh Ruiz5112Lac Ste. Anne2001/09/0228%
Athena Aguirre5741Romeral2010/24/0315%
Riley Nunez5533Sart-Eustache2003/26/0230%
Lois Talley9393Dorchester2014/05/0151%
Hop Bass1024Westerlo2012/25/0985%
Kalia Diaz9184Ichalkaranji2013/26/0692%
Maia Pate6682Louvain-la-Neuve2011/23/0450%
Macaulay Pruitt4457Fraser-Fort George2015/03/0892%
Danielle Oconnor9464Neuwied2001/05/1017%
Kato Carr4842Faridabad2012/11/0596%
Malachi Mejia7133Vorst2007/25/0426%
Dominic Carver3476Pointe-aux-Trembles2014/14/0371%
Paki Santos4424;4054Cache Creek2001/18/1182%
Ross Hodges1862Trazegnies2010/19/0987%
Hilda Whitley3514New Sarepta2011/05/0794%
Roth Cherry4006Flin Flon2008/02/098%
Lareina Jones8642East Linton2009/07/0821%
Joshua Weiss2289Saint-Léonard2010/15/0152%
Kiona Lowery5952Inuvik2002/17/1272%
Nina Rush7567Bo'lhe2008/27/016%
Palmer Parker2000Stade2012/24/0758%
Vielka Olsen3745Vrasene2016/08/0170%
Meghan Cunningham8604Söke2007/16/0259%
Iola Shaw6447Albany2014/05/0388%
Imelda Cole4564Haasdonk2007/16/1179%
Jerry Beach6801Gattatico1999/07/0736%
Garrett Rocha3938Gavorrano2000/06/0871%
Derek Kerr1724Gualdo Cattaneo2014/21/0189%
Shad Hudson5944Salamanca2014/10/1298%
Daryl Ayers8276Barchi2012/12/1188%
Caleb Livingston3094Fatehpur2014/13/028%
Sydney Meyer4576Neubrandenburg2015/06/0222%
Lani Lawrence8501Turnhout2008/07/0516%
Allegra Shepherd2576Meeuwen-Gruitrode2004/19/0441%
Fallon Reyes3178Monceau-sur-Sambre2005/15/0216%
Karen Whitley4357Sluis2003/02/0523%
Stewart Stephenson5350Villa Faraldi2003/05/0765%
Ursula Reynolds7544Southampton1999/16/1261%
Adrienne Winters4425Laguna Blanca2014/15/0924%
Francesca Brock1337Oban2000/12/0690%
Ursa Davenport7629New Plymouth2013/27/0637%
Mark Brock3310Veenendaal2006/08/0941%
Dale Rush5050Chicoutimi2000/27/032%
Shellie Murphy3845Marlborough2013/13/1172%
Porter Nicholson4539Bismil2012/22/1023%
Oliver Huber1265Hannche2002/11/0194%
Calista Maynard3315Pozzuolo del Friuli2006/23/035%
Lois Vargas6825Cumberland1999/25/0450%
Hermione Dickson2785Woodstock2001/22/032%
Dalton Jennings5416Dudzele2015/09/0274%
Cathleen Kramer3380Crowsnest Pass2012/27/0753%
Zachery Morgan6730Collines-de-l'Outaouais2006/04/0951%
Yoko Freeman4077Lidköping2002/27/1248%
Chaim Waller4240North Shore2010/25/0725%
Berk Johnston4532Vergnies2016/23/0293%
Tad Munoz2902Saint-Nazaire2010/09/0565%
Vivien Dominguez5653Bargagli2001/09/0186%
Carissa Lara3241Sherborne2015/07/1272%
Hammett Gordon8101Wah1998/06/0920%
Walker Nixon6901Metz2011/12/1141%
Nathan Espinoza5956Strathcona County2002/25/0147%
Blossom Cameron4836Fontaine-Valmont1999/02/0724%
Kyra Moses3796Quenast1998/07/0768%
Grace Bishop8340Rodez2012/02/104%
Haviva Hernandez8136Suwałki2000/30/0116%
Alisa Horn9853Ucluelet2007/01/1139%
Zelenia Roman7516Redwater2012/03/0331%
  • Svelte
<script lang="ts">
  import { Table } from "@flowbite-svelte-plugins/datatable";
  import andsearch from "./data/andsearch.json";
  import type { DataTableOptions } from "simple-datatables";

  const andsearchOptions: DataTableOptions = {
    perPageSelect: [5, 10, 15, ["All", -1]],
    columns: [
      {
        select: 1,
        searchItemSeparator: ";",
        ignorePunctuation: false
      },
      {
        select: 2,
        sortSequence: ["desc", "asc"]
      },
      {
        select: 3,
        sortSequence: ["desc"]
      },
      {
        select: 4,
        cellClass: "green",
        headerClass: "red"
      }
    ],
    template: (options, dom) => `<div class='${options.classes.top}'>
        <div class='${options.classes.dropdown}'>
            <label>
                <select class='${options.classes.selector}'></select> ${options.labels.perPage}
            </label>
        </div>
        <div class='${options.classes.search}'>
            <input class='${options.classes.input}' placeholder='OR search' type='search' title='${options.labels.searchTitle}'${dom.id ? ` aria-controls="${dom.id}"` : ""}>
            <input class='${options.classes.input}' placeholder='AND search' type='search' data-and="true" title='${options.labels.searchTitle}'${dom.id ? ` aria-controls="${dom.id}"` : ""}>
        </div>
        </div>
        <div class='${options.classes.container}'${options.scrollY.length ? ` style='height: ${options.scrollY}; overflow-Y: auto;'` : ""}></div>
        <div class='${options.classes.bottom}'>
        <div class='${options.classes.info}'></div>
        <nav class='${options.classes.pagination}'></nav>
    </div>`
  };
</script>

<Table items={andsearch} dataTableOptions={andsearchOptions} />

DataTable Event Callbacks #

The DataTable component exposes callback props that allow you to hook into the underlying simple-datatables library events. These callbacks provide access to the table lifecycle and user interactions.

Initialization Events #

onInitStart

Called when table initialization begins. Useful for showing loading indicators.

typescriptonInitStart?: () => void

onInitComplete

Called when the table is fully initialized and ready for interaction.

typescriptonInitComplete?: (dataTable: DataTable) => void

onInitError

Called if table initialization fails.

typescriptonInitError?: (error: Error) => void

Data Events #

onRefresh

Called when the table data is refreshed.

typescriptonRefresh?: (dataTable: DataTable) => void

onUpdate

Called when the table is updated (e.g., after sorting or filtering).

typescriptonUpdate?: (dataTable: DataTable) => void

User Interaction Events #

onSort

Called when a column is sorted.

typescriptonSort?: (column: number, direction: string, dataTable: DataTable) => void

onSearch

Called when a search is performed.

typescriptonSearch?: (query: string, matched: any[], dataTable: DataTable) => void

onPage

Called when pagination changes.

typescriptonPage?: (page: number, dataTable: DataTable) => void

Selection Events (when selectable=true) #

onSelectRow

Called when a row is selected.

typescriptonSelectRow?: (rowIndex: number, event: Event, dataTable: DataTable) => void

onSelectAll

Called when all rows are selected.

typescriptonSelectAll?: (dataTable: DataTable) => void

onDeselectRow

Called when a row is deselected.

typescriptonDeselectRow?: (rowIndex: number, dataTable: DataTable) => void

onDeselectAll

Called when all rows are deselected.

typescriptonDeselectAll?: (dataTable: DataTable) => void
  • Svelte
<script lang="ts">
  import { Table } from "@flowbite-svelte-plugins/datatable";
  import items from "./data/sample.json";
  import type { DataTable } from "simple-datatables";
  import { Spinner } from "flowbite-svelte";

  let isTableLoading = true;
  let tableInstance: DataTable | null = null;

  function handleInitStart(): void {
    console.log("Table initialization started");
    isTableLoading = true;
  }

  function handleInitComplete(dataTable: DataTable): void {
    console.log("Table ready:", dataTable);
    isTableLoading = false;
  }

  function handleInitError(error: Error): void {
    console.error("Table initialization failed:", error);
    isTableLoading = false;
  }

  function handleSort(column: number, direction: string, dataTable: DataTable): void {
    console.log(`Column ${column} sorted ${direction}`);
  }

  function handleSearch(query: string, matched: any[], dataTable: DataTable): void {
    console.log(`Search: "${query}" found ${matched.length} results`);
  }

  function handleRowSelect(rowIndex: number, event: Event, dataTable: DataTable): void {
    console.log(`Row ${rowIndex} selected`);
  }
</script>

{#if isTableLoading}
  <div class="loading-spinner">
    <div class="h-8 w-8 animate-spin rounded-full border-b-2 border-blue-600"></div>
    <span>Loading table...</span>
  </div>
{/if}

<Table {items} bind:isLoading={isTableLoading} bind:dataTableInstance={tableInstance} onInitStart={handleInitStart} onInitComplete={handleInitComplete} onInitError={handleInitError} onSort={handleSort} onSearch={handleSearch} onSelectRow={handleRowSelect} selectable={true} dataTableOptions={selectRowsOptions} />

Component data #

The component has the following props, type, and default values. See types page for type information.

References #