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 extend payload selectInput, with images?

default discord avatar
rnbsovlast year
6

I have input for selecting users, but I want to see their avatars in the options



@654031862146007055

Hello, I need your advice please 🥺

  • default discord avatar
    forrest.devlast year

    is this on the admin panel you want to do this?



    And you have a field on a collection with type relationship to the users collection?



    https://github.com/payloadcms/payload/discussions/2934

    something like that?

  • default discord avatar
    rnbsovlast year

    yes!!!

  • default discord avatar
    forrest.devlast year

    youll want to create a custom component for this. Look into the docs here about it:

    https://payloadcms.com/docs/fields/overview#custom-components

    heres a super rough idea. Make this as the server comp which you add in the field

    admin.components.Field

    import { RelationshipFieldServerProps } from 'payload'
    import Client from './comp.client'
    
    export default async function CustomUserRelationshipField({
      path,
      field,
      payload,
    }: RelationshipFieldServerProps) {
      if (field.type === 'relationship') {
        const { relationTo } = field
    
        if (Array.isArray(relationTo)) {
          throw new Error('relationTo must be a single collection slug')
        }
    
        if (relationTo !== 'users') {
          throw new Error('relationTo must be a equal to the users collection')
        }
    
        const res = await payload.find({
          collection: 'users',
          where: {},
        })
    
        const docs = res.docs
    
        return <Client docs={docs} path={path} />
      }
    
      return <>NOT SETUP</>
    }


    then the Client component, this is where you use the

    useField

    hook passing it the path.

    'use client'
    
    import React from 'react'
    import { User } from '@payload-types'
    import { useField } from '@payloadcms/ui'
    
    export default function Client({ docs, path }: { docs: User[]; path: string }) {
      const { value, setValue } = useField({ path })
    
      return (
        <div className="custom-select-container">
          <select
            value={value as string}
            onChange={(e) => setValue(e.target.value)}
            className="custom-select"
          >
            <option value="">Select a user</option>
            {docs.map((doc) => (
              <option key={doc.id} value={doc.id.toString()}>
                {doc.email} (ID: {doc.id})
              </option>
            ))}
          </select>
        </div>
      )
    }


    then add this to the field you want to do it on assuming its a field with relationship to the users collection.

    admin: {
            components: {
              Field: 'path-to-server-comp/CustomUserRelationshipField',
            },
          },


    this is just a basic implementation and doesn't show any image. but if you can get to this point you would be able to change the component ui and use the

    doc.avatar

    field to either show a payload Media comp or an img if its just a src string. Might also have to make a custom select because I know you can't put

    <img/>

    comps directly inside a html

    <option/>

    tag.

  • default discord avatar
    rnbsovlast year

    oh, thanks a lot for such extensive answer!



    I appreciate that



    and will try to implement as you've said

  • default discord avatar
    forrest.devlast year

    Let me know if you can get what you want working.



    Anytime 👍🏽

  • default discord avatar
    rnbsovlast year

    that's really kind from you! thanks, and best wishes!

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.