Use the value from another field inside a block.

default discord avatar
hosmelqlast year
18
  • discord user avatar
    jmikrut
    last year

    Hey @hosmelq i'd just build a custom

    Field

    component for your

    code

    field that's just a little "wrapper" around the built-in Code field



    there, you can use the

    useFormFields

    hook to retrieve the field's value that will determine your code field's language



    and then adjust the props, and send to the built-in Code field

  • default discord avatar
    hosmelqlast year

    That's awesome 😱



    Is it a package?

  • discord user avatar
    jmikrut
    last year

    no, you want to render the built-in field straight from Payload itself



    we don't expose the built-in Code field directly, but you can easily import it from dist



    import CodeField from 'payload/dist/admin/components/forms/field-types/Code
  • default discord avatar
    hosmelqlast year

    Ok, perfect. Thank you!



    To render this custom field i need to use the

    ui

    type?

  • discord user avatar
    jmikrut
    last year

    no, you would want to use the

    code

    field itself



    because you still want to store the data in the same way that the

    type: 'code'

    field will do



    the

    ui

    field type will not store anything in the database at all



    that field type is good for cases where you just wanna inject a button, or a third-party integration, or something, into the admin UI - - but not store data



    instead, what you want to do is just have a code field, but simply render a custom code field component

  • default discord avatar
    hosmelqlast year

    Ok, got it. I have to use the

    admin.components.Field

    property 😅



    I made it works with the following code.



    import {useFormFields} from 'payload/components/forms'
    import CodeField from 'payload/dist/admin/components/forms/field-types/Code'
    import type {Block, SelectField} from 'payload/types'
    import {createElement} from 'react'
    import type {Entries} from 'type-fest'
    
    const LANGUAGES = {
      go: 'Go',
      javascript: 'JavaScript',
      php: 'PHP',
      rust: 'Rust',
      typescript: 'TypeScript',
    }
    
    export default {
      fields: [
        {
          name: 'language',
          options: (Object.entries(LANGUAGES) as Entries<typeof LANGUAGES>).map(
            ([key, value]) => ({
              label: value,
              value: key,
            })
          ),
          required: true,
          type: 'select',
        },
        {
          name: 'code',
          required: true,
          type: 'code',
          admin: {
            components: {
              Field(field: SelectField & {path?: string}) {
                const language = useFormFields(
                  ([fields]) => fields[`${field.path?.replace('code', 'language')}`]
                )
                const value = language.value as keyof typeof LANGUAGES
    
                if (LANGUAGES[value] === undefined) {
                  return null
                }
    
                return createElement(CodeField, {
                  admin: {
                    language: value,
                  },
                  name: field.name,
                  path: field.path,
                })
              },
            },
            language: 'php',
          },
        },
      ],
      slug: 'code',
    } satisfies Block


Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.