Skip to content

Template Refs

Template refs give you access to the same useTable and useActions methods you'd get from a custom table, without actually building one. Attach a ref to the default <Table> component, then call its exposed methods from anywhere in your page (add or remove filters, toggle row selection, change sort, trigger actions) to drive the table from custom buttons, keyboard shortcuts, or other components.

Basic Usage

To access the table's methods, create a template ref and call the exposed methods:

vue
<script setup>
import { ref } from 'vue'
import { Table } from '@inertiaui/table-vue'

const props = defineProps({
    users: Object,
})

const tableRef = ref()

function addFilter() {
    const filter = props.users.filters.find(f => f.attribute === 'status')
    tableRef.value.addFilter(filter)
}

function selectAll() {
    tableRef.value.toggleItem('*')
}
</script>

<template>
    <Table ref="tableRef" :resource="users" />
</template>
jsx
import { useRef } from 'react'
import { Table } from '@inertiaui/table-react'

export default function Users({ users }) {
    const tableRef = useRef()

    function addFilter() {
        const filter = users.filters.find(f => f.attribute === 'status')
        tableRef.current.addFilter(filter)
    }

    function selectAll() {
        tableRef.current.toggleItem('*')
    }

    return <Table ref={tableRef} resource={users} />
}

Table Methods

MethodDescription
addFilter(filter)Add a filter
removeFilter(filter)Remove a filter
resetAllFilters()Remove all active filters
setFilter(attribute, clause, value)Set a filter by attribute, clause, and value
setSearch(search)Set the search query
toggleColumn(column)Show/hide a column
setSort(sort)Set the table sort
setPerPage(perPage)Change items per page
makeSticky(column)Make columns sticky
undoSticky(column)Remove sticky positioning
putState(newState)Replace the table state
toggleItem(key)Toggle item selection (use '*' for all)
performAction(action, keys)Execute an action

Table State

PropertyTypeDescription
stateObjectReactive table state
hasFiltersBooleanWhether filters are active
hasSelectableRowsBooleanWhether rows are selectable
selectedItemsArraySelected item keys
allItemsAreSelectedBooleanWhether all items are selected
isNavigatingBooleanWhether navigating

Accessing State

You may access the table's reactive state. In Vue, the state is automatically reactive. In React, access the state in response to user interactions or component lifecycle events:

vue
<script setup>
import { ref } from 'vue'
import { Table } from '@inertiaui/table-vue'

const props = defineProps({
    users: Object,
})

const tableRef = ref()

function checkState() {
    // Access state when needed
    const selectedItems = tableRef.value.selectedItems
    const currentSearch = tableRef.value.state.search

    console.log(`Selected ${selectedItems.length} items`)
    console.log(`Current search: ${currentSearch}`)
}
</script>

<template>
    <div>
        <button @click="checkState">
            Check State
        </button>
        <Table ref="tableRef" :resource="users" />
    </div>
</template>
jsx
function MyComponent({ users }) {
    const tableRef = useRef()

    function checkState() {
        // Access state when needed
        const selectedItems = tableRef.current.selectedItems
        const currentSearch = tableRef.current.state.search

        console.log(`Selected ${selectedItems.length} items`)
        console.log(`Current search: ${currentSearch}`)
    }

    return (
        <div>
            <button onClick={checkState}>
                Check State
            </button>
            <Table ref={tableRef} resource={users} />
        </div>
    )
}

Custom Filter Controls

You may build custom filter interfaces that integrate with the table's filtering system. setFilter enables a filter and sets its clause and value in one call, without needing to call addFilter first:

vue
<script setup>
import { ref } from 'vue'
import { Table } from '@inertiaui/table-vue'

const props = defineProps({
    users: Object,
})

const tableRef = ref()

function applyStatusFilter(status) {
    tableRef.value.setFilter('status', 'equals', status)
}

function clearFilters() {
    tableRef.value.resetAllFilters()
}
</script>

<template>
    <div class="mb-4 space-x-2">
        <button @click="applyStatusFilter('active')">Show Active</button>
        <button @click="applyStatusFilter('inactive')">Show Inactive</button>
        <button @click="clearFilters">Clear Filters</button>
    </div>

    <Table ref="tableRef" :resource="users" />
</template>
jsx
function MyComponent({ users }) {
    const tableRef = useRef()

    function applyStatusFilter(status) {
        tableRef.current.setFilter('status', 'equals', status)
    }

    function clearFilters() {
        tableRef.current.resetAllFilters()
    }

    return (
        <div>
            <div className="mb-4 space-x-2">
                <button onClick={() => applyStatusFilter('active')}>
                    Show Active
                </button>
                <button onClick={() => applyStatusFilter('inactive')}>
                    Show Inactive
                </button>
                <button onClick={clearFilters}>
                    Clear Filters
                </button>
            </div>

            <Table ref={tableRef} resource={users} />
        </div>
    )
}

Use setSearch to update the search query programmatically:

vue
<script setup>
import { ref } from 'vue'
import { Table } from '@inertiaui/table-vue'

const props = defineProps({
    users: Object,
})

const tableRef = ref()

function searchForUser(name) {
    tableRef.value.setSearch(name)
}
</script>

<template>
    <div class="mb-4 space-x-2">
        <button @click="searchForUser('John')">Search for John</button>
        <button @click="searchForUser('')">Clear Search</button>
    </div>

    <Table ref="tableRef" :resource="users" />
</template>
jsx
function MyComponent({ users }) {
    const tableRef = useRef()

    function searchForUser(name) {
        tableRef.current.setSearch(name)
    }

    return (
        <div>
            <div className="mb-4 space-x-2">
                <button onClick={() => searchForUser('John')}>
                    Search for John
                </button>
                <button onClick={() => searchForUser('')}>
                    Clear Search
                </button>
            </div>

            <Table ref={tableRef} resource={users} />
        </div>
    )
}

Custom Bulk Actions

You may trigger bulk actions programmatically and control row selection:

vue
<script setup>
import { ref } from 'vue'
import { Table } from '@inertiaui/table-vue'

const props = defineProps({
    users: Object,
})

const tableRef = ref()

function selectAll() {
    tableRef.value.toggleItem('*')
}

function bulkDelete() {
    const deleteAction = props.users.actions.find(a => a.id === 'delete')

    if (deleteAction && tableRef.value.selectedItems.length > 0) {
        tableRef.value.performAction(deleteAction, tableRef.value.selectedItems)
    }
}
</script>

<template>
    <div class="mb-4 space-x-2">
        <button @click="selectAll">Toggle All</button>
        <button @click="bulkDelete" :disabled="!tableRef?.selectedItems?.length">
            Delete Selected ({{ tableRef?.selectedItems?.length || 0 }})
        </button>
    </div>

    <Table ref="tableRef" :resource="users" />
</template>
jsx
function MyComponent({ users }) {
    const tableRef = useRef()

    function selectAll() {
        tableRef.current.toggleItem('*')
    }

    function bulkDelete() {
        const deleteAction = users.actions.find(a => a.id === 'delete')

        if (deleteAction && tableRef.current.selectedItems.length > 0) {
            tableRef.current.performAction(deleteAction, tableRef.current.selectedItems)
        }
    }

    return (
        <div>
            <div className="mb-4 space-x-2">
                <button onClick={selectAll}>Toggle All</button>
                <button onClick={bulkDelete}>
                    Delete Selected
                </button>
            </div>

            <Table ref={tableRef} resource={users} />
        </div>
    )
}