1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ag-gridメモ的な

Last updated at Posted at 2019-01-27

ag-grid使っていてやってみたこともろもろのメモです。

編集要素を持ったセルコンポーネントのエディタ切り替えを不可にする

と言うとわかりずらいですが、

  1. 例えばセルの表示状態(RendererComponent)をチェックボックスにしているときなど、カラム定義(ColumnDefs)のeditable:trueにしていると、ダブルクリックなどでinput要素に切り替わりカッコ悪くなる。
  2. それを回避しようと、該当するRendererを使うときは常にeditable:falseにして、そのうえでRendererParamsにreadonlyプロパティなどを勝手に渡して活性制御を行っていたのですが、そのうち、今度は行ごとに活性制御を行いたくなってきた。
  3. そうなると、やはりカラム定義のeditableには本来の用途で柔軟性をもたせたい。

で、EditorConponentへの切り替え自体をキャンセルさせてしまおう。と思いました。

UneditableEditor.vue
<template>
    <div>dammy template</div>
</template>

<script>
import Vue from "vue";
export default Vue.extend({
    methods: {
        isCancelBeforeStart() {
            return true;
        },
    },
})
</script>

つまり、編集不可能なEditorを設定する。
チェックボックスセルでは以下のようにeditableプロパティを使用できる。

ComboBoxCell.vue
<template>
    <div>
        <input type="checkbox" 
        v-model="isChecked"
        @change="onChange"
        :disabled="isDisabled"
        >
    </div>
</template>

<script>
import Vue from "vue";

export default Vue.extend({
    data() {
        return {
            isChecked: false,
            isDisabled: false
        }
    },
    methods:{
        onChange(){
            this.params.setValue(this.isChecked);
            this.params.api.refreshHeader();
        },
    },
    mounted(){
        let isChecked = true;
        this.isChecked = this.params.value;
        if(typeof(this.params.colDef.editable) === 'function'){
            this.isDisabled = !this.params.colDef.editable(this.params)
        }else{
            this.isDisabled = !this.params.colDef.editable
        }
    }
})
</script>

ついでにヘッダーも。

CheckBoxColumn.vue
<template>
    <div>
        <input
        :id="'id_'+params.column.colDef.field" 
        type="checkbox" 
        v-model="isChecked"
        @change="onChange">
        <label :for="'id_'+params.column.colDef.field">
            {{ params.displayName }}
        </label>
    </div>
</template>

<script>
import Vue from "vue";

export default Vue.extend({
    data() {
        return {
            isChecked: false
        }
    },
    methods:{
        onChange(){
            this.params.api.forEachNode(node =>{
                if(this.isEditable(node)){
                    node.setDataValue(this.params.column.colId, this.isChecked);
                }
            });
            this.params.api.redrawRows();
        },
        updateCheckBoxCol(){
            let isChecked = true;
            this.params.api.forEachNode(node => {
                if(this.isEditable(node) && 
                !node.data[this.params.column.colId]) {
                    isChecked = false;
                }
            });
            this.isChecked = isChecked;
        },
        /***
         * checkboxセルの編集可否を判定
         * colDefのeditableプロパティが関数の場合、RowNodeを与えて呼び出し。
         * (引数のオブジェクトはdataプロパティを持っていることを前提)
         * Params
         * ------
         *     node: RowNode
         */
        isEditable(node){
            if(typeof(this.params.column.colDef.editable) === "function"){
                return this.params.column.colDef.editable(node)
            }
            return this.params.column.colDef.editable
        }
    },
    beforeUpdate(){
        this.updateCheckBoxCol();
    },
    mounted(){
        this.updateCheckBoxCol();
    },
})

</script>

セルの入力状態(バリデーション)を管理する

以下、公式ドキュメントのソースをバリデーション用に修正。

<template>
<div>
    <input 
    :ref="'input'" 
    v-model="value"
    :maxlength="maxlength"
    />
</div>
</template>


<script>
import Vue from "vue";

export default Vue.extend({
    data() {
        return {
            value: '',
            cancelBeforeStart: false,
            maxlength: 255
        }
    },
    methods: {
        getValue() {
            /* 多分セルの編集完了時に呼び出されるだろうgetValueメソッド内で
               バリデーションを実施。不正な入力が行われたセルのインデックスを
               paramsのcontextプロパティに設定。 */
            if(this.params.pattern){
                let isValid = new RegExp(this.params.pattern).test(this.value)
                // 当該セルをinvalidCellsリストから除外。
                this.params.context.invalidCells = this.params.context.invalidCells.filter(
                    c => c[this.params.column.colId] !== this.params.rowIndex)
                if(!isValid){
                    // 不正入力の場合は該当するセルのcolId:RowIndexのオブジェクトを設定。
                    const invalidCell = {}
                    invalidCell[this.params.column.colId] = this.params.rowIndex
                    this.params.context.invalidCells.push(invalidCell)
                }
            }
            return this.value;
        },
        getCharCodeFromEvent(event) {
            event = event || window.event;
            return (typeof event.which === "undefined") ? event.keyCode : event.which;
        },
    },
    created() {
        this.value = this.params.value;
        this.maxlength = this.params.maxlength
    },
    mounted() {
        Vue.nextTick(() => {
            if (this.$refs.input) {
                this.$refs.input.focus();
            }
        });
    }
})

</script>

例えば、上の情報をセルのスタイルなどに使用する。


            this.gridOptions = {
                context:{
                    invalidCells:[]
                },
                defaultColDef:{
                    cellClassRules: {
                        'invalid-input-cell': function(params) {
                            return params.context.invalidCells.find(c => c[params.colDef.field] === params.rowIndex)
                        },
                    }
                },

(ちなみに)
javascript慣れてないです。
また、ag-gridのAPIにもっといい機能がすでにあるかもなので、ご指摘・情報あれば教えていただきたく。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?