React-jsonschema-form: Ordering of schema-depended fields

Created on 24 Jan 2018  路  12Comments  路  Source: rjsf-team/react-jsonschema-form

Prerequisites

  • [x] I have read the documentation;
  • [x] In the case of a bug report, I understand that providing a SSCCE example is tremendously useful to the maintainers.

Description

Hello there, thank you for the great work on this project. I am exploring the use of schema dependencies but I encounter a trouble in ordering the depended fields. I created a minimal example here: https://codesandbox.io/s/8kw2wq6z08

In this example, there are two selects. When every of them is selected "yes", a depended field will be triggered to display. So "Select A" triggers "Textbox A" and "Select B" triggers "Textbox B".

What I am trying to achieve is an ordering of "Select A", "Textbox A", "Select B", "Textbox B", but setting ui:order as is (you can modify the uiSchema to uiSchema_not_working) will throw the following error:

Invalid root object field configuration:uiSchema order list contains extraneous properties

If there is a way to correctly define the ordering, could you please kindly inform?

Copy-paste the schema here:

{
  "type": "object",
  "properties": {
    "Show first name?": {
      "type": "string",
      "enum": ["yes", "no"]
    },
    "Show family name?": {
      "type": "string",
      "enum": ["yes", "no"]
    }
  },
  "dependencies": {
    "Show first name?": {
      "oneOf": [{
        "properties": {
          "Show first name?": {
            "enum": ["yes"]
          },
          "First name": {
            "type": "string"
          }
        }
      }, {
        "properties": {
          "Show first name?": {
            "enum": ["no"]
          }
        }
      }]
    },
    "Show family name?": {
      "oneOf": [{
        "properties": {
          "Show family name?": {
            "enum": ["yes"]
          },
          "Family name": {
            "type": "string"
          }
        }
      }, {
        "properties": {
          "Show family name?": {
            "enum": ["no"]
          }
        }
      }]
    }
  }
}

The uiSchema I was trying to set:

{
  "ui:order": ["Show family name?", "Family name", "Show first name?", "First name"]
}

Version

React 16.0.0
react-jsonschema-form latest

Most helpful comment

You can use a wildcard like this:

    'ui:order': [
      'description',
      'method',
      'url',
      'headers',
      '*', // all undefined ones come here.
      'variable',
      'results',
    ],

All 12 comments

Facing with the same issue

You can use a wildcard like this:

    'ui:order': [
      'description',
      'method',
      'url',
      'headers',
      '*', // all undefined ones come here.
      'variable',
      'results',
    ],

@Pruxis This wildcard:
(1) cannot define the order of undefined ones;
(2) requires that all undefined ones are grouped together in display.

I found this https://github.com/audibene-labs/react-jsonschema-form-layout. Haven't yet worked on it. But that might be an alternative solution.

@Pruxis That worked in my use case! Thanks a lot buddy!

No, there's no way to do what you want at present @lingxiaoyang. I think the approach you suggest -- adding all properties to order -- is the right way to go. I'd be happy to review a PR that loosens the check on order when there are dependencies -- either to not check at all, or maybe to somehow include the properties from all the dependencies.

It would be great if you could add this capability @glasserc

Hi everyone!
I work at Taboola, and we are using your project. It's an amazing project! Thank you!
We have fixed this issue on our own fork.

Basically there is no guarantee for the keys order in an object, but we found a simple fix which works for us.

From our check: as long as the key can't be parsed as an integer, the key's order is the insertion order

In the function mergeObjects, we are splitting the object to 2 parts, inserting the dependent fields to the first part and then inserting the second part back to the first part.

Do you want me to open a pull request for this fix?

@DanielMargolin-Taboola That solution isn't really acceptable as it relies on the ordering of object keys, which by definition (and the specification) are unordered. See this Stackoverflow question.

@glasserc PR #814 fixes this, is there any reason it hasn't been merged yet? In @igorgubernat's fix, extraneous ui:order properties are ignored in all circumstances, instead of only when there are dependencies, but I don't really see that as an issue.

If you think that "loosening" the check is really important as opposed to ignoring, then there would have to be some refactoring of the retrieveSchema function, since that "resolves" dependencies and essentially leaves no trace that they were ever there (which makes knowing whether a schema has a dependency difficult).

Also, a temporary way to fix this (until it actually gets fixed) without modifying any core library code is to register a custom ObjectField component that looks like this:

import React from 'react'
import PropTypes from 'prop-types'
import BaseObjectField from 'react-jsonschema-form/lib/components/fields/ObjectField'

const filterOrder = (properties, order) =>
  order.filter(prop => prop === '*' || properties.includes(prop))

const ObjectField = ({ uiSchema, ...props }) => {
  const properties = Object.keys(props.schema.properties)
  const order = uiSchema['ui:order']
  const newUISchema = order
    ? { ...uiSchema, ['ui:order']: filterOrder(properties, order) }
    : uiSchema

  return <BaseObjectField {...props} uiSchema={newUISchema} />
}

ObjectField.propTypes = {
  schema: PropTypes.object.isRequired,
  uiSchema: PropTypes.object.isRequired,
}

export default ObjectField

@DanielMargolin-Taboola Sorry, maybe I don't understand the linked code, but I don't see how it allows the user to set the order of dependent fields. It seems like it just picks a specific order (the order in obj1?) and enforces it.

@jaminthorns I am not crazy about removing the check. For this reason, I don't think I'm going to merge #814.

Closing this now that #814 has been merged.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mfulton26 picture mfulton26  路  3Comments

epicfaace picture epicfaace  路  3Comments

marinav picture marinav  路  3Comments

sstarrAtmeta picture sstarrAtmeta  路  3Comments

ClockerZadq picture ClockerZadq  路  3Comments