Created BodyCell component
parent
335aa8dbba
commit
4ccf281d7f
|
@ -0,0 +1,71 @@
|
||||||
|
<template>
|
||||||
|
<td :style="column.bodyStyle" :class="column.bodyClass">
|
||||||
|
<ColumnSlot :data="rowData" :column="column" type="body" v-if="column.$scopedSlots.body" />
|
||||||
|
<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'" />
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.rowReorder">
|
||||||
|
<i :class="['p-datatable-reorderablerow-handle', column.rowReorderIcon]"></i>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.expander">
|
||||||
|
<button class="p-row-toggler p-link" @click="toggleRow">
|
||||||
|
<span :class="rowTogglerIcon"></span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
<template v-else>{{resolveFieldData()}}</template>
|
||||||
|
</td>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ObjectUtils from '../utils/ObjectUtils';
|
||||||
|
import ColumnSlot from './ColumnSlot.vue';
|
||||||
|
import RowRadioButton from './RowRadioButton';
|
||||||
|
import RowCheckbox from './RowCheckbox.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
rowData: {
|
||||||
|
type: Object,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
type: Object,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
rowTogglerIcon: {
|
||||||
|
type: Array,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
selected: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.children = this.$children;
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
resolveFieldData() {
|
||||||
|
return ObjectUtils.resolveFieldData(this.rowData, this.column.field);
|
||||||
|
},
|
||||||
|
toggleRow(event) {
|
||||||
|
this.$emit('row-toggle', {
|
||||||
|
originalEvent: event,
|
||||||
|
data: this.rowData
|
||||||
|
});
|
||||||
|
},
|
||||||
|
toggleRowWithRadio(event) {
|
||||||
|
this.$emit('radio-change', event);
|
||||||
|
},
|
||||||
|
toggleRowWithCheckbox(event) {
|
||||||
|
this.$emit('checkbox-change', event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'ColumnSlot': ColumnSlot,
|
||||||
|
'DTRadioButton': RowRadioButton,
|
||||||
|
'DTCheckbox': RowCheckbox
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,26 @@
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
functional: true,
|
||||||
|
props: {
|
||||||
|
column: {
|
||||||
|
type: null,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: null,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render(createElement, context) {
|
||||||
|
const content = context.props.column.$scopedSlots[context.props.type]({
|
||||||
|
'data': context.props.data,
|
||||||
|
'column': context.props.column
|
||||||
|
});
|
||||||
|
return [content];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -52,25 +52,17 @@
|
||||||
<tbody class="p-datatable-tbody">
|
<tbody class="p-datatable-tbody">
|
||||||
<template v-if="!empty">
|
<template v-if="!empty">
|
||||||
<template v-for="(rowData, index) of dataToRender">
|
<template v-for="(rowData, index) of dataToRender">
|
||||||
|
<tr class="p-rowgroup-header" v-if="rowGroupMode === 'subheader' && shouldRenderRowGroupHeader(dataToRender, rowData, index)" :key="getRowKey(rowData, index)">
|
||||||
|
<td :colspan="columns.length">
|
||||||
|
<slot name="groupheader" :data="rowData"></slot>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr :class="getRowClass(rowData)" :key="getRowKey(rowData, index)"
|
<tr :class="getRowClass(rowData)" :key="getRowKey(rowData, index)"
|
||||||
@click="onRowClick($event, rowData, index)" @touchend="onRowTouchEnd($event)" @keydown="onRowKeyDown($event, rowData, index)" :tabindex="selectionMode ? '0' : null"
|
@click="onRowClick($event, rowData, index)" @touchend="onRowTouchEnd($event)" @keydown="onRowKeyDown($event, rowData, index)" :tabindex="selectionMode ? '0' : null"
|
||||||
@mousedown="onRowMouseDown($event)" @dragstart="onRowDragStart($event, index)" @dragover="onRowDragOver($event,index)" @dragleave="onRowDragLeave($event)" @dragend="onRowDragEnd($event)" @drop="onRowDrop($event)">
|
@mousedown="onRowMouseDown($event)" @dragstart="onRowDragStart($event, index)" @dragover="onRowDragOver($event,index)" @dragleave="onRowDragLeave($event)" @dragend="onRowDragEnd($event)" @drop="onRowDrop($event)">
|
||||||
<td v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.bodyStyle" :class="col.bodyClass">
|
<DTBodyCell v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :rowData="rowData" :column="col" :selected="isSelected(rowData)"
|
||||||
<ColumnSlot :data="rowData" :column="col" type="body" v-if="col.$scopedSlots.body" />
|
:rowTogglerIcon="rowTogglerIcon(rowData)" @row-toggle="toggleRow"
|
||||||
<template v-else-if="col.selectionMode">
|
@radio-change="toggleRowWithRadio" @checkbox-change="toggleRowWithCheckbox" />
|
||||||
<DTRadioButton :value="rowData" :checked="isSelected(rowData)" @change="toggleRowWithRadio" v-if="col.selectionMode === 'single'" />
|
|
||||||
<DTCheckbox :value="rowData" :checked="isSelected(rowData)" @change="toggleRowWithCheckbox" v-else-if="col.selectionMode ==='multiple'" />
|
|
||||||
</template>
|
|
||||||
<template v-else-if="col.rowReorder">
|
|
||||||
<i :class="['p-datatable-reorderablerow-handle', col.rowReorderIcon]"></i>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="col.expander">
|
|
||||||
<button class="p-row-toggler p-link" @click="toggleRow($event, rowData)">
|
|
||||||
<span :class="rowTogglerIcon(rowData)"></span>
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
<template v-else>{{resolveFieldData(rowData, col.field)}}</template>
|
|
||||||
</td>
|
|
||||||
</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'">
|
||||||
<td :colspan="columns.length">
|
<td :colspan="columns.length">
|
||||||
|
@ -132,31 +124,8 @@ import Paginator from '../paginator/Paginator';
|
||||||
import RowRadioButton from './RowRadioButton';
|
import RowRadioButton from './RowRadioButton';
|
||||||
import RowCheckbox from './RowCheckbox.vue';
|
import RowCheckbox from './RowCheckbox.vue';
|
||||||
import HeaderCheckbox from './HeaderCheckbox.vue';
|
import HeaderCheckbox from './HeaderCheckbox.vue';
|
||||||
|
import ColumnSlot from './ColumnSlot.vue';
|
||||||
const ColumnSlot = {
|
import BodyCell from './BodyCell.vue';
|
||||||
functional: true,
|
|
||||||
props: {
|
|
||||||
column: {
|
|
||||||
type: null,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
type: null,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
render(createElement, context) {
|
|
||||||
const content = context.props.column.$scopedSlots[context.props.type]({
|
|
||||||
'data': context.props.data,
|
|
||||||
'column': context.props.column
|
|
||||||
});
|
|
||||||
return [content];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
@ -299,6 +268,14 @@ export default {
|
||||||
collapsedRowIcon: {
|
collapsedRowIcon: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'pi-chevron-right'
|
default: 'pi-chevron-right'
|
||||||
|
},
|
||||||
|
rowGroupMode: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
groupRowsBy: {
|
||||||
|
type: [Array,String],
|
||||||
|
default: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -1228,7 +1205,8 @@ export default {
|
||||||
this.onRowDragEnd(event);
|
this.onRowDragEnd(event);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
},
|
},
|
||||||
toggleRow(event, rowData) {
|
toggleRow(event) {
|
||||||
|
let rowData = event.data;
|
||||||
let expanded;
|
let expanded;
|
||||||
let expandedRowIndex;
|
let expandedRowIndex;
|
||||||
let _expandedRows = this.expandedRows ? [...this.expandedRows] : [];
|
let _expandedRows = this.expandedRows ? [...this.expandedRows] : [];
|
||||||
|
@ -1247,18 +1225,29 @@ export default {
|
||||||
}
|
}
|
||||||
_expandedRows.splice(expandedRowIndex, 1);
|
_expandedRows.splice(expandedRowIndex, 1);
|
||||||
this.$emit('update:expandedRows', _expandedRows);
|
this.$emit('update:expandedRows', _expandedRows);
|
||||||
this.$emit('row-collapse', {originalEvent: event,data: rowData});
|
this.$emit('row-collapse', event);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_expandedRows.push(rowData);
|
_expandedRows.push(rowData);
|
||||||
this.$emit('update:expandedRows', _expandedRows);
|
this.$emit('update:expandedRows', _expandedRows);
|
||||||
this.$emit('row-expand', {originalEvent: event,data: rowData});
|
this.$emit('row-expand', event);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
rowTogglerIcon(rowData) {
|
rowTogglerIcon(rowData) {
|
||||||
const icon = this.isRowExpanded(rowData) ? this.expandedRowIcon : this.collapsedRowIcon;
|
const icon = this.isRowExpanded(rowData) ? this.expandedRowIcon : this.collapsedRowIcon;
|
||||||
return ['p-row-toggler-icon pi pi-fw p-clickable', icon];
|
return ['p-row-toggler-icon pi pi-fw p-clickable', icon];
|
||||||
},
|
},
|
||||||
|
shouldRenderRowGroupHeader(value, rowData, i) {
|
||||||
|
if (i === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let currentRowFieldData = ObjectUtils.resolveFieldData(rowData, this.groupRowsBy);
|
||||||
|
let previousRowFieldData = ObjectUtils.resolveFieldData(value[i - 1], this.groupRowsBy);
|
||||||
|
|
||||||
|
return currentRowFieldData !== previousRowFieldData;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
containerClass() {
|
containerClass() {
|
||||||
|
@ -1410,7 +1399,8 @@ export default {
|
||||||
'DTPaginator': Paginator,
|
'DTPaginator': Paginator,
|
||||||
'DTRadioButton': RowRadioButton,
|
'DTRadioButton': RowRadioButton,
|
||||||
'DTCheckbox': RowCheckbox,
|
'DTCheckbox': RowCheckbox,
|
||||||
'DTHeaderCheckbox': HeaderCheckbox
|
'DTHeaderCheckbox': HeaderCheckbox,
|
||||||
|
'DTBodyCell': BodyCell
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -151,6 +151,11 @@ export default new Router({
|
||||||
name: 'datatablereorder',
|
name: 'datatablereorder',
|
||||||
component: () => import('./views/datatable/DataTableReorderDemo.vue')
|
component: () => import('./views/datatable/DataTableReorderDemo.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/datatable/rowgroup',
|
||||||
|
name: 'datatablerowgroup',
|
||||||
|
component: () => import('./views/datatable/DataTableRowGroupDemo.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/datatable/responsive',
|
path: '/datatable/responsive',
|
||||||
name: 'datatableresponsive',
|
name: 'datatableresponsive',
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<DataTableSubMenu />
|
||||||
|
|
||||||
|
<div class="content-section introduction">
|
||||||
|
<div class="feature-intro">
|
||||||
|
<h1>DataTable - Row Grouping</h1>
|
||||||
|
<p>Rows can either be grouped by a separate grouping row or using rowspan.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-section implementation">
|
||||||
|
<DataTable :value="cars" rowGroupMode="subheader" groupRowsBy="brand"
|
||||||
|
sortMode="single" sortField="brand" :sortOrder="1">
|
||||||
|
<template #header>
|
||||||
|
Subheader Grouping
|
||||||
|
</template>
|
||||||
|
<Column field="brand" header="Brand"></Column>
|
||||||
|
<Column field="vin" header="Vin"></Column>
|
||||||
|
<Column field="year" header="Year"></Column>
|
||||||
|
<Column field="color" header="Color"></Column>
|
||||||
|
<template #groupheader="slotProps">
|
||||||
|
<strong>{{slotProps.data.brand}}</strong>
|
||||||
|
</template>
|
||||||
|
<template #groupfooter="slotProps">
|
||||||
|
<td colspan="3" style="text-align: right">Total Price</td>
|
||||||
|
<td>20000</td>
|
||||||
|
</template>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-section documentation">
|
||||||
|
<TabView>
|
||||||
|
<TabPanel header="Source">
|
||||||
|
<CodeHighlight>
|
||||||
|
<template v-pre>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</CodeHighlight>
|
||||||
|
|
||||||
|
<CodeHighlight lang="javascript">
|
||||||
|
|
||||||
|
</CodeHighlight>
|
||||||
|
</TabPanel>
|
||||||
|
</TabView>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CarService from '../../service/CarService';
|
||||||
|
import DataTableSubMenu from './DataTableSubMenu';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
cars: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
carService: null,
|
||||||
|
created() {
|
||||||
|
this.carService = new CarService();
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.carService.getCarsMedium().then(data => this.cars = data);
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'DataTableSubMenu': DataTableSubMenu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -13,6 +13,7 @@
|
||||||
<li><router-link to="/datatable/coltoggle">● ColToggle</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/colresize">● ColResize</router-link></li>
|
||||||
<li><router-link to="/datatable/reorder">● Reorder</router-link></li>
|
<li><router-link to="/datatable/reorder">● Reorder</router-link></li>
|
||||||
|
<li><router-link to="/datatable/rowgroup">● RowGroup</router-link></li>
|
||||||
<li><router-link to="/datatable/responsive">● Responsive</router-link></li>
|
<li><router-link to="/datatable/responsive">● Responsive</router-link></li>
|
||||||
<li><router-link to="/datatable/export">● Export</router-link></li>
|
<li><router-link to="/datatable/export">● Export</router-link></li>
|
||||||
<li><router-link to="/datatable/crud">● Crud</router-link></li>
|
<li><router-link to="/datatable/crud">● Crud</router-link></li>
|
||||||
|
|
Loading…
Reference in New Issue