Save array based on the selected option

default discord avatar
CAPTKEN
4 weeks ago
20

Hello, would someone be kind enough to show the function / hook method to update the name of an array based on the selected option in the array before saving. I have been going around in circles for two days, example code attached, - greatly appreciated.


{


name: 'theNameOfCertificate',


label: 'Add Certificate',


type: 'array',


fields: [


{


name: 'addCertificate',


type: 'select',


label: 'Select Certificate',


required: true,


options: [


{label: 'Drivers Licence', value: 'driversLicence',},


{label: 'Car Insurance', value: 'car_insurance',},


],


},


{


name: 'certificateImage',


type: 'upload',


label: 'Upload an image of your qualification',


unique: true,


relationTo: 'media',


required: true,


}


],


},

  • default discord avatar
    thisisnotchris
    4 weeks ago

    @CAPTKEN do you want to update the 'name' property on the array field? Maybe a different field would be better to update, for instance a text field, as the name is an identifier for the field and changing it dynamically will make it harder to query



    like a certificateName field that is a string, and you set the value based on the selection of the select field



    That way your addCertificate field isn't modified directly

  • default discord avatar
    CAPTKEN
    4 weeks ago

    @thisisnotchris thanks for your input, I had not thought of that, good point on searchability but these docs are in a users personal profile. Please see the screen shot attached which outlines the problem - the records are incremented by 01 and the user does not know which document is in the record ( the only way to find your drivers license is start opening every record until you get lucky ). Maybe their is another way of doing this if anyone knows - can a hook can be used or validateBefore function ? sorry but I do not have the smarts to work this out and chatgpt is dream up crazy answers so any help is greatly appreciated, as I am sure this question is bound to be raised again in the future.🙏

    Screenshot_2023-04-27_at_2.42.54_PM.png
  • discord user avatar
    Jarrod
    Payload Team
    4 weeks ago

    @CAPTKEN you are looking for “RowLabel” see the bottom of this docs page for an example:

    https://payloadcms.com/docs/fields/array#config


    You could add a name field inside the array as well, and then use that as the label. Or combine it with the type, or only use the type as a fallback. Plenty of ways to do what you are looking for 🙂

  • default discord avatar
    CAPTKEN
    4 weeks ago

    @Jarrod Thanks so much, learning as I go and will post results for others to follow



    For those people that get stuck - this example code will help:



    {


    name: 'slider',


    type: 'array',


    label: 'Image Slider',


    fields: [


    {


    name: 'Fruit',


    type: 'select',


    options: [


    {label: "Apple", value: "apple"},


    {label: "Pair", value: "pair"},


    ],


    },


    {


    name: 'title',


    type: 'text',


    label: 'Title'


    },


    {


    name: 'image',


    type: 'upload',


    label: 'Image',


    relationTo: 'media',


    required: true


    },


    ],


    admin: {


    components: {


    RowLabel: ({ data, index }) => {


    const label = data?.title ? data.title :

    Slide

    ;


    return

    ${label} ${String(index + 1).padStart(2, '0')}

    ;


    }


    }


    }


    }



    if you want to update the tile from the select option then replace the admin section with this code:



    admin: {


    components: {


    RowLabel: ({ data, index }) => {


    const label = data.fruit ? data.fruit:

    Slide

    ;


    return

    ${label} ${String(index + 1).padStart(2, '0')}

    ;


    }


    }


    }



    Thanks to @thisisnotchris and @Jarrod for your help 👋

  • default discord avatar
    thisisnotchris
    4 weeks ago

    Happy to help!

  • default discord avatar
    CAPTKEN
    4 weeks ago

    @thisisnotchris or @Jarrod I found that the above line in the admin section "const label = data.fruit ? data.fruit: Slide;" returns the value and not the label of the selected option- so fields in the array are renamed for example "apple_crumble_desert" rather then "Apple Crumble Desert". I have tried retrieving the label from that data using "const label = data.fruit.label ? data.fruit.label: Slide; " but it returns "unknown. Can you point me in the right direction please and thanks for your help guys.

  • discord user avatar
    Jarrod
    Payload Team
    4 weeks ago

    You won't be able to get the label, just the value. However, you could think about this differently and move your options out of the select, turn them into a const variable, and then use that to determine what label to show in your row label

  • default discord avatar
    CAPTKEN
    4 weeks ago

    @Jarrod thanks for the pointer - Sorry I am still learning and only understanding the basics of what your saying - any chance you could share a code snippet that I can expand on and document in this post for others as well?

  • discord user avatar
    Jarrod
    Payload Team
    4 weeks ago
    const fruits = {
      apple: 'Apple',
      pair: 'Pair',
    }
    
    const fruitOptions = Object.keys(fruits).map((key) => ({
      value: key,
      label: fruits[key],
    }));


    {
      name: 'slider',
      type: 'array',
      label: 'Image Slider',
      fields: [
        {
          name: 'Fruit',
          type: 'select',
          options: fruitOptions,
        },
        {
          name: 'title',
          type: 'text',
          label: 'Title'
        },
        {
          name: 'image',
          type: 'upload',
          label: 'Image',
          relationTo: 'media',
          required: true
        },
      ],
      admin: {
        components: {
          RowLabel: ({ data, index }) => {
            const label = data.fruit ? fruits[data.fruit] : Slide;
            return ${label} ${String(index + 1).padStart(2, '0')};
          }
        }
      }
    }
  • default discord avatar
    CAPTKEN
    4 weeks ago

    @Jarrod many thanks once again - would not of got this far with out your help - the complete code is below for others to follow



    import { CollectionConfig, FieldHook } from 'payload/types';



    const fruits = {


    apple: 'Apple',


    pear: 'Pear',


    };



    const fruitOptions = Object.keys(fruits).map((key) => ({


    value: key,


    label: fruits[key],


    }));



    const Test: CollectionConfig = {


    slug: 'test',


    fields: [


    {


    name: 'fruitshop',


    type: 'array',


    label: 'Image Slider',


    fields: [


    {


    name: 'fruit',


    type: 'select',


    options: fruitOptions,


    },


    {


    name: 'title',


    type: 'text',


    label: 'Title'


    },


    {


    name: 'image',


    type: 'upload',


    label: 'Image',


    relationTo: 'media',


    required: true


    },


    ],


    admin: {


    components: {


    RowLabel: ({ data, index }) => {


    const label = data.fruit ? fruits[data.fruit] : "Fruits";


    return

    ${label} ${String(index + 1).padStart(2, '0')}

    ;


    }


    }


    }


    }


    ],


    };



    export default Test;

  • discord user avatar
    Jarrod
    Payload Team
    4 weeks ago

    absolutely! happy to help 🙂

Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

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