Skip to content

Instantly share code, notes, and snippets.

@ferdinandsalis
Created December 27, 2021 13:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ferdinandsalis/79b8042237eb182fa606441cebe785fa to your computer and use it in GitHub Desktop.
Save ferdinandsalis/79b8042237eb182fa606441cebe785fa to your computer and use it in GitHub Desktop.
Multiple items form
import * as R from "ramda";
import { json, ActionFunction, Form, redirect, useActionData } from "remix";
export const action: ActionFunction = async ({ request }) => {
const formData = await request.formData();
let fields = {};
for (const [key, value] of formData.entries()) {
const path = key
.split(".")
.map((value) => (Number.isNaN(Number(value)) ? value : parseInt(value)));
fields = R.assocPath(path, value, fields);
}
let didRemove = false;
fields.items = fields?.items?.filter((item) => {
const shouldFilter = item?.__remove === "true";
if (didRemove === false) {
didRemove = shouldFilter;
}
return !shouldFilter;
});
let didAdd = formData.has("__add");
if (formData.has("__add")) {
fields.items
? fields.items.push({
description: "",
price: 0,
__id: Math.random().toString(36).substr(2, 9),
})
: (fields.items = [
{
description: "",
price: 0,
__id: Math.random().toString(36).substr(2, 9),
},
]);
}
if (didRemove || didAdd) {
return json({ fields });
} else {
return redirect("/?submitted=true");
}
};
export default function MultiItemForm() {
const actionData = useActionData();
const fields = actionData?.fields || {
items: [{ description: "", price: 0, __id: "initial" }],
};
return (
<Form method="post">
<section>
{fields.items.map((item, idx) => (
<fieldset key={JSON.stringify(item)}>
<legend>Item</legend>
<input type="hidden" value={item.__id} name={`items.${idx}.__id`} />
<label>
Description
<input
name={`items.${idx}.description`}
defaultValue={item.description}
/>
</label>
<label>
Price
<input
type="number"
name={`items.${idx}.price`}
defaultValue={item.price}
/>
</label>
<button name={`items.${idx}.__remove`} value="true">
Remove Item
</button>
</fieldset>
))}
<button type="submit" name="__add" value="true">
Add Item
</button>
</section>
<footer>
<button type="submit">Submit</button>
<button type="reset">Reset</button>
</footer>
</Form>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment