Skip to content
Advertisement

onRowDoubleClick shouldn’t trigger onSelectionChange in prime-react

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:

https://codesandbox.io/s/primereact-datatable-single-and-double-click-selection-0in9em?file=/src/demo/DataTableSelectionDemo.js

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.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement