【備忘】Vue.js で ag-grid を使う（値の設定ほか）

# 今回やること
今回は表示したグリッドの値を画面から変更するやり方を中心にまとめたいと思います。

# 参考資料
1. 公式サイト: https://www.ag-grid.com/vuejs-grid/
1. [前回記事](https://qiita.com/smatsu/items/ceb04e1f9d1cec0d2447)


# グリッド列の書き込みを可能にする
* カラム定義のオブジェクト配列（前回記事で言うと colDefs）の各要素の中に editable というプロパティを作成し true を設定すると、その列は画面上でそこにカーソルを合わせたときに書き込みが可能になります。
* 下記は、数量という列を作った例です

```javascript
  {
    headerName: '数量', 
    field: 'quantity', 
    editable: true,
  }
```

* field の'quantity' は前回記事で書いた通り、各行に対応する rowData にあるプロパティの名前です。
* 該当列にカーソルを合わせてクリックするとこんなふうになり、値の書き込みができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178615/1c151046-05a5-aedf-8887-c9877b18cbe9.png)　→　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178615/c9764987-d109-5eb5-08f7-0fd479af6842.png)

* 実行時に動的に、ある特定の条件では書き込み可／不可を切り替えたいということもあると思います。その場合は、editable に関数を設定することができます。

```javascript
        editable: (params) => {
          // false を返せば編集不可になる
          return (<paramsを使った条件判定>) ? false : true;
        },
```

この関数に引数として渡ってくる params にはそのセルについての情報が入ってきますので、その値を使った判定ができるわけです。params にどんな値が入ってくるかについては、公式ページで説明されています。
* [Cell Editing](https://www.ag-grid.com/javascript-grid-cell-editing/)

# 入力値のチェックはどうやる？
* 入力するときには入力値が正しいかどうかチェックをしたくなると思います。
* そのための手段として、入力値が入ったときにそれをインターセプトする関数を列ごとに設定できるようになっています。valueSetter という名前の関数を列定義オブジェクトの中に定義すると、値を設定する前にそれが呼ばれます。コード例です。

```javascript
      {
        headerName: '取引通貨金額', 
        field: 'amount', 
        editable: true,
        cellStyle: {textAlign: 'right'},
        maxWidth:150,
        valueSetter(params) {
          let s = params.newValue;
          if (common.isNum(s)) {
            s = Number(s);
            params.data.amount = s;
            self.errMsg = '';
            return true;
          } else {
            self.errMsg = err + s;
            return false;
          }
        },
      }
```

* params.newValue にユーザが画面から入力した値が入ってきます。valueSetter() で true を返せばそのままその値が(この場合は rowData[<この行の番目>].amount に)設定されます。false を返すと設定されません。この例では入力値が数値かどうかチェックし、数値以外ならエラー扱いにしてメッセージを出すようなことをしています。

# 値の表示をカスタマイズしたい場合
* 余談ですが似たような関数として valueGetter() というのも用意されています。これは値を表示するときにそのまま値を表示するのではなく、値によって他の表現にしたい(たとえば値によって 〇/× 表示にしたいとか)ような場合に使えます。

```javascript
        valueGetter(params) {
          return params.data.amount; // ここでは変換せずそのまま表示している
        },
```

# 金額の表示はカンマ編集で表示したい
値の表示で金額のカンマ編集というのはよくやると思います。データは数値で持っているので、データ自体にはカンマは入れずに、表示するときにだけ変換をかけたいですよね。上に書いた valueGetter() でやってもよいですが、そういうことをするための valueFormatter というプロパティも用意されています。上の例に追記するとこんな感じになります。

```javascript
      {
        headerName: '取引通貨金額',
        field: 'amount', 
        editable: true,
        cellStyle: {textAlign: 'right'},
        valueFormatter: self.gridCommaFilter, // カンマ編集フィルタ
        maxWidth:150,
        valueGetter(params) {
          return params.data.amount; 
        },
        valueSetter(params) {
          let s = params.newValue;
          if (common.isNum(s)) {
            s = Number(s);
            params.data.amount = s;
            self.errMsg = '';
            return true;
          } else {
            self.errMsg = err + s;
            return false;
          }
        },
      }
```

* ここで self.gridCommaFilter というのは .vue の methods プロパティに設定しています。 self はたまたまこのサンプルで this を保持しているローカル変数ですので、this を直接使えるならそれで構いません。
* gridCommaFilter の実装はこんな感じです。

```javascript
methods: {
    ...
    // カンマ編集
    // ag-grid のフォーマッタは methods の一つとして定義する 
    // Vueの filters に定義しても効かないので注意
    gridCommaFilter(params) {
      const num = new Number(params.value);
      return num.toLocaleString(); // カンマ編集
    },
    ...

```

* このときの注意点としてコメントにも書きましたが、Vue.js ではこういうこと（金額のカンマ編集など）をやるときに使う filters というプロパティがあるので methods ではなく filters に作りたくなるかも知れませんが、ag-grid 用のフィルタは普通の関数なので methods に定義しないといけません。（適切な形をした関数であればどこに定義してもいいのかも知れませんが、methods に置いておくのが無難だと思います）

以上です。