jsonforms icon indicating copy to clipboard operation
jsonforms copied to clipboard

Add placeholder support for React Vanilla

Open andresgutgon opened this issue 3 years ago • 10 comments

Is your feature request related to a problem? Please describe.

It would be great when placeholders could be defined via the ui schema and set in the respective inputs

Describe the solution you'd like

Allow for the optional attribute placeholder, e.g.

{
  "type": "Control",
  "scope": "#",
  "options": {
    "placeholder": "This is a placeholder"
  }
}

Describe alternatives you've considered

We could also think about checking for a placeholder attribute in the JSON Schema

Framework

React

RendererSet

Vanilla

Additional context

At least for Vue-Vanilla. When adding the possibility of defining a placeholder to the JSON Schema, then we could think about adding this to the JSON Forms core so any renderer set benefits from that.

This issue is a copy of this Vue issue https://github.com/eclipsesource/jsonforms/issues/1729

I guess the implementation would similar.

andresgutgon avatar Dec 02 '21 09:12 andresgutgon

Hi @andresgutgon, thanks for the suggestion. This could definitely be added to each renderer set.

we could think about adding this to the JSON Forms core so any renderer set benefits from that.

We have to think about whether it makes sense to add it to the core framework. Up until recently I would definitely have said no, as there is not much benefit of receiving a placeholder prop than just looking it up in the renderer via something like uischema.options.placeholder. It's not really a feature affecting the core.

However as we recently introduced translation support it now might make sense to also provide the user a default translated placeholder as the renderer code now not only needs to look up the placeholder but potentially also translate it.

sdirix avatar Dec 02 '21 11:12 sdirix

However as we recently introduced translation support

Just was reading about it! Rework i18n support in JSON Forms core.

Not sure how to i18n my forms though. Not seing documentation related with this

andresgutgon avatar Dec 02 '21 11:12 andresgutgon

I found the way the new i18n prop in jsonforms v.3 is used.

I did a hook where I can use my i18n solution. Which in my case is react-intl. Then I use the hook on the JSONForms i18n prop. The hook

import { useIntl } from 'react-intl'
import { UISchemaElement, Translator } from '@jsonforms/core'
import { ErrorObject } from 'ajv'
export const useTranslateError = () => {
  const intl = useIntl()
  return (
    error: ErrorObject,
    _translate: Translator,
    uischema: UISchemaElement
  ): string => {
    const params = error.params
    switch(error.keyword) {
      case 'required':
        const fieldName = ((uischema as any)?.label || params.singProperty || '').toLowerCase()
        return intl.formatMessage(
          { id: '3Fs00I', defaultMessage: 'El campo {fieldName} es obligatorio' },
          { fieldName }
        )
        break;
      default:
        return error.message
    }
  }
}

And then I use this way:

import { useTranslateError } from './useTranslateError'

const MyComponent = () => {
  const translateError = useTranslateError()
  return (
        <JsonForms
          schema={jsonSchema}
          uischema={uiSchema}
          config={{ hideRequiredAsterisk: true }}
          data={data}
          renderers={vanillaRenderers}
          cells={vanillaCells}
          onChange={onChange}
          i18n={{ translateError }}
        />
  )
}

image

andresgutgon avatar Dec 02 '21 14:12 andresgutgon

I'm pretty happy with the approach. The only thing I don't like so far is that errors appears when the form renders for the first time. Which is a bit weird. But I think is related with required prop in the schema.

andresgutgon avatar Dec 02 '21 14:12 andresgutgon

You can use the translation like this, however usually I would expect people to use the translate function instead of the translateError one. The default translateError makes heavy use of translate.

translate has the type (key: string, defaultMessage: string | undefined) => string | undefined). Whenever you have a translation for a key you can return it. If you don't have one then return the defaultMessage. Just register one in your app and then you can check what keys JSON Forms is looking for.

You can also add i18n keys to the schema or UISchema, which will then be used by JSON Forms instead of the default ones.

sdirix avatar Dec 02 '21 16:12 sdirix

~I'll try with translate but I tried and was a bit confusing, maybe today I get more lucky.~ Ok I remember why I went with translateError the context of the error is not present the original translateError therefor I can't access error.params as I do overriding it

If translate do the translation work, for what is used the { {i18n: { locale: 'my-locale' }}? I mean, is used internally for something?

andresgutgon avatar Dec 03 '21 07:12 andresgutgon

Ok I remember why I went with translateError the context of the error is not present the original translateError therefor I can't access error.params as I do overriding it

That's fine! We should probably pass the error object as an additional parameter to the translate function when used for error messages.

If translate do the translation work, for what is used the { {i18n: { locale: 'my-locale' }}? I mean, is used internally for something?

At the moment only the Angular Material renderers read the locale and use it for number formatting. In general it's a useful attribute for custom renderers in case they would like to query the locale of the form for some purpose.

sdirix avatar Dec 03 '21 08:12 sdirix

I guess this can be closed : )

andresgutgon avatar Dec 07 '21 07:12 andresgutgon

Not yet right? The PR only added placeholder support for text and textarea cells. However placeholders could also be supported for example for number inputs.

sdirix avatar Dec 07 '21 08:12 sdirix

I see image

All these are <input /> that can have placeholder. I missed it sorry

andresgutgon avatar Dec 07 '21 08:12 andresgutgon