我有一个项目与nextjs和typescript。我使用prime react作为我项目的UI工具包。在我的一个页面上,我有一个表,在这个表中,每一行都有一个复选框,用于选择该行此外,如果用户点击一行,它应该导航到另一个页面。我的问题是,当我dblClick上的行复选框被触发(onSelectionChange方法触发器)。我知道prime表可以得到selectionMode='checkbox' prop和在这种情况下,复选框触发只有当用户点击一个复选框本身,但我想如果用户singleclick上一行onSelectionChange触发器也。
我为prime表组件(<" table someProps/>)写了一个包装器
这是我的代码
import React, {useEffect, useState} from 'react';
import {DataTableDataSelectableParams} from 'primereact/datatable';
import Table from '../Table';
import {AutoCompleteCompleteMethodParams} from 'primereact/autocomplete';
import {FlightStaticService} from '../../../adapter/FlightStaticService';
import OptionsMenu from '../../OptionsMenu/OptionsMenu';
import {InputSwitch} from 'primereact/inputswitch';
import InputWrapper from '../../InputWrapper/InputWrapper';
import {FlightService} from '../../../adapter/FlightService';
import ConfirmationStatus from '../../ConfirmationStatus/ConfirmationStatus';
import {useRouter} from 'next/router';
const flightStaticInstance = new FlightStaticService();
const flightInstance = new FlightService();
const FlightsListTable = () => {
const [selectedRows, setSelectedRows] = useState<{ [key: string]: string | number | boolean }[]>([]);
const [filteredAirlines, setFilteredAirlines] = useState([]);
const [filteredAirports, setFilteredAirports] = useState([]);
const [shouldUpdateTable, setShouldUpdateTable] = useState(false);
const router = useRouter();
const searchAirlines = (e: AutoCompleteCompleteMethodParams) => {
if (!e.query) {
e.query = 'as';
}
flightStaticInstance
.getAirlines(e.query)
.then((res) => {
setFilteredAirlines(res.data.result);
})
.catch(e => {
setFilteredAirlines([]);
});
};
const searchAirports = (e: AutoCompleteCompleteMethodParams) => {
if (!e.query) {
e.query = 'meh';
}
flightStaticInstance
.getAirports(e.query)
.then((res) => {
setFilteredAirports(res.data.result);
})
.catch(e => {
setFilteredAirports([]);
});
};
const isRowSelectable = (event: DataTableDataSelectableParams) => {
const data = event.data;
if (selectedRows.find((sel) => sel.id === data.id)) {
return true;
}
return selectedRows.length < 2 && data.isActive;
};
useEffect(() => {
if (shouldUpdateTable) {
setShouldUpdateTable(false);
}
}, [shouldUpdateTable]);
useEffect(() => {
if (selectedRows.length > 0) {
sessionStorage.setItem('flights', JSON.stringify(selectedRows));
}
}, [selectedRows]);
const confirmStatusBodyTemplate = (rowData: any) => {
return <ConfirmationStatus status={rowData.status}/>
};
const statusBodyTemplate = (rowData: any) => {
return rowData.isActive ? 'فعال' : 'غیرفعال';
};
const optionsBodyTemplate = (rowData: any) => {
return <OptionsMenu options={[{
type: 'link',
url: `/flight/${rowData.id}`,
label: 'جزییات پرواز',
iconName: 'icon-note-text2'
}, {
type: 'link',
url: `/flight/${rowData.id}/edit`,
label: 'ویرایش پرواز',
iconName: 'icon-edit-2'
},
{
type: 'link',
url: `/flight/${rowData.id}/pricing?flightGroupTitle=${rowData.flightGroupTitle}`,
label: 'تقویم قیمتی',
iconName: 'icon-calendar-2'
},
{
type: 'element',
element: <div className='w-full' onClick={e => e.stopPropagation()}>
<InputWrapper labelClassName='text-grey-4' className='w-full' labelBeforeInput={true}
labelBesideInput label='وضعیت'>
<InputSwitch
onChange={e => {
flightInstance.toggleFlightStatus(rowData.id).then(res => {
setShouldUpdateTable(true);
}).catch(e => {
});
}
}
checked={rowData.isActive}
className='mr-auto'/>
</InputWrapper>
</div>
}
]}/>
}
return (
<Table
url="/Flight/GetFlights"
shouldUpdateTable={shouldUpdateTable}
filters={[
{
name: 'airlineId',
label: 'ایرلاین',
type: 'autocomplete',
value: '',
suggestions: filteredAirlines,
completeMethod: searchAirlines,
optionValue: 'iata',
optionType: 'string',
fieldName: 'nameFa'
},
{
name: 'flightGroupTitle',
label: 'عنوان پرواز',
type: 'text',
value: ''
},
{
name: 'originAirPortId',
label: 'فرودگاه مبدا',
type: 'autocomplete',
value: '',
optionValue: 'iata',
optionType: 'string',
suggestions: filteredAirports,
completeMethod: searchAirports,
fieldName: 'nameFa'
},
{
name: 'destinationAirPortId',
label: 'فرودگاه مقصد',
type: 'autocomplete',
value: '',
optionValue: 'iata',
optionType: 'string',
suggestions: filteredAirports,
completeMethod: searchAirports,
fieldName: 'nameFa'
}
]}
columns={[
{
field: 'airlineNameFa',
header: 'ایرلاین',
},
{
field: 'flightGroupTitle',
header: 'عنوان پرواز',
sortable: true,
},
{field: 'originCityNameFa', header: 'مبدا'},
{field: 'destinationCityNameFa', header: 'مقصد'},
{field: 'baggageAllowance', header: 'بار مجاز', sortable: true},
{
field: 'confirmStatus',
header: 'وضعیت تایید',
body: confirmStatusBodyTemplate,
},
{
field: 'isActive',
header: 'وضعیت',
body: statusBodyTemplate,
},
{
field: 'options',
body: optionsBodyTemplate
},
]}
tableProps={{
selection: selectedRows,
onSelectionChange: (e) => setSelectedRows(e.value),
isDataSelectable: isRowSelectable,
showSelectAll: false,
rowClassName: (data) => data.isActive ? '' : 'text-disabled',
onRowDoubleClick: (e) => router.push(`/flight/${e.data.id}`)
}}
/>
);
};
export default FlightsListTable;
好的,这里是一个工作代码沙箱,它显示了您想要做的事情:
https://codesandbox.io/s/primereact-datatable-single-and-double-click-selection-0in9em?file=/src/demo/DataTableSelectionDemo.js
技巧是自己处理onRowClick
。
const onRowClick = (event) => {
if (event.originalEvent.detail === 1) {
timer.current = setTimeout(() => {
const selected = [...selectedProducts8];
selected.push(event.data);
setSelectedProducts8(selected);
}, 300);
}
};
const onRowDoubleClick = (e) => {
clearTimeout(timer.current);
console.log("dblclick");
};
如果你同意这个,不要忘记选择这个作为正确的答案。