diff --git a/src/components/datatable/BodyCell.vue b/src/components/datatable/BodyCell.vue
index bf9e7fd3c..b2e2d9d46 100644
--- a/src/components/datatable/BodyCell.vue
+++ b/src/components/datatable/BodyCell.vue
@@ -148,24 +148,26 @@ export default {
}
},
onKeyDown(event) {
- switch (event.which) {
- case 13:
- this.completeEdit(event, 'enter');
- break;
-
- case 27:
- this.switchCellToViewMode();
- this.$emit('cell-edit-cancel', {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index});
- break;
+ if (this.editMode === 'cell') {
+ switch (event.which) {
+ case 13:
+ this.completeEdit(event, 'enter');
+ break;
+
+ case 27:
+ this.switchCellToViewMode();
+ this.$emit('cell-edit-cancel', {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index});
+ break;
- case 9:
- this.completeEdit(event, 'tab');
+ case 9:
+ this.completeEdit(event, 'tab');
- if (event.shiftKey)
- this.moveToPreviousCell(event);
- else
- this.moveToNextCell(event);
- break;
+ if (event.shiftKey)
+ this.moveToPreviousCell(event);
+ else
+ this.moveToNextCell(event);
+ break;
+ }
}
},
moveToPreviousCell(event) {
diff --git a/src/views/datatable/DataTableEditDemo.vue b/src/views/datatable/DataTableEditDemo.vue
index 9b889c0dd..b54a853c8 100644
--- a/src/views/datatable/DataTableEditDemo.vue
+++ b/src/views/datatable/DataTableEditDemo.vue
@@ -4,7 +4,7 @@
-
DataTable
+
DataTable - InCell Edit
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.
@@ -45,7 +45,7 @@
Advanced Cell Editing
-
Custom implementation with validations, dynamic columns and ability to revert values with the escape key.
+
Custom implementation with validations, dynamic columns and reverting values with the escape key.
@@ -53,6 +53,28 @@
+
+
Row Editing
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -60,12 +82,170 @@
+<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>
+
+<h3>Row Editing</h3>
+<DataTable :value="cars3" 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 DataTableSubMenu from './DataTableSubMenu';
+import Vue from 'vue';
+export default {
+ data() {
+ return {
+ cars1: null,
+ cars2: null,
+ cars3: null,
+ editingCellRows: {},
+ editingRows: [],
+ 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,
+ originalRows: null,
+ created() {
+ this.carService = new CarService();
+
+ this.columns = [
+ {field: 'vin', header: 'Vin'},
+ {field: 'year', header: 'Year'},
+ {field: 'brand', header: 'Brand'},
+ {field: 'color', header: 'Color'}
+ ];
+
+ this.originalRows = {};
+ },
+ 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;
+ },
+ 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.cars1 = data);
+ this.carService.getCarsSmall().then(data => this.cars2 = data);
+ this.carService.getCarsSmall().then(data => this.cars3 = data);
+ },
+ components: {
+ 'DataTableSubMenu': DataTableSubMenu
+ }
+}
@@ -84,7 +264,8 @@ export default {
cars1: null,
cars2: null,
cars3: null,
- editingRows: {},
+ editingCellRows: {},
+ editingRows: [],
columns: null,
brands: [
{brand: 'Audi', value: 'Audi'},
@@ -100,6 +281,7 @@ export default {
}
},
carService: null,
+ originalRows: null,
created() {
this.carService = new CarService();
@@ -109,37 +291,39 @@ export default {
{field: 'brand', header: 'Brand'},
{field: 'color', header: 'Color'}
];
+
+ this.originalRows = {};
},
methods: {
onCellEditComplete(event) {
- if (!this.editingRows[event.index]) {
+ if (!this.editingCellRows[event.index]) {
return;
}
- const editingCellValue = this.editingRows[event.index][event.field];
+ const editingCellValue = this.editingCellRows[event.index][event.field];
switch (event.field) {
case 'year':
if (this.isPositiveInteger(editingCellValue))
- Vue.set(this.cars2, event.index, this.editingRows[event.index]);
+ 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.editingRows[event.index]);
+ Vue.set(this.cars2, event.index, this.editingCellRows[event.index]);
else
event.preventDefault();
break;
}
},
onCellEdit(newValue, props) {
- if (!this.editingRows[props.index]) {
- this.editingRows[props.index] = {...props.data};
+ if (!this.editingCellRows[props.index]) {
+ this.editingCellRows[props.index] = {...props.data};
}
- this.editingRows[props.index][props.column.field] = newValue;
+ this.editingCellRows[props.index][props.column.field] = newValue;
},
isPositiveInteger(val) {
let str = String(val);
@@ -150,6 +334,12 @@ export default {
str = str.replace(/^0+/, "") || "0";
var n = Math.floor(Number(str));
return n !== Infinity && String(n) === str && n >= 0;
+ },
+ onRowEditInit(event) {
+ this.originalRows[event.index] = {...this.cars3[event.index]};
+ },
+ onRowEditCancel(event) {
+ Vue.set(this.cars3, event.index, this.originalRows[event.index]);
}
},
mounted() {