Skip to content

Tabulator Component

A flexible and customizable Vue 3 wrapper for Tabulator.js with column visibility settings, pagination size control, configurable action buttons, and support for both local and remote data modes. Enhanced with export, print functionality, and customizable header/footer blocks.


Props

PropTypeDefaultDescription
dataArray<any>[]The table's data rows.
columnsArray<TabulatorHeader>[]Column definitions. Use isNotMandatory: false to make columns always visible.
placeholderstring""Message shown when no data is available.
paginationSizenumber25Number of rows per page.
paginationSizeSelectorArray<number>[25, 50, 100, 200]List of pagination options available in settings.
actionbooleanfalseIf true, adds a rightmost column with action buttons.
actionMode"frontend" | "api""frontend"- "frontend": Uses actionButtons array.- "api": Expects actions array per row.
actionButtonsArray<{ name: string, emit: string, class?: string }>[]Button definitions used in "frontend" mode.
heightOffsetnumber250Subtracted from window height to calculate table height.
showOptionsbooleantrueShow/hide the options buttons in the header.
settingsButtonbooleantrueShow/hide the settings button in the header.
printButtonbooleanfalseShow/hide the print button in the header.
exportButtonbooleanfalseShow/hide the export button in the header.
sheetNamestring"download"Name of the exported Excel file and sheet.
paginationType"local" | "remote""local"Data pagination mode - local for client-side, remote for server-side.
apiEndpointstring""API endpoint URL for remote pagination mode.
apiInstanceAxiosInstanceundefinedAxios instance for API calls (required for remote mode).
queryParamsobject{}Additional query parameters for API requests.
headerContentstringundefinedHTML content to display above the table.
footerContentstringundefinedHTML content to display below the table.
enableHeaderBlockbooleantrueEnable/disable the header content block.
enableFooterBlockbooleanfalseEnable/disable the footer content block.
enableHeaderPrintbooleantrueInclude header content when printing.
enableFooterPrintbooleantrueInclude footer content when printing.

Exposed Functions

FunctionTypeDescriptionUsage
reInitializeTabulator()VoidReinitialize/Rerender TabulatorCreate a Tabulator reference variable and call the exposed function
print()VoidPrint the table with current dataCall to trigger print dialog with table content
exportTable()VoidExport table data to Excel fileCall to download table data as XLSX file

Data Modes

Local Mode (Default)

  • All data is provided via the data prop
  • Filtering, sorting, and pagination happen client-side
  • Best for smaller datasets that can be loaded entirely

Remote Mode

  • Data is fetched from a server via API calls
  • Requires apiEndpoint and apiInstance props
  • Supports server-side filtering, sorting, and pagination
  • Automatically sends filter and sort parameters to the API
  • Shows loading state during API requests
  • Expected API response format:
    json
    {
      "data": [...], // Array of table rows
      "meta": {
        "total": 100,      // Total number of records
        "last_page": 4     // Total number of pages
      }
    }

Emits

EventDescription
onCloseFired when the settings modal is closed without applying changes.
onSaveFired when settings are applied (e.g., visibility, page size).
onDataFetechedFired when remote data is successfully fetched, returns meta information.
[custom]Emits custom events from action buttons (e.g., deleteRow, editUser).

Note: Custom event names come from the emit property in actionButtons.


Features

Core Features

  • Column Settings
    Users can toggle visibility of optional columns via a settings modal. Mandatory columns (isNotMandatory: false) cannot be hidden.

  • Column Search
    Search/filter columns by name in the settings modal for easier management of tables with many columns.

  • Pagination Size Selector
    Change the number of rows per page using radio buttons in the settings modal.

  • Action Buttons
    Per-row dropdown buttons with customizable styling, generated either from props (frontend mode) or row data (api mode).

Export & Print Features

  • Excel Export
    Export table data to XLSX format with customizable sheet names. Uses SheetJS library for robust Excel file generation.

  • Print Functionality
    Print tables with optional header and footer content. Configurable print settings for headers and footers.

  • Header/Footer Blocks
    Display custom HTML content above and below the table with separate controls for visibility and print inclusion.

Interactive Features

  • Row Selection & Highlighting
    Clicking a row highlights it with a gray background when actions are enabled (action: true).

  • Smart Dropdown Positioning
    Action dropdowns automatically position themselves to stay within table boundaries and adjust position based on available space.

  • Click Outside Handling
    Action dropdowns close when clicking outside the table, scrolling, or clicking on other table elements.

  • Configurable Toolbar
    Flexible header toolbar with individual controls for settings, print, and export buttons.

Responsive & Dynamic

  • Responsive Height
    Automatically adjusts table height using window.innerHeight - heightOffset.

  • Dynamic Updates
    Table automatically updates when data, columns, or queryParams props change.

  • Multiple Instance Support
    Each component instance uses a unique tableID to avoid conflicts when multiple tables exist on the same page.

Remote Data Features

  • Server-side Operations
    Supports remote filtering, sorting, and pagination when paginationType="remote".

  • Loading States
    Built-in loading state management for API requests with proper state handling.

  • Error Handling
    Graceful handling of API errors with automatic loading state cleanup.

  • Header Filters
    Live filter delay of 500ms for better performance with remote data.

  • Data Fetch Events
    Emits onDataFeteched event with metadata when remote data is successfully loaded.


Usage Examples

Basic Local Table

vue
<script setup>
const data = [
  { id: 1, name: 'Alice', role: 'Admin', email: '[email protected]' },
  { id: 2, name: 'Bob', role: 'User', email: '[email protected]' },
]

const columns = [
  { title: 'ID', field: 'id', isNotMandatory: true },
  { title: 'Name', field: 'name', isNotMandatory: false }, // Always visible
  { title: 'Role', field: 'role', isNotMandatory: true },
  { title: 'Email', field: 'email', isNotMandatory: true },
]
</script>

<template>
  <Tabulator 
    :data="data" 
    :columns="columns" 
    :pagination-size="25"
    :pagination-size-selector="[10, 25, 50, 100]"
    placeholder="No users found"
  />
</template>

Table with Export and Print Features

vue
<script setup>
const headerContent = `
  <div class="bg-blue-50 p-4 mb-4 rounded-lg">
    <h2 class="text-xl font-bold text-blue-800">User Management Report</h2>
    <p class="text-blue-600">Generated on ${new Date().toLocaleDateString()}</p>
  </div>
`

const footerContent = `
  <div class="mt-4 p-3 bg-gray-50 rounded text-sm text-gray-600">
    <p>© 2025 Company Name. Confidential Report.</p>
  </div>
`
</script>

<template>
  <Tabulator 
    :data="data" 
    :columns="columns"
    :export-button="true"
    :print-button="true"
    :settings-button="true"
    sheet-name="user-report"
    :header-content="headerContent"
    :footer-content="footerContent"
    :enable-header-block="true"
    :enable-footer-block="true"
    :enable-header-print="true"
    :enable-footer-print="true"
  />
</template>

Table with Frontend Actions

vue
<script setup>
const actionButtons = [
  { name: 'Edit', emit: 'editUser', class: 'text-blue-600' },
  { name: 'Delete', emit: 'deleteUser', class: 'text-red-600' },
  { name: 'View Details', emit: 'viewUser', class: 'text-green-600' },
]

function handleEdit(rowData) {
  console.log('Editing user:', rowData)
}

function handleDelete(rowData) {
  console.log('Deleting user:', rowData)
}

function handleView(rowData) {
  console.log('Viewing user:', rowData)
}
</script>

<template>
  <Tabulator 
    :data="data" 
    :columns="columns"
    :action="true"
    action-mode="frontend"
    :action-buttons="actionButtons"
    @editUser="handleEdit"
    @deleteUser="handleDelete"
    @viewUser="handleView"
  />
</template>

Remote Data Table with Export

vue
<script setup>
import axios from 'axios'

const apiInstance = axios.create({
  baseURL: 'https://api.example.com',
  headers: { 'Authorization': 'Bearer your-token' }
})

const queryParams = ref({
  status: 'active',
  department: 'engineering'
})

function handleDataFetched(meta) {
  console.log('Total records:', meta.total)
  console.log('Current page:', meta.current_page)
}

// Update query params to trigger new API request
function filterByDepartment(dept) {
  queryParams.value.department = dept
}
</script>

<template>
  <Tabulator 
    :columns="columns"
    :api-instance="apiInstance"
    api-endpoint="/api/users"
    pagination-type="remote"
    :query-params="queryParams"
    :pagination-size="50"
    :action="true"
    action-mode="api"
    :export-button="true"
    :print-button="true"
    sheet-name="remote-users"
    @onDataFeteched="handleDataFetched"
  />
</template>

Table with API-based Actions

vue
<!-- When using actionMode="api", each row should include an actions array -->
<script setup>
// Example API response structure:
const exampleApiData = [
  {
    id: 1,
    name: 'Alice',
    role: 'Admin',
    actions: [
      { name: 'Edit', emit: 'editUser', class: 'text-blue-600' },
      { name: 'Promote', emit: 'promoteUser', class: 'text-green-600' }
    ]
  },
  {
    id: 2,
    name: 'Bob',
    role: 'User',
    actions: [
      { name: 'Edit', emit: 'editUser', class: 'text-blue-600' },
      { name: 'Delete', emit: 'deleteUser', class: 'text-red-600' }
    ]
  }
]
</script>

<template>
  <Tabulator 
    :data="exampleApiData"
    :columns="columns"
    :action="true"
    action-mode="api"
    @editUser="handleEdit"
    @deleteUser="handleDelete"
    @promoteUser="handlePromote"
  />
</template>

Customized Table with All Features

vue
<script setup>
const tabulatorRef = ref()

function customPrint() {
  tabulatorRef.value.print()
}

function customExport() {
  tabulatorRef.value.exportTable()
}

function reInitialize() {
  tabulatorRef.value.reInitializeTabulator()
}
</script>

<template>
  <Tabulator 
    ref="tabulatorRef"
    :data="data"
    :columns="columns"
    :show-options="true"
    :settings-button="true"
    :print-button="false"
    :export-button="false"
    :height-offset="200"
    :pagination-size="100"
    :pagination-size-selector="[50, 100, 200, 500]"
    placeholder="No records available at this time"
    sheet-name="custom-export"
    header-content="<h3>Custom Header</h3>"
    footer-content="<p>Custom Footer</p>"
    :enable-header-block="true"
    :enable-footer-block="true"
  />
  
  <!-- Custom external buttons -->
  <div class="mt-4 flex gap-2">
    <button @click="customPrint" class="btn btn-secondary">
      Custom Print
    </button>
    <button @click="customExport" class="btn btn-secondary">
      Custom Export
    </button>
    <button @click="reInitialize" class="btn btn-outline">
      Reinitialize
    </button>
  </div>
</template>

API Request Format (Remote Mode)

When using paginationType="remote", the component sends requests with these parameters:

javascript
{
  page: 1,              // Current page number
  per_page: 25,         // Items per page
  filters: "[...]",     // JSON string of active filters (only if filters exist)
  sorters: "[...]",     // JSON string of active sorters (only if sorters exist)
  ...queryParams        // Additional custom parameters
}

Expected response format:

json
{
  "data": [
    { "id": 1, "name": "Alice", "role": "Admin" },
    { "id": 2, "name": "Bob", "role": "User" }
  ],
  "meta": {
    "total": 150,
    "last_page": 6,
    "current_page": 1,
    "per_page": 25
  }
}

Component Behavior Details

Action Dropdown Behavior

  • Positioning: Dropdowns automatically position to the right (35px from right edge) and adjust vertically if they would overflow the table bounds
  • State Management: Only one dropdown can be open at a time; opening a new one closes others
  • Event Handling: Dropdowns close on outside clicks, scrolling, or row clicks (unless clicking the action button itself)
  • Conditional Rendering: Action column only appears when action is true AND there are actual actions to display

Row Interaction

  • Selection: Clicking any part of a row (except action buttons) selects it and applies the datarow-selected class
  • Styling: Selected rows get a light gray background (#f3f4f6)
  • Cursor: Rows show pointer cursor when actions are enabled

Export & Print Behavior

  • Excel Export: Creates XLSX files using SheetJS library with configurable sheet names
  • Print Functionality: Uses Tabulator's built-in print feature with optional header/footer content
  • Content Blocks: Header and footer content can be shown in the UI independently of print settings
  • Button Visibility: Individual control over settings, print, and export button visibility

Loading States

  • Remote Mode: Shows loading state during API requests
  • Error Handling: Automatically clears loading state on API errors
  • Page Changes: Loading state is cleared when page data loads successfully

Event Lifecycle

  • Component Mounting: Initializes Tabulator instance and sets up event listeners
  • Component Unmounting: Properly cleans up all event listeners to prevent memory leaks
  • Data Changes: Automatically updates table data and rebuilds columns when props change
  • Query Parameter Changes: Triggers new API requests in remote mode when queryParams change

Notes & Best Practices

  • Event Naming: Ensure emit values in actionButtons match the @ event handlers in parent components
  • Remote Mode: Always provide both apiEndpoint and apiInstance when using remote pagination
  • Performance: Use local mode for datasets under 1000 rows, remote mode for larger datasets
  • Unique Keys: The component generates unique IDs automatically using a 5-character random string to support multiple instances
  • Column Management: Mark essential columns with isNotMandatory: false to prevent accidental hiding
  • Error Handling: Implement proper error handling in your API instance for better user experience
  • Memory Management: Component properly cleans up event listeners on unmount to prevent memory leaks
  • Action Validation: Action column only renders when there are actual actions to display, improving performance
  • Filter Performance: Header filters have a 500ms delay/debounce time for better performance with remote data sources
  • Export Features: Export functionality requires the SheetJS library (XLSX) which is automatically imported
  • Print Customization: Use headerContent and footerContent props for custom print headers and footers
  • Toolbar Customization: Use individual button props (settingsButton, printButton, exportButton) to customize the toolbar
  • Content Blocks: Header and footer blocks can be used for additional context or branding around the table
  • Exposed Functions: Access component methods through template refs for custom implementations

Dependencies

  • Tabulator.js: Core table functionality
  • SheetJS (XLSX): Excel export functionality
  • Vue 3: Component framework
  • Axios: HTTP client for remote data (when using remote mode)

Screenshot

tabulator image