DEV Community

Kamran Khan
Kamran Khan

Posted on

One modal, two modes: my add-user and edit-user forms are the same form

My admin Users page has one user form, not two. It is the same modal, driven by a single state value:

const [modal, setModal] = useState(null); // 'add' | 'edit' | null
Enter fullscreen mode Exit fullscreen mode

openAdd resets the form to blanks and sets mode 'add'. openEdit pre-fills name, email and role from the row, deliberately blanks the password, and sets mode 'edit'. Everything else — the inputs, the error rendering, the buttons — is shared.

The mode shows up in exactly the places where add and edit genuinely differ:

<input
  type="password"
  required={modal === 'add'}
  ...
/>
Enter fullscreen mode Exit fullscreen mode

Password is required when creating, optional when editing, with a small "(leave blank to keep current)" note in edit mode. And on submit:

if (modal === 'add') {
  await client.post('/users', form);
} else {
  const payload = { name: form.name, email: form.email, role: form.role };
  if (form.password) payload.password = form.password;
  await client.put(`/users/${editing.id}`, payload);
}
Enter fullscreen mode Exit fullscreen mode

The edit payload strips the password unless the admin actually typed one. This mirrors the backend exactly: the create request requires the password, the update request says sometimes. The frontend and the backend agree on which fields are mandatory in which mode, and that agreement lives in exactly one place on each side.

Two more small things. The submit button reads "Create User" or "Save Changes" from the mode. And closeModal() always resets the form to the empty shape, so opening Add right after an Edit never leaks the previous user's email into the blank form.

I keep reaching for this pattern because the alternative — two near-identical forms — is where add and edit quietly drift apart. One form, one mode flag, and the two modes can only disagree where they are supposed to.

This modal ships as-is in my Laravel + React SaaS starter kit, with the matching backend rules, auth and roles around it: https://kamranofficial.gumroad.com/l/mhekoig

Top comments (0)