skip to Main Content

I am creating a table in React that has multiple rows. For each row there will be a React component underneath called AutoShopPricesExpanded that has more details about that row’s prices. When I click on a single row I want to show only 1 of the components underneath.

Currently, the code shows all the components for every row when the user clicks on the ‘Toggle Show’ button.

My question is, how do I only show a single component for the relevant table row.

The code below is my current progress

import { Box, Text, Table, Tbody, Td, Th, Thead, Tr} from '@chakra-ui/react';
import {AutoShopPriceExpand} from './autoShopPriceExpand';
import { useState } from 'react';

export const AutoShopPricesList = ({filteredAutoShopPricesLists}:{filteredAutoShopPricesLists: any}) => {
    const [isOpen, setIsOpen] = useState(false);
    function toggle() {
        setIsOpen((isOpen) => !isOpen);
    }

    return (
        <Box py={1}>
            <Table variant='striped'>
                <Thead>
                    <Tr>
                        <Th>Vehicle</Th>
                        <Th>Service</Th>
                        <Th isNumeric>Price</Th>
                    </Tr>
                </Thead>
                <Tbody>
                    {filteredAutoShopPricesLists.map((autoshop: any)=>{
                        return(
                            <>
                                <button onClick={toggle}>Toggle show</button>
                                <Tr key = "lol">
                                    <Td>{autoshop.car_year} {autoshop.car_make} {autoshop.car_model} <br/> <Text color='gray' fontSize='sm'> {autoshop.car_trim} </Text></Td>
                                    <Td>{autoshop.service} <br/>  <Text color='gray' fontSize='sm'>{autoshop.date_of_quote} </Text> </Td>
                                    <Td isNumeric> ${autoshop.service_price} <br/>  <Text color='gray' fontSize='sm'>{autoshop.source_of_price} </Text></Td>
                                </Tr>
                                {isOpen && <AutoShopPriceExpand details = {autoshop}/>}
                            </>
                        );
                        
                    })}
                </Tbody> 
            </Table>  
        </Box>
    );
};

2

Answers


  1. you can achieve this using multiple approaches.

    1. You can keep "isopen" flag inside your "filteredAutoShopPricesLists" object and then individual "AutoShopPrice" will have their own "isopen" flag.
    2. Otherwise you can keep key-value pair list to store "isOpen" like this
      const [isItemOpen, setIsItemOpen] = useState<Array<{id:string,isOpen:boolean}>>([]);
      const toogle =(id:string)=>{
        //find and update or insert
    
      }
      const getIsOpen = (id:string)=>{
        // find and return val or return false
      }
    Login or Signup to reply.
  2. You can try this code,in which the toggle function takes the index of the clicked row, and the isRowOpen variable is used to conditionally render the AutoShopPriceExpand component only for the clicked row.

    import { Box, Text, Table, Tbody, Td, Th, Thead, Tr } from '@chakra-ui/react';
    import { AutoShopPriceExpand } from './autoShopPriceExpand';
    import { useState } from 'react';
    
    export const AutoShopPricesList = ({ filteredAutoShopPricesLists }: { filteredAutoShopPricesLists: any }) => {
      const [openRowIndex, setOpenRowIndex] = useState<number | null>(null);
    
      function toggle(index: number) {
        setOpenRowIndex((prevIndex) => (prevIndex === index ? null : index));
      }
    
      return (
        <Box py={1}>
          <Table variant='striped'>
            <Thead>
              <Tr>
                <Th>Vehicle</Th>
                <Th>Service</Th>
                <Th isNumeric>Price</Th>
              </Tr>
            </Thead>
            <Tbody>
              {filteredAutoShopPricesLists.map((autoshop: any, index: number) => {
                const isRowOpen = openRowIndex === index;
    
                return (
                  <React.Fragment key={index}>
                    <Tr key={index}>
                      <Td>
                        {autoshop.car_year} {autoshop.car_make} {autoshop.car_model} <br />
                        <Text color='gray' fontSize='sm'>
                          {' '}
                          {autoshop.car_trim}{' '}
                        </Text>
                      </Td>
                      <Td>
                        {autoshop.service} <br />
                        <Text color='gray' fontSize='sm'>{autoshop.date_of_quote} </Text>{' '}
                      </Td>
                      <Td isNumeric>
                        ${autoshop.service_price} <br />
                        <Text color='gray' fontSize='sm'>{autoshop.source_of_price} </Text>
                      </Td>
                      <Td>
                        <button onClick={() => toggle(index)}>Toggle show</button>
                      </Td>
                    </Tr>
                    {isRowOpen && <AutoShopPriceExpand details={autoshop} />}
                  </React.Fragment>
                );
              })}
            </Tbody>
          </Table>
        </Box>
      );
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search