Initiated Row Editing for Table
parent
c759ca869a
commit
c576587060
|
@ -22,4 +22,5 @@ export declare class Column extends Vue {
|
||||||
rowReorder?: boolean;
|
rowReorder?: boolean;
|
||||||
rowReorderIcon?: string;
|
rowReorderIcon?: string;
|
||||||
reorderableColumn?: boolean;
|
reorderableColumn?: boolean;
|
||||||
|
rowEditor?: boolean;
|
||||||
}
|
}
|
|
@ -85,6 +85,10 @@ export default {
|
||||||
reorderableColumn: {
|
reorderableColumn: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
rowEditor: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<td :style="column.bodyStyle" :class="containerClass" @click="onClick" @keydown="onKeyDown">
|
<td :style="column.bodyStyle" :class="containerClass" @click="onClick" @keydown="onKeyDown">
|
||||||
<ColumnSlot :data="rowData" :column="column" :index="index" type="body" v-if="column.$scopedSlots.body && !editing" />
|
<ColumnSlot :data="rowData" :column="column" :index="index" type="body" v-if="column.$scopedSlots.body && !d_editing" />
|
||||||
<ColumnSlot :data="rowData" :column="column" :index="index" type="editor" v-else-if="column.$scopedSlots.editor && editing" />
|
<ColumnSlot :data="rowData" :column="column" :index="index" type="editor" v-else-if="column.$scopedSlots.editor && d_editing" />
|
||||||
<template v-else-if="column.selectionMode">
|
<template v-else-if="column.selectionMode">
|
||||||
<DTRadioButton :value="rowData" :checked="selected" @change="toggleRowWithRadio" v-if="column.selectionMode === 'single'" />
|
<DTRadioButton :value="rowData" :checked="selected" @change="toggleRowWithRadio" v-if="column.selectionMode === 'single'" />
|
||||||
<DTCheckbox :value="rowData" :checked="selected" @change="toggleRowWithCheckbox" v-else-if="column.selectionMode ==='multiple'" />
|
<DTCheckbox :value="rowData" :checked="selected" @change="toggleRowWithCheckbox" v-else-if="column.selectionMode ==='multiple'" />
|
||||||
|
@ -14,6 +14,17 @@
|
||||||
<span :class="rowTogglerIcon"></span>
|
<span :class="rowTogglerIcon"></span>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-else-if="editMode === 'row' && column.rowEditor">
|
||||||
|
<button class="p-row-editor-init p-link" v-if="!d_editing" @click="onRowEditInit">
|
||||||
|
<span class="p-row-editor-init-icon pi pi-fw pi-pencil p-clickable"></span>
|
||||||
|
</button>
|
||||||
|
<button class="p-row-editor-save p-link" v-if="d_editing" @click="onRowEditSave">
|
||||||
|
<span class="p-row-editor-save-icon pi pi-fw pi-check p-clickable"></span>
|
||||||
|
</button>
|
||||||
|
<button class="p-row-editor-cancel p-link" v-if="d_editing" @click="onRowEditCancel">
|
||||||
|
<span class="p-row-editor-cancel-icon pi pi-fw pi-times p-clickable"></span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
<template v-else>{{resolveFieldData()}}</template>
|
<template v-else>{{resolveFieldData()}}</template>
|
||||||
</td>
|
</td>
|
||||||
</template>
|
</template>
|
||||||
|
@ -47,18 +58,31 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
editing: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
editMode: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
documentEditListener: null,
|
documentEditListener: null,
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
editing: false
|
d_editing: this.editing
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
editing(newValue) {
|
||||||
|
this.d_editing = newValue;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.children = this.$children;
|
this.children = this.$children;
|
||||||
},
|
},
|
||||||
updated() {
|
updated() {
|
||||||
if (this.editing) {
|
if (this.d_editing) {
|
||||||
let focusable = DomHandler.findSingle(this.$el, 'input');
|
let focusable = DomHandler.findSingle(this.$el, 'input');
|
||||||
if (focusable) {
|
if (focusable) {
|
||||||
focusable.focus();
|
focusable.focus();
|
||||||
|
@ -102,22 +126,22 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
switchCellToViewMode() {
|
switchCellToViewMode() {
|
||||||
this.editing = false;
|
this.d_editing = false;
|
||||||
this.unbindDocumentEditListener();
|
this.unbindDocumentEditListener();
|
||||||
},
|
},
|
||||||
isOutsideClicked(event) {
|
isOutsideClicked(event) {
|
||||||
return !this.$el.contains(event.target) && !this.$el.isSameNode(event.target);
|
return !this.$el.contains(event.target) && !this.$el.isSameNode(event.target);
|
||||||
},
|
},
|
||||||
onClick(event) {
|
onClick(event) {
|
||||||
if (this.isEditable() && !this.editing) {
|
if (this.editMode === 'cell' && this.isEditable() && !this.d_editing) {
|
||||||
this.editing = true;
|
this.d_editing = true;
|
||||||
this.bindDocumentEditListener();
|
this.bindDocumentEditListener();
|
||||||
this.$emit('edit-init', {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index});
|
this.$emit('cell-edit-init', {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
completeEdit(event, type) {
|
completeEdit(event, type) {
|
||||||
let editEvent = {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index, type: type, preventDefault: () => event.preventDefault()};
|
let editEvent = {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index, type: type, preventDefault: () => event.preventDefault()};
|
||||||
this.$emit('edit-complete', editEvent);
|
this.$emit('cell-edit-complete', editEvent);
|
||||||
|
|
||||||
if (!event.defaultPrevented) {
|
if (!event.defaultPrevented) {
|
||||||
this.switchCellToViewMode();
|
this.switchCellToViewMode();
|
||||||
|
@ -131,7 +155,7 @@ export default {
|
||||||
|
|
||||||
case 27:
|
case 27:
|
||||||
this.switchCellToViewMode();
|
this.switchCellToViewMode();
|
||||||
this.$emit('edit-cancel', {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index});
|
this.$emit('cell-edit-cancel', {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9:
|
case 9:
|
||||||
|
@ -217,6 +241,15 @@ export default {
|
||||||
},
|
},
|
||||||
isEditingCellValid() {
|
isEditingCellValid() {
|
||||||
return (DomHandler.find(this.$el, '.p-invalid').length === 0);
|
return (DomHandler.find(this.$el, '.p-invalid').length === 0);
|
||||||
|
},
|
||||||
|
onRowEditInit(event) {
|
||||||
|
this.$emit('row-edit-init', {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index});
|
||||||
|
},
|
||||||
|
onRowEditSave(event) {
|
||||||
|
this.$emit('row-edit-save', {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index});
|
||||||
|
},
|
||||||
|
onRowEditCancel(event) {
|
||||||
|
this.$emit('row-edit-cancel', {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -224,7 +257,7 @@ export default {
|
||||||
return [this.column.bodyClass, {
|
return [this.column.bodyClass, {
|
||||||
'p-selection-column': this.column.selectionMode != null,
|
'p-selection-column': this.column.selectionMode != null,
|
||||||
'p-editable-column': this.isEditable(),
|
'p-editable-column': this.isEditable(),
|
||||||
'p-cell-editing': this.editing
|
'p-cell-editing': this.d_editing
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -57,9 +57,12 @@ export declare class DataTable extends Vue {
|
||||||
$emit(eventName: 'row-collapse', event: Event): this;
|
$emit(eventName: 'row-collapse', event: Event): this;
|
||||||
$emit(eventName: 'rowgroup-expand', event: Event): this;
|
$emit(eventName: 'rowgroup-expand', event: Event): this;
|
||||||
$emit(eventName: 'rowgroup-collapse', event: Event): this;
|
$emit(eventName: 'rowgroup-collapse', event: Event): this;
|
||||||
$emit(eventName: 'edit-init', event: Event): this;
|
$emit(eventName: 'cell-edit-init', event: Event): this;
|
||||||
$emit(eventName: 'edit-complete', event: Event): this;
|
$emit(eventName: 'cell-edit-complete', event: Event): this;
|
||||||
$emit(eventName: 'edit-cancel', event: Event): this;
|
$emit(eventName: 'cell-edit-cancel', event: Event): this;
|
||||||
|
$emit(eventName: 'row-edit-init', event: Event): this;
|
||||||
|
$emit(eventName: 'row-edit-save', event: Event): this;
|
||||||
|
$emit(eventName: 'row-edit-cancel', event: Event): this;
|
||||||
$slots: {
|
$slots: {
|
||||||
header: VNode[];
|
header: VNode[];
|
||||||
paginatorLeft: VNode[];
|
paginatorLeft: VNode[];
|
||||||
|
|
|
@ -72,7 +72,9 @@
|
||||||
:rowTogglerIcon="col.expander ? rowTogglerIcon(rowData): null" @row-toggle="toggleRow"
|
:rowTogglerIcon="col.expander ? rowTogglerIcon(rowData): null" @row-toggle="toggleRow"
|
||||||
@radio-change="toggleRowWithRadio" @checkbox-change="toggleRowWithCheckbox"
|
@radio-change="toggleRowWithRadio" @checkbox-change="toggleRowWithCheckbox"
|
||||||
:rowspan="rowGroupMode === 'rowspan' ? calculateRowGroupSize(dataToRender, col, index) : null"
|
:rowspan="rowGroupMode === 'rowspan' ? calculateRowGroupSize(dataToRender, col, index) : null"
|
||||||
@edit-init="onEditInit" @edit-complete="onEditComplete" @edit-cancel="onEditCancel" />
|
:editMode="editMode" :editing="editMode === 'row' && isRowEditing(rowData)"
|
||||||
|
@cell-edit-init="onCellEditInit" @cell-edit-complete="onCellEditComplete" @cell-edit-cancel="onCellEditCancel"
|
||||||
|
@row-edit-init="onRowEditInit" @row-edit-save="onRowEditSave" @row-edit-cancel="onRowEditCancel"/>
|
||||||
</template>
|
</template>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="p-datatable-row-expansion" v-if="expandedRows && isRowExpanded(rowData)" :key="getRowKey(rowData, index) + '_expansion'">
|
<tr class="p-datatable-row-expansion" v-if="expandedRows && isRowExpanded(rowData)" :key="getRowKey(rowData, index) + '_expansion'">
|
||||||
|
@ -308,6 +310,10 @@ export default {
|
||||||
editMode: {
|
editMode: {
|
||||||
type: String,
|
type: String,
|
||||||
default: null
|
default: null
|
||||||
|
},
|
||||||
|
editingRows: {
|
||||||
|
type: Array,
|
||||||
|
default: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -320,7 +326,8 @@ export default {
|
||||||
d_multiSortMeta: this.multiSortMeta ? [...this.multiSortMeta] : [],
|
d_multiSortMeta: this.multiSortMeta ? [...this.multiSortMeta] : [],
|
||||||
d_selectionKeys: null,
|
d_selectionKeys: null,
|
||||||
d_expandedRowKeys: null,
|
d_expandedRowKeys: null,
|
||||||
d_columnOrder: null
|
d_columnOrder: null,
|
||||||
|
d_editingRowKeys: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
rowTouched: false,
|
rowTouched: false,
|
||||||
|
@ -365,6 +372,11 @@ export default {
|
||||||
if (this.dataKey) {
|
if (this.dataKey) {
|
||||||
this.updateExpandedRowKeys(newValue);
|
this.updateExpandedRowKeys(newValue);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
editingRows(newValue) {
|
||||||
|
if (this.dataKey) {
|
||||||
|
this.updateEditingRowKeys(newValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
|
@ -854,6 +866,17 @@ export default {
|
||||||
this.d_expandedRowKeys = null;
|
this.d_expandedRowKeys = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
updateEditingRowKeys(editingRows) {
|
||||||
|
if (editingRows && editingRows.length) {
|
||||||
|
this.d_editingRowKeys = {};
|
||||||
|
for (let data of editingRows) {
|
||||||
|
this.d_editingRowKeys[String(ObjectUtils.resolveFieldData(data, this.dataKey))] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.d_editingRowKeys = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
equals(data1, data2) {
|
equals(data1, data2) {
|
||||||
return this.compareSelectionBy === 'equals' ? (data1 === data2) : ObjectUtils.equals(data1, data2, this.dataKey);
|
return this.compareSelectionBy === 'equals' ? (data1 === data2) : ObjectUtils.equals(data1, data2, this.dataKey);
|
||||||
},
|
},
|
||||||
|
@ -1563,14 +1586,42 @@ export default {
|
||||||
headers.forEach((header, index) => header.style.width = widths[index] + 'px');
|
headers.forEach((header, index) => header.style.width = widths[index] + 'px');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onEditInit(event) {
|
onCellEditInit(event) {
|
||||||
this.$emit('edit-init', event);
|
this.$emit('cell-edit-init', event);
|
||||||
},
|
},
|
||||||
onEditComplete(event) {
|
onCellEditComplete(event) {
|
||||||
this.$emit('edit-complete', event);
|
this.$emit('cell-edit-complete', event);
|
||||||
},
|
},
|
||||||
onEditCancel(event) {
|
onCellEditCancel(event) {
|
||||||
this.$emit('edit-cancel', event);
|
this.$emit('cell-edit-cancel', event);
|
||||||
|
},
|
||||||
|
isRowEditing(rowData) {
|
||||||
|
if (rowData && this.editingRows) {
|
||||||
|
if (this.dataKey)
|
||||||
|
return this.d_editingRowKeys ? this.d_editingRowKeys[ObjectUtils.resolveFieldData(rowData, this.dataKey)] !== undefined : false;
|
||||||
|
else
|
||||||
|
return this.findIndex(rowData, this.editingRows) > -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
onRowEditInit(event) {
|
||||||
|
let _editingRows = this.editingRows ? [...this.editingRows] : [];
|
||||||
|
_editingRows.push(event.data);
|
||||||
|
this.$emit('update:editingRows', _editingRows);
|
||||||
|
this.$emit('row-edit-init', event);
|
||||||
|
},
|
||||||
|
onRowEditSave(event) {
|
||||||
|
let _editingRows = [...this.editingRows];
|
||||||
|
_editingRows.splice(this.findIndex(event.data, this._editingRows), 1);
|
||||||
|
this.$emit('update:editingRows', _editingRows);
|
||||||
|
this.$emit('row-edit-save', event);
|
||||||
|
},
|
||||||
|
onRowEditCancel(event) {
|
||||||
|
let _editingRows = [...this.editingRows];
|
||||||
|
_editingRows.splice(this.findIndex(event.data, this._editingRows), 1);
|
||||||
|
this.$emit('update:editingRows', _editingRows);
|
||||||
|
this.$emit('row-edit-cancel', event);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -44,15 +44,15 @@
|
||||||
|
|
||||||
<h3>Advanced Cell Editing</h3>
|
<h3>Advanced Cell Editing</h3>
|
||||||
<p>Advanced editors with validations and ability to revert values with escape key.</p>
|
<p>Advanced editors with validations and ability to revert values with escape key.</p>
|
||||||
<DataTable :value="cars2" editMode="cell" @edit-init="onEditInit" @edit-complete="onEditComplete" @edit-cancel="onEditCancel">
|
<DataTable :value="cars2" editMode="cell" @cell-edit-init="onCellEditInit" @cell-edit-complete="onCellEditComplete" @cell-edit-cancel="onCellEditCancel">
|
||||||
<Column field="vin" header="Vin">
|
<Column field="vin" header="Vin">
|
||||||
<template #editor="slotProps">
|
<template #editor="slotProps">
|
||||||
<InputText :value="slotProps.data[slotProps.column.field]" @input="onEdit($event, slotProps)" />
|
<InputText :value="slotProps.data[slotProps.column.field]" @input="onCellEdit($event, slotProps)" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="year" header="Year">
|
<Column field="year" header="Year">
|
||||||
<template #editor="slotProps">
|
<template #editor="slotProps">
|
||||||
<InputText :value="slotProps.data[slotProps.column.field]" @input="onEdit($event, slotProps)" />
|
<InputText :value="slotProps.data[slotProps.column.field]" @input="onCellEdit($event, slotProps)" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="brand" header="Brand">
|
<Column field="brand" header="Brand">
|
||||||
|
@ -69,10 +69,38 @@
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="color" header="Color">
|
<Column field="color" header="Color">
|
||||||
<template #editor="slotProps">
|
<template #editor="slotProps">
|
||||||
<InputText :value="slotProps.data[slotProps.column.field]" @input="onEdit($event, slotProps)" />
|
<InputText :value="slotProps.data[slotProps.column.field]" @input="onCellEdit($event, slotProps)" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
|
|
||||||
|
<h3>Row Editing</h3>
|
||||||
|
<DataTable :value="cars3" editMode="row" dataKey="vin" :editingRows.sync="editingRows">
|
||||||
|
<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">
|
||||||
|
<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>
|
||||||
|
<Column :rowEditor="true" headerStyle="width:6em" bodyStyle="text-align:center"></Column>
|
||||||
|
</DataTable>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content-section documentation">
|
<div class="content-section documentation">
|
||||||
|
@ -80,161 +108,12 @@
|
||||||
<TabPanel header="Source">
|
<TabPanel header="Source">
|
||||||
<CodeHighlight>
|
<CodeHighlight>
|
||||||
<template v-pre>
|
<template v-pre>
|
||||||
<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>Advanced editors with validations and ability to revert values with escape key.</p>
|
|
||||||
<DataTable :value="cars2" editMode="cell" @edit-init="onEditInit" @edit-complete="onEditComplete" @edit-cancel="onEditCancel">
|
|
||||||
<Column field="vin" header="Vin">
|
|
||||||
<template #editor="slotProps">
|
|
||||||
<InputText :value="slotProps.data[slotProps.column.field]" @input="onEdit($event, slotProps)" />
|
|
||||||
</template>
|
|
||||||
</Column>
|
|
||||||
<Column field="year" header="Year">
|
|
||||||
<template #editor="slotProps">
|
|
||||||
<InputText :value="slotProps.data[slotProps.column.field]" @input="onEdit($event, slotProps)" />
|
|
||||||
</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 :value="slotProps.data[slotProps.column.field]" @input="onEdit($event, slotProps)" />
|
|
||||||
</template>
|
|
||||||
</Column>
|
|
||||||
</DataTable>
|
|
||||||
</template>
|
</template>
|
||||||
</CodeHighlight>
|
</CodeHighlight>
|
||||||
|
|
||||||
<CodeHighlight lang="javascript">
|
<CodeHighlight lang="javascript">
|
||||||
import CarService from '../../service/CarService';
|
|
||||||
import DataTableSubMenu from './DataTableSubMenu';
|
|
||||||
import Vue from 'vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
cars1: null,
|
|
||||||
cars2: null,
|
|
||||||
editingCar: null,
|
|
||||||
editingCarIndex: null,
|
|
||||||
originalCar: 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();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onEditInit(event) {
|
|
||||||
this.editingCarIndex = event.index;
|
|
||||||
this.editingCar = {...event.data}; //update on input
|
|
||||||
this.originalCar = {...event.data}; //revert with escape key
|
|
||||||
},
|
|
||||||
onEditComplete(event) {
|
|
||||||
switch (event.field) {
|
|
||||||
case 'year':
|
|
||||||
if (this.isPositiveInteger(this.editingCar.year)) {
|
|
||||||
Vue.set(this.cars2, this.editingCarIndex, this.editingCar);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.$toast.add({severity:'error', summary: 'Validation Failed', detail:'Year must be a number', life: 3000});
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (this.editingCar[event.field].trim().length > 0) {
|
|
||||||
Vue.set(this.cars2, this.editingCarIndex, this.editingCar);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.$toast.add({severity:'error', summary: 'Validation Failed', detail: event.field + ' is required', life: 3000});
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
clearEditorState() {
|
|
||||||
this.editingCar = null;
|
|
||||||
this.originalCar = null;
|
|
||||||
},
|
|
||||||
onEdit(newValue, props) {
|
|
||||||
this.editingCar[props.column.field] = newValue;
|
|
||||||
},
|
|
||||||
onEditCancel(event) {
|
|
||||||
Vue.set(this.cars2, event.index, this.originalCar);
|
|
||||||
this.editingCar = null;
|
|
||||||
},
|
|
||||||
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);
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
'DataTableSubMenu': DataTableSubMenu
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</CodeHighlight>
|
</CodeHighlight>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</TabView>
|
</TabView>
|
||||||
|
@ -252,9 +131,11 @@ export default {
|
||||||
return {
|
return {
|
||||||
cars1: null,
|
cars1: null,
|
||||||
cars2: null,
|
cars2: null,
|
||||||
|
cars3: null,
|
||||||
editingCar: null,
|
editingCar: null,
|
||||||
editingCarIndex: null,
|
editingCarIndex: null,
|
||||||
originalCar: null,
|
originalCar: null,
|
||||||
|
editingRows: null,
|
||||||
brands: [
|
brands: [
|
||||||
{brand: 'Audi', value: 'Audi'},
|
{brand: 'Audi', value: 'Audi'},
|
||||||
{brand: 'BMW', value: 'BMW'},
|
{brand: 'BMW', value: 'BMW'},
|
||||||
|
@ -273,12 +154,12 @@ export default {
|
||||||
this.carService = new CarService();
|
this.carService = new CarService();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onEditInit(event) {
|
onCellEditInit(event) {
|
||||||
this.editingCarIndex = event.index;
|
this.editingCarIndex = event.index;
|
||||||
this.editingCar = {...event.data}; //update on input
|
this.editingCar = {...event.data}; //update on input
|
||||||
this.originalCar = {...event.data}; //revert with escape key
|
this.originalCar = {...event.data}; //revert with escape key
|
||||||
},
|
},
|
||||||
onEditComplete(event) {
|
onCellEditComplete(event) {
|
||||||
switch (event.field) {
|
switch (event.field) {
|
||||||
case 'year':
|
case 'year':
|
||||||
if (this.isPositiveInteger(this.editingCar.year)) {
|
if (this.isPositiveInteger(this.editingCar.year)) {
|
||||||
|
@ -301,17 +182,13 @@ export default {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clearEditorState() {
|
onCellEditCancel(event) {
|
||||||
this.editingCar = null;
|
|
||||||
this.originalCar = null;
|
|
||||||
},
|
|
||||||
onEdit(newValue, props) {
|
|
||||||
this.editingCar[props.column.field] = newValue;
|
|
||||||
},
|
|
||||||
onEditCancel(event) {
|
|
||||||
Vue.set(this.cars2, event.index, this.originalCar);
|
Vue.set(this.cars2, event.index, this.originalCar);
|
||||||
this.editingCar = null;
|
this.editingCar = null;
|
||||||
},
|
},
|
||||||
|
onCellEdit(newValue, props) {
|
||||||
|
this.editingCar[props.column.field] = newValue;
|
||||||
|
},
|
||||||
isPositiveInteger(val) {
|
isPositiveInteger(val) {
|
||||||
let str = String(val);
|
let str = String(val);
|
||||||
str = str.trim();
|
str = str.trim();
|
||||||
|
@ -326,6 +203,7 @@ export default {
|
||||||
mounted() {
|
mounted() {
|
||||||
this.carService.getCarsSmall().then(data => this.cars1 = data);
|
this.carService.getCarsSmall().then(data => this.cars1 = data);
|
||||||
this.carService.getCarsSmall().then(data => this.cars2 = data);
|
this.carService.getCarsSmall().then(data => this.cars2 = data);
|
||||||
|
this.carService.getCarsSmall().then(data => this.cars3 = data);
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
'DataTableSubMenu': DataTableSubMenu
|
'DataTableSubMenu': DataTableSubMenu
|
||||||
|
|
Loading…
Reference in New Issue