payloadcms / plugin-form-builder Goto Github PK
View Code? Open in Web Editor NEWThe official form builder plugin for Payload
The official form builder plugin for Payload
Currently it is possible to overwrite the fields of the form-field blocks completely, but it is not possible to add an additional custom field.
If I'd like to add the custom field 'test', all other fields are gone.
formBuilder({ fields: { email: { fields: [ { name: 'test', type: 'text', }, ], }, }, })
I think, it's because the the merge in
I know that there are cases where one wants to redefine all form-fields, however it would be nice if a way to simply add custom fields to an form-field could be provided.
I thought about two possible ways to achieve this:
import formFields from '@payloadcms/plugin-form-builder/'; [...] formBuilder({ fields: { email: { fields: [ ...formFields.email.fields, { name: 'test', type: 'text', }, ], }, }, })
The latest version of payload 1.3.0
has a breaking change camelCase slugs will not be auto converted to kebab case anymore.
This will cause a problem when using this plugin and upgrading to version 1.3.0
of payload.
I'm not sure if its best to change or just to link to this issue for visibility.
If a change is going to be made, it should be made here:
a workaround for anyone else that runs into this issue is adding this
formSubmissionOverrides: {
slug: 'form-submissions',
}
As per #31 , the locale
info is not used when querying forms
collections. This may lead to scenarios where a missing field on a localized entity is throwing errors but is impossible to spot.
By using a Partial
type for field blocks, all properties become optional including those which are truly required for Payload to operate, namely slug
. We need to explicitly require this field and any others that might be necessary.
From this Discord thread: https://discord.com/channels/967097582721572934/1088878072180244510
Hello, I need an input type hidden but I can't find it in the default configuration.
Can you explain me how can I implement it?
Very minor issue but I've already had a user contact me about it. At smaller viewport heights I am unable to view all of field options when adding a new field. It also hides the field search bar.
It can get a little funky- sometimes when adjusting the window the select popup flickers back and forth from above the add button to below it. Happening to me on both Chrome and Firefox.
Feature request from discord to add a new upload
option to the form builder fields
Now that the form builder plugin helps to build great and easy forms, all data collected ends up in the form submission collection.
It would be amazing to have a feature on that collection (or can be on all collections and used as a general payload feature) to export the entire collection data as csv
for further processing :)
I was creating an HR form that I didn’t catch before but just got a request to update, and when I was in there doing the email confirmations, I just realized we don’t have the option for “From Name” on the email that goes to the user who fills out the form. We normally do something like “Hope Network Human Resources or Hope Network Transportation” for that, rather than just the email address
I would like to be able to set what columns the form submission collection must have.
For example, i have a registration for with a field email
and would like to display it here:
but simply adding:
formSubmissionOverrides: {
admin: {
defaultColumns: ['email'],
useAsTitle: 'email',
},
},
does not work because form submission db document is stored as:
From the README:
You can also provide your own custom field definitions by passing a new Payload Block object into fields.
Currently not possible.
Neither the logic nor the typescript type definitions allow custom fields like this: formBuilder({fields: {myField: {...}})
Currently you can create form submissions with arbitrary data. This means that you're front-end is relied upon entirely to validate your data. We need to set up the form-submissions
collection to do this natively. See the TODO noted in code here: https://github.com/payloadcms/plugin-form-builder/blob/main/src/collections/FormSubmissions/index.ts#L58
Discord: https://discord.com/channels/967097582721572934/1136001656253861888
This isn't really an issue but a feature request/query. Is there a native file upload field yet or in the pipeline?
Is there a way to send different emails based on a field a user fills out
As of now, one has to dig pretty deep to figure out how to post to the form-submissions endpoint (I had to watch a 15 minute Youtube video that did not fully explain it). There even was no information that you had to post to that endpoint in the docs.
I suggest some information about the endpoint and how it is called is added to the README file in this repository.
I noticed one small bug in form submitting when trying to figure out how to post to the endpoint. If the post request is of the form:
{
"form": <form-id-here>,
"submissionData": {}
}
the API creates an empty form submission, even if I have required fields in the form.
Hope this helps!
I have an error after sending the API request for form-submission which is:
err: "Error while sending one or more emails in form submission id: undefined.
Here is my frontend implementation:
const {
id: formID,
submitButtonLabel,
confirmationType,
redirect,
fields,
confirmationMessage,
} = form
const [name, email, message, budget, found_us] = fields
const onSubmit = useCallback(
(data) => {
const submitForm = async () => {
setError(undefined)
const dataToSend = Object.entries(data).map(([name, value]) => ({
field: name,
value,
}))
try {
const req = await fetch(
`${process.env.NEXT_PUBLIC_CMS_URL}/api/form-submissions`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
form: formID,
submissionData: dataToSend,
}),
}
)
const res = await req.json()
if (req.status >= 400) {
setIsLoading(false)
setError({
status: res.status,
message: res.errors?.[0]?.message || 'Internal Server Error',
})
return
}
setIsLoading(false)
setHasSubmitted(true)
if (confirmationType === 'redirect' && redirect) {
const { url } = redirect
const redirectUrl = url
if (redirectUrl) router.push(redirectUrl)
}
} catch (err) {
console.warn(err)
setIsLoading(false)
setError({
message: 'Something went wrong.',
})
}
}
submitForm()
},
[router, formID, redirect, confirmationType]
)
I guess labels should be configurable via formSubmissionOverrides and formOverrides in payload.config.ts
It's just not yet implemented (see here and here).
This should work but it doesn't
formBuilder({
formOverrides: {
labels: {
singular: {
en: "Form",
xx: "Xxxxx",
},
plural: {
en: "Forms",
xx: "Xxxxxx",
},
},
},
Originally posted by @zanami in #11 (comment)
Hello,
is it possible to translate the labels or other fileds?
Thank you
Is there any recommended way to group fields?
In my use case, I have a giant form, whoses fields on the frontend are seperated into groups, e.g. either rendered as tabs or steppers. Currently I have to define multiple forms and then merge it into one on the frontend. Just wondering if there is a better approach to acchieve this?
0|prod | Error while sending one or more emails in form submission id: undefined.
0|prod | TypeError: variables.find is not a function
0|prod | at /home/payload/prod/node_modules/@payloadcms/plugin-form-builder/dist/utilities/replaceDoubleCurlys.js:8:43
0|prod | at String.replace (<anonymous>)
0|prod | at replaceDoubleCurlys (/home/payload/prod/node_modules/@payloadcms/plugin-form-builder/dist/utilities/replaceDoubleCurlys.js:7:20)
0|prod | at /home/payload/prod/node_modules/@payloadcms/plugin-form-builder/dist/collections/FormSubmissions/hooks/sendEmail.js:91:81
0|prod | at Array.map (<anonymous>)
0|prod | at /home/payload/prod/node_modules/@payloadcms/plugin-form-builder/dist/collections/FormSubmissions/hooks/sendEmail.js:85:42
0|prod | at step (/home/payload/prod/node_modules/@payloadcms/plugin-form-builder/dist/collections/FormSubmissions/hooks/sendEmail.js:44:23)
0|prod | at Object.next (/home/payload/prod/node_modules/@payloadcms/plugin-form-builder/dist/collections/FormSubmissions/hooks/sendEmail.js:25:53)
0|prod | at fulfilled (/home/payload/prod/node_modules/@payloadcms/plugin-form-builder/dist/collections/FormSubmissions/hooks/sendEmail.js:16:58)
0|prod | at processTicksAndRejections (node:internal/process/task_queues:96:5)
Issue
Ideally, form values should be validated server-side as well as client side. While the "required" field is passed to the client side, no validation is implemented on the client side.
Solution
This could likely be solved with a beforeValidate hook that fetches the related form, and ensures each required field is present.
Is it possible to create checkbox groups or radio button groups? If so how?
https://github.com/payloadcms/plugin-form-builder/blob/main/src/types.ts
The type definitions for a width is a string should it not be a number? Because when you generate types within a payload project width is set to be a number for form field types
Hi,
I have set up resend in my email config, using the example transport from here https://github.com/resendlabs/resend-nodemailer-smtp-example/blob/main/index.ts
If I send an email using payload.sendEmail() after the payload.init(), I receive the email without any problems, and I can see it logged in my resend dashboard.
However, when using plugin-form-builder, the emails aren't being sent & I can't see any logs in the resend dashboard.
I've enabled debug & logger in the createTransport options, and I can see logs when using payload.sendEmail(), but no logs are output after a successful form submission, so it looks like the plugin isn't trying to send the email at all.
Does anyone know how I can debug this or what the issue could be?
Thank you
// Logs to console showing authentication is OK
const transport = await nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: 465,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
secure: true,
debug: true,
logger: true,
});
await payload.init({
secret: process.env.PAYLOAD_SECRET,
express: app,
email: {
transport,
fromName: process.env.EMAIL_FROM_NAME,
fromAddress: process.env.EMAIL_FROM,
},
onInit: async () => {
payload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`);
},
});
// This sends OK
try {
const res = await payload.sendEmail({
from: '[email protected]',
to: '[email protected]',
subject: 'Test Email',
text: 'Test email content',
});
console.log(res);
} catch (e) {
console.log(e);
}
Screenshot showing how the email is configured inside Payload, but this email doesn't send:
This line
formConfig?.formOverrides?.slug
instead.
Would that be an issue?
Seems like the plugin requires the 'Email to' and 'Email From' fields before sending e-mails (See this line)
However, the "Email From" field is missing required: true
.
The blog post goes into detail about the front end implementation for calling the endpoint.
This is not addressed in the README. One user was slightly confused because they were figuring out the endpoints on their own.
Likely can move over the section from the blog post directly into the readme.
I currently have this quick and dirty way to do this but I'm not sure if it's correct,
actions.ts
"use server"
// import { revalidatePath } from "next/cache"
import { getPayloadClient } from "@payload/payloadClient"
import { FormDataSchema, type FormDataSchemaType } from "./schema"
export async function saveForm(data: FormDataSchemaType) {
const payload = await getPayloadClient()
try {
await payload.create({
collection: "form-submissions",
data: FormDataSchema.parse(data),
})
return [true, ""]
} catch (e) {
console.log(e)
return [false, JSON.stringify(e)]
}
}
schema.ts
import { z } from "zod"
export const FormDataSchema = z.object({
form: z.string(),
submissionData: z
.object({
field: z.string(),
value: z.unknown(),
})
.array(),
})
export type FormDataSchemaType = z.infer<typeof FormDataSchema>
Would be great if there is multiple select support.
<select name="cars" id="cars" multiple>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.