ag-gridの公式ドキュメントにサンプルはあるもののその場で作って設定するみたいな感じになっていたのでangularで再利用できるようにコンポーネント化してみます
- 公式ドキュメント
Cell Editing: A Core Feature of our Datagrid
今回使うmodule
- ag-grid-angular
- ag-grid
- ngx-bootstrap
環境
- angular
npx ng -v
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 6.1.5
Node: 9.10.1
OS: linux x64
Angular: 6.1.4
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.7.5
@angular-devkit/build-angular 0.7.5
@angular-devkit/build-optimizer 0.7.5
@angular-devkit/build-webpack 0.7.5
@angular-devkit/core 0.7.5
@angular-devkit/schematics 0.7.5
@angular/cli 6.1.5
@angular/tsc-wrapped 4.4.6
@ngtools/json-schema 1.2.0
@ngtools/webpack 6.1.5
@schematics/angular 0.7.5
@schematics/update 0.7.5
ng-packagr 1.7.0
rxjs 6.2.2
typescript 2.9.2
webpack 4.9.2
- node_module
"ag-grid": "18.1.2", "ag-grid-angular": "18.1.0", "ngx-bootstrap": "3.0.1",
やること
今回やることはこれだけです
- cellEditorComponentの作成
- cellEditorFrameworkに設定
cellEditorの設定方法はいくつかあるみたいです
Rendererに定義する- Editorのinterfaceを満たす関数を定義する
RendererFrameworkICellEditorCompinterfaceを満たすコンポーネントを定義する
gridOptionsのcomponentsに定義して呼び出す- interfaceを満たす関数を
gridOptionsのcomponentsに適当なキー(サンプルだとdatepicker)で定義 columnDefのcellEditorに定義したキーを設定
- interfaceを満たす関数を
3つ目はサンプル見るまで知らなかったです
探した感じドキュメントにも載ってないのですがグリッドで使用するコンポーネントは一括でcomponentsに入れてあとは設定から呼び出すといった流れにしておけばスッキリしそうですね
今回は2つめでコンポーネント化していろんな画面で日付編集ができるようにします
- ICellEditorComp
ag-Grid Components: Cell Editors
基本的には上記interfaceに沿って実装すればOKそうです
コンポーネントの作成
npx ng g component components/ag-grid-cell-editor.datepicker --skip-import
- ts(一部抜粋)
public datepickerModel: Date;
@ViewChild('picker') bsDatepickerElement;
ngAfterViewInit() {
this.bsDatepickerElement.show();
}
getValue(): string {
return moment(this.datepickerModel).format('YYYY-MM-DD');
}
- html
<input type="text"
[bsConfig]="{ dateInputFormat: 'YYYY-MM-DD', containerClass: 'theme-dark-blue' }"
[(ngModel)]="datepickerModel"
#picker="bsDatepicker"
bsDatepicker>
HTMLはこんな感じ
ngModelを使ってコンポーネントのインスタンス変数と同期させてる感じですね
デフォルトだとダブルクリックで編集用のコンポーネントが展開されます
ngx-bootstrapのサンプルをそのまま貼っただけだとポップアップにフォームが出てくるのでそれをクリックしないとカレンダーが出てこない
なのでテンプレート側でbsDatepickerディレクティブのインスタンスをテンプレート変数に代入して
#picker="bsDatepicker"
ViewChildを使ってコンポーネント側でbsDatepickerのインスタンスを取得して
@ViewChild('picker') bsDatepickerElement;
コンポーネント側でbsDatepickerディレクティブのメソッドを叩く
this.bsDatepickerElement.show();
これでグリッド側で編集を開始した瞬間にカレンダーが開くようになりました
getValueは編集を終えた際に編集した値をag-grid側に渡すための関数です
今回は文字列を返すようにしました
カラム定義
{
headerName: '開始日',
field: 'startDate',
width: 120,
editable: true,
cellEditorFramework:AgGridCellEditorDatepickerComponent
},
先程作ったコンポーネントを直接指定すればOK!
無事日付編集機能を実装できました
サンプルは下記においておきます
https://swfz.github.io/ngx-sample/grid/reactiveswfz.github.io
まとめ
簡単にカスタムしたセルエディタを作成することができました
凝ったコンポーネントを作ればパターンが広がりそうですね
無料でもこの機能は使うことができるのでぜひお試ししていただけたらと思います
また、ただのコンポーネント作ってその中で無理やりgridのデータに対して変更かけるみたいなこともできるのですが、ag-gridの流儀にそってないので全部自前でやらなくてはなりません。
それに対してこちらの方法であれば値の変更やイベントの伝搬などもフォローしてもらえるのでだいぶ実装がらくになると思います。
余談ですが、これを作っている時点でngx-bootstrapのdatepickerはまだ開発版らしいのでこんなwarningが出てきました
BsDatepickerModule is under development,
BREAKING CHANGES are possible,
PLEASE, read changelog
まぁupdateで変えられたらその時対応しましょうw