I have the following DOM element select:
<select title="select" value={selectedOption} onChange={(e) => handleChange(e, path)}>
{options.map((option, index) => <option value={option}>{option}</option>)}
</select>
The above works as expected
I'm trying to use payload's Select, as referenced in the subject title. I imagine hooks is the way to manage state, as onChange isn't provided - but they aren't ever triggered?
<Select name='select' label="my select" options={options} hooks={{
afterChange: [() => console.log('afterChange')],
beforeChange: [() => console.log('beforeChange')],
afterRead: [() => console.log('afterRead')],
beforeValidate: [() => console.log('beforeValidate')],
}} />
Am I missing something? I would like to set a default value from
useFormFields
and update the selected value onChange (as achieved in the first example)
AH!
I linked the wrong import path in our last discussion. 1 min
Ok so you will want to import the Select component like so
import SelectInput from 'payload/dist/admin/components/forms/field-types/Select/Input';
(see the component here:
https://github.com/payloadcms/payload/blob/master/src/admin/components/forms/field-types/Select/Input.tsx)
This will give you the styled component - so it looks and feels like other payload select components.
What you need to do is implement similar functionality seen in this file in your custom Field component:
https://github.com/payloadcms/payload/blob/master/src/admin/components/forms/field-types/Select/index.tsxYou can see how that file imports the
<SelectInput />
which is the one you will import, all of the state management (getting and setting options for your custom select) will live in a file that then passes props (onChange, value, options, etc) down to the SelectInput component.
I hope this makes sense and steers you in the right direction!!
Hi @Jarrod , I'm back! Following your recommendation above I have the following:
<SelectInput
path={p}
name='l'
label='logic'
options={options.map(option => option...)}
onChange={e => handlePrerequisiteChange(e, path)}
/>
The above doesn't persist between refreshes.
The following sometimes works when another field is updated:
<select
title='prerequisite'
value={selectedOption}
onChange={e => handlePrerequisiteChange(e, path)}
>
{options.map((option, index) => (
<option key={`r-${index}`} value={`${option.question}_${option.answer}`}>
{`${option.question}_${option.answer}`}
</option>
))}
</select>
* I'm still using
useFormFields
, I can't see how to make use of
useFields
(without violating react hook laws). How could I update each dropdown with useFields? My implementation is below
* Changing an option in my select won't trigger the clean/dirty flag for saving/publishing changes but sometimes persists when other fields change
Hopefully the content below will help paint a picture of what I'm working with and why I chose
useFormFields
:
// fields param is from:
// const { fields, dispatch } = useFormFields(([fields, dispatch]) => ({ fields, dispatch }))
const generateOptions: (fields: any) => string[] = fields => {
const numberOfPages = pageState.pages.value
const questionCombination = [...Array(numberOfPages).keys()].flatMap(pageNo =>
getAnswerOptionsFromAnswerTypes( // checks if boolean/multiple choice, etc
// assuming there is currently only one question and answer
fields[`pages.${pageNo}.content.questions.0.answerType.0.blockType`],
).map<ConditionalLogicOptions>(option => ({
question: fields[`pages.${pageNo}.content.questions.0.text`].value,
answer: fields[`pages.${pageNo}.content.questions.0.answerType.0.${option}`]?.value || '',
})),
)
return questionCombination
}
Here's a screenshot displaying the dropdown comprised of state from multiple fields.
using
useField
for the
selectedValue
triggers the clean/dirty flag for saving a draft/publishing and reloading sends it back to its previous value, so it's still not persisting
Progress!
I've used
useField
instead of
useState
to set the selectedOption. That sorts out my clean/dirty and the reload.
The only remaining issue is converting my un-styled select to your SelectInput. My select HTML is still as above. I'm getting page ids coming through for the dropdown when I use the following:
<SelectInput
path={path}
name='logic'
label='logic'
options={options.map((option) => ({</option>)
label: option,
value: option
}))}
onChange={e => handlePrerequisiteChange(e, path)}
/>
Star
Discord
online
Get help straight from the Payload team with an Enterprise License.