#form builder plugin: forms are created but aren't accessed to render on frontend

24 messages · Page 1 of 1 (latest)

halcyon osprey
#

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'.

Tired of implementing HubSpot forms that look like garbage? Struggling with iFrames, or having nightmares thinking about integrating Gravity Forms? With Payload's Form builder plugin, you can easily implement custom forms without the headache.

Form Builder Plugin - https://github.com/payloadcms/plugin-form-builder

Form Builder Plugin Blog Post...

▶ Play video
night breachBOT
void escarp
#

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.

vagrant plover
#

I'm having the exact same issue and have attempted the same debug methods you have@halcyon osprey Did you find a solution?

vagrant plover
#

@void escarp 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 [email protected] 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.

Payload CMS

Tired of dealing with microservices hell? Implement and create forms with ease using Payload’s free form builder plugin.

#

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

vagrant plover
#

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...

covert cloud
#

@vagrant plover I think I have this fixed. I was hitting the same issues you and @halcyon osprey were 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.

vagrant plover
#

@covert cloud 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.

covert cloud
# vagrant plover <@231946132949827584> I came to the same solution last night after using yarn ge...

(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} }}
}`
vagrant plover
#

Also, I had to make ./src/app/_components/Blocks/Form/index.tsx 'use client' and change that useRouter reference to next/navigation

vagrant plover
#

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-render
RichText@webpack-internal:///(app-pages-browser)/./src/app/_components/RichText/index.tsx:13:34

GitHub

Note: React 16.13.1 fixed some cases where this was overfiring. If upgrading React and ReactDOM to 16.13.1 doesn't fix the warning, read this: #18178 (comment) React version: 16.13.0 Steps To R...

covert cloud
#

@vagrant plover
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>
  )
}
vagrant plover
# covert cloud <@411047128673288192> To your first message, yes, I also had to add `'use clien...

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}
  />
)}```
covert cloud
halcyon osprey
#

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

night breachBOT
#

You do not have permission to mark this thread as solved. Only thread creators, contributors and payload team members can mark a thread as solved.

vagrant plover
night breachBOT
inland knoll
#

@vagrant plover Would it be possible you upload a boilerplate with working form to GH? Because I got the exact same issue atm 😄

vagrant plover