4
votes

How can one change the value that is displayed in the UI filter elements(input, dropdown etc) in vue-good-table programmatically?

For example if I call: this.$set(this.table.columnsFilters, 'name', 'bob')

I want the value in the HTML input field 'name' to display bob.

Unfortunatly the settting the values as i described above does not work

3
I don't understand what you mean by "I want the value in the HTML input field 'name' to display bob. Instead what happens is my data is filtered by bob..." Are you referring to like placeholder text? - Matt Oestreich
Jakobovski - can you elaborate on what you mean? - Matt Oestreich
@MattOestreich I added clarification - Jakobovski
So you want to programmatically change the current filter for a column? - Matt Oestreich
@MattOestreich. Yes, but there is a difference between the filter and the value displayed in the UI, that is why I specifically mention the UI value. Usually the should be the same, but what I found is sometime the filter value is not identical to the value being displayed in UI. - Jakobovski

3 Answers

1
votes

Edit If you are using version 2.16.0 or above, you'll need to do this:

CodePen for v2.16.0 +

// v2.16.0 or higher
...
changeFilter(field, newFilter) {
      let newCols = JSON.parse(JSON.stringify(this.columns));
      let found = newCols.find(c => {
        return c.field == field;
      });
      console.log(found);
      if (found) {
        if (found.hasOwnProperty("filterOptions")) {
            found.filterOptions.filterValue = newFilter;
            this.columns = newCols;
        } else {
          alert(`Column '${field}' does not have filtering configured!`);
        }
      } else {
        alert(`Field '${field}' does not exist!`);
      }
}

Original Answer

If I am understanding this correctly you want to set the filter for a field programmatially... Something like this should work.. Click the button to change the filter programamaticlly... If you change this line to any valid name, it will filter by that name... Change 'Bob' to a valid name...(like Dan)...

<button 
  style="width:200px;" 
  @click.stop="changeFilter('name', 'Bob')"
>Click To Change Name Filter</button>

CodePen Mirror

const vm = new Vue({
  el: "#app",
  name: "my-component",
  data: {
    columns: [
      {
        label: "Name",
        field: "name",
        filterOptions: {
          enabled: true, // enable filter for this column
          placeholder: "Filter Name", // placeholder for filter input
          filterValue: "", // initial populated value for this filter
          filterDropdownItems: [], // dropdown (with selected values) instead of text input
          filterFn: this.columnFilterFn, //custom filter function that
          trigger: "enter" //only trigger on enter not on keyup
        }
      },
      {
        label: "Age",
        field: "age",
        type: "number"
      },
      {
        label: "Created On",
        field: "createdAt",
        type: "date",
        dateInputFormat: "YYYY-MM-DD",
        dateOutputFormat: "MMM Do YY"
      },
      {
        label: "Percent",
        field: "score",
        type: "percentage"
      }
    ],
    rows: [
      {
        id: 1,
        name: "John",
        age: 20,
        createdAt: "201-10-31:9: 35 am",
        score: 0.03343
      },
      {
        id: 2,
        name: "Jane",
        age: 24,
        createdAt: "2011-10-31",
        score: 0.03343
      },
      {
        id: 3,
        name: "Susan",
        age: 16,
        createdAt: "2011-10-30",
        score: 0.03343
      },
      {
        id: 4,
        name: "Bob",
        age: 55,
        createdAt: "2011-10-11",
        score: 0.03343
      },
      {
        id: 5,
        name: "Dan",
        age: 40,
        createdAt: "2011-10-21",
        score: 0.03343
      },
      {
        id: 6,
        name: "John",
        age: 20,
        createdAt: "2011-10-31",
        score: 0.03343
      }
    ]
  },
  methods: {
    clearFilter(field) {
      try {
        let found = this.columns.find((c) => {
          return c.field == field
        });
        found.filterOptions.filterValue = "";
      } catch {
        alert(`Unable to clear ${field} filter`)
      }
    },
    changeFilter(field, newFilter) {
      let found = this.columns.find((c) => {
        return c.field == field
      });
      if(found) {
        if(found.hasOwnProperty("filterOptions")) {
          if(found.filterOptions.hasOwnProperty("filterValue")) {
            found.filterOptions.filterValue = newFilter;
          } else {
            alert(`Column '${field}' does not have filterValue property!`)
          }          
        } else {
          alert(`Column '${field}' does not have filtering configured!`)
        }
      } else {
        alert(`Field '${field}' does not exist!`)
      }
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-good-table.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-good-table.css" rel="stylesheet"/>

<div id="app">
  <div>
    <div style="margin:10px 10px 10px 10px;">
      <button 
        style="width:200px;" 
        @click.stop="changeFilter('name', 'Bob')"
      >Click To Change Name Filter</button>
      <button 
        style="width:200px;" 
        @click.stop="clearFilter('name')"
      >Clear Name Filter</button>
    </div>
    <vue-good-table :columns="columns" :rows="rows" />
  </div>
</div>
0
votes

Vue cannot detect normal property additions (e.g. this.myObject.newProperty = 'hi')

Therefore, using this.$set(this.table.columnsFilters, 'name', 'bob') instead of your code.

More information about $set

0
votes

See: https://github.com/xaksis/vue-good-table/issues/475

Official recommended method of doing this for version >= 2.17.5:

this.$set(this.columns[foundIndex].filterOptions, 'filterValue', value);

If you want to have it done using $route query params:

for (var key in this.$route.query){
    var field = key;
    let foundIndex = this.columns.findIndex((c) => {
      return c.field == field
    });

    if (foundIndex !== -1 ){
      this.$set(this.columns[foundIndex].filterOptions, 'filterValue', this.$route.query[key]);
    }
}