Initiated Cell Editing
parent
35f0c7ace7
commit
0bf443fc8e
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<td :style="column.bodyStyle" :class="column.bodyClass">
|
||||
<ColumnSlot :data="rowData" :column="column" :index="index" type="body" v-if="column.$scopedSlots.body" />
|
||||
<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="editor" v-else-if="column.$scopedSlots.editor && editing" />
|
||||
<template v-else-if="column.selectionMode">
|
||||
<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'" />
|
||||
|
@ -18,6 +19,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import DomHandler from '../utils/DomHandler';
|
||||
import ObjectUtils from '../utils/ObjectUtils';
|
||||
import ColumnSlot from './ColumnSlot.vue';
|
||||
import RowRadioButton from './RowRadioButton';
|
||||
|
@ -46,9 +48,23 @@ export default {
|
|||
default: false
|
||||
},
|
||||
},
|
||||
documentEditListener: null,
|
||||
data() {
|
||||
return {
|
||||
editing: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.children = this.$children;
|
||||
},
|
||||
updated() {
|
||||
if (this.editing) {
|
||||
let focusable = DomHandler.findSingle(this.$el, 'input');
|
||||
if (focusable) {
|
||||
focusable.focus();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
resolveFieldData() {
|
||||
return ObjectUtils.resolveFieldData(this.rowData, this.column.field);
|
||||
|
@ -64,6 +80,54 @@ export default {
|
|||
},
|
||||
toggleRowWithCheckbox(event) {
|
||||
this.$emit('checkbox-change', event);
|
||||
},
|
||||
onClick() {
|
||||
if (this.isEditable() && !this.editing) {
|
||||
this.editing = true;
|
||||
|
||||
this.bindDocumentEditListener();
|
||||
}
|
||||
},
|
||||
isEditable() {
|
||||
return this.column.$scopedSlots.editor != null;
|
||||
},
|
||||
bindDocumentEditListener() {
|
||||
if (!this.documentEditListener) {
|
||||
this.documentEditListener = (event) => {
|
||||
if (this.isOutsideClicked(event)) {
|
||||
this.switchCellToViewMode();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('click', this.documentEditListener);
|
||||
}
|
||||
},
|
||||
unbindDocumentEditListener() {
|
||||
if (this.documentEditListener) {
|
||||
document.removeEventListener('click', this.documentEditListener);
|
||||
this.documentEditListener = null;
|
||||
}
|
||||
},
|
||||
switchCellToViewMode() {
|
||||
this.editing = false;
|
||||
this.unbindDocumentEditListener();
|
||||
},
|
||||
isOutsideClicked(event) {
|
||||
return !this.$el.contains(event.target) && !this.$el.isSameNode(event.target);
|
||||
},
|
||||
onKeyDown(event) {
|
||||
if (event.which === 13 || event.which === 9 || event.which === 27) {
|
||||
this.switchCellToViewMode();
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
containerClass() {
|
||||
return [this.column.bodyClass, {
|
||||
'p-selection-column': this.column.selectionMode != null,
|
||||
'p-editable-column': this.isEditable(),
|
||||
'p-cell-editing': this.editing
|
||||
}];
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
|
@ -191,6 +191,11 @@ export default new Router({
|
|||
name: 'datatablestate',
|
||||
component: () => import('./views/datatable/DataTableStateDemo.vue')
|
||||
},
|
||||
{
|
||||
path: '/datatable/edit',
|
||||
name: 'datatableedit',
|
||||
component: () => import('./views/datatable/DataTableEditDemo.vue')
|
||||
},
|
||||
{
|
||||
path: '/datatable/crud',
|
||||
name: 'datatablecrud',
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
<template>
|
||||
<div>
|
||||
<DataTableSubMenu />
|
||||
|
||||
<div class="content-section introduction">
|
||||
<div class="feature-intro">
|
||||
<h1>DataTable</h1>
|
||||
<p>Cell and Row editing provide a rapid and user friendly way to manipulate data within the table.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-section implementation">
|
||||
<h3>Cell Editing</h3>
|
||||
<DataTable :value="cars">
|
||||
<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['year']" />
|
||||
</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['color']" />
|
||||
</template>
|
||||
</Column>
|
||||
</DataTable>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CarService from '../../service/CarService';
|
||||
import DataTableSubMenu from './DataTableSubMenu';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
columns: null,
|
||||
cars: 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'}
|
||||
];
|
||||
},
|
||||
mounted() {
|
||||
this.carService.getCarsSmall().then(data => this.cars = data);
|
||||
},
|
||||
components: {
|
||||
'DataTableSubMenu': DataTableSubMenu
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/deep/ .p-datatable th,
|
||||
/deep/ .p-datatable td {
|
||||
height: 3.5em;
|
||||
}
|
||||
|
||||
.p-dropdown-car-option {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
margin-right: .5em;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
span {
|
||||
margin-top: .125em;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -10,6 +10,7 @@
|
|||
<li><router-link to="/datatable/selection">● Selection</router-link></li>
|
||||
<li><router-link to="/datatable/lazy">● Lazy</router-link></li>
|
||||
<li><router-link to="/datatable/rowexpand">● Expand</router-link></li>
|
||||
<li><router-link to="/datatable/edit">● Edit</router-link></li>
|
||||
<li><router-link to="/datatable/coltoggle">● ColToggle</router-link></li>
|
||||
<li><router-link to="/datatable/colresize">● ColResize</router-link></li>
|
||||
<li><router-link to="/datatable/reorder">● Reorder</router-link></li>
|
||||
|
|
Loading…
Reference in New Issue