I am trying to get the form builder plugin working for a group project and I have gone through the docs (
https://payloadcms.com/docs/plugins/form-builder), guide (
https://payloadcms.com/blog/create-custom-forms-with-the-official-form-builder-plugin), youtube example (
https://www.youtube.com/watch?v=Fm4YaG__EHg), and referenced the example code (
https://github.com/payloadcms/payload/tree/main/examples/form-builder). I am able to create forms on the CMS but they do not render when I add them to a page. Adding in console.logs in different places confirms that the forms are created, but they are lost somewhere along the way. In the picture, at app/_components/Blocks/index.tsx, blocks returns an empty object for the form.
Please, is anyone able to help? Here is the repository:
https://github.com/michaelgolshani/oh-man-clothing-redesign-backend/tree/chad_form_builder. At the moment, the form builder is only in the branch 'chad_form_builder'.
Thanks for the help everyone! Real life caught up to me the past couple weeks so I haven’t been on here but I should have some time soon to try this again with your help
Does your pages collection have versions enabled with drafts, if so have you published the page?
Can you verify that the API is returning the page with the data. Compare that data to what your frontend is expecting and debug until you find the mismatch.
I'm having the exact same issue and have attempted the same debug methods you have
@201951622866272256Did you find a solution?
I've checked the API call against the FormBlockType and it matches but still no data for the FormBlock is coming through. Is there a GraphQL queries missing somewhere in the codebase do you think? or is it purely REST? I'm running payload@2.9.0 and plugin-form-builder^1.2.0. Followed the guide here (
https://payloadcms.com/blog/create-custom-forms-with-the-official-form-builder-plugin) and the example repo to the letter, I believe.
My project is a clone of the e-commerce example repo, which I'm trying to add forms to. Forgive me, this is my first Payload project, so I'm still getting my bearings with the CMS
Since Forms don't seem to populate on a page when following the guide or Youtube tutorial, I've added this export to
./src/app/_graphql/
export const FORM_BLOCK = `
...on FormBlock {
blockType
enableIntro
introContent
${FORM}
}
And created
./src/app/_graphql/form.ts
export const FORM = ` form {
id
title
submitButtonLabel
confirmationType
confirmationMessage
fields {
name
label
required
width
blockName
blockType
}
}
And amended the PAGE query in
./src/app/_graphql/pages.ts
to include the ${FORM_BLOCK} in the layout object.
But now I'm getting a 404 error...
I came to the same solution last night after using yarn generate:types and gradually building out the query using hoppscotch at the /api/graphql endpoint. Smart minds think alike!
The only field I’ve not been able to add to the query is defaultValue. Obviously you can define this in the form builder and the property gets stored to the database, however, adding it to the query I get a type error.
Also, I had to add type=“submit” to the Button in order to get the form to POST, which I assume you did as well if you’ve got working forms.
Also, I had to make ./src/app/_components/Blocks/Form/index.tsx 'use client' and change that useRouter reference to next/navigation
The RichText message is broken upon sending the form. Are you experiencing the same thing?
This is the error I see in the browser console
Warning: Cannot update a component (
HotReload
) while rendering a different component (
RichText
). To locate the bad setState() call inside
RichText
, follow the stack trace as described in
https://reactjs.org/link/setstate-in-renderRichText@webpack-internal:///(app-pages-browser)/./src/app/_components/RichText/index.tsx:13:34
Quick question, are you using the lexical editor or slate editor? I think my error arose from switching to the Lexical editor. I had to drill down on a prop to access the underlying array that the RichText component was expecting. Just giving you a heads up in case you experience the same thing upon migrating.
My
./src/app/_components/Blocks/Form/index.tsx
looks like this from lines lines 140-145 Notice the RichText component that gets rendered for a
confirmationType === 'message'
, the content has to be access from
confirmationMessage.root.children
.
{!isLoading && hasSubmitted && confirmationType === 'message' && (
<RichText
className={classes.confirmationMessage}
content={confirmationMessage.root.children}
/>
)}
All good dude. Happy we all managed to get to the solution 🙂 Mark it as solved if you can.
I'm in the process of submitting a PR to the templates/ subdirectory of the main repo with the updates. It depends on when/if the changes get approved by the Payload team but I'll be submitting them very soon
PR related to this thread:
https://github.com/payloadcms/payload/pull/5199I think I have this fixed. I was hitting the same issues you and
@201951622866272256were having.
I saw in the console there was an error was complaining that it
Cannot query field "name" on type "Form_Fields". Did you mean to use an inline fragment on "Checkbox", "Country", "Email", "Number", or "Select"?
whenever you see the 404 error in the web.
Using that I changed the
./src/app/_graphql/form.ts
to the following:
export const FORM_FIELDS = `
... on Checkbox { blockName blockType label name required width }
... on Country { label name required width }
... on Email { blockName blockType label name required width }
... on Message { blockName blockType message }
... on Select { blockName blockType label name options { label value } required width }
... on State { blockName blockType label name required width }
... on Text { blockName blockType label name required width }
... on Textarea { blockName blockType label name required width }
... on Number { blockName blockType label name required width }
`
export const FORM = `form {
id
title
submitButtonLabel
confirmationType
confirmationMessage
fields {... on Form_Fields { ${FORM_FIELDS} }}
}`
You can find the valid form fields and their properties within
./src/payload/payload_types.ts
I used this to 'fill in the blanks' per say.
With these changes, I have functioning forms.
(edit): I also had to add the
type="submit"
to make the button submit the form
I'm seeing the same thing as far as adding the defaultValue to the query.
Getting an error:
Error: Fields "defaultValue" conflict because they return conflicting types "Boolean" and "String". Use different aliases on the fields to fetch both if this was intentional.
Which from
payload-types.ts
there are
number
,
boolean
and
string
values returned from each of the fields and this is why graphQL is complaining to us, it wants one return type per field name. I'm looking into this as well, I've gotten
Text
,
TextArea
and
Select
fields to return the default values, but nothing else so far without returning the error mentioned above.
I had thought that keeping everything in one
export
field made things look messy and I was under the presumption that graphql would read the
defaultValue
as required per field, that is not the case however. My
form.ts
file looks like the following:
export const CHECKBOX_FIELD = `
... on Checkbox {
blockName
blockType
label
name
required
width
}
`
export const TEXT_FIELD = `
... on Text {
blockName
blockType
label
name
required
width
defaultValue
}
`
export const TEXTAREA_FIELD = `
... on Textarea {
blockName
blockType
label
name
required
width
defaultValue
}
`
export const SELECT_FIELD = `
... on Select {
blockName
blockType
label
name
required
width
options { label value }
defaultValue
}
`
export const EMAIL_FIELD = `
... on Email {
blockName
blockType
label
name
required
width
}
`
export const STATE_FIELD = `
... on State {
blockName
blockType
label
name
required
width
}
`
export const COUNTRY_FIELD = `
... on Country {
blockName
blockType
label
name
required
width
}
`
export const MESSAGE_FIELD = `
... on Message {
blockName
blockType
message
}
`
export const FORM_FIELDS = `
... on Checkbox { ${CHECKBOX_FIELD} }
... on Country { ${COUNTRY_FIELD} }
... on Email { ${EMAIL_FIELD} }
... on Message { ${MESSAGE_FIELD} }
... on Select { ${SELECT_FIELD} }
... on State { ${STATE_FIELD} }
... on Text { ${TEXT_FIELD} }
... on Textarea { ${TEXTAREA_FIELD} }
`
export const FORM = `form {
id
title
submitButtonLabel
confirmationType
confirmationMessage
fields {... on Form_Fields { ${FORM_FIELDS} }}
}`
To your first message, yes, I also had to add
'use client'
and swap the
useRouter
to
next/navigation
To your second message: I'm not seeing where the rich text field is broken upon form submission. What I place in the textArea is what appears in the admin panels form submissions on my side. What are you seeing on your end? I did get the defaultValue to appear in the textArea though, I did have to go into the textArea component and and the defaultValue into it. I'll link that code below.
On the third message: I've seen this error as well, typically when I am changing code of the page also viewing in the browser. A hard refresh of the page fixes it for me, CTRL + SHIFT + R is the keyboard shortcut for windows.
TextArea component with defaultValue added:
export const Textarea: React.FC<
TextField & {
register: UseFormRegister<FieldValues & any>
defaultValue?: string
rows?: number
errors: Partial<
FieldErrorsImpl<{
[x: string]: any
}>
>
}
> = ({ name, label, width, defaultValue = "Your text here.", rows = 3, register, required: requiredFromProps, errors }) => {
return (
<Width width={width}>
<div className={classes.wrap}>
<label htmlFor={name} className={classes.label}>
{label}
</label>
<textarea
rows={rows}
className={classes.textarea}
id={name}
defaultValue={defaultValue}
{...register(name, { required: requiredFromProps })}
/>
{requiredFromProps && errors[name] && <Error />}
</div>
</Width>
)
}
I'm using the slate editor for now. I don't have any plans to use the lexical editor as of now.
I also dusted off my HTML skills and replaced the
defaultValue={defaultValue}
to
placeholder={defaultValue}
This got the defaultValue to appear in the
input
fields better, text will auto clear on typing rather than clearing the box by manually.
Would it be possible you upload a boilerplate with working form to GH? Because I got the exact same issue atm 😄
Star
Discord
online
Get dedicated engineering support directly from the Payload team.