form icon indicating copy to clipboard operation
form copied to clipboard

Meta api for form fields

Open harry-whorlow opened this issue 11 months ago • 16 comments

Continuation from the discussion #709. Listeners are implemented, however the meta field is yet to be started.

The proposal is to have the meta data available to the field component:

(example shamelessly ripped form #709)

<form.Field
  name="foo"
  meta={({ fieldApi }) => ({
    disabled: fieldApi.form.getFieldValue('someOtherField') == null,
    ...
  })}
  // or maybe expose values directly like form.Subscribe
  meta={({ values }) => ({
    disabled: values.someOtherField == null,
    ...
  })}
>
  {(field, meta) => <Comp
    disabled={meta.disabled}
    ...

You can subscribe to the meta from the Form but its pretty handy to have it available to the Field component.

I'm happy to give this a go, I just need the go ahead from a maintainer. 🤟

harry-whorlow avatar Jan 13 '25 15:01 harry-whorlow

Hey 👋 , this sounds like a great idea. Personally, I prefer the second version (less verbose and more straight-forward). Are you still ready to create a PR? If yes, then this is the "go ahead"! ☺️☺️

Edit: Just to make it easy for people who visit this discussion later, this is the second version:

  // or maybe expose values directly like form.Subscribe
  meta={({ values }) => ({
    disabled: values.someOtherField == null,
    ...
  })}

fulopkovacs avatar Jan 19 '25 21:01 fulopkovacs

Yeah, me too.

Absolutely, I'll start it this week, and hopefully have a PR ready by next weekend. 🫡

Thanks for the go ahead 🤘

harry-whorlow avatar Jan 19 '25 21:01 harry-whorlow

Thank you for your enthusiasm! 🙌 Feel free to ping me in the comments when the PR is ready!

fulopkovacs avatar Jan 20 '25 08:01 fulopkovacs

@fulopkovacs, l've left a couple questions on #1125. If you get a chance to take a look it would be appreciated 🤟

harry-whorlow avatar Jan 24 '25 10:01 harry-whorlow

@fulopkovacs, l've left a couple questions on #1125. If you get a chance to take a look it would be appreciated 🤟

Awesome, thanks for your work! I'll look at them tomorrow, this week was pretty busy...

fulopkovacs avatar Jan 24 '25 11:01 fulopkovacs

@fulopkovacs, no worries... thanks!

harry-whorlow avatar Jan 24 '25 12:01 harry-whorlow

✨ Hi everyone,

I commented on a post by @crutchcorn on LinkedIn and we talked about disabling form-fields. I was told it is okay to have a discussion about it here as a part of this issue.

I have this request/idea that I would like to suggest, a setDisabled() method for form-fields. I don't know if it's a good idea.. but I had this problem where I was building a complicated form using react-hook-form, I had a field containing data about a heart's rhythm disorder, when you pick one you must setValue() and also disable other fields, for example: a patient's pulse value. Assuming I had generic inputs I found myself creating an array of disabled values, and then each input checked if it was contained in this array, passing "disabled" as a component prop to the input. This caused weird bugs when put in a register() function (it has a disabled key in it).

Anyway.. what are your thoughts about such feature (setDiasbled())? Do you think it'll have any value for the community/developers?

itayperry avatar Feb 12 '25 11:02 itayperry

Hi @itayperry, have you checked out the PR over at #1125. That's kind of the idea I was going for... in a sense that you can create your own meta for your fields.

<form.Field
  name="foo"
  meta={({ values }) => ({
    disabled: values.someOtherField == null,
    ...
  })}
>
  {(field, meta) => 
  <Component
    disabled={meta.disabled}
    ... >
  </Component>

I've got a working MVP that allows for this functionality. Dose this api address your needs?

harry-whorlow avatar Feb 12 '25 12:02 harry-whorlow

Hi there @harry-whorlow, this looks great, but will the form be aware of that? Or just the input itself? What I mean to ask is, will the form in its entirety know which of its fields are disabled? I think Angular has this kind of data, not that I am saying we should do what they do, it's obviously not React and it's different.

itayperry avatar Feb 12 '25 12:02 itayperry

@itayperry the field.meta is stored in the form store... so yes it will be accessible globally.

I know I asked this, but that was a couple weeks ago and I now realise that question doesn’t make a lot of sense, plus the value exists in the store... its more the Ts inference thing. I think for all intents and purposes, that question can be ignored 🙃

But the meta api is for user defined meta so if you don't add it it won't show up. I suppose we could always add disabled to the FieldMetaBase type.

harry-whorlow avatar Feb 12 '25 13:02 harry-whorlow

@harry-whorlow I see, thank you :) Regarding your question, the main form will have access to these values but it won't have a type for them, right?

itayperry avatar Feb 12 '25 13:02 itayperry

@itayperry yeah, you can see it in the image I posted, but if you log the meta its there, its just Ts inference... But, as I said just ignore the question as it needs to be globally typed.

harry-whorlow avatar Feb 12 '25 13:02 harry-whorlow

What are your thoughts regarding a global mechanism, such as setDisabled()?

itayperry avatar Feb 16 '25 15:02 itayperry

Is there also planned support for accessing custom meta properties when accessing the field through the useFieldContext context?

danielkjellid avatar Apr 03 '25 10:04 danielkjellid

Hi @danielkjellid, thats a good question, when I created this issue and the original pr when useAppForm wasn’t part of the library. I'll have to think about this, but we will strive for its integration. 😄

I've been rather busy as of late, but either next week or the week after I might have some time to take a pass.

harry-whorlow avatar Apr 27 '25 10:04 harry-whorlow

Is there also planned support for accessing custom meta properties when accessing the field through the useFieldContext context?

Absolutely, if the ordinary field api e.g.

<form.Field
  name="foo"
  meta={({ values }) => ({
    disabled: values.someOtherField == null,
    ...
  })}
>
  {(field, meta) => 
  <Component
    disabled={meta.disabled}
    ... >
  </Component>

supports custom meta properties then the useFieldContext hook would also have the exact same functionality because it's the same FieldApi class instance passed through React.Context.

kavyantic avatar Sep 25 '25 07:09 kavyantic