rstgroup / react-components-form

React components form give you posibility to create forms with schema validation using "form-schema-validation".
https://rstgroup.gitbooks.io/react-components-form/
MIT License
30 stars 15 forks source link

Is there any way to alter the schema in runtime? #42

Closed leroy0211 closed 7 years ago

leroy0211 commented 7 years ago

I have a use case in which the schema has to be altered whenever a Model has changed. We have a system which uses sections and categories. Each section has it's own categories. Both Section and Categories are SelectFields. Whenever someone changes the Section field, the label and options of the Categories field must change.

The options of the Categories SelectField are fetched from an API.

Currently I try to recreate the schema, but the schema passed as Form prop is not being converted to state. I tried to change the state:schema by myself, that changed the schema, but didn't changed any labels or options. Only when I click on the SubmitField, the new label and options are passed to the SelectField.

mprzodala commented 7 years ago

You can use eventsListener to manage this case. You can listen on select change and set new default value on category field.

Example

import React, { Component } from 'react';
import Schema from 'form-schema-validation';
import {
    Form,
    SelectField,
    SubmitField,
    FormEventsListener,
} from 'react-components-form';

const schema = new Schema({
    section: {
        type: String,
    },
    category: {
        type: String,
    },
});

const sections = ['s1','s2'];
const categories = ['a1','a2','a3','a4'];
const categories2 = ['b1','b2','b3','b4'];

class SectionsCaseForm extends Component{
    constructor(props) {
        super(props);
        this.eventListener = new FormEventsListener();
        this.eventListener.registerEvent('changeSection');
        this.state = {
            categories: categories,
            sections: sections,
        };
        this.setCategoriesOptions = this.setCategoriesOptions.bind(this);
    }
    setCategoriesOptions(options) {
        this.setState({ categories: options }, () => {
            this.eventListener.callEvent('changeSection', options);
        });
    }
    render() {
        const { categories, sections } = this.state;
        return (
            <Form
                eventsListener={this.eventListener}
                schema={schema}
                onSubmit={data => console.log(data)}
                onError={(errors, data) => console.log('error', errors, data)}
            >
                <h4>FORM</h4>
                <div className="row">
                    <div className="col-xs-6">
                        <SelectField
                            name="section"
                            options={sections}
                            callbacks={{
                                onChange: (value) => {
                                    if (value === 's1') {
                                        this.setCategoriesOptions(categories);
                                    }
                                    if (value === 's2') {
                                        this.setCategoriesOptions(categories2);
                                    }
                                }
                            }}
                            defaultOption={0}
                        />
                    </div>
                    <div className="col-xs-6">
                        <SelectField
                            name="category"
                            options={categories}
                            defaultOption={0}
                            onEmitEvents={{
                                name: 'changeSection',
                                method: (options, Field) => {
                                    Field.onChangeData(options[0]);
                                }
                            }}
                        />
                    </div>
                </div>
                <SubmitField value="Submit"/>
            </Form>
        );
    }
}

export default SectionsCaseForm;