Skip to content

Commit

Permalink
Fixed #1100
Browse files Browse the repository at this point in the history
  • Loading branch information
Çağatay Çivici committed Oct 21, 2016
1 parent 614bfae commit 867fce3
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 139 deletions.
32 changes: 30 additions & 2 deletions components/common/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,34 @@ export class Column implements AfterContentInit{
}
}

@Component({
selector: 'p-row',
template: ``
})
export class Row {

@ContentChildren(Column) columns: QueryList<Column>;

}

@Component({
selector: 'p-headerColumnGroup',
template: ``
})
export class HeaderColumnGroup {

@ContentChildren(Row) rows: QueryList<any>;
}

@Component({
selector: 'p-footerColumnGroup',
template: ``
})
export class FooterColumnGroup {

@ContentChildren(Row) rows: QueryList<any>;
}

@Component({
selector: 'p-columnBodyTemplateLoader',
template: ``
Expand Down Expand Up @@ -170,7 +198,7 @@ export class TemplateLoader {

@NgModule({
imports: [CommonModule],
exports: [Header,Footer,Column,TemplateWrapper,ColumnHeaderTemplateLoader,ColumnBodyTemplateLoader,ColumnFooterTemplateLoader,PrimeTemplate,TemplateLoader],
declarations: [Header,Footer,Column,TemplateWrapper,ColumnHeaderTemplateLoader,ColumnBodyTemplateLoader,ColumnFooterTemplateLoader,PrimeTemplate,TemplateLoader]
exports: [Header,Footer,Column,TemplateWrapper,ColumnHeaderTemplateLoader,ColumnBodyTemplateLoader,ColumnFooterTemplateLoader,PrimeTemplate,TemplateLoader,Row,HeaderColumnGroup,FooterColumnGroup],
declarations: [Header,Footer,Column,TemplateWrapper,ColumnHeaderTemplateLoader,ColumnBodyTemplateLoader,ColumnFooterTemplateLoader,PrimeTemplate,TemplateLoader,Row,HeaderColumnGroup,FooterColumnGroup]
})
export class SharedModule { }
64 changes: 38 additions & 26 deletions components/datatable/datatable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {FormsModule} from '@angular/forms'
import {SharedModule} from '../common/shared';
import {PaginatorModule} from '../paginator/paginator';
import {InputTextModule} from '../inputtext/inputtext';
import {Column,Header,Footer} from '../common/shared';
import {Column,Header,Footer,HeaderColumnGroup,FooterColumnGroup} from '../common/shared';
import {LazyLoadEvent,FilterMetadata,SortMeta} from '../common/api';
import {DomHandler} from '../dom/domhandler';
import {Subscription} from 'rxjs/Subscription';
Expand Down Expand Up @@ -100,7 +100,7 @@ export class RowExpansionLoader {
<div class="ui-datatable-tablewrapper" *ngIf="!scrollable">
<table>
<thead>
<tr *ngIf="!headerRows" class="ui-state-default">
<tr *ngIf="!headerColumnGroup" class="ui-state-default">
<th #headerCell *ngFor="let col of columns;let lastCol = last" [ngStyle]="col.style" [class]="col.styleClass" [style.display]="col.hidden ? 'none' : 'table-cell'"
(click)="sort($event,col)" (mouseenter)="hoveredHeader = $event.target" (mouseleave)="hoveredHeader = null"
[ngClass]="{'ui-state-default ui-unselectable-text':true, 'ui-state-hover': headerCell === hoveredHeader && col.sortable,'ui-state-focus': headerCell === focusedHeader && col.sortable,
Expand All @@ -118,34 +118,46 @@ export class RowExpansionLoader {
<p-dtCheckbox *ngIf="col.selectionMode=='multiple'" (onChange)="toggleRowsWithCheckbox($event)" [checked]="allSelected" [disabled]="isEmpty()"></p-dtCheckbox>
</th>
</tr>
<tr *ngFor="let headerRow of headerRows" class="ui-state-default">
<th #headerCell *ngFor="let col of headerRow.columns" [ngStyle]="col.style" [class]="col.styleClass" [attr.colspan]="col.colspan" [attr.rowspan]="col.rowspan"
(click)="sort($event,col)" (mouseenter)="hoveredHeader = $event.target" (mouseleave)="hoveredHeader = null" [style.display]="col.hidden ? 'none' : 'table-cell'"
[ngClass]="{'ui-state-default ui-unselectable-text':true, 'ui-state-hover': headerCell === hoveredHeader && col.sortable,
'ui-sortable-column': col.sortable,'ui-state-active': isSorted(col), 'ui-resizable-column': resizableColumns}"
[tabindex]="col.sortable ? tabindex : -1" (focus)="focusedHeader=$event.target" (blur)="focusedHeader=null" (keydown)="onHeaderKeydown($event,col)">
<span class="ui-column-resizer" *ngIf="resizableColumns && ((columnResizeMode == 'fit' && !lastCol) || columnResizeMode == 'expand')" (mousedown)="initColumnResize($event)"></span>
<span class="ui-column-title">{{col.header}}</span>
<span class="ui-sortable-column-icon fa fa-fw fa-sort" *ngIf="col.sortable"
[ngClass]="{'fa-sort-desc': (getSortOrder(col) == -1),'fa-sort-asc': (getSortOrder(col) == 1)}"></span>
<input type="text" pInputText class="ui-column-filter" *ngIf="col.filter" [value]="filters[col.field] ? filters[col.field].value : ''" (click)="onFilterInputClick($event)" (keyup)="onFilterKeyup($event.target.value, col.field, col.filterMatchMode)"/>
</th>
</tr>
<template [ngIf]="headerColumnGroup">
<tr *ngFor="let headerRow of headerColumnGroup.rows" class="ui-state-default">
<th #headerCell *ngFor="let col of headerRow.columns" [ngStyle]="col.style" [class]="col.styleClass" [attr.colspan]="col.colspan" [attr.rowspan]="col.rowspan"
(click)="sort($event,col)" (mouseenter)="hoveredHeader = $event.target" (mouseleave)="hoveredHeader = null" [style.display]="col.hidden ? 'none' : 'table-cell'"
[ngClass]="{'ui-state-default ui-unselectable-text':true, 'ui-state-hover': headerCell === hoveredHeader && col.sortable,
'ui-sortable-column': col.sortable,'ui-state-active': isSorted(col), 'ui-resizable-column': resizableColumns}"
[tabindex]="col.sortable ? tabindex : -1" (focus)="focusedHeader=$event.target" (blur)="focusedHeader=null" (keydown)="onHeaderKeydown($event,col)">
<span class="ui-column-resizer" *ngIf="resizableColumns && ((columnResizeMode == 'fit' && !lastCol) || columnResizeMode == 'expand')" (mousedown)="initColumnResize($event)"></span>
<span class="ui-column-title" *ngIf="!col.selectionMode&&!col.headerTemplate">{{col.header}}</span>
<span class="ui-column-title" *ngIf="col.headerTemplate">
<p-columnHeaderTemplateLoader [column]="col"></p-columnHeaderTemplateLoader>
</span>
<span class="ui-sortable-column-icon fa fa-fw fa-sort" *ngIf="col.sortable"
[ngClass]="{'fa-sort-desc': (getSortOrder(col) == -1),'fa-sort-asc': (getSortOrder(col) == 1)}"></span>
<input type="text" pInputText class="ui-column-filter" *ngIf="col.filter" [value]="filters[col.field] ? filters[col.field].value : ''" (click)="onFilterInputClick($event)" (keyup)="onFilterKeyup($event.target.value, col.field, col.filterMatchMode)"/>
</th>
</tr>
</template>
</thead>
<tfoot *ngIf="hasFooter()">
<tr *ngIf="!footerRows">
<tr *ngIf="!footerColumnGroup">
<th *ngFor="let col of columns" [ngStyle]="col.style" [class]="col.styleClass" [ngClass]="{'ui-state-default':true}" [style.display]="col.hidden ? 'none' : 'table-cell'">
<span class="ui-column-footer" *ngIf="!col.footerTemplate">{{col.footer}}</span>
<span class="ui-column-footer" *ngIf="col.footerTemplate">
<p-columnFooterTemplateLoader [column]="col"></p-columnFooterTemplateLoader>
</span>
</th>
</tr>
<tr *ngFor="let footerRow of footerRows">
<th *ngFor="let col of footerRow.columns" [ngStyle]="col.style" [class]="col.styleClass"
[attr.colspan]="col.colspan" [attr.rowspan]="col.rowspan" [style.display]="col.hidden ? 'none' : 'table-cell'"
[ngClass]="{'ui-state-default':true}">{{col.footer}}</th>
</tr>
<template [ngIf]="footerColumnGroup">
<tr *ngFor="let footerRow of footerColumnGroup.rows">
<th *ngFor="let col of footerRow.columns" [ngStyle]="col.style" [class]="col.styleClass"
[attr.colspan]="col.colspan" [attr.rowspan]="col.rowspan" [style.display]="col.hidden ? 'none' : 'table-cell'"
[ngClass]="{'ui-state-default':true}">
<span class="ui-column-footer" *ngIf="!col.footerTemplate">{{col.footer}}</span>
<span class="ui-column-footer" *ngIf="col.footerTemplate">
<p-columnFooterTemplateLoader [column]="col"></p-columnFooterTemplateLoader>
</span>
</th>
</tr>
</template>
</tfoot>
<tbody class="ui-datatable-data ui-widget-content">
<template ngFor let-rowData [ngForOf]="dataToRender" let-even="even" let-odd="odd" let-rowIndex="index">
Expand Down Expand Up @@ -302,10 +314,6 @@ export class DataTable implements AfterViewChecked,AfterViewInit,AfterContentIni

@Input() scrollWidth: any;

@Input() headerRows: any;

@Input() footerRows: any;

@Input() style: any;

@Input() styleClass: string;
Expand Down Expand Up @@ -360,6 +368,10 @@ export class DataTable implements AfterViewChecked,AfterViewInit,AfterContentIni

@ContentChildren(Column) cols: QueryList<Column>;

@ContentChild(HeaderColumnGroup) headerColumnGroup: HeaderColumnGroup;

@ContentChild(FooterColumnGroup) footerColumnGroup: FooterColumnGroup;

protected dataToRender: any[];

protected first: number = 0;
Expand Down Expand Up @@ -1275,7 +1287,7 @@ export class DataTable implements AfterViewChecked,AfterViewInit,AfterContentIni
}

hasFooter() {
if(this.footerRows) {
if(this.footerColumnGroup) {
return true;
}
else {
Expand Down
66 changes: 33 additions & 33 deletions showcase/demo/datatable/datatabledemo.html
Original file line number Diff line number Diff line change
Expand Up @@ -295,43 +295,43 @@ <h3>Facets</h3>
<p>See the <a [routerLink]="['/datatablefacets']">live example.</a></p>

<h3>Grouping</h3>
<p>Columns can be grouped at header and footer using headerRows and footerRows properties that both define an array
of columns each having colspan and rowspan.</p>
<p>Columns can be grouped at header and footer using headerColumnGroup and footerColumnGroup components containing rows with
columns. Templating is also supported inside grouped columns.</p>
<pre>
<code class="language-markup" pCode>
&lt;p-dataTable [value]="cars" [headerRows]="headerRows"&gt;
&lt;p-column field="vin" header="Vin"&gt;&lt;/p-column&gt;
&lt;p-column field="year" header="Year"&gt;&lt;/p-column&gt;
&lt;p-column field="brand" header="Brand"&gt;&lt;/p-column&gt;
&lt;p-column field="color" header="Color"&gt;&lt;/p-column&gt;
&lt;p-dataTable [value]="sales"&gt;
&lt;p-headerColumnGroup&gt;
&lt;p-row&gt;
&lt;p-column header="Brand" rowspan="3"&gt;&lt;/p-column&gt;
&lt;p-column header="Sale Rate" colspan="4"&gt;&lt;/p-column&gt;
&lt;/p-row&gt;
&lt;p-row&gt;
&lt;p-column header="Sales" colspan="2"&gt;&lt;/p-column&gt;
&lt;p-column header="Profits" colspan="2"&gt;&lt;/p-column&gt;
&lt;/p-row&gt;
&lt;p-row&gt;
&lt;p-column header="Last Year"&gt;&lt;/p-column&gt;
&lt;p-column header="This Year"&gt;&lt;/p-column&gt;
&lt;p-column header="Last Year"&gt;&lt;/p-column&gt;
&lt;p-column header="This Year"&gt;&lt;/p-column&gt;
&lt;/p-row&gt;
&lt;/p-headerColumnGroup&gt;

&lt;p-column field="brand"&gt;&lt;/p-column&gt;
&lt;p-column field="lastYearSale"&gt;&lt;/p-column&gt;
&lt;p-column field="thisYearSale"&gt;&lt;/p-column&gt;
&lt;p-column field="lastYearProfit"&gt;&lt;/p-column&gt;
&lt;p-column field="thisYearProfit"&gt;&lt;/p-column&gt;

&lt;p-footerColumnGroup&gt;
&lt;p-row&gt;
&lt;p-column footer="Totals:" colspan="3"&gt;&lt;/p-column&gt;
&lt;p-column footer="$506,202"&gt;&lt;/p-column&gt;
&lt;p-column footer="$531,020"&gt;&lt;/p-column&gt;
&lt;/p-row&gt;
&lt;/p-footerColumnGroup&gt;
&lt;/p-dataTable&gt;
</code>
</pre>
<pre>
<code class="language-typescript" pCode>
this.headerRows = [
&#123;
columns: [
&#123;headerText: 'Brand', rowspan: 3&#125;,
&#123;headerText: 'Sale Rate', colspan: 4&#125;
]
&#125;,
&#123;
columns: [
&#123;headerText: 'Brand', colspan: 2&#125;,
&#123;headerText: 'Sale Rate', colspan: 2&#125;
]
&#125;,
&#123;
columns: [
&#123;headerText: 'Last Year'&#125;,
&#123;headerText: 'This Year'&#125;,
&#123;headerText: 'Last Year'&#125;,
&#123;headerText: 'This Year'&#125;
]
&#125;
];
</code>
</pre>
<p>See the <a [routerLink]="['/datatablegroup']">live example.</a></p>

Expand Down
91 changes: 52 additions & 39 deletions showcase/demo/datatable/datatablegroupdemo.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,37 @@
</div>

<div class="ContentSideSections Implementation">
<p-dataTable [value]="sales" [headerRows]="headerRows" [footerRows]="footerRows">
<p-dataTable [value]="sales">
<p-headerColumnGroup>
<p-row>
<p-column header="Brand" rowspan="3"></p-column>
<p-column header="Sale Rate" colspan="4"></p-column>
</p-row>
<p-row>
<p-column header="Sales" colspan="2"></p-column>
<p-column header="Profits" colspan="2"></p-column>
</p-row>
<p-row>
<p-column header="Last Year"></p-column>
<p-column header="This Year"></p-column>
<p-column header="Last Year"></p-column>
<p-column header="This Year"></p-column>
</p-row>
</p-headerColumnGroup>

<p-column field="brand"></p-column>
<p-column field="lastYearSale"></p-column>
<p-column field="thisYearSale"></p-column>
<p-column field="lastYearProfit"></p-column>
<p-column field="thisYearProfit"></p-column>

<p-footerColumnGroup>
<p-row>
<p-column footer="Totals:" colspan="3"></p-column>
<p-column footer="$506,202"></p-column>
<p-column footer="$531,020"></p-column>
</p-row>
</p-footerColumnGroup>
</p-dataTable>
</div>

Expand All @@ -27,10 +52,6 @@

sales: any[];

headerRows: any[];

footerRows: any[];

ngOnInit() &#123;
this.sales = [
&#123;brand: 'Apple', lastYearSale: '51%', thisYearSale: '40%', lastYearProfit: '$54,406.00', thisYearProfit: '$43,342'&#125;,
Expand All @@ -44,39 +65,6 @@
&#123;brand: 'HTC', lastYearSale: '90%', thisYearSale: '56%', lastYearProfit: '$765,442', thisYearProfit: '$296,232'&#125;,
&#123;brand: 'Toshiba', lastYearSale: '75%', thisYearSale: '54%', lastYearProfit: '$21,212', thisYearProfit: '$12,533'&#125;
];

this.headerRows = [
&#123;
columns: [
&#123;header: 'Brand', rowspan: 3&#125;,
&#123;header: 'Sale Rate', colspan: 4&#125;
]
&#125;,
&#123;
columns: [
&#123;header: 'Brand', colspan: 2&#125;,
&#123;header: 'Sale Rate', colspan: 2&#125;
]
&#125;,
&#123;
columns: [
&#123;header: 'Last Year'&#125;,
&#123;header: 'This Year'&#125;,
&#123;header: 'Last Year'&#125;,
&#123;header: 'This Year'&#125;
]
&#125;
];

this.footerRows = [
&#123;
columns: [
&#123;footer: 'Totals:', colspan: 3&#125;,
&#123;footer: '$506,202'&#125;,
&#123;footer: '$531,020'&#125;
]
&#125;
];
&#125;
&#125;
</code>
Expand All @@ -86,12 +74,37 @@
<p-tabPanel header="datatablegroupdemo.html">
<pre>
<code class="language-markup" pCode>
&lt;p-dataTable [value]="sales" [headerRows]="headerRows" [footerRows]="footerRows"&gt;
&lt;p-dataTable [value]="sales"&gt;
&lt;p-headerColumnGroup&gt;
&lt;p-row&gt;
&lt;p-column header="Brand" rowspan="3"&gt;&lt;/p-column&gt;
&lt;p-column header="Sale Rate" colspan="4"&gt;&lt;/p-column&gt;
&lt;/p-row&gt;
&lt;p-row&gt;
&lt;p-column header="Sales" colspan="2"&gt;&lt;/p-column&gt;
&lt;p-column header="Profits" colspan="2"&gt;&lt;/p-column&gt;
&lt;/p-row&gt;
&lt;p-row&gt;
&lt;p-column header="Last Year"&gt;&lt;/p-column&gt;
&lt;p-column header="This Year"&gt;&lt;/p-column&gt;
&lt;p-column header="Last Year"&gt;&lt;/p-column&gt;
&lt;p-column header="This Year"&gt;&lt;/p-column&gt;
&lt;/p-row&gt;
&lt;/p-headerColumnGroup&gt;

&lt;p-column field="brand"&gt;&lt;/p-column&gt;
&lt;p-column field="lastYearSale"&gt;&lt;/p-column&gt;
&lt;p-column field="thisYearSale"&gt;&lt;/p-column&gt;
&lt;p-column field="lastYearProfit"&gt;&lt;/p-column&gt;
&lt;p-column field="thisYearProfit"&gt;&lt;/p-column&gt;

&lt;p-footerColumnGroup&gt;
&lt;p-row&gt;
&lt;p-column footer="Totals:" colspan="3"&gt;&lt;/p-column&gt;
&lt;p-column footer="$506,202"&gt;&lt;/p-column&gt;
&lt;p-column footer="$531,020"&gt;&lt;/p-column&gt;
&lt;/p-row&gt;
&lt;/p-footerColumnGroup&gt;
&lt;/p-dataTable&gt;
</code>
</pre>
Expand Down
Loading

0 comments on commit 867fce3

Please sign in to comment.