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を満たす関数を定義する
RendererFramework
ICellEditorComp
interfaceを満たすコンポーネントを定義する
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