saadeghi / daisyui

๐ŸŒผ ๐ŸŒผ ๐ŸŒผ ๐ŸŒผ ๐ŸŒผ โ€ƒThe most popular, free and open-source Tailwind CSS component library
https://daisyui.com
MIT License
34.14k stars 1.3k forks source link

bug: Modal display always the first item in an array #3121

Closed DenisBytes closed 4 months ago

DenisBytes commented 4 months ago

What version of daisyUI are you using?

v4.12.2

Which browsers are you seeing the problem on?

Firefox, Other

Reproduction URL

https://notpublicrepo.com

Describe your issue

Description When i loop thorough the certificate from the CertificateTable component to CerticateRow it displays every single item in certificates correctly. but when i pass that single item to CertificateRowDelete it always displays and refers to the first item in the array. the problem is the daisyui modal classes, beacuse when i removed theme id displaayed every single item correctly. I believe there is some caching / storing mechanism taking place?

Tech: React+Vite+JS

export function CertificatesTable() {
    const {
        data: certificates,
        isLoading,
        isSuccess,
        isError,
        error
    } = useGetCertificatesQuery()
    return (
        <>
            <div className="border shadow-sm rounded-lg">
                {isLoading ? CertificatesTableSkeleton() : ""}
                {!isLoading?<Table>
                    <TableHeader>
                        <TableRow>
                            <TableHead className="hidden md:table-cell">Common Name</TableHead>
                             <TableHead>...</TableHead>
                             <TableHead></TableHead>
                        </TableRow>
                    </TableHeader>
                    <TableBody>
                        {isSuccess ?
                            (certificates.length > 0 ?
                                [...Array(certificates.length)].map((cert, index) => (
                                <CertificateRow data={certificates[index]} key={index} />
                            )): <TableRow> </TableRow>)
                            : ""
                        }
                    </TableBody>
                </Table>:""}
                {isError ? <div className='flex justify-center text-center py-4'>
                            Error fetching data
                        </div>:""}
                {
                    isSuccess  && certificates.length <= 0 ? (
                        <div className='flex justify-center text-center py-4'>
                            No data to display
                        </div>
                    ) : ""
                }
            </div>
        </>
    );
}

function CertificateRow(data, key) {
    const certificate = data.data
    return (
        <TableRow key={data.key}>
            <TableCell  className="font-medium hover:cursor-pointer">{certificate.common_name || "/"} 
            </TableCell>
            <TableCell className="hidden md:table-cell">
            ...
            </TableCell>
            <TableCell className='hidden md:table-cell md:flex justify-center'>
                <label htmlFor="delete_modal" className="btn hover:text-red-500">
                    <FontAwesomeIcon icon={faTrash} title='Delete' className="h-6 w-6" />
                </label>
                <CertificateRowDelete certificate={certificate} />
            </TableCell>
        </TableRow>
    );
}

export function CertificateRowDelete(data) {
    const [ deleteCertificate, response] = useDeleteCertificateMutation()
    const { register, handleSubmit, reset } = useForm();
    const onSubmit = async () => {
        deleteCertificate({ "sha1": data.certificate._key })
            .unwrap()
            .then(() => { })
            .catch((error) => {
                console.log(error)
            })
        reset();
    }
    return (
        <>
            <input type="checkbox" id="delete_modal" className="modal-toggle" />
            <div className="modal" role="dialog">
                <div className="modal-box max-w-[50%]">
                    <h3 className="text-lg font-bold">Confirmation</h3>
                    <p className="py-4">Are you sure you want to delete {data.certificate._key}?</p>
                    <div className="modal-action">
                        <form className='flex text-center items-center' onSubmit={handleSubmit(onSubmit)}>
                            <Button type="submit" className="btn bg-black text-white hover:bg-slate-800">Save</Button>
                            <label htmlFor="delete_modal" className="btn bg-slate-300 hover:bg-slate-200">Close</label>
                        </form>
                    </div>
                </div>
            </div>
        </>
    )
}
github-actions[bot] commented 4 months ago

Thank you @DenisBytes for reporting issues. It helps daisyUI a lot ๐Ÿ’š
I'll be working on issues one by one. I will help with this one as soon as a I find a solution.
In the meantime providing more details and reproduction links would be helpful.

saadeghi commented 4 months ago

daisyUI is just CSS. It can't change the functionality of your content or the content of arrays.

I have to close this issue because it's not related to daisyUI. However I would be happy to help.

but when i pass that single item to CertificateRowDelete it always displays and refers to the first item in the array

I'm not sure if I'm understanding the issue. what's the array?

the problem is the daisyui modal classes, beacuse when i removed theme id displaayed every single item correctly.

How is it related to theme id?

I believe there is some caching / storing mechanism taking place?

No. daisyUI is just CSS.

DenisBytes commented 3 months ago

My fault. The error was with not daisyui indeed. It was useForm. every time i looped through the map, the "register" function was reassigning the same value to the same useState. the solution is to put inside the map a component, and inside the component put the useForm(), in order to have new states everytime it loops, if it makes sense.