diff --git a/src/components/datatable/DataTable.d.ts b/src/components/datatable/DataTable.d.ts
index b82ff065a..6989dfbdf 100644
--- a/src/components/datatable/DataTable.d.ts
+++ b/src/components/datatable/DataTable.d.ts
@@ -45,6 +45,7 @@ export declare class DataTable extends Vue {
stateStorage?: string;
stateKey?: string;
editMode?: string;
+ editingRows?: any[];
$emit(eventName: 'page', event: Event): this;
$emit(eventName: 'sort', event: Event): this;
$emit(eventName: 'filter', event: Event): this;
diff --git a/src/views/datatable/DataTableDoc.vue b/src/views/datatable/DataTableDoc.vue
index 2d67c07ef..fbcb28452 100644
--- a/src/views/datatable/DataTableDoc.vue
+++ b/src/views/datatable/DataTableDoc.vue
@@ -256,6 +256,12 @@ export default {
true |
Defines if the column itself can be reordered with dragging. |
+
+ rowEditor |
+ boolean |
+ false |
+ When enabled, column displays row editor controls. |
+
@@ -683,6 +689,205 @@ export default {
}
+ InCell Editing
+ In cell editing provides a rapid and user friendly way to manipulate the data. The datatable provides a flexible API
+ so that the editing behavior is implemented by the page author whether it utilizes v-model or vuex.
+
+
+ Individuals cell editing is configured by setting the editMode to "cell" and defining editors with the "editor" template. The content of the
+ editor defines how the editing is implemented, below example demonstrates two cases. In the first example, simple v-model editors are utilized. This is pretty straightforward in most cases.
+ On the other hand, second example is more advanced to consider validations and ability to revert values with the escape key.
+
+
+<h3>Basic Cell Editing</h3>
+<p>Simple editors with v-model.</p>
+<DataTable :value="cars1" editMode="cell">
+ <Column field="vin" header="Vin">
+ <template #editor="slotProps">
+ <InputText v-model="slotProps.data[slotProps.column.field]" />
+ </template>
+ </Column>
+ <Column field="year" header="Year">
+ <template #editor="slotProps">
+ <InputText v-model="slotProps.data[slotProps.column.field]" />
+ </template>
+ </Column>
+ <Column field="brand" header="Brand">
+ <template #editor="slotProps">
+ <Dropdown v-model="slotProps.data['brand']" :options="brands" optionLabel="brand" optionValue="value" placeholder="Select a Brand">
+ <template #option="optionProps">
+ <div class="p-dropdown-car-option">
+ <img :alt="optionProps.option.brand" :src="'demo/images/car/' + optionProps.option.brand + '.png'" />
+ <span>{{optionProps.option.brand}}</span>
+ </div>
+ </template>
+ </Dropdown>
+ </template>
+ </Column>
+ <Column field="color" header="Color">
+ <template #editor="slotProps">
+ <InputText v-model="slotProps.data[slotProps.column.field]" />
+ </template>
+ </Column>
+</DataTable>
+
+<h3>Advanced Cell Editing</h3>
+<p>Custom implementation with validations, dynamic columns and reverting values with the escape key.</p>
+<DataTable :value="cars2" editMode="cell" @cell-edit-complete="onCellEditComplete">
+ <Column v-for="col of columns" :field="col.field" :header="col.header" :key="col.field">
+ <template #editor="slotProps">
+ <InputText :value="slotProps.data[slotProps.column.field]" @input="onCellEdit($event, slotProps)" />
+ </template>
+ </Column>
+</DataTable>
+
+
+
+
+import CarService from '../../service/CarService';
+import Vue from 'vue';
+
+export default {
+ data() {
+ return {
+ cars1: null,
+ cars2: null,
+ cars3: null,
+ editingCellRows: {},
+ columns: null,
+ brands: [
+ {brand: 'Audi', value: 'Audi'},
+ {brand: 'BMW', value: 'BMW'},
+ {brand: 'Fiat', value: 'Fiat'},
+ {brand: 'Honda', value: 'Honda'},
+ {brand: 'Jaguar', value: 'Jaguar'},
+ {brand: 'Mercedes', value: 'Mercedes'},
+ {brand: 'Renault', value: 'Renault'},
+ {brand: 'Volkswagen', value: 'Volkswagen'},
+ {brand: 'Volvo', value: 'Volvo'}
+ ]
+ }
+ },
+ carService: null,
+ created() {
+ this.carService = new CarService();
+
+ this.columns = [
+ {field: 'vin', header: 'Vin'},
+ {field: 'year', header: 'Year'},
+ {field: 'brand', header: 'Brand'},
+ {field: 'color', header: 'Color'}
+ ];
+ },
+ methods: {
+ onCellEditComplete(event) {
+ if (!this.editingCellRows[event.index]) {
+ return;
+ }
+
+ const editingCellValue = this.editingCellRows[event.index][event.field];
+
+ switch (event.field) {
+ case 'year':
+ if (this.isPositiveInteger(editingCellValue))
+ Vue.set(this.cars2, event.index, this.editingCellRows[event.index]);
+ else
+ event.preventDefault();
+ break;
+
+ default:
+ if (editingCellValue.trim().length > 0)
+ Vue.set(this.cars2, event.index, this.editingCellRows[event.index]);
+ else
+ event.preventDefault();
+ break;
+ }
+ },
+ onCellEdit(newValue, props) {
+ if (!this.editingCellRows[props.index]) {
+ this.editingCellRows[props.index] = {...props.data};
+ }
+
+ this.editingCellRows[props.index][props.column.field] = newValue;
+ },
+ isPositiveInteger(val) {
+ let str = String(val);
+ str = str.trim();
+ if (!str) {
+ return false;
+ }
+ str = str.replace(/^0+/, "") || "0";
+ var n = Math.floor(Number(str));
+ return n !== Infinity && String(n) === str && n >= 0;
+ }
+ },
+ mounted() {
+ this.carService.getCarsSmall().then(data => this.cars1 = data);
+ this.carService.getCarsSmall().then(data => this.cars2 = data);
+ }
+}
+
+
+ Row Editing is defined by setting cellEdit as "row", defining editingRows with the sync operator to hold the reference to the editing rows and adding a row editor column to provide the editing controls. Note that
+ since editingRows is two-way binding enabled, you may use it to initially display one or more rows in editing more or programmatically toggle row editing.
+
+
+<h3>Row Editing</h3>
+<DataTable :value="cars" editMode="row" dataKey="vin" :editingRows.sync="editingRows"
+ @row-edit-init="onRowEditInit" @row-edit-cancel="onRowEditCancel">
+ <Column field="vin" header="Vin"></Column>
+ <Column field="year" header="Year">
+ <template #editor="slotProps">
+ <InputText v-model="slotProps.data[slotProps.column.field]" />
+ </template>
+ </Column>
+ <Column field="brand" header="Brand">
+ <template #editor="slotProps">
+ <InputText v-model="slotProps.data[slotProps.column.field]" />
+ </template>
+ </Column>
+ <Column field="color" header="Color">
+ <template #editor="slotProps">
+ <InputText v-model="slotProps.data[slotProps.column.field]" />
+ </template>
+ </Column>
+ <Column :rowEditor="true" headerStyle="width:6em" bodyStyle="text-align:center"></Column>
+</DataTable>
+
+
+
+
+import CarService from '../../service/CarService';
+import Vue from 'vue';
+
+export default {
+ data() {
+ return {
+ cars: null,
+ editingRows: []
+ }
+ },
+ carService: null,
+ originalRows: null,
+ created() {
+ this.carService = new CarService();
+
+ this.originalRows = {};
+ },
+ methods: {
+ onRowEditInit(event) {
+ this.originalRows[event.index] = {...this.cars3[event.index]};
+ },
+ onRowEditCancel(event) {
+ Vue.set(this.cars3, event.index, this.originalRows[event.index]);
+ }
+ },
+ mounted() {
+ this.carService.getCarsSmall().then(data => this.cars = data);
+ }
+}
+
+
Column Resize
Columns can be resized using drag drop by setting the resizableColumns to true. There are two resize modes; "fit" and "expand". Fit is the default one and the overall table width does not change when a column is resized.
In "expand" mode, table width also changes along with the column width. column-resize-end is a callback that passes the resized column header and delta change as a parameter.
@@ -1413,6 +1618,18 @@ export default {
null |
Unique identifier of a stateful table to use in state storage. |
+
+ editMode |
+ string |
+ null |
+ Defines the incell editing mode, valid options are "cell" and "row". |
+
+
+ editingRows |
+ array |
+ null |
+ A collection of rows to represent the current editing data in row edit mode. |
+
@@ -1516,6 +1733,55 @@ export default {
event.data: Collapsed group value.
Callback to invoke when a row group is collapsed. |
+
+ cell-edit-init |
+ event.originalEvent: Browser event
+ event.data: Row data to edit.
+ event.field: Field name of the row data.
+ event.index: Index of the row data to edit.
|
+ Callback to invoke when cell edit is initiated. |
+
+
+ cell-edit-complete |
+ event.originalEvent: Browser event
+ event.data: Row data to edit.
+ event.field: Field name of the row data.
+ event.index: Index of the row data to edit.
+ event.type: Type of completion such as "enter", "outside" or "tab".
|
+ Callback to invoke when cell edit is completed. |
+
+
+ cell-edit-cancel |
+ event.originalEvent: Browser event
+ event.data: Row data to edit.
+ event.field: Field name of the row data.
+ event.index: Index of the row data to edit.
|
+ Callback to invoke when cell edit is cancelled with escape key. |
+
+
+ row-edit-init |
+ event.originalEvent: Browser event
+ event.data: Row data to edit.
+ event.field: Field name of the row data.
+ event.index: Index of the row data to edit.
|
+ Callback to invoke when row edit is initiated. |
+
+
+ row-edit-save |
+ event.originalEvent: Browser event
+ event.data: Row data to edit.
+ event.field: Field name of the row data.
+ event.index: Index of the row data to edit.
|
+ Callback to invoke when row edit is saved. |
+
+
+ row-edit-cancel |
+ event.originalEvent: Browser event
+ event.data: Row data to edit.
+ event.field: Field name of the row data.
+ event.index: Index of the row data to edit.
|
+ Callback to invoke when row edit is cancelled. |
+