Reputation: 69
I'm struggling to get the checkbox
working using TanStack
in Solidjs
. The docs doesn't have much information about creating a checkbox column which is why i followed the TanStack React Table Examples
and some of the Solidjs Table Examples
. The checkbox would not update and i am assuming this has something to do with Solidjs
reactivity. Here props is not updating since i tried to console.log it and it only ran once which was when the component rendered.
const checkbox = {
accessorKey: "checkbox",
header: (props) => (
<Checkbox
{...{
checked: props.table.getIsAllRowsSelected(),
indeterminate: props.table.getIsSomeRowsSelected(),
onChange: props.table.getToggleAllRowsSelectedHandler(),
}}
/>
),
cell: (props) => {
return (
<Checkbox
{...{
checked: props.row.getIsSelected(),
disabled: !props.row.getCanSelect(),
onChange: props.row.getToggleSelectedHandler(),
}}
/>
);
},
};
If i do it without TanStack, it would look something like this but it defeats the purpose of using TanStack
cell: () => {
const [isSelected , setIsSelected] = createSignal(false)
const toggleSelected = (event , checked) => {
setIsSelected(checked)
}
return (
<Checkbox
{...{
checked: isSelected(),
onChange: toggleSelected,
}}
/>
);
},
*** Update 1: Here is the whole code of creating the table
const generateColumns = (columns) => {
const result = columns.map((value) => {
return {
accessorKey: value,
};
});
return result;
};
const DataTable = (props) => {
const [rowSelection, setRowSelection] = createSignal({});
const checkbox = {
accessorKey: "checkbox",
header: (props) => (
<Checkbox
{...{
checked: props.table.getIsAllRowsSelected,
indeterminate: props.table.getIsSomeRowsSelected,
onChange: props.table.getToggleAllRowsSelectedHandler,
}}
/>
),
cell: () => {
const [isSelected , setIsSelected] = createSignal(false)
const toggleSelected = (event , checked) => {
setIsSelected(checked)
}
return (
<Checkbox
{...{
checked: isSelected(),
onChange: toggleSelected,
}}
/>
);
},
};
const columns = [checkbox, ...generateColumns(props.columns)];
const table = createSolidTable({
get data() {
return props.data;
},
columns: columns,
state: {
get rowSelection() {
return rowSelection();
},
},
onRowSelectionChange: setRowSelection,
getCoreRowModel: getCoreRowModel(),
});
return (
<TableContainer component={Paper}>
<Table>
<TableHead>
<For each={table.getHeaderGroups()}>
{(headerGroup) => (
<TableRow>
<For each={headerGroup.headers}>
{(header) => (
<TableCell>
{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
</TableCell>
)}
</For>
</TableRow>
)}
</For>
</TableHead>
<TableBody>
<For each={table.getRowModel().rows}>
{(row) => (
<TableRow>
<For each={row.getVisibleCells()}>
{(cell) => <TableCell>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>}
</For>
</TableRow>
)}
</For>
</TableBody>
</Table>
</TableContainer>
);
};
Upvotes: 0
Views: 1332
Reputation: 537
I was in a similar spot, coming from the React version of Tanstack Table.
Having looked at your code I was able to make mine work with some minor modifications based on your implementation.
Hopefully this can help you finalize a working solution as well.
Here's the code for my SolidJS table component with working select column:
export const Table: Component<TableData> & TableSubComponentsInterface = (props) => {
const merged = mergeProps({
enableRowSelection: () => true,
}, props);
const isWorking = useWorking();
const [sorting, sortingSet] = createSignal<ColumnSort[]>();
const [rowSelection, rowSelectionSet] = createSignal<RowSelectionState>();
const [columnFilters, setColumnFilters] = createSignal<ColumnFilter[]>();
const tableOptions = {
get data() {
return merged.columnData ?? [];
},
// eslint-disable-next-line solid/reactivity
columns: merged.columns ?? [],
state: {
get rowSelection() {
return rowSelection();
},
get sorting() {
return sorting();
},
get columnFilters() {
return columnFilters();
},
},
enableRowSelection: (row: TanstackRow<Record<string, unknown>>) => merged.enableRowSelection(row),
onColumnFiltersChange: setColumnFilters,
getFilteredRowModel: getFilteredRowModel(),
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
onSortingChange: sortingSet,
onRowSelectionChange: rowSelectionSet,
};
const solidTable = createSolidTable(tableOptions);
return (
<section class="no-scrollbar table-rounded-md max-w-xl7 w-full overflow-auto rounded-md border border-gray-200 bg-white drop-shadow-sm">
<table class="w-full">
<thead>
<For each={solidTable.getHeaderGroups()}>{(headerGroup) => (
<tr
class="items-center border-b border-b-gray-200 text-left font-semibold capitalize"
>
<For each={headerGroup.headers}>{(header) => (
<th colSpan={header.colSpan}>
<Show when={!header.isPlaceholder}>
<div
class={`${header.column.getCanSort() ? "cursor-pointer select-none" : ""} flex items-center gap-x-2 p-4`}
onClick={header.column.getToggleSortingHandler()}
>
{flexRender(header.column.columnDef.header, header.getContext())}
{{
asc: <ExpandLessIcon size={Size.XS} />,
desc: <ExpandMoreIcon size={Size.XS} />,
}[header.column.getIsSorted() as string]
?? (header.column.getCanSort() ? (
<UnfoldMoreIcon size={Size.SM} />
) : null)}
</div>
</Show>
</th>
)
}</For>
</tr>
)}</For>
</thead>
<tbody>
<For each={solidTable.getRowModel().rows}>{(row) => (
<tr class=" border-b border-b-gray-200 hover:bg-gray-50">
<For each={row.getVisibleCells()}>{(cell) => (
<td class="p-4">
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
)}</For>
</tr>
)}</For>
</tbody>
</table>
</section>
);
};
Excerpt usage:
import { createColumnHelper } from "@tanstack/solid-table";
const TableUsageComponent = () => {
const columnHelper = createColumnHelper<Record<string, unknown>>();
const columns = [
columnHelper.accessor("id", selectColumn), // This would be the select column
// Other required columns for your use case.
]
// In case you have fetching/loading logic.
const isFetching = false;
// Data for columns should go here.
const columnData = [
{
key1: "some value",
key2: "some value 2",
// ...
}
];
return (
<Show when={!isFetching} fallback={<TableLoader />}>
<Table
columnData={columnData}
columns={columns}
/>
</Show>
);
}
export default TableUsageComponent;
The selectColumn
column helper variable (where Checkbox
component is a custom component in this case. You might have to accommodate any properties or parameters for you checkbox component):
import { Row as TanstackRow, Table as TanstackTable } from "@tanstack/solid-table";
import { Show } from "solid-js";
import { Checkbox } from "../form";
export const selectColumn = {
id: "select",
header: (props: { table: TanstackTable<Record<string, unknown>>; }) => (
<Checkbox
{...{
checked: props.table.getIsAllRowsSelected(),
indeterminate: !props.table.getIsAllRowsSelected() && props.table.getIsSomeRowsSelected(),
onChange: props.table.getToggleAllRowsSelectedHandler(),
}}
/>
),
cell: (props: { row: TanstackRow<Record<string, unknown>>; }) => (
<Show when={props.row.getCanSelect()}>
<div class="px-1">
<Checkbox
{...{
checked: props.row.getIsSelected(),
indeterminate: props.row.getIsSomeSelected(),
onChange: props.row.getToggleSelectedHandler(),
}}
/>
</div>
</Show>
),
enableSorting: false,
};
Upvotes: 1