有人可以帮助我使用数据表过滤器吗?
我有一个对象。该对象具有由字符串 0、1 或 2 提供的 paymentStatus(不要问我为什么不是 int 哈哈)。我有 const paymentStatuses 是一个对象。我有钥匙名称、代码和严重性。
我的过滤器不起作用。我不知道为什么。
<script setup>
import { FilterMatchMode } from 'primevue/api';
import { storeToRefs } from 'pinia'
import { ref, onMounted } from 'vue';
import { CharteredService } from '@/service/CharteredService';
import { useToast } from 'primevue/usetoast';
const toast = useToast();
const { $api } = useNuxtApp();
const selectedChartered = ref()
const charteredList = ref()
const charteredItem = ref(
{
"type": "",
"name": "",
"description": "",
"client": "",
"performer": "",
"contacts": "",
"orderSumm": "",
"paymentType": "",
"paymentStatus": 0,
"orderDate": "",
"receiptDate": "",
"dopInfo": ""
}
)
const filters = ref({
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
paymentStatuses: {value: null, matchMode: FilterMatchMode.IN },
});
const onChartSelect = async (event) => {
selectedChartered.value = event.data
};
const onChartUnselect = async (event) => {
}
const onCellEditComplete = async (event) => {
let { data, newValue, field } = event;
if (data[field] !== newValue) {
data[field] = newValue;
await CharteredService.updateChartered(data)
.then(response => response.json())
.then(result =>
toast.add({ severity: 'success', summary: 'Данные успешно сохранены!', detail: result.message, life: 4000 })
)
.catch((err) => {
let data = JSON.parse(err.request.response);
toast.add({ severity: 'error', summary: 'Что то пошло не так!', detail: data.error_description, life: 4000 });
})
}
else {
toast.add({ severity: 'info', summary: 'Изменений нет', detail: 'Вы ничего не меняли', life: 4000 });
}//event.preventDefault();
};
onMounted(async () => {
await CharteredService.loadCharteredList()
.then(response => response.json())
.then(result => charteredList.value = result.result)
});
const paymentStatuses = ref([
{ name: 'Ожидает оплаты', code: '0', severity: 'danger' },
{ name: 'Оплачено', code: '1', severity: 'success' },
{ name: 'В работе', code: '2', severity: 'info' },
])
const expandedRows = ref([]);
const addNewRow = () => {
charteredList.value.unshift(charteredItem.value)
CharteredService.addChartered($api, charteredItem.value)
}
const onRowExpand = (event) => {
const expandedChartedInfo = CharteredService.getCharteredInfo($api, event.data.id).then((response) => response.json().result)
}
</script>
<template>
<div class="card">
<h5>Заказные перевозки</h5>
<DataTable v-model:expandedRows="expandedRows" :filters="filters" scrollable editMode="cell" @cell-edit-complete="onCellEditComplete"
v-model:selection="selectedChartered" :value="charteredList" :paginator="true" class="p-datatable-sm"
showGridlines :rows="40" dataKey="id" :rowHover="true" responsiveLayout="scroll" filterDisplay="row"
:globalFilterFields="['name', 'contacts', 'paymentStatuses']" :metaKeySelection=false @rowSelect="onChartSelect"
@rowExpand="onRowExpand($event)"
@rowUnselect="onChartUnselect">
<template #header>
<div class="flex justify-content-between flex-column sm:flex-row">
<div class="flex">
<Button @click="addNewRow()" type="button" icon="pi pi-plus-circle" label="Новый заказ"></Button>
</div>
<div class="flex">
<span class="p-input-icon-left mb-2">
<i class="pi pi-search" />
<InputText v-model="filters['global'].value" placeholder="Искать..." style="width: 100%"
name="filterForm" />
</span>
<Button type="button" icon="pi pi-filter-slash" class="p-button-outlined mb-2 ml-2"
@click="clearFilter1()" />
</div>
</div>
</template>
<template #empty> Совпадения не найдены. </template>
<template #loading> <i class="pi pi-spin pi-spinner" style="font-size: 2rem"></i> Загрузка данных. Пожалуйста подождите. </template>
<Column expander style="width: 2rem" />
<Column header="ID" field="id" sortable style="min-width: 2rem; max-width: 2rem;">
<template #body="{ data }">
<div class="text-center p-2 border-round-sm font-bold ">{{ data.id }}</div>
</template>
</Column>
<Column header="Название" field="name" sortable sortField="name">
<template #body="{ data }">
<div>
<p v-html="data.name"></p>
</div>
</template>
<template #editor="{ data, field }">
<InputText v-model="data[field]" autofocus />
</template>
</Column>
<Column header="Тип заказа" field="type" sortable sortField="type">
<template #body="{ data }">
<div>
<p v-html="data.type"></p>
</div>
</template>
<template #editor="{ data, field }">
<InputText v-model="data[field]" autofocus />
</template>
</Column>
<Column header="Дата" field="orderDate" sortable sortField="orderDate">
<template #body="{ data }">
<div>
<p v-html="data.orderDate"></p>
</div>
</template>
<template #editor="{ data, field }">
<InputText v-model="data[field]" autofocus />
</template>
</Column>
<Column header="Контакты" field="contacts" sortable sortField="contacts">
<template #body="{ data }">
<div>
<p v-html="data.contacts"></p>
</div>
</template>
<template #editor="{ data, field }">
<InputText v-model="data[field]" autofocus />
</template>
</Column>
<Column header="Сумма" field="orderSumm" sortable sortField="orderSumm">
<template #body="{ data }">
<div>
<p v-html="data.orderSumm"></p>
</div>
</template>
<template #editor="{ data, field }">
<InputText v-model="data[field]" autofocus />
</template>
</Column>
<Column header="Тип оплаты" field="paymentType" sortable sortField="paymentType">
<template #body="{ data }">
<div>
<p v-html="data.paymentType"></p>
</div>
</template>
<template #editor="{ data, field }">
<InputText v-model="data[field]" autofocus />
</template>
</Column>
<Column header="Статус" filterField="paymentStatuses" :showFilterMenu="false" sortable sortField="paymentStatus">
<template #filter="{ filterModel, filterCallback }">
<Dropdown v-model="filterModel.value" @change="filterCallback()" :options="paymentStatuses" optionValue="code" optionLabel="name" placeholder="Статусы" class="p-column-filter" style="min-width: 12rem" :showClear="true">
<template #option="slotProps">
<Tag :value="slotProps.option.name" :severity="slotProps.option.severity" >{{ slotProps.option.name }}</Tag>
</template>
</Dropdown>
</template>
<template #body="{ data }">
<div>
<Tag v-if="data.paymentStatus === '0'" severity="danger">Ожидает оплаты</Tag>
<Tag v-if="data.paymentStatus === '1'" severity="success">Оплачено</Tag>
<Tag v-if="data.paymentStatus === '2'" severity="info">В работе</Tag>
</div>
</template>
</Column>
<template #expansion="slotProps">
<div class="p-3">
<h5>Дополнительная информация для {{ slotProps.data.name }}</h5>
<DataTable :value="slotProps.data.charteredInfo">
<Column field="id" header="ID" sortable></Column>
<Column field="dataTimeStart" header="Дата и время начала заказа" sortable></Column>
<Column field="dataTimeEnd" header="Дата и время ориентировочного освобождения" sortable></Column>
<Column field="type" header="Тип" sortable></Column>
<Column field="vedomostiiID" header="Ведомости ID"></Column>
<Column field="driver" header="Водитель"></Column>
</DataTable>
</div>
</template>
</DataTable>
</div>
</template>
首先,我尝试按照文档中的说明进行操作。但遗憾的是没有成功。
终于找到解决办法了。模板过滤器有filterCallback。由于某些原因,这对我不起作用。因此,我创建了函数 setFilterPaymentStatus 并为付款状态添加值。我更改了全局过滤器,并从 API 接收的对象项中添加了 paymentStatus。
所以,你必须这样做:
<template #filter="{ filterModel }">
<Dropdown v-model="filterModel.value" @change="setFilterPaymentStatus(filterModel.value)" :options="paymentStatuses" optionValue="code" optionLabel="name" placeholder="Статусы" class="p-column-filter" style="min-width: 12rem" :showClear="true">
<template #option="slotProps">
<Tag :value="slotProps.option.name" :severity="slotProps.option.severity" >{{ slotProps.option.name }}</Tag>
</template>
</Dropdown>
</template>
添加全局过滤器:
:globalFilterFields="['name', 'contacts', 'name', 'orderDate', 'orderSumm', 'paymentType', 'type', 'paymentStatus']"
接下来,您需要添加自定义回调:
const setFilterPaymentStatus = (value) => {
filters.value.paymentStatus.value = value}
完成!