I have a project with nextjs and typescript.I use prime react as a UI kit for my project. On one of my pages I have a table and in this table I have a checkbox per row for select that row also if user dblClicked on a row it should navigate into another page.my issue is when I dblClick on a row checkbox is triggered(onSelectionChange method trigger). I know that prime table can get selectionMode=’checkbox’ prop and in that case checkbox triggered only if user clicks on a checkbox itself but I want if user singleClicks on a row onSelectionChange trigger too.
I wrote a wrapper for prime table component (<“Table someProps />)
this is my code
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;
Advertisement
Answer
OK here is a working Code Sandbox showing exactly what you want to do:
The trick is to handle onRowClick
yourself.
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"); };
If you agree with this don’t forget to select this as the right answer.