Initiated Cell Editing

pull/104/head
cagataycivici 2019-10-28 22:36:06 +03:00
parent 35f0c7ace7
commit 0bf443fc8e
4 changed files with 181 additions and 2 deletions

View File

@ -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: {

View File

@ -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',

View File

@ -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>

View File

@ -10,6 +10,7 @@
<li><router-link to="/datatable/selection">&#9679; Selection</router-link></li>
<li><router-link to="/datatable/lazy">&#9679; Lazy</router-link></li>
<li><router-link to="/datatable/rowexpand">&#9679; Expand</router-link></li>
<li><router-link to="/datatable/edit">&#9679; Edit</router-link></li>
<li><router-link to="/datatable/coltoggle">&#9679; ColToggle</router-link></li>
<li><router-link to="/datatable/colresize">&#9679; ColResize</router-link></li>
<li><router-link to="/datatable/reorder">&#9679; Reorder</router-link></li>