2
votes

I am quite new to vue-js and ag-grid, I would like to have a custom filter on my ag-grid so tried using component as filter as shown in vue-js ag-grid example: "https://www.ag-grid.com/javascript-grid-filter-component/" but its not working and giving "componentType is not a constructor" error in console.

Below is my code:

Gird:

<template>
  <div class="all-devices" style="width: 100%; height: 425px;">
    <ag-grid-vue
      style="width: 100%; height: 100%;"
      class="ag-theme-balham"
      :gridOptions="gridOptions"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :rowData="rowData"
      :frameworkComponents="frameworkComponents"
    ></ag-grid-vue>
  </div>
</template>

<script>
import { AgGridVue } from "ag-grid-vue";
import PartialMatchFilter from "./PartialMatchFilter";

export default {
  name: "AllDevices",
  components: {},
  data() {
    return {
      gridOptions: null,
      columnDefs: null,
      defaultColDef: null,
      rowData: null,
      frameworkComponents: null
    };
  },
  components: {
    AgGridVue
  },
  beforeMount() {
    this.gridOptions = {};
    this.columnDefs = [
      {
        headerName: "Row",
        field: "row",
        width: 450
      },
      {
        headerName: "Filter Component",
        field: "name",
        width: 430,
        filter: "partialMatchFilter"
      }
    ];

    this.rowData = [
      {
        row: "Row 1",
        name: "Michael Phelps"
      },
      {
        row: "Row 2",
        name: "Natalie Coughlin"
      },
      {
        row: "Row 3",
        name: "Aleksey Nemov"
      },
      {
        row: "Row 4",
        name: "Alicia Coutts"
      },
      {
        row: "Row 5",
        name: "Missy Franklin"
      },
      {
        row: "Row 6",
        name: "Ryan Lochte"
      },
      {
        row: "Row 7",
        name: "Allison Schmitt"
      },
      {
        row: "Row 8",
        name: "Natalie Coughlin"
      },
      {
        row: "Row 9",
        name: "Ian Thorpe"
      },
      {
        row: "Row 10",
        name: "Bob Mill"
      },
      {
        row: "Row 11",
        name: "Willy Walsh"
      },
      {
        row: "Row 12",
        name: "Sarah McCoy"
      },
      {
        row: "Row 13",
        name: "Jane Jack"
      },
      {
        row: "Row 14",
        name: "Tina Wills"
      }
    ];

    this.defaultColDef = { filter: true };
    this.frameworkComponents = { partialMatchFilter: PartialMatchFilter };
  },
  methods: {
    onGridReady(params) {
      params.api.sizeColumnsToFit();
    }
  }
};
</script>

<style>
</style>

Filter component:

<template>
  <div>
    <input style="height: 20px" :ref="'input'" v-model="text" />
  </div>
</template>
<script>
export default {
  name: "PartialMatchFilter",
  data() {
    return {
      text: "",
      valueGetter: null
    };
  },
  methods: {
    isFilterActive() {
      return this.text !== null && this.text !== undefined && this.text !== "";
    },
    doesFilterPass(params) {
      return (
        !this.text ||
        this.text
          .toLowerCase()
          .split(" ")
          .every(filterWord => {
            return (
              this.valueGetter(params.node)
                .toString()
                .toLowerCase()
                .indexOf(filterWord) >= 0
            );
          })
      );
    },
    getModel() {
      return { value: this.text };
    },
    setModel(model) {
      if (model) {
        this.text = model.value;
      }
    },
    afterGuiAttached() {
      this.$refs.input.focus();
    },
    componentMethod(message) {
      alert(`Alert from PartialMatchFilterComponent ${message}`);
    }
  },
  watch: {
    text: function(val, oldVal) {
      if (val !== oldVal) {
        this.params.filterChangedCallback();
      }
    }
  },
  created() {
    this.valueGetter = this.params.valueGetter;
  }
};
</script>

Am I missing something? Please help! - Thanks

1
I don't know Vue (I use the Angular wrapper), but just a guess - you might want to initialize your 'frameworkComponents' member before you initialize your 'columnDefs', which reference it. Since 'frameworkComponents' never changes, you could just initialize it where you currently declare it as null. - GreyBeardedGeek
Tried as you suggested but still not working :( - Salman

1 Answers

5
votes

I had the same problem.

First, make this change in your columnDefs and get rid of frameworkComponents. Its just cleaner.

filter: "partialMatchFilter" -> filterFramework: PartialMatchFilter

Then the actual fix. In your filter component add Vue.extend:

<template>
   ...
</template>

<script>
import Vue from "vue";

export default Vue.extend({
   ...
});

The example I followed -> https://github.com/ag-grid/ag-grid-vue-example/tree/master/src/rich-grid-example Ref for Vue.extend -> https://vuejs.org/v2/api/#Vue-extend