lundi 3 juillet 2023

How to handle checkbox change in React.js?

I'm trying to handle change of the value when a check box is clicked. The component loads a response like this:

[
   {
       "id_ver_group": 7,
       "checklist": [
           {
            "check": "Custom ver 1",
            "valor": false,
            "opcional": true
           },
        {
            "check": "Custom ver 2",
            "valor": false,
            "opcional": false
        }
       ],
       "id_ver_group_char": "7",
       "fecha_crea": "2023-07-02T18:07:56.756521"
  },
  {
       "id_ver_group": 6,
       "checklist": [
           {
               "check": "Custom ver 1",
               "valor": false,
               "opcional": true
           },
           {
               "check": "Custom ver 2",
               "valor": false,
               "opcional": false
           },
       ],
       "id_ver_group_char": "7",
       "fecha_crea": "2023-07-02T18:07:56.756521"
  },
]

The response is grouped by "id_ver_group" in an "Accordion" tag where each "checklist" item is displayed in a table, its columns are: "verify" (string), "value" (bool) and "optional " (bool) , the checkbox tag is used to display the "value" and "optional" columns, the latter being read-only. This is the component code:

// imports...
import {
  Accordion,
  AccordionSummary,
  AccordionDetails,
  Typography,
  Table,
  TableHead,
  TableBody,
  TableRow,
  TableCell,
  Checkbox,
  Select,
  InputLabel,
  Button,
} from '@material-ui/core'

export function AddEditChecklist(props) {
     
const { Tanques, onClose, onRefetch } = props
const { Successful, errores } = alertas()
const { Data, getBaseVer } = useVerificaciones()
const { addTankVer, updateTankVer } = useTanques()
const { OperadorDB, getOperadorDB } = useOperador()
const [selectedOperator, setSelectedOperator] = useState('');
const [isOperatorSelected, setIsOperatorSelected] = useState(true);

const [selectedGroup, setSelectedGroup] = useState(null);
  const [selectedGroupIndex, setSelectedGroupIndex] = useState(null);

  useEffect(() => {
    getOperadorDB()
    getBaseVer()
  }, []);

  const [data, setData] = useState([]);

  useEffect(() => {
    setData(Data?.map(item => ({
      ...item,
      checklist: item.checklist.map(checklistItem => ({
        ...checklistItem,
        valor: false  
      }))
    })) || []);
  }, [OperadorDB, Data]);

  const handleAccordionChange = (groupId) => {
    setSelectedGroupIndex(groupId); 
    setSelectedGroup(groupId)
    
    if (selectedGroup === groupId) {
      setSelectedGroup(null); 
    } else {
      setSelectedGroup(groupId); 
    }
  };

// check box handle
  const handleCheckboxChange = (groupId, itemIndex, checklistItem) => {
    setData((prevData) => {
      const updatedData = [...prevData];
      const groupData = updatedData[groupId];

      if (groupData && groupData[itemIndex]) {
        checklistItem.valor = !checklistItem.valor; 
      }

      return updatedData;
    });
  };

  // group data by id
  const groupedData = data ? data.reduce((groups, item) => {
    const groupId = item.id_ver_group;
    if (!groups[groupId]) {
      groups[groupId] = [];
    }
    groups[groupId].push(item);
    return groups;
  }, {}) : {};
// handleSubmit...

return (
    <>
      {/* checklist */}
      {Object.keys(groupedData).map((groupId) => (
        <Accordion
          key={groupId}
          expanded={selectedGroup === groupId}
          onChange={() => handleAccordionChange(groupId)}
        >
          <AccordionSummary expandIcon={<ExpandMoreIcon />}>
            <Typography variant="h6">Conjunto de verificaciones # {groupId}</Typography>
          </AccordionSummary>
          <AccordionDetails>
            <div>
              {groupedData[groupId].map((item, index) => (
                <div key={item.id_ver_group}>
                  <Table>
                    <TableHead>
                      <TableRow>
                        <TableCell><strong>Verificación</strong></TableCell>
                        <TableCell><strong>¿Cumple?</strong></TableCell>
                        <TableCell><strong>¿Opcional? (no modificable)</strong></TableCell>
                      </TableRow>
                    </TableHead>
                    {item.checklist.map((checklistItem) => (
                      <TableBody key={checklistItem.check}>
                        <TableRow>
                          <TableCell>
                            {checklistItem.check}
                          </TableCell>
                          <TableCell>
                            <Checkbox
                              checked={checklistItem.valor}
                              name={checklistItem.check}
                              onChange={() => handleCheckboxChange(groupId, index, checklistItem)}
                            />
                          </TableCell>
                          <TableCell>
                            <Checkbox
                              readOnly
                              checked={checklistItem.opcional}
                              name={checklistItem.check}
                            />
                          </TableCell>
                        </TableRow>
                      </TableBody>
                    ))}
                  </Table>
                </div>
              ))}
            </div>
          </AccordionDetails>
        </Accordion>
      ))}
      <br></br>
      <Divider></Divider>
      <br></br>
      <Button variant="contained" color="primary" onClick={handleSubmit}>
        Save
      </Button>
    </>
  )
} 

Doing some research, I was able to come up with something to handle the checkbox changing, but the checkbox doesn't change its value when clicked. I really don't know how to solve this. Any help is appreciated.




Aucun commentaire:

Enregistrer un commentaire