如何解决PrimeVue中DataTable的问题

问题描述 投票:0回答:1

有人可以帮助我使用数据表过滤器吗?

我有一个对象。该对象具有由字符串 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>

首先,我尝试按照文档中的说明进行操作。但遗憾的是没有成功。

vue.js datatable nuxt.js primevue
1个回答
0
投票

终于找到解决办法了。模板过滤器有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}

完成!

© www.soinside.com 2019 - 2024. All rights reserved.