This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
"use client";
|
||||
|
||||
import { Save } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
type FormSaveButtonProps = {
|
||||
formId: string;
|
||||
label?: string;
|
||||
};
|
||||
|
||||
function serializeForm(form: HTMLFormElement) {
|
||||
return JSON.stringify(
|
||||
Array.from(new FormData(form).entries()).map(([key, value]) => [
|
||||
key,
|
||||
value instanceof File ? `${value.name}:${value.size}:${value.type}` : value,
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
export function FormSaveButton({
|
||||
formId,
|
||||
label = "Speichern",
|
||||
}: FormSaveButtonProps) {
|
||||
const [isDirty, setIsDirty] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const form = document.getElementById(formId);
|
||||
|
||||
if (!(form instanceof HTMLFormElement)) {
|
||||
setIsDirty(false);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const initialSnapshot = serializeForm(form);
|
||||
|
||||
const updateDirtyState = () => {
|
||||
setIsDirty(serializeForm(form) !== initialSnapshot);
|
||||
};
|
||||
|
||||
updateDirtyState();
|
||||
|
||||
form.addEventListener("input", updateDirtyState);
|
||||
form.addEventListener("change", updateDirtyState);
|
||||
form.addEventListener("reset", updateDirtyState);
|
||||
|
||||
return () => {
|
||||
form.removeEventListener("input", updateDirtyState);
|
||||
form.removeEventListener("change", updateDirtyState);
|
||||
form.removeEventListener("reset", updateDirtyState);
|
||||
};
|
||||
}, [formId]);
|
||||
|
||||
return (
|
||||
<Button type="submit" form={formId} disabled={!isDirty}>
|
||||
<Save className="h-4 w-4" />
|
||||
{label}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user