JavaScript Events & API

TableCrafter ships a self-initializing frontend library that mounts every [tablecrafter] table and exposes a global TableCrafter class. This page documents the real custom DOM events it dispatches and the public instance methods you can call to drive a table from your own scripts.

Custom Events Auto-Init Public API SSR Hydration Auto-Refresh

How tables are initialized

When you place the [tablecrafter] shortcode on a page, the plugin enqueues two scripts: the core library (tablecrafter-lib, from assets/js/tablecrafter.js, which defines window.TableCrafter) and the bootstrap (tablecrafter-frontend, from assets/js/frontend.js). The bootstrap runs on DOMContentLoaded, queries the page for .tablecrafter-container elements, reads their data-* attributes, and constructs a TableCrafter instance for each one.

There is no separate init() call: the constructor renders the table immediately. Once mounted, a container is flagged with data-tc-initialized="true" so it is not initialized twice. The bootstrap also re-runs once after a 500 ms delay to guard against races with other scripts.

// Simplified from assets/js/frontend.js — what the bootstrap does per container
const containers = document.querySelectorAll('.tablecrafter-container');
containers.forEach(container => {
  if (container.dataset.tcInitialized === "true" && !container.dataset.ssr) return;
  new TableCrafter('#' + container.id, {
    data: container.getAttribute('data-source'),
    responsive: true,
    globalSearch: container.getAttribute('data-search') === 'true'
  });
});
ℹ️

The shortcode renders the initial rows server-side inside a <script class="tc-initial-data"> JSON block and marks the container data-ssr="true". On first run the library hydrates that existing markup instead of re-fetching, then sets data-ssr="false".

Container markup and attributes

The bootstrap and the library both read configuration from the container's data-* attributes. These mirror the shortcode attributes set in any post or page via [tablecrafter ...], and they are the same values the public API reads through parseDataAttributes().

AttributeMaps to configNotes
data-sourceconfig.dataRequired URL of the JSON/data source loaded by loadData().
data-searchconfig.globalSearchOptional "true" enables the global search box.
data-filtersconfig.filterableOptional Anything other than "false"/"0" enables column filters.
data-exportconfig.exportableOptional "true" enables CSV/XLSX/PDF export controls.
data-per-pageconfig.pageSizeOptional A value > 0 turns on pagination at that page size.
data-sortconfig.sortOptional Default sort field.
data-includeconfig.includeOptional Column include list.
data-auto-refreshconfig.autoRefresh.enabledOptional Pairs with data-refresh-interval (ms).

Custom DOM events

TableCrafter fires native CustomEvent objects so you can react to user interactions without patching the library. Every event name is prefixed with tablecrafter:, is dispatched on the table's container element, and bubbles (bubbles: true) so you can also listen at document level. The relevant data is always on event.detail.

These events originate from the mobile/touch card view (the responsive layout TableCrafter renders on small screens and touch devices), where rows become tappable cards.

Event nameFires whenevent.detail payload
tablecrafter:cardTapA user taps a card in mobile/card view (also toggles expand/collapse){ rowData, rowIndex, card }
tablecrafter:cardViewThe "view details" action is triggered for a card{ rowData, rowIndex }
tablecrafter:cardEditThe "edit" action is triggered for a card{ rowData, rowIndex }

Where rowData is the object for that record, rowIndex is its index in the current dataset, and card (cardTap only) is the card DOM element.

// Listen at the document level — events bubble up from the container
document.addEventListener('tablecrafter:cardTap', function (e) {
  console.log('Tapped row', e.detail.rowIndex, e.detail.rowData);
});

// Or scope a listener to one specific table by container id
const el = document.getElementById('my-table');
el.addEventListener('tablecrafter:cardEdit', (e) => {
  openEditorFor(e.detail.rowData);
});
⚠️

These three are the only custom events the library dispatches. There is no generic change, render, or filter event, and no .on() subscription helper. To react to data changes, listen for the card events above or wrap the public methods you call yourself.

Getting a table instance

Because the bootstrap creates instances internally, the simplest way to control a table from your own code is to construct your own instance against the same container after the page loads. The constructor accepts a CSS selector string (or an element) and a config object.

const table = new TableCrafter('#my-table', {
  data: '/wp-json/myplugin/v1/rows',
  globalSearch: true,
  filterable: true,
  pagination: true,
  pageSize: 25
});

The class is exposed both as window.TableCrafter (browser) and as a CommonJS/AMD module export, so it works in bundled environments too.

Public instance methods

The following methods are part of the practical public surface for driving a table after it is mounted. All are called on a TableCrafter instance.

Data

MethodPurpose
getData()Returns the current in-memory dataset array.
setData(data)Replaces the dataset, auto-optimizes config for large sets, and re-renders if the table is already mounted.
loadData()Fetches from the configured data-source / config.data URL (via the AJAX proxy when configured) and renders. Returns a promise.
refreshNow()Triggers an immediate data refresh and resets the auto-refresh interval.

Sorting, filtering & paging

MethodPurpose
sort(field)Sorts by the given field, toggling ascending/descending on repeat calls.
setFilter(field, value)Applies a filter value to a column and re-renders.
clearFilters()Removes all active column filters.
goToPage(page)Jumps to a specific page number.
nextPage() / prevPage()Steps forward or back one page.

Auto-refresh control

MethodPurpose
startAutoRefresh()Starts the polling interval defined by config.autoRefresh.interval.
stopAutoRefresh()Clears the polling interval.
pauseAutoRefresh() / resumeAutoRefresh()Temporarily halts and resumes polling (e.g., while the user is interacting).
toggleAutoRefresh()Flips auto-refresh on or off.

Lifecycle & permissions

MethodPurpose
setCurrentUser(user)Sets the active user object used by permission-aware rendering and editing.
destroy()Saves state, removes the resize listener, clears the container and internal data/caches, and removes any body-appended dropdowns.
// Example: wire custom controls to the public API
const table = new TableCrafter('#my-table', { data: '/data.json' });

document.querySelector('#refresh-btn').addEventListener('click', () => table.refreshNow());
document.querySelector('#status-filter').addEventListener('change', (e) => {
  table.setFilter('status', e.target.value);
});

// Tear down before removing the container from the DOM
table.destroy();

Globals and configuration objects

The plugin localizes a few globals that the library and your scripts can rely on.

GlobalDescription
window.tablecrafterDataLocalized on the frontend script. Contains ajaxUrl, nonce (proxy fetch), exportNonce, downloadNonce, and an i18n strings object.
window.tcExportNonceInline-injected export nonce used by the enhanced export flow.
window.TABLECRAFTER_DEBUGSet to true before the library runs to enable verbose [TableCrafter] console logging.
💡

To debug initialization, set window.TABLECRAFTER_DEBUG = true in an inline script that runs before TableCrafter, or add data-debug="true" to the container. Errors are always logged; this flag adds the informational and warning output.

End-to-end example

Place the shortcode in the WordPress editor (any post or page), then enhance it with your own listeners. Admin path for managing data sources: WordPress Admin → TableCrafter.

[tablecrafter id="orders" source="/wp-json/shop/v1/orders" search="true" filters="true" export="true" per_page="25"]
<!-- Add to your theme or a custom-HTML block on the same page -->
<script>
document.addEventListener('DOMContentLoaded', () => {
  const el = document.getElementById('orders');

  // React to mobile card interactions
  el.addEventListener('tablecrafter:cardView', (e) => {
    showOrderModal(e.detail.rowData);
  });

  // Drive the table programmatically
  const table = new TableCrafter('#orders', {
    data: '/wp-json/shop/v1/orders',
    globalSearch: true,
    filterable: true
  });
  window.ordersTable = table; // keep a handle for refreshNow(), setFilter(), etc.
});
</script>

Next, see shortcode-reference.html for the full list of [tablecrafter] attributes, and export-formats.html for how the CSV, XLSX, and PDF export pipeline works alongside these client APIs.