Hi, I am new to Payload and starting to learn my way around the codebase. Enjoying it so far!
This post explains my scenario but basically asks "Are there any existing examples of replacing the relationship field in
Editviews with a custom component that can get me started?"
I have followed the method in this thread to populate images within custom
Cellcomponents as pictured in the attachments.
I would like to create a similar component for relationship types in
Editview to replace the dropdown list item (last image attachment).
Am I correct in thinking that I will need to target changing the
SingleValuecomponent? Here in the source:
Or are there multiple components that I will have to target?
For example, does the
SingleValuecomponent specify the selections only when the drop down
DocumentDraweris open but there is a different component I need to target for when it is closed?
If this is the scenario of Payload - I would have to target the
Relationshipcomponent in addition to
SingleValue?
And in my definition for the collection that makes use of this relationship - the field object will look something like this if my new component is called
ImageTitleRelationshipField?
{
name: "competitorOne",
type: "relationship",
relationTo: ["artworks"],
admin: {
components: {
Cell: ImageTitleCell,
Field: ImageTitleRelationshipField
},
},
},I guess I am asking - what is the best approach? and are there any existing examples of replacing the relationship field in
Editviews with a custom component that can get me started?
sorry i don't have the answer but i was wondering if i could see your ImageTitleCell and ImageTitleRelationshipField codes if possible? i'm trying to make a custom component to make my images look like those rather than appearing as filenames 😄
i made my own component but i can't seem to locate the image's url inside the props, i just get the element's name
See this message for a good starting point:
https://discordapp.com/channels/967097582721572934/1041362545501548624/1041487440310964225I have not yet started to create code for
ImageTitleRelationshipFieldcomponent yet because it's what I opened this thread to ask about.
ohhh gotcha, thanks a lot, good luck! 😄
I don't know of any examples of replacing this field. That field component is by far the most complex of all the fields, so swapping that one out would be pretty intense.
Thanks for your reply. I suppose that doesn't surprise me. Looking at the
Relationshipfield source code (
https://github.com/payloadcms/payload/blob/master/src/admin/components/forms/field-types/Relationship/index.tsx) it doesn't seem very maintainable in the long term to try swapping this whole field out with all its dependencies... If I am correct in my reading of the source what I am actually interested in is changing the usage of
propswithin
ReactSelectcomponent...in my case for the
SingleValuevariant.
I'll have to do more thinking about this caveat over the next week or so when I have the time. I'll update this thread when I can.
For now I could categorize this potential issue in broader terms by saying: Without any concept of an attached featured image per collection item, content editors do not have a way of rapidly identifying a target item when attaching as a relationship via the existing
ReactSelectUI if they are not sure about its name because the UI offers text only. Any alternative suggestions for working around this issue would be appreciated 🙂 .
Okay, so your goal is for admin users to rapidly scan the list view for image relationships? The only other workaround I can think of is to make a
uitype field with a custom cell component and render anything helpful in it.
Thanks for thinking it though. My ideal scenario is for the dropdown list items of the
Relationshipfield in the
Editview to appear similarly to the custom
Cellcomponent I successfully created for the
Listview, where a related image thumbnail appears before the title. (This successful
Listview for the Polls collection is shown as an attached image to the original post).
Is your suggested workaround to include a custom
UItype component in the collection
Editview, adjacent to the
Relationshipfield, that somehow listens for changes on the
Relationshipfield and updates with a thumbnail image from the selected item?
Yes, correct.
Essentially, another field to augment the functionality instead of replacing the relationship field altogether
I'd be happy to take a stab at that. Can you give an approach for the
UIfield to listen for changes on another field?
@281120856527077378
Can you assist here? I'm not as familiar with the React hooks we have available to accomplish this
These docs would be a good start from the react side:
https://payloadcms.com/docs/admin/hooks#useformfieldsmake a ui type field with a custom component and render anything helpful in it.
This is probably the way to go here
To listen to changes on that field from within your custom component, fire the
useFormFieldshook like this:
const { value } = useFormFields(([fields, dispatch]) => fields.yourRelationshipField);Awesome, thanks for your help! Hopefully I'll be able to update this thread later with my usage.
Okay, thanks for all the help again. Here is a basic snippet to get anyone else started if searching in the future. The attached image shows how the custom
UIcomponent based on the code snippet looks next to the standard
Relationshipfield...while using the
Rowfield to parent both and with some additional CSS.
import React, { useState, useEffect } from "react";
import { useFormFields } from "payload/components/forms";
const baseUrl = process.env.PAYLOAD_PUBLIC_SERVER_URL;
const ThumbnailListener = (props) => {
// value key holds current value of fields[props.label]
// I am using the label key in the UI field options (defined in the collection) to pass the name of the target relationship field via props
const { value } = useFormFields(([fields, dispatch]) => fields[props.label]);
const [fetchItem, setFetchItem] = useState();
useEffect(() => {
value &&
fetch(`${baseUrl}/api/${value.relationTo}/${value.value}/?depth=1`)
.then((data) => data.json())
.then((object) => setFetchItem(object));
}, [value]);
return (
<>
{fetchItem?.image?.sizes?.thumbnail?.url && (
<img
src={fetchItem.image.sizes.thumbnail.url}
></img>
)}
</>
);
};BOOM! That's great.
Star
Discord
online
Get dedicated engineering support directly from the Payload team.