Fixed #63 - ColumnGroups for DataTable

pull/104/head
cagataycivici 2019-10-16 06:50:25 +03:00
parent 13a1525829
commit c5d097bad6
8 changed files with 275 additions and 15 deletions

View File

@ -65,6 +65,14 @@ export default {
expander: {
type: Boolean,
default: false
},
colspan: {
type: Number,
default: null
},
rowspan: {
type: Number,
default: null
}
},
render() {

View File

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

View File

@ -22,8 +22,9 @@
</DTPaginator>
<table ref="table">
<thead class="p-datatable-thead">
<tr>
<th v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.headerStyle" :class="getColumnHeaderClass(col)" @click="onColumnHeaderClick($event, col)">
<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)"
:colspan="col.colspan" :rowspan="col.rowspan">
<span class="p-column-resizer p-clickable" @mousedown="onColumnResizeStart" v-if="resizableColumns"></span>
<ColumnSlot :column="col" type="header" v-if="col.$scopedSlots.header" />
<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'" />
</th>
</tr>
<template v-else>
<tr v-for="(row,i) of headerColumnGroup.rows" :key="i">
<th v-for="(col,i) of row.columns" :key="col.columnKey||col.field||i" :style="col.headerStyle" :class="getColumnHeaderClass(col)" @click="onColumnHeaderClick($event, col)"
:colspan="col.colspan" :rowspan="col.rowspan">
<ColumnSlot :column="col" type="header" v-if="col.$scopedSlots.header" />
<span class="p-column-title" v-if="col.header">{{col.header}}</span>
<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>
</template>
</thead>
<tfoot class="p-datatable-tfoot" v-if="hasFooter">
<tr>
<td v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.footerStyle" :class="col.footerClass">
<ColumnSlot :column="col" type="footer" v-if="col.$scopedSlots.footer" />
{{col.footer}}
</td>
</tr>
</tfoot>
<tbody class="p-datatable-tbody">
<template v-if="!empty">
<tr :class="getRowClass(rowData)" v-for="(rowData, index) of dataToRender" :key="getRowKey(rowData, index)"
@ -61,6 +66,24 @@
</td>
</tr>
</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>
<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">
@ -948,10 +971,32 @@ export default {
},
columns() {
if (this.allChildren) {
return this.allChildren.filter(child => child.$options._propKeys.indexOf('columnKey') !== -1);
return this.allChildren.filter(child => child.$options._propKeys.indexOf('columnKey') !== -1);
}
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() {
if (this.lazy) {
return this.value;
@ -1014,10 +1059,15 @@ export default {
hasFooter() {
let hasFooter = false;
for (let col of this.columns) {
if (col.footer || col.$scopedSlots.footer) {
hasFooter = true;
break;
if (this.footerColumnGroup) {
hasFooter = true;
}
else {
for (let col of this.columns) {
if (col.footer || col.$scopedSlots.footer) {
hasFooter = true;
break;
}
}
}

View File

@ -0,0 +1,21 @@
<template>
<div>
<slot></slot>
</div>
</template>
<script>
export default {
props: {
},
data() {
return {
columns: null
};
},
mounted() {
this.columns = this.$children;
}
}
</script>

View File

@ -12,6 +12,7 @@ import Chart from './components/chart/Chart';
import Checkbox from './components/checkbox/Checkbox';
import Chips from './components/chips/Chips';
import Column from './components/column/Column';
import ColumnGroup from './components/columngroup/ColumnGroup';
import DataTable from './components/datatable/DataTable';
import DataView from './components/dataview/DataView';
import DataViewLayoutOptions from './components/dataviewlayoutoptions/DataViewLayoutOptions';
@ -40,6 +41,7 @@ import ProgressBar from './components/progressbar/ProgressBar';
import ProgressSpinner from './components/progressspinner/ProgressSpinner';
import Rating from './components/rating/Rating';
import RadioButton from './components/radiobutton/RadioButton';
import Row from './components/row/Row';
import SelectButton from './components/selectbutton/SelectButton';
import Slider from './components/slider/Slider';
import Sidebar from './components/sidebar/Sidebar';
@ -93,6 +95,7 @@ Vue.component('Editor', Editor);
Vue.component('Fieldset', Fieldset);
Vue.component('FileUpload', FileUpload);
Vue.component('FullCalendar', FullCalendar);
Vue.component('ColumnGroup', ColumnGroup);
Vue.component('Inplace', Inplace);
Vue.component('InputSwitch', InputSwitch);
Vue.component('InputText', InputText);
@ -111,6 +114,7 @@ Vue.component('ProgressBar', ProgressBar);
Vue.component('ProgressSpinner', ProgressSpinner);
Vue.component('RadioButton', RadioButton);
Vue.component('Rating', Rating);
Vue.component('Row', Row);
Vue.component('SelectButton', SelectButton);
Vue.component('Slider', Slider);
Vue.component('Sidebar', Sidebar);

View File

@ -156,6 +156,11 @@ export default new Router({
name: 'datatableexport',
component: () => import('./views/datatable/DataTableExportDemo.vue')
},
{
path: '/datatable/colgroup',
name: 'datatablecolgroup',
component: () => import('./views/datatable/DataTableColGroupDemo.vue')
},
{
path: '/datatable/colresize',
name: 'datatablecolresize',

View File

@ -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>
&lt;DataTable :value="sales"&gt;
&lt;ColumnGroup type="header"&gt;
&lt;Row&gt;
&lt;Column header="Brand" :rowspan="3" /&gt;
&lt;Column header="Sale Rate" :colspan="4" /&gt;
&lt;/Row&gt;
&lt;Row&gt;
&lt;Column header="Sales" :colspan="2" /&gt;
&lt;Column header="Profits" :colspan="2" /&gt;
&lt;/Row&gt;
&lt;Row&gt;
&lt;Column header="Last Year" /&gt;
&lt;Column header="This Year" /&gt;
&lt;Column header="Last Year" /&gt;
&lt;Column header="This Year" /&gt;
&lt;/Row&gt;
&lt;/ColumnGroup&gt;
&lt;Column field="brand" /&gt;
&lt;Column field="lastYearSale" /&gt;
&lt;Column field="thisYearSale" /&gt;
&lt;Column field="lastYearProfit" /&gt;
&lt;Column field="thisYearProfit" /&gt;
&lt;ColumnGroup type="footer"&gt;
&lt;Row&gt;
&lt;Column footer="Totals:" :colspan="3" /&gt;
&lt;Column footer="$506,202" /&gt;
&lt;Column footer="$531,020" /&gt;
&lt;/Row&gt;
&lt;/ColumnGroup&gt;
&lt;/DataTable&gt;
</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>

View File

@ -8,6 +8,7 @@
<li><router-link to="/datatable/filter">&#9679; Filter</router-link></li>
<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/colgroup">&#9679; ColGroup</router-link></li>
<li><router-link to="/datatable/coltoggle">&#9679; ColToggle</router-link></li>
<li><router-link to="/datatable/responsive">&#9679; Responsive</router-link></li>
<li><router-link to="/datatable/export">&#9679; Export</router-link></li>