I am using Vue via via CDN to add progressive reactivity to a few pages in an existing website. I have found the PrimeView DataTable which seems very capable and offers comprehensive filter functionality. The filtering is working fine via the UI, but when the user applies a filter, I cannot figure out how to get the list of rows in the current filter.
This is pretty much the same question as here: Filtered array in PrimeVue datatable?
The accepted answer does not explain how to access the methods/properties from javascript. I have tried the Vue.js devtools but still cannot find the answer
Filters are stored as an object in your local state. Try using the Vue.js devtools extension to see the format of that object.
How do I get the filtered array from the DataTable when using the built-in filters
property?
Here is a simple example. The filter "bob" is applied using the filters
property of the DataTable. When the user clicks the "Show Alert" button, the alert should show all the customers in the currently filtered list (Bob Smith, Bob Jones and Bob Tailor)
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/primevue/umd/primevue.min.js"></script>
<script src="https://unpkg.com/@primevue/themes/umd/aura.min.js"></script>
<div id="app">
<input type="text" v-model="customerFilters['global'].value" />
Searching for: {{customerFilters['global'].value}}
<p-datatable :value="customers" :filters="customerFilters">
<p-column field="fullname" header="Full Name"></p-column>
<p-column field="sales" header="Total Sales"></p-column>
</p-datatable>
<button @click="showAlert">Show Alert</button>
</div>
<script>
const { createApp, ref } = Vue
const customers = ref([
{ fullname: "Bob Smith", sales: 11 },
{ fullname: "Bob Jones", sales: 22 },
{ fullname: "Bob Tailor", sales: 33 },
{ fullname: "Fred Bloggs", sales: 44 },
{ fullname: "Fred Baker", sales: 55 },
{ fullname: "Tom Peterson", sales: 66 },
])
const customerFilters = ref({
global: { value: "Bob", matchMode: PrimeVue.FilterMatchMode.CONTAINS },
})
function showAlert() {
let filteredCustomers = [] // ???
let str = "Customers in filter: "
// str += filteredCustomers[0]["fullname"] + ", "
// str += filteredCustomers[1]["fullname"] + ", "
// str += filteredCustomers[2]["fullname"]
alert(str) // "Customers in filter: Bob Smith, Bob Jones, Bob Tailor"
}
const app = createApp({
setup() {
return {
customers,
customerFilters,
showAlert
}
},
})
app.use(PrimeVue.Config, {
theme: {
preset: PrimeVue.Themes.Aura
}
})
app.component("p-datatable", PrimeVue.DataTable)
app.component("p-column", PrimeVue.Column)
app.mount("#app")
</script>
Fiddle: https://jsfiddle.net/kq4sr85u/14/
Or am I going about this completely the wrong way? Would it be better to use a computed to filter the array in the view-model and bind the DataTable to the computed, filtered array. I know this would work but it seems crazy when the PrimeVue DataTable has all the advanced filter functionality already baked-in out the box.
Unfortunately, it seems that PrimeVue did not document a way to access filtered data directly, which is indeed strange for such a powerful component. However, it is still possible to do that in the following way:
const datatable = useTemplateRef('datatable');
<p-datatable :value="customers" :filters="customerFilters" ref="datatable">
...
</p-datatable>
processedData
computed property is the one you are looking for:const showAlert = () => {
let filteredCustomers = datatable.value.processedData
let str = "Customers in filter: "
str += filteredCustomers.map(customer => customer.fullname).join();
alert(str)
}
As an alternative, you can use the event-based approach, and just store the latest known event.filteredValue
in a ref:
const filteredRows = ref([])
const onDatatableFilter = event => {
filteredRows.value = event.filteredValue
}
const showAlert = () => {
//access filteredRows.value
}
I have created an updated fiddle for your example: https://jsfiddle.net/293ot74d/