Angular Grid のセル編集
Ignite UI for Angular Grid コンポーネントは、Angular CRUD 操作のための優れたデータ操作機能と強力な API を提供します。デフォルトで Grid はセル編集を使用し、デフォルトのセル編集テンプレートによって、列のデータ型に基づいてさまざまなエディターが表示されます。さらに、データ更新アクション用の独自のカスタム テンプレートを定義したり、変更をコミット/破棄したりするためのデフォルトの動作をオーバーライドすることもできます。
Angular Grid セル編集とセル テンプレートの例
Note
任意のタイプのエディター コンポーネントで igxCellEditor
を使用すると、キーボード ナビゲーション フローが中断されます。同じことが、編集モードに入るカスタム セルの直接編集にも当てはまります。これは、追加したエディター コンポーネント (igxSelect
、igxCombo
など) ではなく、セル要素にフォーカスが残るためです。これが、igxFocus
ディレクティブを利用する必要がある理由です。これにより、フォーカスがセル内コンポーネントに直接移動し、セル/行の流暢な編集フロー
が維持されます。
セルの編集
UI を介した編集
編集可能なセルがフォーカスされたときに以下のいずれかの方法で特定のセルを編集モードにすることができます。
- ダブルクリック;
- シングル クリック - 以前選択したセルが編集モードで現在選択したセルが編集可能な場合のみ、シングル クリックで編集モードに入ります。以前選択したセルが編集モードではない場合、編集モードに入らずにシングル クリックでセルを選択します。
Enter
キーの押下;F2
キーの押下;
変更をコミットしない場合も以下の方法で編集モードを終了できます。
Escape
キーの押下;- ソート、フィルターリング、検索、非表示 操作の実行時。
変更をコミットしない場合も以下の方法で編集モードを終了できます。
Enter
キーの押下;F2
キーの押下;Tab
キーの押下;- 他のセルをシングル クリック - Grid で他のセルをクリックしたときに変更がサブミットされます。
- その他の操作 (ページング、サイズ変更、ピン固定、移動など) は、編集モードを終了して変更を送信します。
Note
セルは、垂直/水平方向へのスクロールや Grid 以外をクリックした場合も編集モードのままです。セル編集と行編集両方で有効です。
API を介した編集
プライマリキーが定義されている場合のみ IgxGrid API でもセル値を変更することができます。
public updateCell() {
this.grid1.updateCell(newValue, rowID, 'ReorderLevel');
}
セルを更新するその他の方法として IgxGridCell
の update
メソッドで直接更新する方法があります。
public updateCell() {
const cell = this.grid1.getCellByColumn(rowIndex, 'ReorderLevel');
// You can also get cell by rowID if primary key is defined
// cell = this.grid1.getCellByKey(rowID, 'ReorderLevel');
cell.update(70);
}
セル編集テンプレート
デフォルトのセル編集テンプレートの詳細については、編集トピックを参照してください。
セルが編集モードのときに適用されるカスタム テンプレートを提供する場合は、igxCellEditor
ディレクティブを使用できます。これを行うには、igxCellEditor
ディレクティブでマークされた ng-template
を渡し、カスタム コントロールを cell.editValue
に適切にバインドする必要があります:
<igx-column field="class" header="Class" [editable]="true">
<ng-template igxCellEditor let-cell="cell" let-value>
<igx-select class="cell-select" [(ngModel)]="cell.editValue" [igxFocus]="true">
<igx-select-item *ngFor="let class of classes" [value]="class">
{{ class }}
</igx-select-item>
</igx-select>
</ng-template>
</igx-column>
このコードは、Race
、Class
、および Alignment
列のセルに IgxSelectComponent
を実装する以下のサンプルで使用されています。
Note
編集モードでセルの editValue
に加えられた変更は、終了時に適切な編集イベント
をトリガーし、トランザクション状態に適用されます (トランザクションが有効な場合)。
Note
セルテンプレート igxCell
は、編集モード外での列のセルの表示方法を制御します。
igxCellEditor
セル編集テンプレート ディレクティブは、編集モードでの列のセルの表示方法を処理し、編集されたセルの編集値を制御します。
Note
任意のタイプのエディター コンポーネントで igxCellEditor
を使用すると、キーボード ナビゲーション フローが中断されます。同じことが、編集モードに入るカスタム セルの直接編集にも当てはまります。これは、追加したエディター コンポーネント (igxSelect
、igxCombo
など) ではなく、セル要素にフォーカスが残るためです。これが、igxFocus
ディレクティブを利用する必要がある理由です。これにより、フォーカスがセル内コンポーネントに直接移動し、セル/行の 流暢な編集フロー
が維持されます。
列とそのテンプレートの構成方法の詳細については、グリッド列構成のドキュメントを参照してください。
Grid Excel スタイル編集
Excel スタイル編集を使用すると、Excel を使用する場合と同じようにセルをナビゲートし、すばやく編集できます。
このカスタム機能を実装するには、グリッドのイベントを使用します。最初にグリッドの keydown イベントにフックし、そこから 2 つの機能を実装できます。
- 常時編集モード
public keydownHandler(event) {
const key = event.keyCode;
const grid = this.grid;
const activeElem = grid.navigation.activeNode;
if(
(key >= 48 && key <= 57) ||
(key >= 65 && key <= 90) ||
(key >= 97 && key <= 122)){
// Number or Alphabet upper case or Alphabet lower case
const columnName = grid.getColumnByVisibleIndex(activeElem.column).field;
const cell = grid.getCellByColumn(activeElem.row, columnName);
if (cell && !cell.editMode) {
cell.editMode = true;
cell.editValue = event.key;
this.shouldAppendValue = true;
} else if (cell && cell.editMode && this.shouldAppendValue) {
event.preventDefault();
cell.editValue = cell.editValue + event.key;
this.shouldAppendValue = false;
}
}
}
Enter
/Shift + Enter
ナビゲーション
if (key == 13) {
let thisRow = activeElem.row;
const column = activeElem.column;
const rowInfo = grid.dataView;
// to find the next eiligible cell, we will use a custom method that will check the next suitable index
let nextRow = this.getNextEditableRowIndex(thisRow, rowInfo, event.shiftKey);
// and then we will navigate to it using the grid's built in method navigateTo
this.grid.navigateTo(nextRow, column, (obj) => {
obj.target.activate();
this.grid.clearCellSelection();
this.cdr.detectChanges();
});
}
次の適格なインデックスを見つけるための重要な部分は以下のようになります。
//first we check if the currently selected cell is the first or the last
if (currentRowIndex < 0 || (currentRowIndex === 0 && previous) || (currentRowIndex >= dataView.length - 1 && !previous)) {
return currentRowIndex;
}
// in case using shift + enter combination, we look for the first suitable cell going up the field
if(previous){
return dataView.findLastIndex((rec, index) => index < currentRowIndex && this.isEditableDataRecordAtIndex(index, dataView));
}
// or for the next one down the field
return dataView.findIndex((rec, index) => index > currentRowIndex && this.isEditableDataRecordAtIndex(index, dataView));
詳細については、サンプルを参照してください。
Angular Grid Excel スタイル編集のサンプル
上記のアプローチの主な利点は次のとおりです:
- 常時編集モード: セルが選択されているときに入力すると、編集モードに入り、入力された値が既存の値を置き換えます。
Enter
/Shift + Enter
で移動する場合、データ以外の行はスキップされます。これにより、ユーザーは値をすばやく切り替えることができます。
CRUD 操作
Note
CRUD 操作を実行した場合、filtering、sorting、grouping などのパイプが再適用されるため、ビューが自動的に更新されることに注意してください。
IgxGridComponent
は基本的な CRUD 操作のための簡易な API を提供します。
新しいレコードの追加
Grid コンポーネントは、提供したデータをデータ ソースに追加する addRow
メソッドを公開します。
// Adding a new record
// Assuming we have a `getNewRecord` method returning the new row data.
const record = this.getNewRecord();
this.grid.addRow(record);
データを Grid で更新
Grid のデータ更新は、グリッドでプライマリキーが定義されている場合のみ updateRow
と updateCell
メソッドで行うことができます。セルと行の値またはそのいずれかを各 update
メソッドで直接更新できます。
// Updating the whole row
this.grid.updateRow(newData, this.selectedCell.cellID.rowID);
// Just a particular cell through the Grid API
this.grid.updateCell(newData, this.selectedCell.cellID.rowID, this.selectedCell.column.field);
// Directly using the cell `update` method
this.selectedCell.update(newData);
// Directly using the row `update` method
const row = this.grid.getRowByKey(rowID);
row.update(newData);
Grid からデータを削除
deleteRow()
メソッドは、プライマリキーが定義されている場合に指定した行のみを削除することに注意してください。
// Delete row through Grid API
this.grid.deleteRow(this.selectedCell.cellID.rowID);
// Delete row through row object
const row = this.grid.getRowByIndex(rowIndex);
row.delete();
igx-grid に関係なく、ボタンのクリックなどのユーザー インタラクションに関連付けできます。
<button igxButton igxRipple (click)="deleteRow($event)">Delete Row</button>
編集イベントでのセル検証
グリッドの編集イベントを使用して、ユーザーがグリッドを操作する方法を変更できます。
この例では、cellEdit
イベントにバインドすることにより、入力されたデータに基づいてセルを検証します。セルの新しい値が事前定義された基準を満たしていない場合、イベントをキャンセルすることでデータソースに到達しないようにします (event.cancel = true
)。また、IgxToast
を使用してカスタム エラーメッセージを表示します。
最初に必要なことは、グリッドのイベントにバインドすることです。
<igx-grid (cellEdit)="handleCellEdit($event)"
...>
...
</igx-grid>
cellEdit
は、セルの値がコミットされる直前に発生します。handleCellEdit
の定義では、アクションを実行する前に特定の列を確認する必要があります。
export class MyGridEventsComponent {
public handleCellEdit(event: IGridEditEventArgs): void {
const column = event.column;
if (column.field === 'Ordered') {
const rowData = event.rowData;
if (!rowData) {
return;
}
if (event.newValue > rowData.UnitsInStock) {
event.cancel = true;
this.toast.open();
}
}
}
}
注文済み列の下のセルに入力された値が使用可能量 (在庫数の値) よりも大きい場合、編集はキャンセルされ、エラー メッセージ付きのトーストが表示されます。
以下は、上記の検証が igx-grid
に適用された結果のデモです。
スタイル設定
IgxGrid で Ignite UI for Angular テーマ ライブラリを使用してセルのスタイルを設定できます。グリッドの theme は、ユーザーがグリッドのさまざまな側面をスタイル設定できる広範なプロパティを公開します。
以下の手順では、編集モードでグリッドのセルのスタイルを設定する方法と、それらのスタイルの範囲を設定する方法について説明します。
Ignite UI Theming ライブラリを使用するには、まずグローバル スタイルでテーマ index
ファイルをインポートする必要があります。
スタイル ライブラリのインポート
@use "igniteui-angular/theming" as *;
// 重要: Ignite UI for Angular 13 より前のバージョンは、次を使用してください。
// @import '~igniteui-angular/lib/core/styles/themes/index';
以上で Ignite UI for Angular テーマ エンジンによって公開されているすべての機能を使用できます。
パレットの定義
インデックス ファイルをインポート後、カスタム パレットを作成します。好きな 2 つの色を定義し、それらを使用して igx-palette
でパレットを作成しましょう。
$white: #fff;
$blue: #4567bb;
$color-palette: palette($primary: $white, $secondary: $blue);
テーマの定義
これで、パレットを使用してテーマを定義できます。セルは grid-theme
によってスタイル設定されているため、それを使用して IgxGrid のテーマを生成できます。
$custom-grid-theme: grid-theme(
$cell-editing-background: $blue,
$cell-edited-value-color: $white,
$cell-active-border-color: $white,
$edit-mode-color: color($color-palette, "secondary", 200)
);
テーマを適用
テーマを適用する最も簡単な方法は、グローバル スタイル ファイルに sass
@include
ステートメントを使用することです。
@include grid($custom-grid-theme);
これにより、テーマはアプリケーションのすべてのグリッドに適用されます。このカスタム スタイルを特定のコンポーネントにのみ適用する場合は、テーマのスコープを設定する必要があります。
スコープ コンポーネント テーマ
カスタム テーマが特定のコンポーネントのみに影響するように、定義したすべてのスタイルをグローバル スタイル ファイルからカスタム コンポーネントのスタイル ファイルに移動できます (index
ファイルの import を含む)。
このように、Angular の ViewEncapsulation
により、スタイルはカスタム コンポーネントにのみ適用されます。
Note
コンポーネントが Emulated
ViewEncapsulation を使用している場合、グリッドのスタイルを設定するには、::ng-deep
を使用してこのカプセル化を解除する必要があります。
Note
ステートメントがコンポーネントの外にある要素に影響を与えないよう、ステートメントを :host
セレクター内にラップします。
:host {
::ng-deep {
@include grid($custom-grid-theme);
}
}
}
デモのスタイル設定
上記の手順に加えて、セルの編集テンプレートに使用されるコントロールのスタイルを設定することもできます (igx-input-group
、igx-datepicker
および igx-checkbox
)。
Note
このサンプルは、「テーマの変更」から選択したグローバル テーマに影響を受けません。
API リファレンス
- IgxGridCell
- IgxGridComponent スタイル
- IgxGridRow
- IgxInputDirective
- IgxDatePickerComponent
- IgxDatePickerComponent スタイル
- IgxCheckboxComponent
- IgxCheckboxComponent スタイル
- IgxOverlay
- IgxOverlay スタイル