eclipsesource / jsonforms

Customizable JSON Schema-based forms with React, Angular and Vue support out of the box.
http://jsonforms.io
Other
2.03k stars 352 forks source link

[question] Support for const? #1587

Open tiloc opened 4 years ago

tiloc commented 4 years ago

Describe the bug I am not sure if this is a feature request or a bug. I am trying to pass constant strings from the schema into the JSON output of the form. According to the JSON Schema spec this should be possible by using the "const" keyword. Unfortunately, I cannot get this to work with JSON Forms.

To Reproduce Steps to reproduce the behavior:

  1. Create a schema with the const keyword
  2. Use it with the "seed" app
  3. The element is ignored, i.e. not shown in the form nor output to the JSON data

Expected behavior The constant data is passed through from the schema into the output.

Browser (please complete the following information): Chrome

Used Setup (please complete the following information):

Additional context I am trying to use JSON Forms to generate valid FHIR healthcare resource output.

sdirix commented 4 years ago

Hi! Thanks for this report. const values were always a little bit out of scope for us as it doesn't really make sense to show an UI for them, however I can understand that you need them in some way in your data at some point.

Current state

Automatic generation within JSON Forms

Let me know whether one of the approaches works for you. If you (or someone else :smile:) would like to contribute something for this use case: I think a const renderer (which is a bit nicer than an enum dropdown with a single entry) which allows to set/unset the value and optionally automatically sets the value (could be made configurable via the ui schema) would be something worthwhile.

In the meantime we could maybe change the default ui schema generation to also include a control for these const properties.

jnothman commented 3 years ago

A case where default is insufficient is where the form requests an array of heterogeneous objects and one wants to label each element by its type:

{
  "type": "array",
  "items": {
    "oneOf": [
      {
        "type": "object",
        "required": ["@type", "name"],
        "properties": {
          "@type": {
            "type": "string",
            "const": "Person"
          },
          "name": {
            "type": "string",
            "title": "Person's name"
          },
          "gender": {
            "type": "string",
            "enum": ["male", "female", "other", "not disclosed"]
          }
        }
      },
      {
        "type": "object",
        "required": ["@type", "name"],
        "properties": {
          "@type": {
            "type": "string",
            "const": "Organisation"
          },
          "name": {
            "type": "string",
            "title": "Org's name"
          }
        }
      }
    ]
  }
}

If one adds defaults and the user selects Organization and enters "name" only, then ajv will fill in "Person" as the default.

This seems to work for me:

import React from 'react';
import { withJsonFormsControlProps } from '@jsonforms/react';

export const ConstRenderer = withJsonFormsControlProps(({schema, handleChange, path}) => {
  React.useEffect(() => {
    handleChange(path, schema['const'])
  }, [schema, path]);
  return (<React.Fragment></React.Fragment>);
});
dgerbe commented 1 year ago

@sdirix What if you're use-case is for the user to type in the const value? As a simple example, say you wanted the user to type "Confirm". This may not be a great UX design, but I have seen it.

My real use-case is I want to create a confirmation field where the user should enter the same value as entered in the previous field.

I tried to accomplish this with the schema below, but it creates a enum drop-down like you described in your previous comment.

{ "required": [ "username", "password", "confirmPassword" ], "properties": { "username": { "minLength": 3, "type": "string" }, "password": { "minLength": 6, "type": "string" }, "confirmPassword": { "const": { "$data": "1/password" }, "type": "string" } }, "type": "object" }

Source

bastianwegge commented 1 year ago

@jnothman thanks a thousand times, this solution helped us save a lot of time rewriting the array renderers.

@sdirix +1 for array types. Maybe there's a different solution to this, as different types of array items seem to be somewhat frequent.

Thanks for jsonforms in any case 😃

sdirix commented 2 months ago

We recently improved some of the const use cases: Whenever we create a new object in JSON Forms, we will look for default declarations and set them immediately. So when you are using const combined with a default set to the same value, JSON Forms will set your const automatically.

Note this only happens on user interactions in which the user triggers the creation of a new object. It's very useful for these "@type" use cases in which a const is used to identify the type of the object.

This is available since 3.2.0