Использование JsonSchemaForm при изменении для обновления содержимого поля - PullRequest
0 голосов
/ 11 октября 2018

Я пытаюсь использовать компонент JsonSchema-Form, но у меня возникла проблема при попытке создать форму, в которой после выбора одного из параметров в первом раскрывающемся списке должно появиться вторичное раскрывающееся меню, которое предоставит пользователю другой набор параметров.варианты выбора в зависимости от того, что он выбрал в первом раскрывающемся списке через вызов API.

Дело в том, что после прочтения документации и некоторых примеров, найденных здесь и здесь соответственно, я все еще не знаю точно, какие ссылки я выбрал в первом вариантеповлиять на второй выпадающий.Вот пример того, что у меня есть прямо сейчас:

Информация о Jsons, которая должна отображаться в первом и втором раскрывающихся списках через вызовы API:

Groups: [
{id: 1,
name: Group1}
{id: 2,
name: Group2}
]
User: [User1.1,User1.2,User2.1,User2.2,User3.1,User3.2, ....]

Если пользователь выбирает первую группузатем я должен использовать следующий вызов API для получения пользовательских типов, который возвращает мне USER json.

Компонент, который вызывает JSonChemaForm

render(){
 return(
          <JsonSchemaForm
            schema={someSchema(GroupOptions)}
            formData={this.state.formData}
            onChange={{}}
            uiSchema={someUiSchema()}
            onError={() => {}}
            showErrorList={false}
            noHtml5Validate
            liveValidate
          > 
 )
}

Содержимое SchemaFile:

export const someSchema = GroupOptions => ({
  type: 'object',
  required: [
    'groups', 'users',
  ],
  properties: {
    groups: {
      title: 'Group',
      enum: GroupOptions.map(i=> i.id),
      enumNames: GroupOptions.map(n => n.name),
    },
    users: {
      title: 'Type',
      enum: [],
      enumNames: [],
    },
  },
});

export const someUISchema = () => ({
  groups: {
    'ui:autofocus': true,
    'ui:options': {
      size: {
        lg: 15,
      },
    },
  },
  types: {
    'ui:options': {
      size: {
        lg: 15,
      },
    },
  },

});

Я не совсем уверен, как поступить с этим, и как использовать метод Onchange, чтобы делать то, что я хочу.

1 Ответ

0 голосов
/ 15 октября 2018

Я нашел решение для вашей проблемы. Существует похожая демонстрационная программа, которая может решить ее в реагировать-jsonschema-form-layout .1. Определите LayoutField, это часть демонстрации в реагировать-jsonschema-form-layout . Чтобы вам было проще, я выложу код здесь.Создайте layoutField.js.:

import React from 'react'
import ObjectField from 'react-jsonschema-form/lib/components/fields/ObjectField'
import { retrieveSchema } from 'react-jsonschema-form/lib/utils'
import { Col } from 'react-bootstrap'

export default class GridField extends ObjectField {
    state = { firstName: 'hasldf' }
    render() {
        const {
            uiSchema,
            errorSchema,
            idSchema,
            required,
            disabled,
            readonly,
            onBlur,
            formData
        } = this.props
        const { definitions, fields, formContext } = this.props.registry
        const { SchemaField, TitleField, DescriptionField } = fields
        const schema = retrieveSchema(this.props.schema, definitions)
        const title = (schema.title === undefined) ? '' : schema.title

        const layout = uiSchema['ui:layout']

        return (
            <fieldset>
                {title ? <TitleField
                    id={`${idSchema.$id}__title`}
                    title={title}
                    required={required}
                    formContext={formContext}/> : null}
                {schema.description ?
                    <DescriptionField
                        id={`${idSchema.$id}__description`}
                        description={schema.description}
                        formContext={formContext}/> : null}
                {
                    layout.map((row, index) => {
                        return (
                            <div className="row" key={index}>
                                {
                                    Object.keys(row).map((name, index) => {
                                        const { doShow, ...rowProps } = row[name]
                                        let style = {}
                                        if (doShow && !doShow({ formData })) {
                                            style = { display: 'none' }
                                        }
                                        if (schema.properties[name]) {
                                            return (
                                                <Col {...rowProps} key={index} style={style}>
                                                    <SchemaField
                                                        name={name}
                                                        required={this.isRequired(name)}
                                                        schema={schema.properties[name]}
                                                        uiSchema={uiSchema[name]}
                                                        errorSchema={errorSchema[name]}
                                                        idSchema={idSchema[name]}
                                                        formData={formData[name]}
                                                        onChange={this.onPropertyChange(name)}
                                                        onBlur={onBlur}
                                                        registry={this.props.registry}
                                                        disabled={disabled}
                                                        readonly={readonly}/>
                                                </Col>
                                            )
                                        } else {
                                            const { render, ...rowProps } = row[name]
                                            let UIComponent = () => null

                                            if (render) {
                                                UIComponent = render
                                            }

                                            return (
                                                <Col {...rowProps} key={index} style={style}>
                                                    <UIComponent
                                                        name={name}
                                                        formData={formData}
                                                        errorSchema={errorSchema}
                                                        uiSchema={uiSchema}
                                                        schema={schema}
                                                        registry={this.props.registry}
                                                    />
                                                </Col>
                                            )
                                        }
                                    })
                                }
                            </div>
                        )
                    })
                }</fieldset>
        )
    }
}

в файле, вы можете определить свойство doShow, чтобы определить, показывать ли другой компонент.Далее. Определите функцию isFilled в JsonChemaForm

const isFilled = (fieldName) => ({ formData }) => (formData[fieldName] && formData[fieldName].length) ? true : false

В-третьих, после выбора первого раскрывающегося списка появится второе раскрывающееся меню

import LayoutField from './layoutField.js'
const  fields={
   layout: LayoutField
}
const uiSchema={
    "ui:field": 'layout',
    'ui:layout': [
        {
            groups: {
                'ui:autofocus': true,
                'ui:options': {
                   size: {
                      lg: 15,
                 },
              },
            }
        },
        {
            users: {
                'ui:options': {
                    size: {
                        lg: 15,
                    },
                },
                doShow: isFilled('groups')
            }
        }
    ]
}
...
render() {
    return (
        <div>
            <Form
                schema={schema}
                uiSchema={uiSchema}
                fields={fields}
            />
        </div>
    )
}
...