Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Can we conditionally change field type based on a sibling value?

default discord avatar
gak4u8 months ago
4

I have a scenario where user needs to select a field type, based on selection I want to show either a text field or a richText field for a sibling field in the same collection. As of now to make this work, I have 2 fields which I conditionally show/hide based on field type selection.



This is precisely what I am doing right now, but I am ending up having 2 separate fields to handle both senarios



[
{
              name: "value",
              type: "text",
              label: "Value",
              required: true,
              admin: {
                condition: (_, siblingData) => siblingData.type !== 'richText',
              }
            },
            {
              name: "rvalue",
              type: "richText",
              label: "Value",
              admin: {
                condition: (_, siblingData) => siblingData.type === 'richText',
              }
            },


But as

@690590499202924574

suggested, using a custom component will be a better solution



@690590499202924574

Thanks for the suggestion, I will try it out

  • default discord avatar
    chrispy.q2 years ago

    You could use a custom component from type ui and handle it by yourself as you can access the values from other input fields with the useFields or useFormFields hook.

    https://payloadcms.com/docs/admin/hooks#usefield
  • default discord avatar
    notchr2 years ago
    @661298338939011077

    I think this is what conditions are for and they should work nicely



    Is the condition feature for fields not suitable?



    I imagine you would do something like



            {
              name: "linkUrl",
              label: "Link URL",
              type: "text",
              required: false,
              admin: {
                condition: (data, siblingData, { user }) => {
                  if (siblingData.linkType === "url") {
                    return true;
                  } else {
                    return false;
                  }
                },
              },
            },


    where linkType is a select field type



            {
              name: "linkType",
    
              type: "select",
              hasMany: false,
              defaultValue: "url",
              admin: {
                description:
                  "Select if the Link should go to another page, a PDF, or show a modal with text.",
              },
              options: [
                {
                  label: "Link",
                  value: "url",
                },
                {
                  label: "PDF",
                  value: "pdf",
                },
                {
                  label: "Text",
                  value: "text",
                },
              ],
            },
  • default discord avatar
    kaspartrlast year

    I am trying to use the custom component strategy to achieve conditional field types.



    I need to decide the field type based on the selected reference field in the same array.


    The problem is I don't know how to pass sibling data to the custom component. As this is an array, I cannot use the

    getSiblingData()

    as it requires hardcoded field name, which in case of an array, you wouldn't know.



    How would one pass sibling data to custom component.



    My collection:


    ...
      fields: [
                {
                  name: 'attributesArray', // required
                  type: 'array', // required
                  minRows: 0,
                  maxRows: 100,
                  fields: [
                    {
                      type: 'row', // required
                      fields: [
                        {
                          name: 'attribute',
                          type: 'relationship',
                          relationTo: ['attributes'],
                        },
                        {
                          name: 'featureValue',
                          type: 'ui',
                          admin: {
                            components: {
                              Field: () =>
                              FeatureValue({path: name}),
                            },
                          },
                        },
                      ]
                    }
                  ],
                },
              ],
    ...


    FieldType (custom component)



    const FeatureValue: React.FC = (props: { siblingData? }) => {
        // const { value, setValue } = useField<string>({ path })
        const [fields] = useAllFormFields();
        console.log("siblingData: ", siblingData)
    
        return (// return some component);
    };
    
    export default FeatureValue;


    Additional question is how to access the referenced field fields?


    In this example

    : I would need to access the referenced attribute's collection entity field named "dataType" which dictates the field type of the fieldValue field.



    I believe the broader question here is, can one access the referenced entity in another collection "deeply" i.e. can I access all the fields of a referenced entity not just its id,



    I did. Via custom components

    @764950583127310376


    Collection.ts


    {
      type: 'row',
      fields: [
        {
          name: 'feature',
          type: 'relationship',
          relationTo: ['flFeatures'],
        },
        {
          name: "featureValue",
          type: "text",
          index: true,
          admin: {
            components: {
              Field: (props) => FeatureValue({ ...props}),
            },
          },
        },
      ]
    }
  • default discord avatar
    maxel080510 months ago

    Did you end up finding out if it's possible? I'm currently having the same problem



    @567578449439621124

    Great! ngl I was hoping not to use a custom component 😅 I'll check it out. thanks

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.