React 계층형 그리드 열 고정
React Hierarchical Grid의 Ignite UI for React Column Pinning 기능을 사용하면 개발자가 원하는 순서로 특정 열을 잠글 수 있으므로 사용자가 가로로 스크롤할 때도 항상 가시성을 보장할 수 있습니다 IgrGrid
. React Hierarchical Grid 도구 모음을 통해 액세스할 수 있는 Column Pinning을 위한 통합 UI가 있습니다. 또한 개발자는 열의 핀 상태를 변경하는 사용자 지정 사용자 인터페이스를 유연하게 구축할 수 있습니다.
React Hierarchical Grid Column Pinning Example
이 예제에서는 열 또는 여러 열을 왼쪽 IgrHierarchicalGrid
또는 오른쪽에 고정하는 방법을 보여 줍니다.
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrHierarchicalGridModule } from "@infragistics/igniteui-react-grids";
import { IgrHierarchicalGrid, IgrGridToolbar, IgrGridToolbarActions, IgrGridToolbarPinning, IgrColumn, IgrRowIsland } from "@infragistics/igniteui-react-grids";
import HierarchicalCustomersData from './HierarchicalCustomersData.json';
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrHierarchicalGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private grid: IgrHierarchicalGrid
private gridRef(r: IgrHierarchicalGrid) {
this.grid = r;
this.setState({});
}
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">
<IgrHierarchicalGrid
ref={this.gridRef}
id="grid"
data={this.hierarchicalCustomersData}
columnSelection="single"
primaryKey="CustomerID">
<IgrGridToolbar
>
<IgrGridToolbarActions
>
<IgrGridToolbarPinning
>
</IgrGridToolbarPinning>
</IgrGridToolbarActions>
</IgrGridToolbar>
<IgrColumn
field="CustomerID"
hidden={true}>
</IgrColumn>
<IgrColumn
field="Company"
header="Company Name"
pinned={true}>
</IgrColumn>
<IgrColumn
field="ContactName"
header="Contact Name">
</IgrColumn>
<IgrColumn
field="ContactTitle"
header="Contact Title">
</IgrColumn>
<IgrColumn
field="Address"
header="Address">
</IgrColumn>
<IgrColumn
field="City"
header="City">
</IgrColumn>
<IgrColumn
field="PostalCode"
header="Postal Code">
</IgrColumn>
<IgrColumn
field="Country"
header="Country">
</IgrColumn>
<IgrColumn
field="Phone">
</IgrColumn>
<IgrColumn
field="Fax">
</IgrColumn>
<IgrRowIsland
childDataKey="Orders"
autoGenerate={false}>
<IgrColumn
field="OrderDate"
header="Order Date"
dataType="date"
resizable={true}>
</IgrColumn>
<IgrColumn
field="RequiredDate"
header="Required Date"
dataType="date"
resizable={true}>
</IgrColumn>
<IgrColumn
field="ShippedDate"
header="Shipped Date"
dataType="date"
resizable={true}>
</IgrColumn>
<IgrColumn
field="ShipName"
header="Ship Name"
dataType="string"
resizable={true}
pinned={true}>
</IgrColumn>
<IgrColumn
field="ShippedVia"
header="Shipped Via"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Freight"
header="Freight"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrRowIsland
childDataKey="OrderDetails"
autoGenerate={false}>
<IgrColumn
field="UnitPrice"
header="Unit Price"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Quantity"
header="Quantity"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Discount"
header="Discount"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Weight"
header="Weight"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Length"
header="Length"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="TotalPrice"
header="Total Price"
dataType="string"
resizable={true}>
</IgrColumn>
</IgrRowIsland>
</IgrRowIsland>
</IgrHierarchicalGrid>
</div>
</div>
);
}
private _hierarchicalCustomersData: any[] = HierarchicalCustomersData;
public get hierarchicalCustomersData(): any[] {
return this._hierarchicalCustomersData;
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
css
Like this sample? Get access to our complete Ignite UI for React toolkit and start building your own apps in minutes. Download it for free.
Column Pinning API
열 고정은 의 IgrColumn
속성을 통해 pinned
제어됩니다. 고정된 열은 기본적으로 의 IgrHierarchicalGrid
왼쪽에 렌더링되며 본문에서 IgrHierarchicalGrid
고정되지 않은 열의 가로 스크롤을 통해 고정된 상태로 유지됩니다.
의 또는 unpinColumn
메소드 IgrHierarchicalGrid
를 사용하여 IgrHierarchicalGrid
pinColumn
필드 이름으로 열을 고정하거나 고정 해제할 수도 있습니다.
this.hierarchicalGrid.pinColumn('Artist');
this.hierarchicalGrid.unpinColumn('Debut');
typescript
두 메서드 모두 해당 작업의 성공 여부를 나타내는 부울 값을 반환합니다. 일반적으로 실패하는 이유는 열이 이미 원하는 상태에 있기 때문입니다.
열은 가장 오른쪽에 고정된 열의 오른쪽에 고정되어 있습니다. 고정된 열의 순서를 변경하려면 ColumnPin
이벤트를 구독하고 이벤트 인수의 InsertAtIndex
속성을 원하는 위치 인덱스로 변경하면 됩니다.
const columnPinning = (event: IgrPinColumnCancellableEventArgs) = {
if (event.detail.column.field === 'Name') {
event.detail.insertAtIndex = 0;
}
}
typescript
Pinning Position
pinning
구성 옵션을 통해 열 고정 위치를 변경할 수 있습니다. 열 위치를 시작 또는 끝으로 설정할 수 있습니다. 끝으로 설정하면 열이 고정 해제된 열 뒤의 그리드 끝에서 렌더링됩니다. 고정되지 않은 열은 가로로 스크롤할 수 있지만 고정된 열은 오른쪽에 고정된 상태로 유지됩니다.
const pinningConfig: IgrPinningConfig = { columns: ColumnPinningPosition.End };
typescript
Demo
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrHierarchicalGridModule } from "@infragistics/igniteui-react-grids";
import { IgrHierarchicalGrid, IgrPinningConfig, ColumnPinningPosition, IgrGridToolbar, IgrGridToolbarActions, IgrGridToolbarPinning, IgrColumn, IgrRowIsland } from "@infragistics/igniteui-react-grids";
import HierarchicalCustomersData from './HierarchicalCustomersData.json';
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrHierarchicalGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private grid: IgrHierarchicalGrid
private gridRef(r: IgrHierarchicalGrid) {
this.grid = r;
this.setState({});
}
private _pinningConfig1: IgrPinningConfig | null = null;
public get pinningConfig1(): IgrPinningConfig {
if (this._pinningConfig1 == null)
{
var pinningConfig1: IgrPinningConfig = {} as IgrPinningConfig;
pinningConfig1.columns = ColumnPinningPosition.End;
this._pinningConfig1 = pinningConfig1;
}
return this._pinningConfig1;
}
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">
<IgrHierarchicalGrid
ref={this.gridRef}
id="grid"
data={this.hierarchicalCustomersData}
columnSelection="single"
primaryKey="CustomerID"
pinning={this.pinningConfig1}>
<IgrGridToolbar
>
<IgrGridToolbarActions
>
<IgrGridToolbarPinning
>
</IgrGridToolbarPinning>
</IgrGridToolbarActions>
</IgrGridToolbar>
<IgrColumn
field="CustomerID"
hidden={true}>
</IgrColumn>
<IgrColumn
field="Company"
header="Company Name"
pinned={true}>
</IgrColumn>
<IgrColumn
field="ContactName"
header="Contact Name">
</IgrColumn>
<IgrColumn
field="ContactTitle"
header="Contact Title">
</IgrColumn>
<IgrColumn
field="Address"
header="Address">
</IgrColumn>
<IgrColumn
field="City"
header="City">
</IgrColumn>
<IgrColumn
field="PostalCode"
header="Postal Code">
</IgrColumn>
<IgrColumn
field="Country"
header="Country">
</IgrColumn>
<IgrColumn
field="Phone">
</IgrColumn>
<IgrColumn
field="Fax">
</IgrColumn>
<IgrRowIsland
childDataKey="Orders"
autoGenerate={false}>
<IgrColumn
field="OrderDate"
header="Order Date"
dataType="date"
resizable={true}>
</IgrColumn>
<IgrColumn
field="RequiredDate"
header="Required Date"
dataType="date"
resizable={true}>
</IgrColumn>
<IgrColumn
field="ShippedDate"
header="Shipped Date"
dataType="date"
resizable={true}>
</IgrColumn>
<IgrColumn
field="ShipName"
header="Ship Name"
dataType="string"
resizable={true}
pinned={true}>
</IgrColumn>
<IgrColumn
field="ShippedVia"
header="Shipped Via"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Freight"
header="Freight"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrRowIsland
childDataKey="OrderDetails"
autoGenerate={false}>
<IgrColumn
field="UnitPrice"
header="Unit Price"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Quantity"
header="Quantity"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Discount"
header="Discount"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Weight"
header="Weight"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Length"
header="Length"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="TotalPrice"
header="Total Price"
dataType="string"
resizable={true}>
</IgrColumn>
</IgrRowIsland>
</IgrRowIsland>
</IgrHierarchicalGrid>
</div>
</div>
);
}
private _hierarchicalCustomersData: any[] = HierarchicalCustomersData;
public get hierarchicalCustomersData(): any[] {
return this._hierarchicalCustomersData;
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
css
Custom Column Pinning UI
관련 API를 통해 사용자 정의 UI를 정의하고 열의 핀 상태를 변경할 수 있습니다.
도구 모음 대신 최종 사용자가 클릭하여 특정 열의 핀 상태를 변경할 수 있는 열 헤더에 핀 아이콘을 정의한다고 가정해 보겠습니다.
이는 사용자 정의 아이콘이 있는 열의 헤더 템플릿을 생성하여 수행할 수 있습니다.
Demo
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrHierarchicalGridModule } from "@infragistics/igniteui-react-grids";
import { IgrHierarchicalGrid, IgrGridToolbar, IgrGridToolbarActions, IgrGridToolbarPinning, IgrColumn, IgrRowIsland } from "@infragistics/igniteui-react-grids";
import HierarchicalCustomersData from './HierarchicalCustomersData.json';
import { IgrColumnTemplateContext } from "@infragistics/igniteui-react-grids";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrHierarchicalGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private grid: IgrHierarchicalGrid
private gridRef(r: IgrHierarchicalGrid) {
this.grid = r;
this.setState({});
}
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">
<IgrHierarchicalGrid
ref={this.gridRef}
id="grid"
data={this.hierarchicalCustomersData}
columnSelection="single"
primaryKey="CustomerID">
<IgrGridToolbar
>
<IgrGridToolbarActions
>
<IgrGridToolbarPinning
>
</IgrGridToolbarPinning>
</IgrGridToolbarActions>
</IgrGridToolbar>
<IgrColumn
field="CustomerID"
hidden={true}>
</IgrColumn>
<IgrColumn
field="Company"
header="Company Name"
pinned={true}
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="ContactName"
header="Contact Name"
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="ContactTitle"
header="Contact Title"
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="Address"
header="Address"
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="City"
header="City"
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="PostalCode"
header="Postal Code"
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="Country"
header="Country"
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="Phone"
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="Fax"
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrRowIsland
childDataKey="Orders"
autoGenerate={false}>
<IgrColumn
field="OrderDate"
header="Order Date"
dataType="date"
resizable={true}
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="RequiredDate"
header="Required Date"
dataType="date"
resizable={true}
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="ShippedDate"
header="Shipped Date"
dataType="date"
resizable={true}
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="ShipName"
header="Ship Name"
dataType="string"
resizable={true}
pinned={true}
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="ShippedVia"
header="Shipped Via"
dataType="string"
resizable={true}
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="Freight"
header="Freight"
dataType="string"
resizable={true}
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrRowIsland
childDataKey="OrderDetails"
autoGenerate={false}>
<IgrColumn
field="UnitPrice"
header="Unit Price"
dataType="string"
resizable={true}
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="Quantity"
header="Quantity"
dataType="string"
resizable={true}
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="Discount"
header="Discount"
dataType="string"
resizable={true}
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="Weight"
header="Weight"
dataType="string"
resizable={true}
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="Length"
header="Length"
dataType="string"
resizable={true}
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
<IgrColumn
field="TotalPrice"
header="Total Price"
dataType="string"
resizable={true}
headerTemplate={this.hierarchicalGridPinHeaderTemplate}>
</IgrColumn>
</IgrRowIsland>
</IgrRowIsland>
</IgrHierarchicalGrid>
</div>
</div>
);
}
private _hierarchicalCustomersData: any[] = HierarchicalCustomersData;
public get hierarchicalCustomersData(): any[] {
return this._hierarchicalCustomersData;
}
public hierarchicalGridPinHeaderTemplate = (props: {dataContext: IgrColumnTemplateContext}) => {
const column = (props.dataContext as any).column;
return (
<div>
<span style={{float: 'left'}}>{column.field}</span>
<span style={{float: 'right'}} onPointerDown={(e: any) => this.toggleColumnPin(column)}>📌</span>
</div>
);
}
public toggleColumnPin(field: IgrColumn) {
if(field) {
field.pinned = !field.pinned;
}
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
css
Pinning Limitations
- 열 너비를 백분율(%)
IgrHierarchicalGrid
로 설정하면 고정된 열이 있을 때 본문과 머리글 내용이 명시적으로 잘못 정렬됩니다. 열 고정이 올바르게 작동하려면 열 너비가 픽셀(px) 단위이거나 에 의해IgrHierarchicalGrid
자동 할당되어야 합니다.
Styling
사전 정의된 테마 외에도 사용 가능한 CSS 속성 중 일부를 설정하여 그리드를 추가로 사용자 정의할 수 있습니다. 일부 색상을 변경하려면 먼저 그리드의 ID
설정해야 합니다.
<IgrHierarchicalGrid id="grid"></IgrHierarchicalGrid>
tsx
그런 다음 관련 CSS 속성을 이 클래스로 설정합니다.
#grid {
--ig-grid-pinned-border-width: 5px;
--ig-grid-pinned-border-color: #FFCD0F;
--ig-grid-pinned-border-style: double;
--ig-grid-cell-active-border-color: #FFCD0F;
}
css
Demo
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrHierarchicalGridModule } from "@infragistics/igniteui-react-grids";
import { IgrHierarchicalGrid, IgrGridToolbar, IgrGridToolbarActions, IgrGridToolbarPinning, IgrColumn, IgrRowIsland } from "@infragistics/igniteui-react-grids";
import HierarchicalCustomersData from './HierarchicalCustomersData.json';
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrHierarchicalGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private grid: IgrHierarchicalGrid
private gridRef(r: IgrHierarchicalGrid) {
this.grid = r;
this.setState({});
}
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">
<IgrHierarchicalGrid
ref={this.gridRef}
id="grid"
data={this.hierarchicalCustomersData}
columnSelection="single"
primaryKey="CustomerID">
<IgrGridToolbar
>
<IgrGridToolbarActions
>
<IgrGridToolbarPinning
>
</IgrGridToolbarPinning>
</IgrGridToolbarActions>
</IgrGridToolbar>
<IgrColumn
field="CustomerID"
hidden={true}>
</IgrColumn>
<IgrColumn
field="Company"
header="Company Name"
pinned={true}>
</IgrColumn>
<IgrColumn
field="ContactName"
header="Contact Name">
</IgrColumn>
<IgrColumn
field="ContactTitle"
header="Contact Title">
</IgrColumn>
<IgrColumn
field="Address"
header="Address">
</IgrColumn>
<IgrColumn
field="City"
header="City">
</IgrColumn>
<IgrColumn
field="PostalCode"
header="Postal Code">
</IgrColumn>
<IgrColumn
field="Country"
header="Country">
</IgrColumn>
<IgrColumn
field="Phone">
</IgrColumn>
<IgrColumn
field="Fax">
</IgrColumn>
<IgrRowIsland
childDataKey="Orders"
autoGenerate={false}>
<IgrColumn
field="OrderDate"
header="Order Date"
dataType="date"
resizable={true}>
</IgrColumn>
<IgrColumn
field="RequiredDate"
header="Required Date"
dataType="date"
resizable={true}>
</IgrColumn>
<IgrColumn
field="ShippedDate"
header="Shipped Date"
dataType="date"
resizable={true}>
</IgrColumn>
<IgrColumn
field="ShipName"
header="Ship Name"
dataType="string"
resizable={true}
pinned={true}>
</IgrColumn>
<IgrColumn
field="ShippedVia"
header="Shipped Via"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Freight"
header="Freight"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrRowIsland
childDataKey="OrderDetails"
autoGenerate={false}>
<IgrColumn
field="UnitPrice"
header="Unit Price"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Quantity"
header="Quantity"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Discount"
header="Discount"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Weight"
header="Weight"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="Length"
header="Length"
dataType="string"
resizable={true}>
</IgrColumn>
<IgrColumn
field="TotalPrice"
header="Total Price"
dataType="string"
resizable={true}>
</IgrColumn>
</IgrRowIsland>
</IgrRowIsland>
</IgrHierarchicalGrid>
</div>
</div>
);
}
private _hierarchicalCustomersData: any[] = HierarchicalCustomersData;
public get hierarchicalCustomersData(): any[] {
return this._hierarchicalCustomersData;
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
#grid {
--ig-grid-pinned-border-width: 5px;
--ig-grid-pinned-border-color: #FFCD0F;
--ig-grid-pinned-border-style: double;
--ig-grid-cell-active-border-color: #FFCD0F;
}
css
API References
Additional Resources
우리 커뮤니티는 활동적이며 항상 새로운 아이디어를 환영합니다.