Angular Hierarchical Grid 列ピン固定
単一または複数の列を Angular UI グリッドの左端にピン固定できます。Ignite UI for Angular の列固定は、ユーザーが特定の列順序で列をロックすることを可能にし、Hierarchical Grid で水平スクロール時にロックされた列が常に表示されます。Material UI Grid には組み込みの列ピン固定 UI があり、Hierarchical Grid のツールバーで列の表示状態を変更できます。その他、カスタム UI を定義し、Column Pinning API を介して列のピン固定状態を変更できます。
Angular Hierarchical Grid 列ピン固定の例
import { NgModule } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { BrowserModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { AppComponent } from "./app.component";
import { IgxHierarchicalGridModule } from "igniteui-angular";
import { HGridToolbarPinningComponent } from "./hierarchical-grid/hierarchical-grid-column-pinning/hierarchical-grid-toolbar-pinning.component";
import { IgxPreventDocumentScrollModule } from "./directives/prevent-scroll.directive";
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
HGridToolbarPinningComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxPreventDocumentScrollModule,
IgxHierarchicalGridModule
],
providers: [],
entryComponents: [],
schemas: []
})
export class AppModule {}
ts
import { Component } from '@angular/core';
import { CUSTOMERS } from '../../data/hierarchical-data';
@Component({
selector: 'app-hierarchical-grid-toolbar-pinning',
styleUrls: ['./hierarchical-grid-toolbar-pinning.component.scss'],
templateUrl: 'hierarchical-grid-toolbar-pinning.component.html'
})
export class HGridToolbarPinningComponent {
public localdata;
constructor() {
this.localdata = CUSTOMERS;
}
}
ts
<div class="grid__wrapper">
<igx-hierarchical-grid [igxPreventDocumentScroll]="true" class="hierarchicalGrid" [data]="localdata" [autoGenerate]="false"
[height]="'480px'" [width]="'100%'" #hierarchicalGrid>
<igx-grid-toolbar>
<igx-grid-toolbar-actions>
<igx-grid-toolbar-pinning></igx-grid-toolbar-pinning>
</igx-grid-toolbar-actions>
</igx-grid-toolbar>
<igx-column field="CompanyName" header="Company Name" width="200px" [pinned]="true"></igx-column>
<igx-column field="ContactName" header="Contact Name" width="150px"></igx-column>
<igx-column field="ContactTitle" header="Contact Title" width="200px"></igx-column>
<igx-column field="Address" width="200px"></igx-column>
<igx-column field="City" width="150px"></igx-column>
<igx-column field="PostalCode" header="Postal Code" width="150px"></igx-column>
<igx-column field="Country" width="150px"></igx-column>
<igx-column field="Phone" width="150px"></igx-column>
<igx-column field="Fax" width="150px"></igx-column>
<igx-row-island [height]="null" [key]="'Orders'" [autoGenerate]="false">
<igx-column field="OrderDate" header="Order Date" [dataType]="'date'" width="150px"></igx-column>
<igx-column field="RequiredDate" header="Required Date" [dataType]="'date'" width="150px"></igx-column>
<igx-column field="ShippedDate" header="Shipped Date" [dataType]="'date'" width="150px"></igx-column>
<igx-column field="ShipVia" header="Ship Via" width="150px"></igx-column>
<igx-column field="Freight" width="150px"></igx-column>
<igx-column field="ShipName" header="Ship Name" width="200px" [pinned]="true"></igx-column>
<igx-column field="ShipAddress" header="Ship Address" width="150px"></igx-column>
<igx-column field="ShipCity" header="Ship City" width="150px"></igx-column>
<igx-column field="ShipPostalCode" header="Ship Postal Code" width="150px"></igx-column>
<igx-column field="ShipCountry" header="Ship Country" width="150px"></igx-column>
<igx-row-island [height]="null" [key]="'OrderDetails'" [autoGenerate]="false">
<igx-column field="UnitPrice" header="Unit Price" width="150px"></igx-column>
<igx-column field="Quantity" width="150px"></igx-column>
<igx-column field="Discount" width="150px"></igx-column>
</igx-row-island>
</igx-row-island>
</igx-hierarchical-grid>
</div>
html
:host ::ng-deep .title {
width: 100%;
}
.grid__wrapper {
margin: 0 auto;
padding: 16px;
}
scss
このサンプルが気に入りましたか? 完全な Ignite UI for Angularツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
列固定 API
列ピン固定は、igx-column
の pinned
入力によって制御されます。ピン固定列は常に Hierarchical Grid の左側に描画され、Hierarchical Grid 本体のピン固定されていない列の水平スクロールで固定されます。
<igx-hierarchical-grid class="hgrid" [data]="localdata" [autoGenerate]="false"
[height]="'600px'" [width]="'800px'" #hierarchicalGrid>
<igx-column [field]="Artist" [width]="200px" [pinned]="true"></igx-column>
<igx-column [field]="Debut" [width]="200px"></igx-column>
</igx-hierarchical-grid>
html
IgxHierarchicalGridComponent
の Hierarchical Grid の pinColumn
または unpinColumn
メソッドを使用してフィールド名によって列をピン固定またはピン固定解除できます。
this.hierarchicalGrid.pinColumn('Artist');
this.hierarchicalGrid.unpinColumn('Debut');
typescript
両方のメソッドは操作に成功したかどうかを示すブール値を返します。よくある失敗の原因として列がすでにそのステートになっていることがあります。
列をピン固定すると、一番右に配置されたピン固定列の右にピン固定されます。ピン固定列の順序を変更するには、columnPin
イベントでイベント引数の insertAtIndex
プロパティを適切な位置インデックスに変更します。
<igx-hierarchical-grid class="hgrid" [data]="localdata" [autoGenerate]="false"
[height]="'600px'" [width]="'800px'"
(columnPin)="columnPinning($event)" #hierarchicalGrid>
</igx-hierarchical-grid>
html
public columnPinning(event) {
if (event.column.field === 'Artist') {
event.insertAtIndex = 0;
}
}
typescript
ピン固定の位置
pinning
設定オプションを使用して、列のピン固定の位置を変更できます。列の位置を Start または End のいずれかに設定できます。End に設定すると、列がピン固定されていない列の後に、グリッドの最後にレンダリングされます。
ピン固定されていない列は水平にスクロールできますが、ピン固定された列は右側に固定されます。
<igx-hierarchical-grid #grid1 [data]="data" [autoGenerate]="true" [pinning]="pinningConfig"></igx-hierarchical-grid>
html
public pinningConfig: IPinningConfig = { columns: ColumnPinningPosition.End };
typescript
デモ
import { NgModule } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { BrowserModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { AppComponent } from "./app.component";
import { HierarchicalGridRightPinningSampleComponent } from "./hierarchical-grid/hierarchical-grid-sample-right-pinning/hierarchical-grid-right-pinning.component";
import {
IgxHierarchicalGridModule,
IgxAvatarModule,
IgxTooltipModule
} from "igniteui-angular";
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
HierarchicalGridRightPinningSampleComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxHierarchicalGridModule,
IgxAvatarModule,
IgxTooltipModule
],
providers: [],
entryComponents: [],
schemas: []
})
export class AppModule {}
ts
import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import {
ColumnPinningPosition,
IgxColumnComponent,
IgxHierarchicalGridComponent,
IPinningConfig
} from 'igniteui-angular';
import { employeesData } from '../../data/employeesData';
import { athletesData } from '../../data/athletesData';
@Component({
encapsulation: ViewEncapsulation.None,
providers: [],
selector: 'hierarchical-grid-sample',
styleUrls: ['hierarchical-grid-right-pinning.component.scss'],
templateUrl: 'hierarchical-grid-right-pinning.component.html'
})
export class HierarchicalGridRightPinningSampleComponent implements OnInit {
@ViewChild('grid1', { static: true })
public grid1: IgxHierarchicalGridComponent;
public data: any[];
public employeesData: any[];
public columns: any[];
public pinningConfig: IPinningConfig = { columns: ColumnPinningPosition.End };
private _columnsPinned = true;
public ngOnInit(): void {
this.data = athletesData;
this.employeesData = employeesData;
let i = 0;
this.data.forEach((x) => {
x.FirstPlaces = Math.floor(Math.random() * Math.floor(3));
x.SecondPlaces = Math.floor(Math.random() * Math.floor(4));
x.ThirdPlaces = Math.floor(Math.random() * Math.floor(5));
x.RegistrationDate = this.generateReadableDate(x.Registered);
x.Birthday = this.generateReadableDate(this.employeesData[i].birthday);
x.Sponsor = this.employeesData[i].company;
x.AgentData = [this.employeesData[i]];
i++;
});
}
public toggleColumn(col: IgxColumnComponent): void {
col.pinned ? col.unpin() : col.pin();
}
public get columnsPinned(): boolean {
return this._columnsPinned;
}
public set columnsPinned(pinned) {
this._columnsPinned = !this._columnsPinned;
}
private generateReadableDate(timestamp: string): Date {
let dateObj = new Date(timestamp);
if (isNaN(dateObj.getTime())) {
dateObj = new Date(timestamp.split(' ')[0]);
}
return dateObj;
}
}
ts
<div class="grid__wrapper">
<igx-hierarchical-grid #grid1 [data]="data" [width]="'100%'" [height]="'480px'" [pinning]="pinningConfig" [autoGenerate]="false">
<igx-grid-toolbar>
<igx-grid-toolbar-actions>
<igx-grid-toolbar-pinning></igx-grid-toolbar-pinning>
</igx-grid-toolbar-actions>
</igx-grid-toolbar>
<igx-column field="CountryName" header="Team" width="88">
<ng-template igxCell let-cell="cell">
<div class="cell__inner country-cell">
<img [src]="cell.row.data.CountryFlag" class="country-flag" #target="tooltipTarget" [igxTooltipTarget]="tooltipRef">
<div #tooltipRef="tooltip" igxTooltip>
{{ cell.row.data.CountryName }}
</div>
</div>
</ng-template>
</igx-column>
<igx-column field="Avatar" header="Photo" dataType="string" width="80" [disablePinning]="true">
<ng-template igxCell let-cell="cell">
<div class="cell__inner avatar-cell">
<igx-avatar [src]="cell.row.data.Avatar" [roundShape]="true" size="small"></igx-avatar>
</div>
</ng-template>
</igx-column>
<igx-column field="Name" header="Name" [disablePinning]="true"></igx-column>
<igx-column field="AthleteNumber" header="Number"></igx-column>
<igx-column field="BeatsPerMinute" header="BPM"></igx-column>
<igx-column field="TopSpeed" header="Top Speed"></igx-column>
<igx-column field="TrackProgress" header="Track Progress" [disablePinning]="true"></igx-column>
<igx-column field="RegistrationDate" header="Date of Registration" width="170" [disablePinning]="true">
<ng-template igxCell let-cell>
{{ cell | date:'longDate' }}
</ng-template>
</igx-column>
<igx-column field="Birthday" header="Birthday" width="170" [disablePinning]="true">
<ng-template igxCell let-cell>
{{ cell | date:'longDate' }}
</ng-template>
</igx-column>
<igx-column field="Sponsor" header="Sponsor Company" width="160"></igx-column>
<igx-column #goldColumn field="FirstPlaces" header="Gold" width="110" [pinned]="true">
<ng-template igxHeader>
<div class="title-inner">
<span style="float:left">{{ goldColumn.header }}</span>
<igx-icon [style.color]="'#d2c206'">emoji_events</igx-icon>
</div>
</ng-template>
</igx-column>
<igx-column #silverColumn field="SecondPlaces" header="Silver" width="110" [pinned]="true">
<ng-template igxHeader>
<div class="title-inner">
<span style="float:left">{{ silverColumn.header }}</span>
<igx-icon [style.color]="'#c5c5c5'">emoji_events</igx-icon>
</div>
</ng-template>
</igx-column>
<igx-column #bronzeColumn field="ThirdPlaces" header="Bronze" width="110" [pinned]="true">
<ng-template igxHeader>
<div class="title-inner">
<span style="float:left">{{ bronzeColumn.header }}</span>
<igx-icon [style.color]="'#bb8b1d'">emoji_events</igx-icon>
</div>
</ng-template>
</igx-column>
<igx-row-island [height]="null" [key]="'AgentData'" [autoGenerate]="false" [pinning]="pinningConfig">
<igx-column field="avatar" header="Agent's Photo" width="80">
<ng-template igxCell let-cell="cell">
<div class="cell__inner avatar-cell">
<igx-avatar [src]="cell.row.data.avatar" [roundShape]="true" size="small"></igx-avatar>
</div>
</ng-template>
</igx-column>
<igx-column field="name" header="Agent"></igx-column>
<igx-column field="company" header="Associated Company" width="160"></igx-column>
<igx-column field="email" header="Work E-mail" width="250"></igx-column>
<igx-column field="work_phone" header="Work Phone" width="160"></igx-column>
<igx-column field="street" header="Street" width="200" [pinned]="true"></igx-column>
<igx-column field="city" header="City" [pinned]="true"></igx-column>
<igx-column field="post_code" header="Post Code"></igx-column>
<igx-column field="state" header="State"></igx-column>
<igx-column field="country" header="Country" [pinned]="true"></igx-column>
<igx-column field="refferred_by" header="Reffered by"></igx-column>
</igx-row-island>
</igx-hierarchical-grid>
</div>
html
.title-inner {
display: flex;
justify-content: space-between;
align-items: center;
}
.grid__wrapper {
margin: 0 auto;
padding: 16px;
}
img.country-flag {
width: 35px;
height: 20px;
}
scss
カスタム列ピン固定 UI
カスタム UI を定義し、関連する API を介して列のピン状態を変更できます。
ツールバーの代わりに、エンドユーザーが特定の列のピンの状態を変更するためにクリックできる列ヘッダーにピンアイコンを定義するとします。
これは、カスタムアイコンを使用して列のヘッダーテンプレートを作成することで実行できます。
<ng-template igxHeader let-column #pinTemplate>
<div class="title-inner">
<span style="float:left">{{column.header || column.field}}</span>
<igx-icon class="pin-icon" [class.pinned]="column.pinned" [class.unpinned]="!column.pinned" fontSet="fas" name="fa-thumbtack"
(click)="toggleColumn(column)"></igx-icon>
</div>
</ng-template>
<igx-hierarchical-grid class="hierarchicalGrid" [data]="localdata" [autoGenerate]="false"
[height]="'500px'" [width]="'100%'" #hierarchicalGrid>
<igx-column field="CompanyName" header="Company Name" [headerTemplate]="pinTemplate" width="200px" [pinned]="true"></igx-column>
<igx-column field="ContactName" header="Contact Name" [headerTemplate]="pinTemplate" width="150px"></igx-column>
<igx-column field="ContactTitle" header="Contact Title" [headerTemplate]="pinTemplate" width="200px"></igx-column>
<igx-row-island [key]="'Orders'" [autoGenerate]="false">
<igx-column field="OrderDate" header="Order Date" [headerTemplate]="pinTemplate" [dataType]="'date'" width="150px"></igx-column>
<igx-column field="RequiredDate" header="Required Date" [headerTemplate]="pinTemplate" [dataType]="'date'" width="150px"></igx-column>
<igx-column field="ShippedDate" header="Shipped Date" [headerTemplate]="pinTemplate" [dataType]="'date'" width="150px"></igx-column>
<igx-column field="ShipVia" header="Ship Via" [headerTemplate]="pinTemplate" width="150px"></igx-column>
<igx-row-island [key]="'OrderDetails'" [autoGenerate]="false">
<igx-column field="UnitPrice" header="Unit Price" width="150px"></igx-column>
<igx-column field="Quantity" width="150px"></igx-column>
<igx-column field="Discount" width="150px"></igx-column>
</igx-row-island>
</igx-row-island>
</igx-hierarchical-grid>
html
カスタムアイコンをクリックすると、関連する列のピン状態は、列の API メソッドを使用して変更できます。
public toggleColumn(col: ColumnType) {
col.pinned ? col.unpin() : col.pin();
}
typescript
デモ
import { NgModule } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { BrowserModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { AppComponent } from "./app.component";
import { IgxHierarchicalGridModule } from "igniteui-angular";
import { HGridPinningSampleComponent } from "./hierarchical-grid/hierarchical-grid-column-pinning/hierarchical-grid-pinning.component";
import { IgxPreventDocumentScrollModule } from "./directives/prevent-scroll.directive";
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
HGridPinningSampleComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxPreventDocumentScrollModule,
IgxHierarchicalGridModule
],
providers: [],
entryComponents: [],
schemas: []
})
export class AppModule {}
ts
import { AfterViewInit, ChangeDetectorRef, Component } from '@angular/core';
import { ColumnType, IgxIconService } from 'igniteui-angular';
import { CUSTOMERS } from '../../data/hierarchical-data';
import { icons } from "../../services/svgIcons";
const FILTERING_ICONS_FONT_SET = 'filtering-icons';
@Component({
selector: 'app-hierarchical-grid-pinning',
styleUrls: ['./hierarchical-grid-pinning.component.scss'],
templateUrl: 'hierarchical-grid-pinning.component.html'
})
export class HGridPinningSampleComponent implements AfterViewInit {
public localdata;
constructor(private cdr: ChangeDetectorRef, private iconService: IgxIconService) {
this.localdata = CUSTOMERS;
}
public ngAfterViewInit() {
const pinnedIcons = icons.filter(icon => icon.name === "pin" || icon.name === "unpin");
pinnedIcons.forEach(icon => {
if (!this.iconService.isSvgIconCached(icon.name, FILTERING_ICONS_FONT_SET)) {
this.iconService.addSvgIconFromText(icon.name, icon.value, FILTERING_ICONS_FONT_SET);
}
});
}
public toggleColumn(column: ColumnType) {
column.pinned ? column.unpin() : column.pin();
this.cdr.detectChanges();
}
}
ts
<div class="grid__wrapper">
<ng-template igxHeader let-column #pinTemplate>
<div class="title-inner">
<span class="header-text">{{column.header || column.field}}</span>
<igx-icon class="pin-icon" [class.pinned]="column.pinned" [class.unpinned]="!column.pinned"
family="filtering-icons" name="{{column.pinned ? 'unpin' : 'pin'}}" (click)="toggleColumn(column)">
</igx-icon>
</div>
</ng-template>
<igx-hierarchical-grid [igxPreventDocumentScroll]="true" class="hierarchicalGrid" [data]="localdata" [autoGenerate]="false"
[height]="'480px'" [width]="'100%'" #hierarchicalGrid>
<igx-column field="CompanyName" header="Company Name" [headerTemplate]="pinTemplate" width="200px" [pinned]="true"></igx-column>
<igx-column field="ContactName" header="Contact Name" [headerTemplate]="pinTemplate" width="150px"></igx-column>
<igx-column field="ContactTitle" header="Contact Title" [headerTemplate]="pinTemplate" width="200px"></igx-column>
<igx-column field="Address" [headerTemplate]="pinTemplate" width="200px"></igx-column>
<igx-column field="City" [headerTemplate]="pinTemplate" width="150px"></igx-column>
<igx-column field="PostalCode" header="Postal Code" [headerTemplate]="pinTemplate" width="150px"></igx-column>
<igx-column field="Country" [headerTemplate]="pinTemplate" width="150px"></igx-column>
<igx-column field="Phone" [headerTemplate]="pinTemplate" width="150px"></igx-column>
<igx-column field="Fax" [headerTemplate]="pinTemplate" width="150px"></igx-column>
<igx-row-island [height]="null" [key]="'Orders'" [autoGenerate]="false">
<igx-column field="OrderDate" header="Order Date" [headerTemplate]="pinTemplate" [dataType]="'date'" width="150px"></igx-column>
<igx-column field="RequiredDate" header="Required Date" [headerTemplate]="pinTemplate" [dataType]="'date'" width="150px"></igx-column>
<igx-column field="ShippedDate" header="Shipped Date" [headerTemplate]="pinTemplate" [dataType]="'date'" width="150px"></igx-column>
<igx-column field="ShipVia" header="Ship Via" [headerTemplate]="pinTemplate" width="150px"></igx-column>
<igx-column field="Freight" [headerTemplate]="pinTemplate" width="150px"></igx-column>
<igx-column field="ShipName" header="Ship Name" [headerTemplate]="pinTemplate" width="200px" [pinned]="true"></igx-column>
<igx-column field="ShipAddress" header="Ship Address" [headerTemplate]="pinTemplate" width="150px"></igx-column>
<igx-column field="ShipCity" header="Ship City" [headerTemplate]="pinTemplate" width="150px"></igx-column>
<igx-column field="ShipPostalCode" header="Ship Postal Code" [headerTemplate]="pinTemplate" width="150px"></igx-column>
<igx-column field="ShipCountry" header="Ship Country" [headerTemplate]="pinTemplate" width="150px"></igx-column>
<igx-row-island [height]="null" [key]="'OrderDetails'" [autoGenerate]="false">
<igx-column field="UnitPrice" header="Unit Price" width="150px"></igx-column>
<igx-column field="Quantity" width="150px"></igx-column>
<igx-column field="Discount" width="150px"></igx-column>
</igx-row-island>
</igx-row-island>
</igx-hierarchical-grid>
</div>
html
.grid__wrapper {
margin: 0 auto;
padding: 16px;
}
.title-inner {
display: flex;
justify-content: space-between;
align-items: center;
}
.header-text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.pin-icon {
margin-left: 8px;
cursor: pointer;
display: flex;
align-items: center;
}
.pinned {
color: #444;
&:hover {
color: #999;
}
}
.unpinned {
color: #999;
&:hover {
color: #444;
}
}
scss

ピン固定の制限
- 列幅をパーセンテージ (%) で設定した場合にピン固定列があると Hierarchical Grid 本体およびヘッダー コンテンツが正しく配置されません。列のピン固定を正しく設定するには、列幅をピクセル (px) に設定するか、Hierarchical Grid によって自動的に割り当てる必要があります。
API リファレンス
その他のリソース
コミュニティに参加して新しいアイデアをご提案ください。