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.

How to reset select value in custom component

default discord avatar
imcorfitz6 months ago

Yup.. Added a

beforeValidate

hook to the collection with the following, and it worked:


hooks: {
    beforeValidate: [
      ({ data }) => {
        const entries = data.entries.map((entry) => {
          if (
            entry.chapter &&
            !data.chapters.find((chapter) => chapter.id === entry.chapter)
          ) {
            entry.chapter = null;
          }
          return entry;
        });

        return {
          ...data,
          entries,
        };
      },
    ],
  },


I realise after writing this, that maybe this cleanup should in fact take place as an

afterDelete

hook on the chapters field 🤔



It is worth noting, that this appears only to be cosmetic, as switching between tabs in the entry does re-render the select field a second time and applies the null state. However, if I simply save the entry after deleting a selected array item, it will keep the value from before.



And the component:


import React from "react";

import { useFormFields, useField, Select } from "payload/components/forms";

// we can use existing Payload types easily
import { Props } from "payload/components/fields/Text";

const InputField: React.FC<Props> = (props) => {
  const { path, label, required, name } = props;

  const { value, setValue } = useField({ path });

  const chapters = useFormFields(([fields]) => {
    const numberOfChapters = parseInt(fields.chapters.value as string);

    const chapterFields = [];

    for (let i = 0; i < numberOfChapters; i++) {
      chapterFields.push({
        label: fields[`chapters.${i}.title`].value,
        value: fields[`chapters.${i}.id`].value,
      });
    }

    return JSON.stringify(chapterFields);
  });

  React.useEffect(() => {
    // Verify if the current value is in the list of chapters
    const chapter = JSON.parse(chapters).find((cph) => cph.value === value);

    // If not, set the value to null
    if (!chapter) {
      setValue(null, true);
    }
  }, [chapters, value, setValue]);

  return (
    <Select
      name={name}
      label={label}
      path={path}
      required={required}
      options={JSON.parse(chapters)}
    />
  );
};

export default InputField;


My custom chapterSelect field:


const chapterSelectField: Field = {
  name: "chapter",
  type: "text",
  admin: {
    components: {
      Field: InputField,
    },
  },
};


My chapters field:


 {
          label: "Chapters",
          fields: [
            {
              name: "chapters",
              label: "Chapters",
              type: "array",
              fields: [
                {
                  name: "title",
                  label: "Title",
                  type: "text",
                  localized: true,
                },
              ],
              admin: {
                components: {
                  RowLabel: ({ data }) => {
                    return data.title;
                  },
                },
              },
            },
          ],
        },


I start by adding items to the chapters array. Then they are made available in the chapters select field. But when I remove an item that has been selected, the value remains, eventhough I try to clean up the value in the react component.



I have created a custom field/component that fetches items from an array field on the same entry and makes them available as options in a dropdown for a different array field. (You can consider it some sort of localised taxonomy.)



I fetch the data correctly, and make the options available correctly in the select field. However, when I remove an item from the source array, and set the value of the select component to null, it preserves the value of the now deleted item.



Please see images and code below.

    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.