React Table – radio input for useRowSelect

How can I use radio inputs instead of checkboxes for a selectable table in React Table?

There is an example for checkboxes but not radio buttons: https://github.com/tannerlinsley/react-table/blob/master/examples/row-selection/src/App.js

Changing the IndeterminateCheckox to use a radio input doesn’t work as the selection state is not updated in React Table:

const IndeterminateCheckbox = React.forwardRef(({ indeterminate, ...rest }, ref) => {
    const defaultRef = React.useRef();
    const resolvedRef = ref || defaultRef;

    useEffect(() => {
      resolvedRef.current.indeterminate = indeterminate;
    }, [resolvedRef, indeterminate]);

    return <input name="select-radio" type="radio" ref={resolvedRef} {...rest} />
    );
  });

It looks correct but does not pass the correct selection state back:
enter image description here

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Had a quick look. Try this:

  • Have a state for the rowId

const [selectedRowId, setSelectedRowId] = useState(null);
  • Pass autoResetSelectedRows: false, to useTable function
  • Write a click handler for the radios by hand

    onClick={() => setSelectedRowId(row.id)}

enter image description here

I have put together the working code here.
https://codesandbox.io/s/objective-faraday-gzf7y

Notes:

Method 2

Based on previous answers, the solution below is with some improvements

  1. Change Checkbox to Radio Input

    Inside IndeterminateCheckbox Component

    Remove  <input type="checkbox" ref={resolvedRef} {...rest} />*/}
    Add     <input type="radio" ref={resolvedRef} {...rest} />
  2. a) Set the initial state if you want to autoselect any row initially

    b) Deselect all the radio buttons

    c) row.getToggleRowSelectedProps().checked give the current state of the radio button of that row. So toggling that value accordingly. i.e

    if checked -> change to unchecked and

    if unchecked -> change to checked

    // This selectedRowIds state gives the information about which row is selected currently.
    const{state: { selectedRowIds }}=useTable(
    {
     ....
     initialState: {
          columns,
          data,
          selectedRowIds: { 2: true },  //a) I want my second row to be autoselected initially
       },
     },
     useRowSelect,
         hooks => {
             hooks.visibleColumns.push(columns => [
                 {
                     id: "selection",                    
                     Cell: ({ row, toggleAllRowsSelected, toggleRowSelected }) => {                      
                        const currentState = row.getToggleRowSelectedProps();
                        return (
                           <IndeterminateCheckbox
                              {...currentState}
                              onClick={() => {
                                // b)
                                  toggleAllRowsSelected(false);
                                // c)
                                  toggleRowSelected(row.id, !currentState.checked);
                          }} />)
    
                        }},
                          ...columns
                        ]);
                        })

Method 3

In case someone is still struggling with this, I found different solution.

IndeterminateCheckbox is same with slight change for input type:

const IndeterminateCheckbox = React.forwardRef(
    ({ indeterminate, ...rest }, ref) => {
        const defaultRef = React.useRef();
        const resolvedRef = ref || defaultRef;

        React.useEffect(() => {
            resolvedRef.current.indeterminate = indeterminate;
        }, [resolvedRef, indeterminate]);

        return (
            <>
                {/*<input type="checkbox" ref={resolvedRef} {...rest} />*/}
                <input type="radio" ref={resolvedRef} {...rest} />
            </>
        );
    }
);

Then onClick we deselect all rows, and select “clicked” row. 🙂
 const {
            getTableProps,
            getTableBodyProps,
            headerGroups,
            rows,
            prepareRow,
            toggleAllRowsSelected,
            toggleRowSelected,
            state: { selectedRowIds },
        } = useTable(
            {
                columns,
                data,
            },
            useRowSelect,
            hooks => {
                hooks.visibleColumns.push(columns => [
                    // Let's make a column for selection
                    {
                        id: "selection",
                        // The cell can use the individual row's getToggleRowSelectedProps method
                        // to the render a checkbox
                        Cell: ({ row }) => {
                            return (
                                <div>
                                    <IndeterminateCheckbox
                                        {...row.getToggleRowSelectedProps()}
                                        onClick={() => {
                                            toggleAllRowsSelected(false);
                                            toggleRowSelected(row.id, true);
                                        }}
                                    />
                                </div>
                            );
                        }
                    },
                    ...columns
                ]);
            }
        );


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x