BTable Filter with a Function

冷暖自知 提交于 2019-12-24 11:08:07

问题


i've been struggling for almost 6 hours with this, but i didn't find a way to accomplish what i need.

the thing is that i need to filter the table of bootstrap vue with a function, but i can't make it work, there is a step that i need, but i can't find it.

here it is a jsfiddle that i grab from the web, that has the simple b-table with property filter.

https://jsfiddle.net/rothariger/oxbrhcqk/1/

now if you check on this example I've replaced the property for a function, but, it just get called in the load, when you change the filter textbox, it doesn't do anything, and here is where i think i'm missing a step.

https://jsfiddle.net/rothariger/oxbrhcqk/3/

new Vue({
  el: '#app',
  data: {
    items: [{
      isActive: true,
      age: 40,
      name: {
        first: 'Dickerson',
        last: 'Macdonald'
      }

    }, {
      isActive: false,
      age: 21,
      name: {
        first: 'Larsen',
        last: 'Shaw'
      }

    }, {
      isActive: false,
      age: 9,
      state: 'success',
      name: {
        first: 'Mitzi',
        last: 'Navarro'
      }

    }, {
      isActive: false,
      age: 89,
      name: {
        first: 'Geneva',
        last: 'Wilson'
      }

    }, {
      isActive: true,
      age: 38,
      name: {
        first: 'Jami',
        last: 'Carney'
      }

    }, {
      isActive: false,
      age: 27,
      name: {
        first: 'Essie',
        last: 'Dunlap'
      }

    }, {
      isActive: true,
      age: 40,
      name: {
        first: 'Dickerson',
        last: 'Macdonald'
      }

    }, {
      isActive: false,
      age: 21,
      name: {
        first: 'Larsen',
        last: 'Shaw'
      }

    }, {
      isActive: false,
      age: 26,
      name: {
        first: 'Mitzi',
        last: 'Navarro'
      }

    }, {
      isActive: false,
      age: 22,
      name: {
        first: 'Geneva',
        last: 'Wilson'
      }

    }, {
      isActive: true,
      age: 38,
      name: {
        first: 'Jami',
        last: 'Carney'
      }

    }, {
      isActive: false,
      age: 27,
      name: {
        first: 'Essie',
        last: 'Dunlap'
      }

    }],
    fields: {
      name: {
        label: 'Person Full name',
        sortable: true
      },
      age: {
        label: 'Person age',
        sortable: true
      },
      isActive: {
        label: 'is Active'
      },
      actions: {
        label: 'Actions'
      }
    },
    currentPage: 1,
    perPage: 5,
    filter: null
  },
  methods: {
    details(item) {
      alert(JSON.stringify(item));
    },
    filterGrid(val) {
      console.log(val);
      return true;
    }
  }
})

any info on what i have to do?

regards.


回答1:


As Vue Bootstrap introdues:,

The filter prop value can be a string, a RegExp or a function reference. If a function is provided, the first argument is the original item record data object. The function should return true if the record matches your criteria or false if the record is to be filtered out.

Then look into the source code at Vue Bootstrap Github, you will find Vue Bootstrap only invoke your filter function inside one computed property=computedItems.

So for your case:

filterGrid(val) {
  console.log(val);
  return true;
}

It does not trigger any reactivity (print then always return true), so it will do nothing (computed property=computedItems will not be re-calculated, so filter function will not be executed either).

so one simple filter function with reactivity will be like:

filterGrid(val){
    return !this.filter || JSON.stringify(val).includes(this.filter)
}

Also you can involves other data/prop/computed property, the filter function will be executed also when reactivity is triggered.

The full demo:

new Vue({
  el: '#app',
  data: {
    items: [{
      isActive: true,
      age: 40,
      name: {
        first: 'Dickerson',
        last: 'Macdonald'
      }

    }, {
      isActive: false,
      age: 21,
      name: {
        first: 'Larsen',
        last: 'Shaw'
      }

    }, {
      isActive: false,
      age: 9,
      state: 'success',
      name: {
        first: 'Mitzi',
        last: 'Navarro'
      }

    }, {
      isActive: false,
      age: 89,
      name: {
        first: 'Geneva',
        last: 'Wilson'
      }

    }, {
      isActive: true,
      age: 38,
      name: {
        first: 'Jami',
        last: 'Carney'
      }

    }, {
      isActive: false,
      age: 27,
      name: {
        first: 'Essie',
        last: 'Dunlap'
      }

    }, {
      isActive: true,
      age: 40,
      name: {
        first: 'Dickerson',
        last: 'Macdonald'
      }

    }, {
      isActive: false,
      age: 21,
      name: {
        first: 'Larsen',
        last: 'Shaw'
      }

    }, {
      isActive: false,
      age: 26,
      name: {
        first: 'Mitzi',
        last: 'Navarro'
      }

    }, {
      isActive: false,
      age: 22,
      name: {
        first: 'Geneva',
        last: 'Wilson'
      }

    }, {
      isActive: true,
      age: 38,
      name: {
        first: 'Jami',
        last: 'Carney'
      }

    }, {
      isActive: false,
      age: 27,
      name: {
        first: 'Essie',
        last: 'Dunlap'
      }

    }],
    fields: {
      name: {
        label: 'Person Full name',
        sortable: true
      },
      age: {
        label: 'Person age',
        sortable: true
      },
      isActive: {
        label: 'is Active'
      },
      actions: {
        label: 'Actions'
      }
    },
    currentPage: 1,
    perPage: 5,
    filter: null
  },
  methods: {
    details(item) {
      alert(JSON.stringify(item));
    },
    filterGrid(val){
    	return !this.filter || JSON.stringify(val).includes(this.filter)
    }
  }
})
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css"/>
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css"/>

<!-- Add this after vue.js -->
<script src="https://unpkg.com/vue@2.5.17/dist/vue.min.js"></script>
<script src="https://unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>

<div id="app">
  <div class="justify-content-centermy-1 row">

    <b-form-fieldset horizontal label="Rows per page" class="col-6" :label-size="6">
      <b-form-select :options="[{text:5,value:5},{text:10,value:10},{text:15,value:15}]" v-model="perPage">
      </b-form-select>
    </b-form-fieldset>

    <b-form-fieldset horizontal label="Filter" class="col-6" :label-size="2">
      <b-form-input v-model="filter" placeholder="Type to Search"></b-form-input>
    </b-form-fieldset>
  </div>

  <!-- Main table element -->
  <b-table striped hover :items="items" :fields="fields" :current-page="currentPage" :per-page="perPage" :filter="filterGrid">
    <template slot="name" scope="item">
      {{item.value.first}} {{item.value.last}}
    </template>
    <template slot="isActive" scope="item">
      {{item.value?'Yes :)':'No :('}}
    </template>
    <template slot="actions" scope="item">
      <b-btn size="sm" @click="details(item.item)">Details</b-btn>
    </template>
  </b-table>

  <div class="justify-content-center row my-1">
    <b-pagination size="md" :total-rows="this.items.length" :per-page="perPage" v-model="currentPage" />
  </div>
</div>


来源:https://stackoverflow.com/questions/52415889/btable-filter-with-a-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!