Fixed #63 - ColumnGroups for DataTable
parent
13a1525829
commit
c5d097bad6
|
@ -65,6 +65,14 @@ export default {
|
||||||
expander: {
|
expander: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
colspan: {
|
||||||
|
type: Number,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
rowspan: {
|
||||||
|
type: Number,
|
||||||
|
default: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'columngroup',
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
_rows: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this._rows = this.$children;
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
rows() {
|
||||||
|
return this._rows;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -22,8 +22,9 @@
|
||||||
</DTPaginator>
|
</DTPaginator>
|
||||||
<table ref="table">
|
<table ref="table">
|
||||||
<thead class="p-datatable-thead">
|
<thead class="p-datatable-thead">
|
||||||
<tr>
|
<tr v-if="!headerColumnGroup">
|
||||||
<th v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.headerStyle" :class="getColumnHeaderClass(col)" @click="onColumnHeaderClick($event, col)">
|
<th v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.headerStyle" :class="getColumnHeaderClass(col)" @click="onColumnHeaderClick($event, col)"
|
||||||
|
:colspan="col.colspan" :rowspan="col.rowspan">
|
||||||
<span class="p-column-resizer p-clickable" @mousedown="onColumnResizeStart" v-if="resizableColumns"></span>
|
<span class="p-column-resizer p-clickable" @mousedown="onColumnResizeStart" v-if="resizableColumns"></span>
|
||||||
<ColumnSlot :column="col" type="header" v-if="col.$scopedSlots.header" />
|
<ColumnSlot :column="col" type="header" v-if="col.$scopedSlots.header" />
|
||||||
<span class="p-column-title" v-if="col.header">{{col.header}}</span>
|
<span class="p-column-title" v-if="col.header">{{col.header}}</span>
|
||||||
|
@ -32,15 +33,19 @@
|
||||||
<DTHeaderCheckbox :checked="allRowsSelected" @change="toggleRowsWithCheckbox" :disabled="empty" v-if="col.selectionMode ==='multiple'" />
|
<DTHeaderCheckbox :checked="allRowsSelected" @change="toggleRowsWithCheckbox" :disabled="empty" v-if="col.selectionMode ==='multiple'" />
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
<template v-else>
|
||||||
<tfoot class="p-datatable-tfoot" v-if="hasFooter">
|
<tr v-for="(row,i) of headerColumnGroup.rows" :key="i">
|
||||||
<tr>
|
<th v-for="(col,i) of row.columns" :key="col.columnKey||col.field||i" :style="col.headerStyle" :class="getColumnHeaderClass(col)" @click="onColumnHeaderClick($event, col)"
|
||||||
<td v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.footerStyle" :class="col.footerClass">
|
:colspan="col.colspan" :rowspan="col.rowspan">
|
||||||
<ColumnSlot :column="col" type="footer" v-if="col.$scopedSlots.footer" />
|
<ColumnSlot :column="col" type="header" v-if="col.$scopedSlots.header" />
|
||||||
{{col.footer}}
|
<span class="p-column-title" v-if="col.header">{{col.header}}</span>
|
||||||
</td>
|
<span v-if="col.sortable" :class="getSortableColumnIcon(col)"></span>
|
||||||
|
<ColumnSlot :column="col" type="filter" v-if="col.$scopedSlots.filter" />
|
||||||
|
<DTHeaderCheckbox :checked="allRowsSelected" @change="toggleRowsWithCheckbox" :disabled="empty" v-if="col.selectionMode ==='multiple'" />
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</template>
|
||||||
|
</thead>
|
||||||
<tbody class="p-datatable-tbody">
|
<tbody class="p-datatable-tbody">
|
||||||
<template v-if="!empty">
|
<template v-if="!empty">
|
||||||
<tr :class="getRowClass(rowData)" v-for="(rowData, index) of dataToRender" :key="getRowKey(rowData, index)"
|
<tr :class="getRowClass(rowData)" v-for="(rowData, index) of dataToRender" :key="getRowKey(rowData, index)"
|
||||||
|
@ -61,6 +66,24 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
<tfoot class="p-datatable-tfoot" v-if="hasFooter">
|
||||||
|
<tr v-if="!footerColumnGroup">>
|
||||||
|
<td v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.footerStyle" :class="col.footerClass"
|
||||||
|
:colspan="col.colspan" :rowspan="col.rowspan">
|
||||||
|
<ColumnSlot :column="col" type="footer" v-if="col.$scopedSlots.footer" />
|
||||||
|
{{col.footer}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<template v-else>
|
||||||
|
<tr v-for="(row,i) of footerColumnGroup.rows" :key="i">
|
||||||
|
<td v-for="(col,i) of row.columns" :key="col.columnKey||col.field||i" :style="col.footerStyle" :class="col.footerClass"
|
||||||
|
:colspan="col.colspan" :rowspan="col.rowspan">
|
||||||
|
<ColumnSlot :column="col" type="footer" v-if="col.$scopedSlots.footer" />
|
||||||
|
{{col.footer}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
<DTPaginator v-if="paginatorBottom" :rows="d_rows" :first="d_first" :totalRecords="totalRecordsLength" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions"
|
<DTPaginator v-if="paginatorBottom" :rows="d_rows" :first="d_first" :totalRecords="totalRecordsLength" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions"
|
||||||
:currentPageReportTemplate="currentPageReportTemplate" class="p-paginator-bottom" @page="onPage($event)" :alwaysShow="alwaysShowPaginator">
|
:currentPageReportTemplate="currentPageReportTemplate" class="p-paginator-bottom" @page="onPage($event)" :alwaysShow="alwaysShowPaginator">
|
||||||
|
@ -952,6 +975,28 @@ export default {
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
},
|
},
|
||||||
|
headerColumnGroup() {
|
||||||
|
if (this.allChildren) {
|
||||||
|
for (let child of this.allChildren) {
|
||||||
|
if (child.$vnode.tag.indexOf('columngroup') !== -1 && child.type === 'header') {
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
footerColumnGroup() {
|
||||||
|
if (this.allChildren) {
|
||||||
|
for (let child of this.allChildren) {
|
||||||
|
if (child.$vnode.tag.indexOf('columngroup') !== -1 && child.type === 'footer') {
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
processedData() {
|
processedData() {
|
||||||
if (this.lazy) {
|
if (this.lazy) {
|
||||||
return this.value;
|
return this.value;
|
||||||
|
@ -1014,12 +1059,17 @@ export default {
|
||||||
hasFooter() {
|
hasFooter() {
|
||||||
let hasFooter = false;
|
let hasFooter = false;
|
||||||
|
|
||||||
|
if (this.footerColumnGroup) {
|
||||||
|
hasFooter = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
for (let col of this.columns) {
|
for (let col of this.columns) {
|
||||||
if (col.footer || col.$scopedSlots.footer) {
|
if (col.footer || col.$scopedSlots.footer) {
|
||||||
hasFooter = true;
|
hasFooter = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return hasFooter;
|
return hasFooter;
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
columns: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.columns = this.$children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -12,6 +12,7 @@ import Chart from './components/chart/Chart';
|
||||||
import Checkbox from './components/checkbox/Checkbox';
|
import Checkbox from './components/checkbox/Checkbox';
|
||||||
import Chips from './components/chips/Chips';
|
import Chips from './components/chips/Chips';
|
||||||
import Column from './components/column/Column';
|
import Column from './components/column/Column';
|
||||||
|
import ColumnGroup from './components/columngroup/ColumnGroup';
|
||||||
import DataTable from './components/datatable/DataTable';
|
import DataTable from './components/datatable/DataTable';
|
||||||
import DataView from './components/dataview/DataView';
|
import DataView from './components/dataview/DataView';
|
||||||
import DataViewLayoutOptions from './components/dataviewlayoutoptions/DataViewLayoutOptions';
|
import DataViewLayoutOptions from './components/dataviewlayoutoptions/DataViewLayoutOptions';
|
||||||
|
@ -40,6 +41,7 @@ import ProgressBar from './components/progressbar/ProgressBar';
|
||||||
import ProgressSpinner from './components/progressspinner/ProgressSpinner';
|
import ProgressSpinner from './components/progressspinner/ProgressSpinner';
|
||||||
import Rating from './components/rating/Rating';
|
import Rating from './components/rating/Rating';
|
||||||
import RadioButton from './components/radiobutton/RadioButton';
|
import RadioButton from './components/radiobutton/RadioButton';
|
||||||
|
import Row from './components/row/Row';
|
||||||
import SelectButton from './components/selectbutton/SelectButton';
|
import SelectButton from './components/selectbutton/SelectButton';
|
||||||
import Slider from './components/slider/Slider';
|
import Slider from './components/slider/Slider';
|
||||||
import Sidebar from './components/sidebar/Sidebar';
|
import Sidebar from './components/sidebar/Sidebar';
|
||||||
|
@ -93,6 +95,7 @@ Vue.component('Editor', Editor);
|
||||||
Vue.component('Fieldset', Fieldset);
|
Vue.component('Fieldset', Fieldset);
|
||||||
Vue.component('FileUpload', FileUpload);
|
Vue.component('FileUpload', FileUpload);
|
||||||
Vue.component('FullCalendar', FullCalendar);
|
Vue.component('FullCalendar', FullCalendar);
|
||||||
|
Vue.component('ColumnGroup', ColumnGroup);
|
||||||
Vue.component('Inplace', Inplace);
|
Vue.component('Inplace', Inplace);
|
||||||
Vue.component('InputSwitch', InputSwitch);
|
Vue.component('InputSwitch', InputSwitch);
|
||||||
Vue.component('InputText', InputText);
|
Vue.component('InputText', InputText);
|
||||||
|
@ -111,6 +114,7 @@ Vue.component('ProgressBar', ProgressBar);
|
||||||
Vue.component('ProgressSpinner', ProgressSpinner);
|
Vue.component('ProgressSpinner', ProgressSpinner);
|
||||||
Vue.component('RadioButton', RadioButton);
|
Vue.component('RadioButton', RadioButton);
|
||||||
Vue.component('Rating', Rating);
|
Vue.component('Rating', Rating);
|
||||||
|
Vue.component('Row', Row);
|
||||||
Vue.component('SelectButton', SelectButton);
|
Vue.component('SelectButton', SelectButton);
|
||||||
Vue.component('Slider', Slider);
|
Vue.component('Slider', Slider);
|
||||||
Vue.component('Sidebar', Sidebar);
|
Vue.component('Sidebar', Sidebar);
|
||||||
|
|
|
@ -156,6 +156,11 @@ export default new Router({
|
||||||
name: 'datatableexport',
|
name: 'datatableexport',
|
||||||
component: () => import('./views/datatable/DataTableExportDemo.vue')
|
component: () => import('./views/datatable/DataTableExportDemo.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/datatable/colgroup',
|
||||||
|
name: 'datatablecolgroup',
|
||||||
|
component: () => import('./views/datatable/DataTableColGroupDemo.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/datatable/colresize',
|
path: '/datatable/colresize',
|
||||||
name: 'datatablecolresize',
|
name: 'datatablecolresize',
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<DataTableSubMenu />
|
||||||
|
|
||||||
|
<div class="content-section introduction">
|
||||||
|
<div class="feature-intro">
|
||||||
|
<h1>DataTable - Column Group</h1>
|
||||||
|
<p>Columns can be grouped at header and footer using headerColumnGroup and footerColumnGroup components.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-section implementation">
|
||||||
|
<DataTable :value="sales">
|
||||||
|
<ColumnGroup type="header">
|
||||||
|
<Row>
|
||||||
|
<Column header="Brand" :rowspan="3" />
|
||||||
|
<Column header="Sale Rate" :colspan="4" />
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Column header="Sales" :colspan="2" />
|
||||||
|
<Column header="Profits" :colspan="2" />
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Column header="Last Year" />
|
||||||
|
<Column header="This Year" />
|
||||||
|
<Column header="Last Year" />
|
||||||
|
<Column header="This Year" />
|
||||||
|
</Row>
|
||||||
|
</ColumnGroup>
|
||||||
|
<Column field="brand" />
|
||||||
|
<Column field="lastYearSale" />
|
||||||
|
<Column field="thisYearSale" />
|
||||||
|
<Column field="lastYearProfit" />
|
||||||
|
<Column field="thisYearProfit" />
|
||||||
|
<ColumnGroup type="footer">
|
||||||
|
<Row>
|
||||||
|
<Column footer="Totals:" :colspan="3" />
|
||||||
|
<Column footer="$506,202" />
|
||||||
|
<Column footer="$531,020" />
|
||||||
|
</Row>
|
||||||
|
</ColumnGroup>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-section documentation">
|
||||||
|
<TabView>
|
||||||
|
<TabPanel header="Source">
|
||||||
|
<CodeHighlight>
|
||||||
|
<template v-pre>
|
||||||
|
<DataTable :value="sales">
|
||||||
|
<ColumnGroup type="header">
|
||||||
|
<Row>
|
||||||
|
<Column header="Brand" :rowspan="3" />
|
||||||
|
<Column header="Sale Rate" :colspan="4" />
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Column header="Sales" :colspan="2" />
|
||||||
|
<Column header="Profits" :colspan="2" />
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Column header="Last Year" />
|
||||||
|
<Column header="This Year" />
|
||||||
|
<Column header="Last Year" />
|
||||||
|
<Column header="This Year" />
|
||||||
|
</Row>
|
||||||
|
</ColumnGroup>
|
||||||
|
<Column field="brand" />
|
||||||
|
<Column field="lastYearSale" />
|
||||||
|
<Column field="thisYearSale" />
|
||||||
|
<Column field="lastYearProfit" />
|
||||||
|
<Column field="thisYearProfit" />
|
||||||
|
<ColumnGroup type="footer">
|
||||||
|
<Row>
|
||||||
|
<Column footer="Totals:" :colspan="3" />
|
||||||
|
<Column footer="$506,202" />
|
||||||
|
<Column footer="$531,020" />
|
||||||
|
</Row>
|
||||||
|
</ColumnGroup>
|
||||||
|
</DataTable>
|
||||||
|
</template>
|
||||||
|
</CodeHighlight>
|
||||||
|
|
||||||
|
<CodeHighlight lang="javascript">
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
sales: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
carService: null,
|
||||||
|
created() {
|
||||||
|
this.sales = [
|
||||||
|
{brand: 'Apple', lastYearSale: '51%', thisYearSale: '40%', lastYearProfit: '$54,406.00', thisYearProfit: '$43,342'},
|
||||||
|
{brand: 'Samsung', lastYearSale: '83%', thisYearSale: '96%', lastYearProfit: '$423,132', thisYearProfit: '$312,122'},
|
||||||
|
{brand: 'Microsoft', lastYearSale: '38%', thisYearSale: '5%', lastYearProfit: '$12,321', thisYearProfit: '$8,500'},
|
||||||
|
{brand: 'Philips', lastYearSale: '49%', thisYearSale: '22%', lastYearProfit: '$745,232', thisYearProfit: '$650,323,'},
|
||||||
|
{brand: 'Song', lastYearSale: '17%', thisYearSale: '79%', lastYearProfit: '$643,242', thisYearProfit: '500,332'},
|
||||||
|
{brand: 'LG', lastYearSale: '52%', thisYearSale: ' 65%', lastYearProfit: '$421,132', thisYearProfit: '$150,005'},
|
||||||
|
{brand: 'Sharp', lastYearSale: '82%', thisYearSale: '12%', lastYearProfit: '$131,211', thisYearProfit: '$100,214'},
|
||||||
|
{brand: 'Panasonic', lastYearSale: '44%', thisYearSale: '45%', lastYearProfit: '$66,442', thisYearProfit: '$53,322'},
|
||||||
|
{brand: 'HTC', lastYearSale: '90%', thisYearSale: '56%', lastYearProfit: '$765,442', thisYearProfit: '$296,232'},
|
||||||
|
{brand: 'Toshiba', lastYearSale: '75%', thisYearSale: '54%', lastYearProfit: '$21,212', thisYearProfit: '$12,533'}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</CodeHighlight>
|
||||||
|
</TabPanel>
|
||||||
|
</TabView>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import DataTableSubMenu from './DataTableSubMenu';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
sales: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
carService: null,
|
||||||
|
created() {
|
||||||
|
this.sales = [
|
||||||
|
{brand: 'Apple', lastYearSale: '51%', thisYearSale: '40%', lastYearProfit: '$54,406.00', thisYearProfit: '$43,342'},
|
||||||
|
{brand: 'Samsung', lastYearSale: '83%', thisYearSale: '96%', lastYearProfit: '$423,132', thisYearProfit: '$312,122'},
|
||||||
|
{brand: 'Microsoft', lastYearSale: '38%', thisYearSale: '5%', lastYearProfit: '$12,321', thisYearProfit: '$8,500'},
|
||||||
|
{brand: 'Philips', lastYearSale: '49%', thisYearSale: '22%', lastYearProfit: '$745,232', thisYearProfit: '$650,323,'},
|
||||||
|
{brand: 'Song', lastYearSale: '17%', thisYearSale: '79%', lastYearProfit: '$643,242', thisYearProfit: '500,332'},
|
||||||
|
{brand: 'LG', lastYearSale: '52%', thisYearSale: ' 65%', lastYearProfit: '$421,132', thisYearProfit: '$150,005'},
|
||||||
|
{brand: 'Sharp', lastYearSale: '82%', thisYearSale: '12%', lastYearProfit: '$131,211', thisYearProfit: '$100,214'},
|
||||||
|
{brand: 'Panasonic', lastYearSale: '44%', thisYearSale: '45%', lastYearProfit: '$66,442', thisYearProfit: '$53,322'},
|
||||||
|
{brand: 'HTC', lastYearSale: '90%', thisYearSale: '56%', lastYearProfit: '$765,442', thisYearProfit: '$296,232'},
|
||||||
|
{brand: 'Toshiba', lastYearSale: '75%', thisYearSale: '54%', lastYearProfit: '$21,212', thisYearProfit: '$12,533'}
|
||||||
|
];
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'DataTableSubMenu': DataTableSubMenu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -8,6 +8,7 @@
|
||||||
<li><router-link to="/datatable/filter">● Filter</router-link></li>
|
<li><router-link to="/datatable/filter">● Filter</router-link></li>
|
||||||
<li><router-link to="/datatable/selection">● Selection</router-link></li>
|
<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/lazy">● Lazy</router-link></li>
|
||||||
|
<li><router-link to="/datatable/colgroup">● ColGroup</router-link></li>
|
||||||
<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/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>
|
||||||
|
|
Loading…
Reference in New Issue