Table editor
Vue Bootstrap 5 Table editor plugin
Table Editor is a useful tool for displaying and managing data. The component works similarly to the Datatable (docs) with an additional column for action buttons.
Responsive interactive built with the latest Bootstrap 5 and Vue 3. Creates editable tables. Delete or edit rows directly or via modal editor.
Note: Read the API tab to find all available options and advanced customization
Basic example
You can initialize the component via MDBTableEditor
.You
can pass the data to the component in two ways. First is to bind the
data with an array of columns and rows to the
dataset
property. Second way is to create a HTML markup
for your table inside MDBDatatable component - you can customize your
table later by adding props to the component. Some of the more
advanced options for columns, can be also used by setting
data-mdb-attributes directly to a th tag (f.e.
<th data-mdb-sort="false">
).
When edit mode is enabled, the user shouldn't be able to interact with
other parts of your website, as it can lead to loss of unsaved
changes. You can control disabled state with
v-model:edit
property binding or by listening to
edit
and exit
events.
Note: search field and add button are not a build-in part of Table Editor.
Table Editor collects information from HTML markup to create a data
structure - the
<table>
element will be replaced in the DOM with a
different node after component initializes.
Company | Address | Employees |
---|---|---|
Smith & Johnson | Park Lane 2, London | 30 |
P.J. Company | Oak Street 7, Aberdeen | 80 |
Food & Wine | Netherhall Gardens 3, Hampstead | 12 |
IT Service | Warwick Road 14, London | 17 |
A. Jonson Gallery | Oaklands Avenue 2, London | 4 |
F.A. Architects | Frognal Way 7, Hampstead | 4 |
<template>
<div class="d-flex justify-content-end mb-4">
<MDBInput
v-model="basicSearch"
label="Search"
:disabled="basicEdit"
/>
<MDBBtn
color="primary"
size="sm"
class="ms-3"
@click="basicEditorRef?.addRow()"
:disabled="basicEdit"
>
<MDBIcon icon="plus"/>
</MDBBtn>
</div>
<hr />
<MDBTableEditor
:search="basicSearch"
:entries="5"
:entriesOptions="[5, 10, 15]"
v-model:edit="basicEdit"
ref="basicEditorRef"
>
<table class="table">
<thead>
<tr>
<th class="th-sm" data-mdb-width="250">Company</th>
<th class="th-sm" data-mdb-width="250" data-mdb-sort="false">
Address
</th>
<th class="th-sm" data-mdb-width="250" data-mdb-sort="false">
Employees
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Smith & Johnson</td>
<td>Park Lane 2, London</td>
<td>30</td>
</tr>
<tr>
<td>P.J. Company</td>
<td>Oak Street 7, Aberdeen</td>
<td>80</td>
</tr>
<tr>
<td>Food & Wine</td>
<td>Netherhall Gardens 3, Hampstead</td>
<td>12</td>
</tr>
<tr>
<td>IT Service</td>
<td>Warwick Road 14, London</td>
<td>17</td>
</tr>
<tr>
<td>A. Jonson Gallery</td>
<td>Oaklands Avenue 2, London</td>
<td>4</td>
</tr>
<tr>
<td>F.A. Architects</td>
<td>Frognal Way 7, Hampstead</td>
<td>4</td>
</tr>
</tbody>
</table>
</MDBTableEditor>
</template>
<script>
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
export default {
components: {
MDBInput, MDBBtn, MDBIcon, MDBTableEditor
},
setup() {
const basicEditorRef = ref(null);
const basicSearch = ref("");
const basicEdit = ref(false);
return {
basicEditorRef,
basicSearch,
basicEdit,
}
}
};
</script>
<script setup lang="ts">
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
const basicEditorRef = ref<InstanceType<typeof MDBTableEditor> | null>(null);
const basicSearch = ref("");
const basicEdit = ref(false);
</script>
Modal
To change the default editing mode (inline) to the modal version, set option
mode
to "modal"
.
<template>
<div class="d-flex justify-content-end mb-4">
<MDBInput v-model="modalSearch" label="Search" :disabled="modalEdit" />
<MDBBtn
color="primary"
size="sm"
class="ms-3"
@click="modalEditorRef?.addRow()"
:disabled="modalEdit"
>
<MDBIcon icon="plus"/>
</MDBBtn>
</div>
<hr />
<MDBTableEditor
mode="modal"
v-model:dataset="modalData"
:search="modalSearch"
:entries="5"
:entriesOptions="[5, 10, 15]"
v-model:edit="modalEdit"
ref="modalEditorRef"
/>
</template>
<script>
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
export default {
components: {
MDBInput, MDBBtn, MDBIcon, MDBTableEditor
},
setup() {
const modalEditorRef = ref(null);
const modalSearch = ref("");
const modalEdit = ref(false);
const modalData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company",
},
{
width: 250,
sort: false,
defaultValue: "Warsaw",
options: ["London", "Warsaw", "New York"],
inputType: "select",
label: "Office",
field: "office",
},
{
width: 250,
inputType: "number",
defaultValue: 1,
label: "Employees",
field: "employees",
},
{
width: 100,
defaultValue: false,
inputType: "checkbox",
label: "International",
field: "international",
},
],
rows: [
{
company: "Smith & Johnson",
office: "London",
employees: 30,
international: true,
},
{
company: "P.J. Company",
office: "London",
employees: 80,
international: false,
},
{
company: "Food & Wine",
office: "London",
employees: 12,
international: false,
},
{
company: "IT Service",
office: "London",
employees: 17,
international: false,
},
{
company: "A. Jonson Gallery",
office: "London",
employees: 4,
international: false,
},
{
company: "F.A. Architects",
office: "London",
employees: 4,
international: false,
}
]
});
return {
modalEditorRef,
modalSearch,
modalEdit,
modalData,
}
}
};
</script>
<script setup lang="ts">
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
const modalEditorRef = ref<InstanceType<typeof MDBTableEditor> | null>(null);
const modalSearch = ref("");
const modalEdit = ref(false);
const modalData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company",
},
{
width: 250,
sort: false,
defaultValue: "Warsaw",
options: ["London", "Warsaw", "New York"],
inputType: "select",
label: "Office",
field: "office",
},
{
width: 250,
inputType: "number",
defaultValue: 1,
label: "Employees",
field: "employees",
},
{
width: 100,
defaultValue: false,
inputType: "checkbox",
label: "International",
field: "international",
},
],
rows: [
{
company: "Smith & Johnson",
office: "London",
employees: 30,
international: true,
},
{
company: "P.J. Company",
office: "London",
employees: 80,
international: false,
},
{
company: "Food & Wine",
office: "London",
employees: 12,
international: false,
},
{
company: "IT Service",
office: "London",
employees: 17,
international: false,
},
{
company: "A. Jonson Gallery",
office: "London",
employees: 4,
international: false,
},
{
company: "F.A. Architects",
office: "London",
employees: 4,
international: false,
}
]
});
</script>
Inputs example
Table Editor supports several input types - for example, if you wish to force a user to enter
only Boolean values in one column, you can set its
inputType
to a checkbox.
Supported input types:
- Text (default)
- Number
- Checkbox - displays a checkbox in edit mode and true/false value otherwise
- Select - additionally requires an array of options
- Autocomplete - additionally requires a filter method inside the
filter
property. Check the autocomplete page to see how it should look like - Datepicker - add
props
property to provide additional options to the datepicker - Timepicker - add
props
property to provide additional options to the datepicker
<template>
<div class="d-flex justify-content-end mb-4">
<MDBInput v-model="inputsSearch" label="Search" :disabled="inputsEdit" />
<MDBBtn
color="primary"
size="sm"
class="ms-3"
@click="inputsEditorRef?.addRow()"
:disabled="inputsEdit"
>
<MDBIcon icon="plus"/>
</MDBBtn>
</div>
<hr />
<MDBTableEditor
v-model:dataset="inputsData"
:search="inputsSearch"
:entries="5"
:entriesOptions="[5, 10, 15]"
v-model:edit="inputsEdit"
ref="inputsEditorRef"
/>
</template>
<script>
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
export default {
components: {
MDBInput, MDBBtn, MDBIcon, MDBTableEditor
},
setup() {
const inputsEditorRef = ref(null);
const inputsSearch = ref("");
const inputsEdit = ref(false);
const inputsData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company",
},
{
width: 250,
sort: false,
defaultValue: "Warsaw",
options: ["London", "Warsaw", "New York"],
inputType: "select",
label: "Office",
field: "office",
},
{
width: 250,
inputType: "number",
defaultValue: 1,
label: "Employees",
field: "employees",
},
{
width: 100,
defaultValue: false,
inputType: "checkbox",
label: "International",
field: "international",
},
],
rows: [
{
company: "Smith & Johnson",
office: "London",
employees: 30,
international: true,
},
{
company: "P.J. Company",
office: "London",
employees: 80,
international: false,
},
{
company: "Food & Wine",
office: "London",
employees: 12,
international: false,
},
{
company: "IT Service",
office: "London",
employees: 17,
international: false,
},
{
company: "A. Jonson Gallery",
office: "London",
employees: 4,
international: false,
},
{
company: "F.A. Architects",
office: "London",
employees: 4,
international: false,
}
]
});
return {
inputsEdit,
inputsEditorRef,
inputsSearch,
inputsData,
}
}
}
</script>
<script setup lang="ts">
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
const inputsEditorRef = ref<InstanceType<typeof MDBTableEditor> | null>(null);
const inputsSearch = ref("");
const inputsEdit = ref(false);
const inputsData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company",
},
{
width: 250,
sort: false,
defaultValue: "Warsaw",
options: ["London", "Warsaw", "New York"],
inputType: "select",
label: "Office",
field: "office",
},
{
width: 250,
inputType: "number",
defaultValue: 1,
label: "Employees",
field: "employees",
},
{
width: 100,
defaultValue: false,
inputType: "checkbox",
label: "International",
field: "international",
},
],
rows: [
{
company: "Smith & Johnson",
office: "London",
employees: 30,
international: true,
},
{
company: "P.J. Company",
office: "London",
employees: 80,
international: false,
},
{
company: "Food & Wine",
office: "London",
employees: 12,
international: false,
},
{
company: "IT Service",
office: "London",
employees: 17,
international: false,
},
{
company: "A. Jonson Gallery",
office: "London",
employees: 4,
international: false,
},
{
company: "F.A. Architects",
office: "London",
employees: 4,
international: false,
}
]
});
</script>
Disable edit
You can disable editing for a column by setting its editable
option to
false
. A user won't be able to change its value in the edit mode.
<template>
<div class="d-flex justify-content-end mb-4">
<MDBInput v-model="disabledSearch" label="Search" :disabled="disabledEdit" />
<MDBBtn
color="primary"
size="sm"
class="ms-3"
@click="disabledEditorRef?.addRow()"
:disabled="disabledEdit"
>
<MDBIcon icon="plus"/>
</MDBBtn>
</div>
<hr />
<MDBTableEditor
v-model:dataset="disabledData"
:search="disabledSearch"
:entries="5"
:entriesOptions="[5, 10, 15]"
v-model:edit="disabledEdit"
ref="disabledEditorRef"
/>
</template>
<script>
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
export default {
components: {
MDBInput, MDBBtn, MDBIcon, MDBTableEditor
},
setup() {
const disabledEditorRef = ref(null);
const disabledSearch = ref("");
const disabledEdit = ref(false);
const disabledData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company",
editable: false
},
{
width: 250,
sort: false,
defaultValue: "Warsaw",
options: ["London", "Warsaw", "New York"],
inputType: "select",
label: "Office",
field: "office",
editable: false
},
{
width: 250,
inputType: "number",
defaultValue: 1,
label: "Employees",
field: "employees",
editable: false
},
{
width: 100,
defaultValue: false,
inputType: "checkbox",
label: "International",
field: "international",
editable: false
},
],
rows: [
{
company: "Smith & Johnson",
office: "London",
employees: 30,
international: true,
},
{
company: "P.J. Company",
office: "London",
employees: 80,
international: false,
},
{
company: "Food & Wine",
office: "London",
employees: 12,
international: false,
},
{
company: "IT Service",
office: "London",
employees: 17,
international: false,
},
{
company: "A. Jonson Gallery",
office: "London",
employees: 4,
international: false,
},
{
company: "F.A. Architects",
office: "London",
employees: 4,
international: false,
}
]
});
return {
disabledEditorRef,
disabledSearch,
disabledEdit,
disabledData,
}
}
};
</script>
<script setup lang="ts">
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
const disabledEditorRef = ref<InstanceType<typeof MDBTableEditor> | null>(null);
const disabledSearch = ref("");
const disabledEdit = ref(false);
const disabledData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company",
editable: false
},
{
width: 250,
sort: false,
defaultValue: "Warsaw",
options: ["London", "Warsaw", "New York"],
inputType: "select",
label: "Office",
field: "office",
editable: false
},
{
width: 250,
inputType: "number",
defaultValue: 1,
label: "Employees",
field: "employees",
editable: false
},
{
width: 100,
defaultValue: false,
inputType: "checkbox",
label: "International",
field: "international",
editable: false
},
],
rows: [
{
company: "Smith & Johnson",
office: "London",
employees: 30,
international: true,
},
{
company: "P.J. Company",
office: "London",
employees: 80,
international: false,
},
{
company: "Food & Wine",
office: "London",
employees: 12,
international: false,
},
{
company: "IT Service",
office: "London",
employees: 17,
international: false,
},
{
company: "A. Jonson Gallery",
office: "London",
employees: 4,
international: false,
},
{
company: "F.A. Architects",
office: "London",
employees: 4,
international: false,
}
]
});
</script>
Confirm delete
If you want to prevent data from being accidentally removed, you can set a
confirm
option to true
. In this case, Table Editor will show a
Popconfirm element before removing an entry.
<template>
<div class="d-flex justify-content-end mb-4">
<MDBInput v-model="confirmSearch" label="Search" :disabled="confirmEdit" />
<MDBBtn
color="primary"
size="sm"
class="ms-3"
@click="confirmEditorRef?.addRow()"
:disabled="confirmEdit"
>
<MDBIcon icon="plus"/>
</MDBBtn>
</div>
<hr />
<MDBTableEditor
confirm
v-model:dataset="confirmData"
:search="confirmSearch"
:entries="5"
:entriesOptions="[5, 10, 15]"
v-model:edit="confirmEdit"
ref="confirmEditorRef"
/>
</template>
<script>
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
export default {
components: {
MDBInput, MDBBtn, MDBIcon, MDBTableEditor
},
setup() {
const confirmEditorRef = ref(null);
const confirmSearch = ref("");
const confirmEdit = ref(false);
const confirmData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company"
},
{
width: 250,
sort: false,
defaultValue: "Warsaw",
options: ["London", "Warsaw", "New York"],
inputType: "select",
label: "Office",
field: "office"
},
{
width: 250,
inputType: "number",
defaultValue: 1,
label: "Employees",
field: "employees"
},
{
width: 100,
defaultValue: false,
inputType: "checkbox",
label: "International",
field: "international"
},
],
rows: [
{
company: "Smith & Johnson",
office: "London",
employees: 30,
international: true,
},
{
company: "P.J. Company",
office: "London",
employees: 80,
international: false,
},
{
company: "Food & Wine",
office: "London",
employees: 12,
international: false,
},
{
company: "IT Service",
office: "London",
employees: 17,
international: false,
},
{
company: "A. Jonson Gallery",
office: "London",
employees: 4,
international: false,
},
{
company: "F.A. Architects",
office: "London",
employees: 4,
international: false,
}
]
});
return {
confirmEditorRef,
confirmSearch,
confirmEdit,
confirmData,
}
}
};
</script>
<script setup lang="ts">
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
const confirmEditorRef = ref<InstanceType<typeof MDBTableEditor> | null>(null);
const confirmSearch = ref("");
const confirmEdit = ref(false);
const confirmData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company"
},
{
width: 250,
sort: false,
defaultValue: "Warsaw",
options: ["London", "Warsaw", "New York"],
inputType: "select",
label: "Office",
field: "office"
},
{
width: 250,
inputType: "number",
defaultValue: 1,
label: "Employees",
field: "employees"
},
{
width: 100,
defaultValue: false,
inputType: "checkbox",
label: "International",
field: "international"
},
],
rows: [
{
company: "Smith & Johnson",
office: "London",
employees: 30,
international: true,
},
{
company: "P.J. Company",
office: "London",
employees: 80,
international: false,
},
{
company: "Food & Wine",
office: "London",
employees: 12,
international: false,
},
{
company: "IT Service",
office: "London",
employees: 17,
international: false,
},
{
company: "A. Jonson Gallery",
office: "London",
employees: 4,
international: false,
},
{
company: "F.A. Architects",
office: "London",
employees: 4,
international: false,
}
]
});
</script>
Advanced Search
You can create more advanced searching functionality and allow a user to specify in which column to search for a given phrase.
Search fields need to be disabled manually in the edit mode.
<template>
<div class="d-flex justify-content-between mb-4">
<div class="d-flex">
<MDBInput v-model="advancedSearchQuery" label="Search" :disabled="advancedSearchEdit" />
<div class="px-3 mt-1">in:</div>
<MDBSelect
v-model:options="advancedSearchQueryCols"
v-model:selected="advancedSearchSelectedValue"
:disabled="advancedSearchEdit"
multiple
/>
<MDBBtn outline="primary" size="sm" class="ms-3" @click="searchAdvanced">
<MDBIcon icon="search" />
</MDBBtn>
</div>
<MDBBtn
color="primary"
size="sm"
class="ms-3"
@click="advancedSearchEditorRef?.addRow()"
:disabled="advancedSearchEdit"
>
<MDBIcon icon="plus"/>
</MDBBtn>
</div>
<hr />
<MDBTableEditor
v-model:dataset="advancedSearchData"
:search="advancedSearchQueryPhrase"
:searchColumns="advancedSearchSelectedCols"
:entries="5"
:entriesOptions="[5, 10, 15]"
v-model:edit="advancedSearchEdit"
ref="advancedSearchEditorRef"
/>
</template>
<script>
import { MDBInput, MDBBtn, MDBIcon, MDBSelect } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
export default {
components: {
MDBInput, MDBSelect, MDBBtn, MDBIcon, MDBTableEditor
},
setup() {
const advancedData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company",
},
{
width: 250,
sort: false,
defaultValue: "Warsaw",
options: ["London", "Warsaw", "New York"],
inputType: "select",
label: "Office",
field: "office",
},
{
width: 250,
inputType: "number",
defaultValue: 1,
label: "Employees",
field: "employees",
},
{
width: 100,
defaultValue: false,
inputType: "checkbox",
label: "International",
field: "international",
},
],
rows: [
{
company: "Smith & Johnson",
office: "London",
employees: 30,
international: true,
},
{
company: "P.J. Company",
office: "London",
employees: 80,
international: false,
},
{
company: "Food & Wine",
office: "London",
employees: 12,
international: false,
},
{
company: "IT Service",
office: "London",
employees: 17,
international: false,
},
{
company: "A. Jonson Gallery",
office: "London",
employees: 4,
international: false,
},
{
company: "F.A. Architects",
office: "London",
employees: 4,
international: false,
},
],
});
const advancedSearchEditorRef = ref(null);
const advancedSearchQuery = ref("");
const advancedSearchEdit = ref(false);
const advancedSearchData = ref(advancedData.value);
const advancedSearchQueryCols = ref([
{ text: "Company", value: "company" },
{ text: "Office", value: "office" },
]);
const advancedSearchSelectedValue = ref("");
const advancedSearchQueryPhrase = ref("");
const advancedSearchSelectedCols = ref([]);
const searchAdvanced = () => {
advancedSearchQueryPhrase.value = advancedSearchQuery.value;
advancedSearchSelectedCols.value =
advancedSearchSelectedValue.value.split(",");
};
return {
advancedData,
advancedSearchEditorRef,
advancedSearchEdit,
advancedSearchData,
advancedSearchQuery,
advancedSearchQueryCols,
advancedSearchSelectedValue,
advancedSearchSelectedCols,
advancedSearchQueryPhrase,
searchAdvanced,
}
}
};
</script>
<script setup lang="ts">
import { MDBInput, MDBBtn, MDBIcon, MDBSelect } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
const advancedData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company",
},
{
width: 250,
sort: false,
defaultValue: "Warsaw",
options: ["London", "Warsaw", "New York"],
inputType: "select",
label: "Office",
field: "office",
},
{
width: 250,
inputType: "number",
defaultValue: 1,
label: "Employees",
field: "employees",
},
{
width: 100,
defaultValue: false,
inputType: "checkbox",
label: "International",
field: "international",
},
],
rows: [
{
company: "Smith & Johnson",
office: "London",
employees: 30,
international: true,
},
{
company: "P.J. Company",
office: "London",
employees: 80,
international: false,
},
{
company: "Food & Wine",
office: "London",
employees: 12,
international: false,
},
{
company: "IT Service",
office: "London",
employees: 17,
international: false,
},
{
company: "A. Jonson Gallery",
office: "London",
employees: 4,
international: false,
},
{
company: "F.A. Architects",
office: "London",
employees: 4,
international: false,
},
],
});
const advancedSearchEditorRef = ref<InstanceType<typeof MDBTableEditor> | null>(null);
const advancedSearchQuery = ref("");
const advancedSearchEdit = ref(false);
const advancedSearchData = ref(advancedData.value);
const advancedSearchQueryCols = ref([
{ text: "Company", value: "company" },
{ text: "Office", value: "office" },
]);
const advancedSearchSelectedValue = ref("");
const advancedSearchQueryPhrase = ref("");
const advancedSearchSelectedCols = ref([]);
const searchAdvanced = () => {
advancedSearchQueryPhrase.value = advancedSearchQuery.value;
advancedSearchSelectedCols.value =
advancedSearchSelectedValue.value.split(",");
};
</script>
Async data
While awaiting data from API, you can prevent a user from interacting with Table Editor by
setting loading
option to true
.
<template>
<div class="d-flex justify-content-between mb-4">
<MDBBtn color="primary" size="sm" @click="loadAsyncData">Load data</MDBBtn>
<div class="d-flex justify-content-end">
<MDBInput v-model="asyncSearch" label="Search" :disabled="asyncEdit" />
<MDBBtn
color="primary"
size="sm"
class="ms-3"
@click="asyncEditorRef?.addRow()"
:disabled="asyncEdit"
>
<MDBIcon icon="plus"/>
</MDBBtn>
</div>
</div>
<hr />
<MDBTableEditor
v-model:dataset="asyncData"
:search="asyncSearch"
:loading="loadingAsync"
v-model:edit="asyncEdit"
ref="asyncEditorRef"
/>
</template>
<script>
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
export default {
components: {
MDBInput, MDBBtn, MDBIcon, MDBTableEditor
},
setup() {
const asyncEditorRef = ref(null);
const asyncSearch = ref("");
const asyncEdit = ref(false);
const asyncData = ref({
columns: [
{ label: "Company", field: "company" },
{ label: "Email", field: "email" },
{ label: "Name", field: "name" },
{ label: "Phone", field: "phone" },
],
rows: [],
});
const loadingAsync = ref(false);
const loadAsyncData = () => {
asyncData.value.rows = [];
loadingAsync.value = true;
fetch("https://jsonplaceholder.typicode.com/users")
.then((response) => response.json())
.then((data) => {
asyncData.value.rows = data.map((user) => ({
...user,
address: `${user.address.city}, ${user.address.street}`,
company: user.company.name,
}));
loadingAsync.value = false;
});
}
return {
asyncEditorRef,
asyncSearch,
asyncEdit,
asyncData,
loadingAsync,
loadAsyncData,
}
}
};
</script>
<script setup lang="ts">
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
const asyncEditorRef = ref<InstanceType<typeof MDBTableEditor> | null>(null);
const asyncSearch = ref("");
const asyncEdit = ref(false);
const asyncData = ref({
columns: [
{ label: "Company", field: "company" },
{ label: "Email", field: "email" },
{ label: "Name", field: "name" },
{ label: "Phone", field: "phone" },
],
rows: [],
});
const loadingAsync = ref(false);
const loadAsyncData = () => {
asyncData.value.rows = [];
loadingAsync.value = true;
fetch("https://jsonplaceholder.typicode.com/users")
.then((response) => response.json())
.then((data) => {
asyncData.value.rows = data.map((user) => ({
...user,
address: `${user.address.city}, ${user.address.street}`,
company: user.company.name,
}));
loadingAsync.value = false;
});
};
</script>
Custom rows
The add()
method takes an optional argument - a row which values will be
preloaded into a new entry.
Note: for this particular use, a row has to be an object.
Note: as adding buttons are initialized manually, they won't be automatically disabled in the edit mode.
M.B.
(5 Avenue 26, New York)
Berkley & Clark
(43th Street 12, New York)
D&D Inc.
(14 Street 67, New York)
Thomas & Co.
(2 Avenue 54, New York)
<template>
<MDBRow>
<MDBCol md="3" sm="6" class="p-3">
<h4>M.B.</h4>
<p>(5 Avenue 26, New York)</p>
<MDBBtn
color="primary"
size="sm"
@click="
customRowsEditorRef?.addRow({
company: 'M.B.',
address: '5 Avenue 26',
city: 'New York'
})
"
>
Load into table
</MDBBtn>
</MDBCol>
<MDBCol md="3" sm="6" class="p-3">
<h4>Berkley & Clark</h4>
<p>(43th Street 12, New York)</p>
<MDBBtn
color="primary"
size="sm"
@click="
customRowsEditorRef?.addRow({
company: 'Berkley & Clark',
address: '43th Street 12',
city: 'New York'
})
"
>
Load into table
</MDBBtn>
</MDBCol>
<MDBCol md="3" sm="6" class="p-3">
<h4>D&D Inc.</h4>
<p>(14 Street 67, New York)</p>
<MDBBtn
color="primary"
size="sm"
@click="
customRowsEditorRef?.addRow({
company: 'D&D Inc.',
address: '14 Street 67',
city: 'New York'
})
"
>
Load into table
</MDBBtn>
</MDBCol>
<MDBCol md="3" sm="6" class="p-3">
<h4>Thomas & Co.</h4>
<p>(2 Avenue 54, New York)</p>
<MDBBtn
color="primary"
size="sm"
@click="
customRowsEditorRef?.addRow({
company: 'Thomas & Co.',
address: '2 Avenue 54',
city: 'New York'
})
"
>
Load into table
</MDBBtn>
</MDBCol>
</MDBRow>
<hr class="mt-3" />
<MDBTableEditor
v-model:dataset="customRowsData"
:search="customRowsSearch"
v-model:edit="customRowsEdit"
ref="customRowsEditorRef"
/>
</template>
<script>
import { MDBBtn, MDBCol, MDBRow } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
export default {
components: {
MDBBtn, MDBCol, MDBRow, MDBTableEditor
},
setup() {
const customRowsEditorRef = ref(null);
const customRowsSearch = ref("");
const customRowsEdit = ref(false);
const customRowsData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company",
},
{
width: 250,
label: "Address",
field: "address",
},
{
width: 250,
label: "City",
field: "city",
},
],
rows: [
{ company: "Smith & Johnson", address: "Park Lane 2", city: "London" },
{ company: "P.J. Company", address: "Oak Street 7", city: "Aberdeen" },
{
company: "Food & Wine",
address: "Netherhall Gardens 3",
city: "Hampstead",
},
{ company: "IT Service", address: "Warwick Road 14", city: "London" },
{
company: "A. Jonson Gallery",
address: "Oaklands Avenue 2",
city: "London",
},
{
company: "F.A. Architects",
address: "Frognal Way 7",
city: "Hampstead",
},
],
});
return {
customRowsEditorRef,
customRowsSearch,
customRowsEdit,
customRowsData,
}
}
};
</script>
<script setup lang="ts">
import { MDBBtn, MDBCol, MDBRow } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
const customRowsEditorRef = ref<InstanceType<typeof MDBTableEditor> | null>(null);
const customRowsSearch = ref("");
const customRowsEdit = ref(false);
const customRowsData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company",
},
{
width: 250,
label: "Address",
field: "address",
},
{
width: 250,
label: "City",
field: "city",
},
],
rows: [
{ company: "Smith & Johnson", address: "Park Lane 2", city: "London" },
{ company: "P.J. Company", address: "Oak Street 7", city: "Aberdeen" },
{
company: "Food & Wine",
address: "Netherhall Gardens 3",
city: "Hampstead",
},
{ company: "IT Service", address: "Warwick Road 14", city: "London" },
{
company: "A. Jonson Gallery",
address: "Oaklands Avenue 2",
city: "London",
},
{
company: "F.A. Architects",
address: "Frognal Way 7",
city: "Hampstead",
},
],
});
</script>
Notifications
In this example, handlers for custom events trigger notifications after adding/deleting/updating an entry.
<template>
<div class="d-flex justify-content-end mb-4">
<MDBInput v-model="notificationsSearch" label="Search" :disabled="notificationsEdit" />
<MDBBtn
color="primary"
size="sm"
class="ms-3"
@click="notificationsEditorRef?.addRow()"
:disabled="notificationsEdit"
>
<MDBIcon icon="plus"/>
</MDBBtn>
</div>
<hr />
<MDBTableEditor
v-model:dataset="notificationsData"
:search="notificationsSearch"
v-model:edit="notificationsEdit"
ref="notificationsEditorRef"
@add="showNotification('success', 'New entry: ', $event)"
@delete="showNotification('danger', 'Deleted entry: ', $event)"
@updateEntry="showNotification('primary', 'Updated entry: ', $event)"
/>
<MDBAlert
v-model="alert"
:color="alertColor"
position="top-right"
width="360px"
:delay="2000"
autohide
>
<div v-html="alertMessage" />
</MDBAlert>
</template>
<script>
import { MDBInput, MDBBtn, MDBIcon, MDBAlert } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
export default {
components: {
MDBInput, MDBBtn, MDBIcon, MDBAlert, MDBTableEditor
},
setup() {
const notificationsEditorRef = ref(null);
const notificationsSearch = ref("");
const notificationsEdit = ref(false);
const notificationsData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company",
},
{
width: 250,
sort: false,
defaultValue: "Warsaw",
options: ["London", "Warsaw", "New York"],
inputType: "select",
label: "Office",
field: "office",
},
{
width: 250,
inputType: "number",
defaultValue: 1,
label: "Employees",
field: "employees",
},
{
width: 100,
defaultValue: false,
inputType: "checkbox",
label: "International",
field: "international",
},
],
rows: [
{
company: "Smith & Johnson",
office: "London",
employees: 30,
international: true,
},
{
company: "P.J. Company",
office: "London",
employees: 80,
international: false,
},
{
company: "Food & Wine",
office: "London",
employees: 12,
international: false,
},
{
company: "IT Service",
office: "London",
employees: 17,
international: false,
},
{
company: "A. Jonson Gallery",
office: "London",
employees: 4,
international: false,
},
{
company: "F.A. Architects",
office: "London",
employees: 4,
international: false,
},
]
});
const alert = ref(false);
const alertColor = ref("primary");
const alertMessage = ref("");
const showNotification = (type, message, event) => {
const { company, office } = event.row;
alertMessage.value = `<strong>${message}</strong> ${company} ${office}`;
alertColor.value = type;
alert.value = true;
};
return {
showNotification,
notificationsEditorRef,
notificationsSearch,
notificationsEdit,
notificationsData,
alert,
alertColor,
alertMessage,
}
}
};
</script>
<script setup lang="ts">
import { MDBInput, MDBBtn, MDBIcon, MDBAlert } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
const notificationsEditorRef = ref<InstanceType<typeof MDBTableEditor> | null>(null);
const notificationsSearch = ref("");
const notificationsEdit = ref(false);
const notificationsData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company",
},
{
width: 250,
sort: false,
defaultValue: "Warsaw",
options: ["London", "Warsaw", "New York"],
inputType: "select",
label: "Office",
field: "office",
},
{
width: 250,
inputType: "number",
defaultValue: 1,
label: "Employees",
field: "employees",
},
{
width: 100,
defaultValue: false,
inputType: "checkbox",
label: "International",
field: "international",
},
],
rows: [
{
company: "Smith & Johnson",
office: "London",
employees: 30,
international: true,
},
{
company: "P.J. Company",
office: "London",
employees: 80,
international: false,
},
{
company: "Food & Wine",
office: "London",
employees: 12,
international: false,
},
{
company: "IT Service",
office: "London",
employees: 17,
international: false,
},
{
company: "A. Jonson Gallery",
office: "London",
employees: 4,
international: false,
},
{
company: "F.A. Architects",
office: "London",
employees: 4,
international: false,
},
]
});
const alert = ref(false);
const alertColor = ref("primary");
const alertMessage = ref("");
const showNotification = (type: string, message: string, event: Event) => {
const { company, office } = event.row;
alertMessage.value = `<strong>${message}</strong> ${company} ${office}`;
alertColor.value = type;
alert.value = true;
};
</script>
Dark
Dark mode can be applied to both modal and inline versions - firstly, add a CSS class which
changes the background color to your page. Secondly, pass the same class name to the
color
option of your Table Editor (f.e. 'bg-dark'). Now change the font to light
by setting dark
attribute to true
.
Tip: add form-white
class to your search input's wrapper.
Company | Address | Employees |
---|---|---|
Smith & Johnson | Park Lane 2, London | 30 |
P.J. Company | Oak Street 7, Aberdeen | 80 |
Food & Wine | Netherhall Gardens 3, Hampstead | 12 |
IT Service | Warwick Road 14, London | 17 |
A. Jonson Gallery | Oaklands Avenue 2, London | 4 |
F.A. Architects | Frognal Way 7, Hampstead | 4 |
<template>
<div class="d-flex justify-content-end mb-4">
<MDBInput v-model="darkSearch" label="Search" :disabled="darkEdit" white />
<MDBBtn
color="primary"
size="sm"
class="ms-3"
@click="darkEditorRef?.addRow()"
:disabled="darkEdit"
>
<MDBIcon icon="plus"/>
</MDBBtn>
</div>
<hr />
<MDBTableEditor
v-model:dataset="darkData"
:search="darkSearch"
v-model:edit="darkEdit"
color="bg-dark"
dark
ref="darkEditorRef"
@add="showNotification('success', 'New entry: ', $event)"
@delete="showNotification('danger', 'Deleted entry: ', $event)"
@updateEntry="showNotification('primary', 'Updated entry: ', $event)"
/>
</template>
<script>
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
export default {
components: {
MDBInput, MDBBtn, MDBIcon, MDBTableEditor
},
setup() {
const darkEditorRef = ref(null);
const darkSearch = ref("");
const darkEdit = ref(false);
const darkData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company"
},
{
width: 250,
sort: false,
defaultValue: "Warsaw",
options: ["London", "Warsaw", "New York"],
inputType: "select",
label: "Office",
field: "office"
},
{
width: 250,
inputType: "number",
defaultValue: 1,
label: "Employees",
field: "employees"
},
{
width: 100,
defaultValue: false,
inputType: "checkbox",
label: "International",
field: "international"
},
],
rows: [
{
company: "Smith & Johnson",
office: "London",
employees: 30,
international: true,
},
{
company: "P.J. Company",
office: "London",
employees: 80,
international: false,
},
{
company: "Food & Wine",
office: "London",
employees: 12,
international: false,
},
{
company: "IT Service",
office: "London",
employees: 17,
international: false,
},
{
company: "A. Jonson Gallery",
office: "London",
employees: 4,
international: false,
},
{
company: "F.A. Architects",
office: "London",
employees: 4,
international: false,
}
]
});
const showNotification = (type: string, message: string, event: Event) => {
const { company, office } = event.row;
alertMessage.value = `<strong>${message}</strong> ${company} ${office}`;
alertColor.value = type;
alert.value = true;
};
return {
darkEditorRef,
darkSearch,
darkEdit,
darkData,
showNotification
}
}
};
</script>
<script setup lang="ts">
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
const darkEditorRef = ref<InstanceType<typeof MDBTableEditor> | null>(null);
const darkSearch = ref("");
const darkEdit = ref(false);
const darkData = ref({
columns: [
{
width: 250,
label: "Company",
field: "company"
},
{
width: 250,
sort: false,
defaultValue: "Warsaw",
options: ["London", "Warsaw", "New York"],
inputType: "select",
label: "Office",
field: "office"
},
{
width: 250,
inputType: "number",
defaultValue: 1,
label: "Employees",
field: "employees"
},
{
width: 100,
defaultValue: false,
inputType: "checkbox",
label: "International",
field: "international"
},
],
rows: [
{
company: "Smith & Johnson",
office: "London",
employees: 30,
international: true,
},
{
company: "P.J. Company",
office: "London",
employees: 80,
international: false,
},
{
company: "Food & Wine",
office: "London",
employees: 12,
international: false,
},
{
company: "IT Service",
office: "London",
employees: 17,
international: false,
},
{
company: "A. Jonson Gallery",
office: "London",
employees: 4,
international: false,
},
{
company: "F.A. Architects",
office: "London",
employees: 4,
international: false,
}
]
});
const showNotification = (type: string, message: string, event: Event) => {
const { company, office } = event.row;
alertMessage.value = `<strong>${message}</strong> ${company} ${office}`;
alertColor.value = type;
alert.value = true;
};
</script>
Table editor - API
Import
<script>
import { MDBTableEditor } from "mdb-vue-table-editor";
</script>
Properties
Property | Type | Default | Description |
---|---|---|---|
actionHeader
|
String | 'Actions' |
Header for action buttons |
actionPosition
|
String | 'end' |
Decides where to render an action column (start/end) |
allowEmptyCells
|
Boolean | false |
Allows to add empty cells in addRow method |
bordered
|
Boolean | false |
Adds borders to a datatable |
borderless
|
Boolean | false |
Removes all borders from a datatable |
borderColor
|
String |
|
Changes a border color to one of main colors |
cancelText
|
String | 'Cancel' |
Text displayed in cancel buttons |
confirm
|
Boolean | false |
Displays a Popconfirm element before removing an entry |
confirmText
|
String | 'Cancel' |
Text displayed in confirm buttons (Popconfirm) |
confirmMessage
|
String | 'Are you sure you want to delete this entry?' |
Text displayed in a Popconfirm element |
color
|
String |
|
Adds a color class to a datatable (f.e 'bg-dark') |
dark
|
Boolean | false |
Changes a font color to white |
defaultValue
|
String | "-" |
This string will be used as a placeholder if a row doesn't have a defined value for a column |
dataset
|
Object | { columns: [], rows: [] } |
Main data object |
v-model:edit
|
Boolean | false |
Keeps information about edit mode |
entries
|
Number | 10 |
Number of visible entries (pagination) |
entriesOptions
|
Array | [10, 25, 50, 200] |
Options available to choose from in a pagination select (rows per page) |
fixedHeader
|
Boolean | false |
When it's set to true, the table's header will remain visible while scrolling |
fullPagination
|
Boolean | false |
Displays additional buttons for the first and last pages |
hover
|
Boolean | false |
Changes the background color of a hovered row |
loaderClass
|
String | "bg-primary" |
The class name for a loader (loading mode) |
loading
|
Boolean | false |
Sets the loading mode - disables interactions and displays a loader |
loadingMessage
|
String | "Loading results..." |
A message displayed while loading data |
maxHeight
|
[Number, String] |
|
Sets a maximum height of a datatable - can be either a string ("10%") or a number of pixels. |
maxWidth
|
[Number, String] | "100%" |
Sets a maximum width of a datatable - can be either a string ("10%") or a number of pixels. |
mode
|
String | 'inline' |
Changes edit mode - available options: 'inline', 'modal' |
multi
|
Boolean | false |
Allows selecting multiple rows (selectable mode) |
newItemHeader
|
String | 'New item' |
A header of modal |
noFoundMessage
|
String | "No matching results found" |
A message displayed when a table is empty |
pagination
|
Boolean | true |
Shows/hides the pagination panel |
rowsText
|
String | "Rows per page:" |
A text indicating a number of rows per page |
saveText
|
String | 'Save |
Text displayed in the save button (modal) |
search
|
String |
|
Search phrase |
searchColumns
|
Array | [] |
Columns to include while searching. All columns included for an empty array |
selectable
|
Boolean | false |
Enables selecting rows with checkboxes |
sm
|
Boolean | false |
Decreases a row's paddings |
sortField
|
String |
|
Default sorted column enabled by a field name |
sortOrder
|
String |
|
Default sorting order. Available values: "asc" or "desc". |
striped
|
Boolean | false |
Slightly changes the background's color in every other row |
tag
|
String | "div" |
Defines wrapper tag |
Column properties
Name | Type | Default | Description |
---|---|---|---|
editable
|
Boolean | true |
Enables/disabled editing fields in this column |
label
|
String | '' |
A displayed header of a column |
field
|
String | label.toLowerCase() |
A field's name - will be used as a key for values in rows |
fixed
|
[Boolean, String] | false |
When set to true , makes a column stick on the
left while scrolling. Changing its value to
right will do the same on the other side. For
this option to work, you need to define width as
well.
|
inputType
|
String | 'text' |
Input type for a column. Available options: 'text', 'number', 'checkbox', 'select' |
options
|
Array | [] |
Array of options (for column with a "select" input type) |
width
|
Number |
|
A column's width in pixels |
sort
|
Boolean | true |
Enables/disables sorting for this column |
format
|
Array |
|
Cell formatting array of objects for each cell. |
Methods
Name | Description |
---|---|
addRow
|
Adds a new row (default values are optional). |
<template>
<div class="d-flex justify-content-end mb-4">
<MDBInput
v-model="basicSearch"
label="Search"
:disabled="basicEdit"
/>
<MDBBtn
color="primary"
size="sm"
class="ms-3"
@click="basicEditorRef?.addRow()"
:disabled="basicEdit"
>
<MDBIcon icon="plus"/>
</MDBBtn>
</div>
<hr />
<MDBTableEditor
:search="basicSearch"
:entries="5"
:entriesOptions="[5, 10, 15]"
v-model:edit="basicEdit"
ref="basicEditorRef"
>
<table class="table">
<thead>
<tr>
<th class="th-sm" data-mdb-width="250">Company</th>
<th class="th-sm" data-mdb-width="250" data-mdb-sort="false">
Address
</th>
<th class="th-sm" data-mdb-width="250" data-mdb-sort="false">
Employees
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Smith & Johnson</td>
<td>Park Lane 2, London</td>
<td>30</td>
</tr>
<tr>
<td>P.J. Company</td>
<td>Oak Street 7, Aberdeen</td>
<td>80</td>
</tr>
<tr>
<td>Food & Wine</td>
<td>Netherhall Gardens 3, Hampstead</td>
<td>12</td>
</tr>
<tr>
<td>IT Service</td>
<td>Warwick Road 14, London</td>
<td>17</td>
</tr>
<tr>
<td>A. Jonson Gallery</td>
<td>Oaklands Avenue 2, London</td>
<td>4</td>
</tr>
<tr>
<td>F.A. Architects</td>
<td>Frognal Way 7, Hampstead</td>
<td>4</td>
</tr>
</tbody>
</table>
</MDBTableEditor>
</template>
<script>
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
export default {
components: {
MDBInput, MDBBtn, MDBIcon, MDBTableEditor
},
setup() {
const basicEditorRef = ref(null);
const basicSearch = ref("");
const basicEdit = ref(false);
return {
basicEditorRef,
basicSearch,
basicEdit,
}
}
};
</script>
<script setup lang="ts">
import { MDBInput, MDBBtn, MDBIcon } from "mdb-vue-ui-kit";
import { MDBTableEditor } from "mdb-vue-table-editor";
import { ref } from "vue";
const basicEditorRef = ref<InstanceType<typeof MDBTableEditor> | null>(null);
const basicSearch = ref("");
const basicEdit = ref(false);
</script>
Events
Name | Description |
---|---|
add
|
This event fires after adding a new row. |
delete
|
This event fires after deleting a row. |
edit
|
This event fires when user enters edit mode. Allows to get the current edited row via parameter. |
exit
|
This event fires when user exits edit mode. |
render
|
Event emitted after the component renders/updates rows. |
update
|
This event fires in an editable mode when a user updates values. |
<template>
<MDBTableEditor @add="doSomething" >...</MDBTableEditor>
</template>