在更改时使用JsonSchemaForm更新字段的内容

时间:2018-10-11 20:20:47

标签: javascript reactjs react-jsonschema-forms

我正在尝试使用JsonSchema-Form组件,但是在尝试创建一个表单时遇到了一个问题,该表单在第一个下拉列表中选择了一个选项之后,应该出现第二个下拉列表,并为用户提供了不同的设置。根据他在API调用的第一个下拉菜单中选择的选项进行选择。

问题是,在阅读了文档和分别找到herehere的一些示例之后,我仍然不完全知道如何引用我在第一个选项中选择的内容来影响第二个下拉菜单。这是我现在拥有的示例:

应该通过api调用的第一个和第二个下拉列表显示的Jsons信息:

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 :(得分:1)

我为您的问题找到了解决方案。react-jsonschema-form-layout中有一个类似的演示可以解决该问题。 1.定义LayoutField,这是react-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属性以定义是否显示其他组件。 接下来,在JsonChemaForm中定义isFilled函数

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>
    )
}