React Grid 行のピン固定
React Grid の Ignite UI for React 行ピン固定機能を使用すると、1 つまたは複数の行をグリッドの上部または下部にピン固定できます。行ピン固定を使用すると、エンドユーザーは特定の順序で行をピン固定し、IgrGrid
を垂直にスクロールしても常に表示される特別な領域に行を複製できます。React Grid には組み込みの行ピン固定 UI が含まれており、Grid のコンテキストで IgrActionStrip
コンポーネントを初期化することで有効になります。その他、カスタム UI を定義し、行のピン固定 API を介して行のピン固定状態を変更できます。
React Grid 行ピン固定の例
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrPropertyEditorPanelModule } from "@infragistics/igniteui-react-layouts";
import { IgrGridModule } from "@infragistics/igniteui-react-grids";
import { IgrPropertyEditorPanel, IgrPropertyEditorPropertyDescription } from "@infragistics/igniteui-react-layouts";
import { IgrGrid, IgrPinningConfig, RowPinningPosition, IgrColumn, IgrActionStrip, IgrGridPinningActions } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, PropertyEditorPanelDescriptionModule, WebGridDescriptionModule } from "@infragistics/igniteui-react-core";
import CustomersDataLocal from './CustomersDataLocal.json';
import { IgrPropertyEditorPropertyDescriptionChangedEventArgs } from "@infragistics/igniteui-react-layouts";
import "@infragistics/igniteui-react-grids/grids/combined";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
import 'igniteui-webcomponents/themes/light/bootstrap.css';
const mods: any[] = [
IgrPropertyEditorPanelModule,
IgrGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private propertyEditorPanel1: IgrPropertyEditorPanel
private propertyEditorPanel1Ref(r: IgrPropertyEditorPanel) {
this.propertyEditorPanel1 = r;
this.setState({});
}
private rowPinningEditor: IgrPropertyEditorPropertyDescription
private grid: IgrGrid
private gridRef(r: IgrGrid) {
this.grid = r;
this.setState({});
}
private _pinningConfig1: IgrPinningConfig | null = null;
public get pinningConfig1(): IgrPinningConfig {
if (this._pinningConfig1 == null)
{
var pinningConfig1: IgrPinningConfig = {} as IgrPinningConfig;
pinningConfig1.rows = RowPinningPosition.Top;
this._pinningConfig1 = pinningConfig1;
}
return this._pinningConfig1;
}
private actionStrip: IgrActionStrip
constructor(props: any) {
super(props);
this.propertyEditorPanel1Ref = this.propertyEditorPanel1Ref.bind(this);
this.webGridSetRowPinning = this.webGridSetRowPinning.bind(this);
this.gridRef = this.gridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="options vertical">
<IgrPropertyEditorPanel
componentRenderer={this.renderer}
target={this.grid}
descriptionType="WebGrid"
isHorizontal="true"
isWrappingEnabled="false"
ref={this.propertyEditorPanel1Ref}>
<IgrPropertyEditorPropertyDescription
name="rowPinningEditor"
valueType="EnumValue"
label="Row Pinning toggle"
dropDownNames={["Top", "Bottom"]}
dropDownValues={["Top", "Bottom"]}
changed={this.webGridSetRowPinning}>
</IgrPropertyEditorPropertyDescription>
</IgrPropertyEditorPanel>
</div>
<div className="container fill">
<IgrGrid
autoGenerate={false}
ref={this.gridRef}
id="grid"
data={this.customersDataLocal}
pinning={this.pinningConfig1}
primaryKey="ID"
cellSelection="none"
rowEditable={true}>
<IgrColumn
field="Company"
header="Company"
width="300px">
</IgrColumn>
<IgrColumn
field="ContactName"
header="Name">
</IgrColumn>
<IgrColumn
field="ContactTitle"
header="Title">
</IgrColumn>
<IgrColumn
field="Address"
header="Address">
</IgrColumn>
<IgrColumn
field="City"
header="City">
</IgrColumn>
<IgrColumn
field="PostalCode"
header="Postal Code">
</IgrColumn>
<IgrColumn
field="Phone"
header="Phone">
</IgrColumn>
<IgrColumn
field="Fax"
header="Fax">
</IgrColumn>
<IgrActionStrip
name="actionStrip">
<IgrGridPinningActions
>
</IgrGridPinningActions>
</IgrActionStrip>
</IgrGrid>
</div>
</div>
);
}
private _customersDataLocal: any[] = CustomersDataLocal;
public get customersDataLocal(): any[] {
return this._customersDataLocal;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
PropertyEditorPanelDescriptionModule.register(context);
WebGridDescriptionModule.register(context);
}
return this._componentRenderer;
}
public webGridSetRowPinning(sender: any, args: IgrPropertyEditorPropertyDescriptionChangedEventArgs): void {
var item = sender as IgrPropertyEditorPropertyDescription;
var newVal = item.primitiveValue;
var grid = this.grid;
grid.pinning.rows = newVal === "Top" ? RowPinningPosition.Top : RowPinningPosition.Bottom;
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx
このサンプルが気に入りましたか? 完全な Ignite UI for Reactツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
行のピン固定 UI
組み込みの行ピン固定 UI は、IgrGridPinningActions
コンポーネントと IgrActionStrip
コンポーネントを追加することで有効になります。アクション ストリップは、行にカーソルを合わせると自動的に表示され、表示されている行の状態に基づいてピン固定またはピン固定解除ボタンのアイコンが表示されます。ピン固定された行のコピーをビューにスクロールする追加のアクションがピン固定された行ごとに表示されます。
<IgrGrid>
<IgrColumn field="Country" header="Country"> </IgrColumn>
<IgrActionStrip key="actionStrip">
<IgrGridPinningActions key="pinningActions"></IgrGridPinningActions>
<IgrGridEditingActions key="editingActions"></IgrGridEditingActions>
</IgrActionStrip>
</IgrGrid>
tsx
行のピン固定 API
行のピン固定は Row
の pinned
入力によって制御されます。デフォルトでピン固定行は IgrGrid
の上側に固定して描画され、IgrGrid
本体のピン固定されていない行は垂直スクロールされます。
gridRef.current.getRowByIndex(0).pinned = true;
tsx
IgrGrid
の pinRow
または unpinRow
メソッドを使用して ID によって行をピン固定またはピン固定解除できます。
gridRef.current.pinRow('ALFKI');
gridRef.current.unpinRow('ALFKI');
tsx
注: 行の ID は、グリッドの primaryKey
またはレコード インスタンス自体によって定義される主キー値です。両方のメソッドは操作に成功したかどうかを示すブール値を返します。よくある失敗の原因に行がすでにその状態になっていることがあります。
行は、最後にピンされた行の下にピン固定されます。ピン固定行の順序を変更するには、RowPinning
イベントでイベント引数の InsertAtIndex
プロパティを適切な位置インデックスに変更します。
function rowPinning(grid: IgrGridBaseDirective, event: IgrPinRowEventArgs ) {
event.detail.insertAtIndex = 0;
}
<IgrGrid autoGenerate="true" rowPinning={rowPinning}>
</IgrGrid>
tsx
ピン固定の位置
pinning
設定オプションを使用して、行のピン固定の位置を変更できます。ピン固定の位置を Top または Bottom のいずれかに設定できます。
Bottom に設定すると、行がピン固定されていない行の後に、グリッドの一番下にレンダリングされます。ピン固定されていない行は垂直にスクロールできますが、ピン固定された行は下側に固定されます。
<IgrGrid id="dataGrid" autoGenerate="true">
</IgrGrid>
var grid = document.getElementById("dataGrid") as IgrGrid;
grid.pinning = { rows: RowPinningPosition.Bottom };
tsx
カスタム行ピン固定 UI
カスタム UI を定義し、関連する API を介して行のピン状態を変更できます。
アイコン付きの追加の列による
アクション ストリップの代わりに、すべての行にピンのアイコンを表示し、エンドユーザーが特定の行のピン状態をクリックして変更できます。
カスタム アイコンを含むセル テンプレートの列を追加することで実行できます。
function cellPinCellTemplate(ctx: IgrCellTemplateContext) {
const index = ctx.dataContext.cell.row.index;
return (
<>
<span onPointerDown={(e: any) => toggleRowPin(index)}>📌</span>
</>
);
}
<IgrGrid primaryKey="ID" autoGenerate="false">
<IgrColumn width="70px" bodyTemplate={cellPinCellTemplate}>
</IgrColumn>
</IgrGrid>
tsx
カスタムアイコンをクリックすると、関連する行のピン状態は、行の API メソッドを使用して変更できます。
function toggleRowPin(index: number) {
const grid = grid1Ref.current;
grid.getRowByIndex(index).pinned = !grid.getRowByIndex(index).pinned;
}
tsx
デモ
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrPropertyEditorPanelModule } from "@infragistics/igniteui-react-layouts";
import { IgrGridModule } from "@infragistics/igniteui-react-grids";
import { IgrGrid, IgrColumn } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, PropertyEditorPanelDescriptionModule, WebGridDescriptionModule } from "@infragistics/igniteui-react-core";
import CustomersDataLocal from './CustomersDataLocal.json';
import { IgrCellTemplateContext } from "@infragistics/igniteui-react-grids";
import "@infragistics/igniteui-react-grids/grids/combined";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrPropertyEditorPanelModule,
IgrGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private grid: IgrGrid
private gridRef(r: IgrGrid) {
this.grid = r;
this.setState({});
}
private column1: IgrColumn
constructor(props: any) {
super(props);
this.gridRef = this.gridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="container fill">
<IgrGrid
ref={this.gridRef}
data={this.customersDataLocal}
primaryKey="ID"
cellSelection="none">
<IgrColumn
width="70px"
filterable={false}
pinned={true}
bodyTemplate={this.webGridRowPinCellTemplate}
name="column1">
</IgrColumn>
<IgrColumn
field="ID"
width="150px"
hidden={true}>
</IgrColumn>
<IgrColumn
field="Company"
header="Company"
width="350px">
</IgrColumn>
<IgrColumn
field="ContactName"
header="Name">
</IgrColumn>
<IgrColumn
field="ContactTitle"
header="Contact Tiasdsadtle">
</IgrColumn>
<IgrColumn
field="Address">
</IgrColumn>
<IgrColumn
field="City">
</IgrColumn>
<IgrColumn
field="PostalCode"
header="Postal Code">
</IgrColumn>
<IgrColumn
field="Phone">
</IgrColumn>
<IgrColumn
field="Fax">
</IgrColumn>
</IgrGrid>
</div>
</div>
);
}
private _customersDataLocal: any[] = CustomersDataLocal;
public get customersDataLocal(): any[] {
return this._customersDataLocal;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
PropertyEditorPanelDescriptionModule.register(context);
WebGridDescriptionModule.register(context);
}
return this._componentRenderer;
}
public webGridRowPinCellTemplate = (e: {dataContext: IgrCellTemplateContext}) => {
const index = e.dataContext.cell.row.index;
return (
<span onPointerDown={(e: any) => this.toggleRowPin(index)} style={{ cursor: 'pointer'}}>📌</span>
);
}
public toggleRowPin(index: number) {
let grid = this.grid;
grid.getRowByIndex(index).pinned = !grid.getRowByIndex(index).pinned;
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx
行ピン固定の制限
- データソースに存在するレコードのみをピン固定できます。
- 行のピン固定状態は Excel にエクスポートされません。グリッドは行のピン固定が適用されずにエクスポートされます。
- グリッドのスクロール可能領域におけるピン固定行のコピーは、ピン固定行が存在する状態で他のグリッド機能が動作するのに不可欠な役割を果たします。そのため、その生成を無効化または削除することはできません。
- 行選択 は 行 ID のみで動作するため、ピン固定行を選択するとそのコピーも選択されます (逆も同様)。さらに、ピン固定領域での範囲選択 (Shift + クリックにより) は、スクロール可能な領域で行を範囲選択する場合と同じように機能します。結果として、間にある行はピン固定されていなくてもすべて選択されます。API を 介して選択した行を取得すると、選択した各レコードの単一のインスタンスのみを返します。
スタイル設定
定義済みのテーマに加えて、利用可能な CSS プロパティのいくつかを設定することで、グリッドをさらにカスタマイズできます。
一部の色を変更したい場合は、最初にグリッドのクラスを設定する必要があります。
<IgrGrid className="grid"></IgrGrid>
tsx
次に、そのクラスに関連する CSS プロパティを設定します。
.grid {
--ig-grid-pinned-border-width: 5px;
--ig-grid-pinned-border-style: double;
--ig-grid-pinned-border-color: #FFCD0F;
--ig-grid-cell-active-border-color: #FFCD0F;
}
css
デモ
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrGridModule, IgrActionStripModule } from "@infragistics/igniteui-react-grids";
import { IgrGrid, IgrPinningConfig, RowPinningPosition, IgrColumn, IgrActionStrip, IgrGridPinningActions } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, WebGridDescriptionModule, WebActionStripDescriptionModule } from "@infragistics/igniteui-react-core";
import CustomersDataLocal from './CustomersDataLocal.json';
import "@infragistics/igniteui-react-grids/grids/combined";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrGridModule,
IgrActionStripModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private grid: IgrGrid
private gridRef(r: IgrGrid) {
this.grid = r;
this.setState({});
}
private _pinningConfig1: IgrPinningConfig | null = null;
public get pinningConfig1(): IgrPinningConfig {
if (this._pinningConfig1 == null)
{
var pinningConfig1: IgrPinningConfig = {} as IgrPinningConfig;
pinningConfig1.rows = RowPinningPosition.Top;
this._pinningConfig1 = pinningConfig1;
}
return this._pinningConfig1;
}
private company: IgrColumn
private contactName: IgrColumn
private contactTitle: IgrColumn
private address: IgrColumn
private city: IgrColumn
private postalCode: IgrColumn
private phone: IgrColumn
private fax: IgrColumn
constructor(props: any) {
super(props);
this.gridRef = this.gridRef.bind(this);
this.webGridPinRowOnRendered = this.webGridPinRowOnRendered.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="container fill">
<IgrGrid
autoGenerate={false}
ref={this.gridRef}
id="grid"
data={this.customersDataLocal}
primaryKey="ID"
cellSelection="none"
rendered={this.webGridPinRowOnRendered}
pinning={this.pinningConfig1}>
<IgrColumn
name="Company"
field="Company"
header="Company"
width="300px">
</IgrColumn>
<IgrColumn
name="ContactName"
field="ContactName"
header="Name">
</IgrColumn>
<IgrColumn
name="ContactTitle"
field="ContactTitle"
header="Title">
</IgrColumn>
<IgrColumn
name="Address"
field="Address"
header="Address">
</IgrColumn>
<IgrColumn
name="City"
field="City"
header="City">
</IgrColumn>
<IgrColumn
name="PostalCode"
field="PostalCode"
header="Postal Code">
</IgrColumn>
<IgrColumn
name="Phone"
field="Phone"
header="Phone">
</IgrColumn>
<IgrColumn
name="Fax"
field="Fax"
header="Fax">
</IgrColumn>
<IgrActionStrip
>
<IgrGridPinningActions
>
</IgrGridPinningActions>
</IgrActionStrip>
</IgrGrid>
</div>
</div>
);
}
private _customersDataLocal: any[] = CustomersDataLocal;
public get customersDataLocal(): any[] {
return this._customersDataLocal;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
WebGridDescriptionModule.register(context);
WebActionStripDescriptionModule.register(context);
}
return this._componentRenderer;
}
public webGridPinRowOnRendered(args: any): void {
var grid = this.grid as any;
grid.pinRow("ALFKI");
grid.pinRow("AROUT");
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx
#grid {
--ig-grid-pinned-border-width: 5px;
--ig-grid-pinned-border-style: double;
--ig-grid-pinned-border-color: #FFCD0F;
--ig-grid-cell-active-border-color: #FFCD0F;
}
css
API リファレンス
その他のリソース
コミュニティに参加して新しいアイデアをご提案ください。