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 can I stop the Save button not to be clickable when viewing virtual fields

default discord avatar
icedcacaolast year
2

I have some problem with the virtual fields where I fetch the data from the api. And it display in the virtual fields. However everytime I viewing the documentation the Save button is appearing ready to be clicked again.



'use client'
import React, { useEffect } from 'react'

import { useField, FieldLabel, TextInput, useFieldProps, useDocumentInfo } from '@payloadcms/ui'
import { TextFieldClientProps } from 'payload'
import { stringify } from 'qs-esm'

const DEFAULT_LIMIT = 9999
const DEFAULT_DEPTH = 0
const DEFAULT_PAGE = 1

export const stockComponent: React.FC<TextFieldClientProps> = ({ field }) => {
  const { label } = field
  const { path, readOnly } = useFieldProps()
  const { value, setValue } = useField<string>({ path })
  const { id } = useDocumentInfo()
  const stringifyQuery = stringify(
    {
      depth: DEFAULT_DEPTH,
      limit: DEFAULT_LIMIT,
      page: DEFAULT_PAGE,
      where: {
        product: {
          equals: id,
        },
      },
    },
    { addQueryPrefix: true },
  )

  const setStockValue = async () => {
    const res = await fetch(
      `${process.env.NEXT_PUBLIC_SERVER_URL}/api/inventory-logs${stringifyQuery}`,
    )
    const data = await res.json()
    let displayValue = 0
    for (let i = 0; i < data.docs.length; i++) {
      if (data.docs[i].type === 'import') {
        displayValue += data.docs[i].quantity
      } else {
        displayValue -= data.docs[i].quantity
      }
    }
    setValue(displayValue.toString())
  }
  useEffect(() => {
    setStockValue()
  }, [])
  // This one is read only
  return (
    <div className="field-type text">
      <FieldLabel field={field} htmlFor={`field-${path}`} label={label} />
      <div className="field-type__wrap">
        <TextInput value={value} path={path} onChange={setValue} readOnly={Boolean(readOnly)} />
      </div>
    </div>
  )
}


import type { TextField } from 'payload'

export const stockField: TextField = {
  name: 'stock',
  type: 'text',
  admin: {
    readOnly: true,
    components: {
      Field: {
        path: '@/payload/fields/productDisplayStock/component#stockComponent',
      },
    },
  },
  hooks: {
    beforeChange: [
      ({ siblingData }) => {
        siblingData.stock = undefined
      },
    ],
  },
}
  • default discord avatar
    minsomailast year

    you can replace Save button with your own component



      admin: {
        components: {
          edit: {
            SaveButton: MySaveButton,
          },
        }
      },


    and in the component the button with type="submit" triggers the save



    <div>
    <!-- Other things, buttons,here -->
    
          <div className="form-submit">
            <button type="submit" id="action-save" className="btn btn--style-primary btn--icon-style-without-border btn--size-small btn--icon-position-right">
              <span className="btn__content">
                <span className="btn__label">My Save</span>
              </span>
            </button>
          </div>
        </div>
  • default discord avatar
    icedcacaolast year

    Thank you!

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.