Select Table
Table-based picker component
Note
rowKey is required. Unlike Element Plus, only string values are supported for now; function values are not. Tree selection is also not supported at the moment.
Tip
When mode is single, value is a single value. When mode is multiple, value is an array.
Markup Schema Multiple Selection Example
<script lang="ts" setup>
import { createForm } from '@silver-formily/core'
import { SelectTable, Submit } from '@silver-formily/element-plus'
import { createSchemaField, FormProvider } from '@silver-formily/vue'
const form = createForm()
const { SchemaField, SchemaStringField } = createSchemaField({
components: {
SelectTable,
},
})
function log(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<FormProvider :form="form">
<SchemaField>
<SchemaStringField
name="selectTable"
x-component="SelectTable"
:x-component-props="{
mode: 'multiple',
rowKey: 'key',
columns: [
{ prop: 'name', label: 'Title' },
{ prop: 'description', label: 'Description' },
],
}"
:enum="[
{ key: '1', name: 'title-1', description: 'description-1' },
{ key: '2', name: 'title-2', description: 'description-2' },
{ key: '3', name: 'title-3', description: 'description-3' },
]"
/>
</SchemaField>
<Submit style="margin-top: 30px;" @submit="log">
Submit
</Submit>
</FormProvider>
</template>Markup Schema Multiple Selection Slot Example
Multiple selection combined with slots.
<script lang="ts" setup>
import { createForm } from '@silver-formily/core'
import { SelectTable, Submit } from '@silver-formily/element-plus'
import { createSchemaField, FormProvider } from '@silver-formily/vue'
import { ElTableColumn } from 'element-plus'
import { h } from 'vue'
const form = createForm()
const { SchemaField, SchemaStringField } = createSchemaField({
components: {
SelectTable,
},
})
function log(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<FormProvider :form="form">
<SchemaField>
<SchemaStringField
name="selectTable" x-component="SelectTable" :x-component-props="{
multiple: true,
rowKey: 'key',
}" :enum="[
{ key: '1', name: 'title-1', description: 'description-1' },
{ key: '2', name: 'title-2', description: 'description-2' },
{ key: '3', name: 'title-3', description: 'description-3' },
]" :x-content="{
default: () => [
h(ElTableColumn, {
prop: 'name',
label: 'Title',
}),
h(ElTableColumn, {
prop: 'description',
label: 'Description',
}, {
default: ({ row }) => `${row.description} - rendered via slot`,
})],
}"
/>
</SchemaField>
<Submit style="margin-top: 30px;" @submit="log">
Submit
</Submit>
</FormProvider>
</template>JSON Schema Multiple Selection Example
<script lang="ts" setup>
import { createForm } from '@silver-formily/core'
import { SelectTable, Submit } from '@silver-formily/element-plus'
import { createSchemaField, FormProvider } from '@silver-formily/vue'
const schema = {
type: 'object',
properties: {
select: {
'type': 'string',
'x-component': 'SelectTable',
'x-component-props': {
mode: 'multiple',
rowKey: 'key',
columns: [
{ prop: 'name', label: 'Title' },
{ prop: 'description', label: 'Description' },
],
},
'enum': [
{
key: '1',
name: 'title-1',
description: 'description-1',
},
{
key: '2',
name: 'title-2',
description: 'description-2',
},
{
key: '3',
name: 'title-3',
description: 'description-3',
},
],
},
},
}
const form = createForm()
const { SchemaField } = createSchemaField({
components: {
SelectTable,
},
})
function log(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<FormProvider :form="form">
<SchemaField :schema="schema" />
<Submit style="margin-top: 30px;" @submit="log">
Submit
</Submit>
</FormProvider>
</template>JSON Schema Single Selection Example
Single selection, returning the whole row and hiding the alert toolbar.
<script lang="ts" setup>
import { createForm } from '@silver-formily/core'
import { SelectTable, Submit } from '@silver-formily/element-plus'
import { createSchemaField, FormProvider } from '@silver-formily/vue'
const schema = {
type: 'object',
properties: {
select: {
'type': 'object',
'x-component': 'SelectTable',
'x-component-props': {
mode: 'single',
rowKey: 'key',
optionAsValue: true,
showAlertToolbar: false,
columns: [
{ prop: 'name', label: 'Title' },
{ prop: 'description', label: 'Description' },
],
},
'enum': [
{
key: '1',
name: 'title-1',
description: 'description-1',
},
{
key: '2',
name: 'title-2',
description: 'description-2',
},
{
key: '3',
name: 'title-3',
description: 'description-3',
},
],
'default': {
key: '2',
name: 'title-2',
description: 'description-2',
},
},
},
}
const form = createForm()
const { SchemaField } = createSchemaField({
components: {
SelectTable,
},
})
function log(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<FormProvider :form="form">
<SchemaField :schema="schema" />
<Submit style="margin-top: 30px;" @submit="log">
Submit
</Submit>
</FormProvider>
</template>Template Single Selection Example
Single selection, returning only the selected key.
<script lang="ts" setup>
import { createForm } from '@silver-formily/core'
import { SelectTable, Submit } from '@silver-formily/element-plus'
import { Field, FormProvider } from '@silver-formily/vue'
const form = createForm()
function log(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<FormProvider :form="form">
<Field
name="selectTable"
:component="[
SelectTable,
{
mode: 'single',
rowKey: 'key',
columns: [
{ prop: 'name', label: 'Title' },
{ prop: 'description', label: 'Description' },
],
},
]"
:data-source="[
{
key: '1',
name: 'title-1',
description: 'description-1',
},
{
key: '2',
name: 'title-2',
description: 'description-2',
},
{
key: '3',
name: 'title-3',
description: 'description-3',
},
]"
/>
<Submit style="margin-top: 30px;" @submit="log">
Submit
</Submit>
</FormProvider>
</template>Template Multiple Selection Example
Multiple selection, returning the whole row and using slots.
<script lang="ts" setup>
import { createForm } from '@silver-formily/core'
import { SelectTable, Submit } from '@silver-formily/element-plus'
import { Field, FormProvider } from '@silver-formily/vue'
const form = createForm()
function log(value: Record<string, any>) {
console.log(value)
}
</script>
<template>
<FormProvider :form="form">
<Field
name="selectTable"
:component="[
SelectTable,
{
rowKey: 'key',
optionAsValue: true,
},
]"
:data-source="[
{
key: '1',
name: 'title-1',
description: 'description-1',
},
{
key: '2',
name: 'title-2',
description: 'description-2',
},
{
key: '3',
name: 'title-3',
description: 'description-3',
},
]"
>
<ElTableColumn prop="name" label="Title" />
</Field>
<Submit style="margin-top: 30px;" @submit="log">
Submit
</Submit>
</FormProvider>
</template>Template Disable Selection Example
This example shows how to disable further selection after more than two rows have been checked.
In real-world projects, you may still choose to hide the select-all checkbox with CSS, but using validation feedback is usually the clearer and more maintainable way to guide users.
<script lang="ts" setup>
import { createForm } from '@silver-formily/core'
import { SelectTable, Submit } from '@silver-formily/element-plus'
import { Field, FormProvider } from '@silver-formily/vue'
const form = createForm()
function log(value: Record<string, any>) {
console.log(value)
}
function selectable(row: Record<string, any>, index: number, field) {
if (field.value === undefined) {
return true
}
return field.value?.length < 2 || row.key === field.value?.find(item => item.key === row.key)?.key
}
</script>
<template>
<FormProvider :form="form">
<Field
name="selectTable"
:component="[
SelectTable,
{
rowKey: 'key',
optionAsValue: true,
selectable,
},
]"
:data-source="[
{
key: '1',
name: 'title-1',
description: 'description-1',
},
{
key: '2',
name: 'title-2',
description: 'description-2',
},
{
key: '3',
name: 'title-3',
description: 'description-3',
},
]"
>
<ElTableColumn prop="name" label="Title" />
</Field>
<Submit style="margin-top: 30px;" @submit="log">
Submit
</Submit>
</FormProvider>
</template>API
SelectTable Props
| Prop | Description | Type | Default |
|---|---|---|---|
mode | Selection mode | enum | multiple |
columns | Table column configuration. See the official documentation. | array | [] |
optionAsValue | Whether the selected value should be the whole row | boolean | false |
rowKey | Required unique field name for each row, corresponding to the Element Plus table prop | string | - |
clickRowToSelect | Whether clicking a whole row triggers selection. Disable this if you need custom click handlers inside the table. | boolean | true |
showAlertToolbar | Whether to show the selection alert toolbar | boolean | true |
selectable 1.0.0 | Return value controls whether the current row can be checked | Function | () => true |
ignoreSelectable 1.0.0 | Whether to ignore selectable restrictions in certain cases | boolean | true |
Tip
onSelect, onSelectAll, and onRowClick are already used internally and should not be overridden. For other props and events, see the official documentation. For example, you can still configure table height or striping, but avoid configurations that go against the Formily contract, such as driving table data through ElTable.data instead of Formily dataSource.
Tip
In Element Plus, the selectable function belongs to the selection column. In Select Table, it has been lifted to the Select Table component itself, and it receives an additional third argument: the current field. If needed, you can use Query syntax to read values from the entire form. Likewise, ignoreSelectable, which acts as the third argument in Element Plus selection logic, is now exposed as a standalone Select Table prop.
Slots
| Slot | Description |
|---|---|
default | Custom column content. In most cases this is used together with ElTableColumn. See the official documentation. |