Skip to content

Instantly share code, notes, and snippets.

@pierr
Last active November 26, 2015 09:07
Show Gist options
  • Save pierr/b15d493d87d4899da0b5 to your computer and use it in GitHub Desktop.
Save pierr/b15d493d87d4899da0b5 to your computer and use it in GitHub Desktop.
form-spec

The page, the forms , the stores, the definition...

Actual spec

When you have a page to create you have to do something like that:

React.createClass({
  render() {
        <ScrollSpy>
           <Child1 />
           <Child2 />
           <Child3 />
           <Child4 />
           <Child5 />
        </ScrollSpy>
    }
});

This component has no state and knows no store. The state is located in each child and is corellated to the store connection of each Block.

Form Mixin

Eacch block is often done with a FormMixin. The formMixin which should be name formPreset is composed of the following mixins

  • ownIdentifierBehaviour Creates a unique identifier for the form in its this
  • definitionMixin Connects to the form to the definitions from the model, it allows the component to have a property definitionPath such as definitionPath: 'contact'
  • referenceBehaviour which connects the component to the master data lists, it allows the component to have a property referenceNames in order to detail which master data list you need in your page such as referenceNames: ['papas', 'monkeys'].
  • storeBehaviour connects the component to the stores using the property stores which have the signature [{store: aReferenceToTheStore, properties: ['node1', 'node4']}] such as stores: [{store: contactStore, properties:['contact', 'commandes']}] it links the components state to the stores changes. Each time a store node is changed, the component state is updated. this behaviour also get storeChangeBehaviour which has the _onChange and _onErrorFunction
  • validationBehaviour Add a _validate method to the form which loops all the components also add a _customValidateMethod
  • actionBehaviour add automatic actions to load and save data
  • builtInComponents, add all custom components such as fieldFor, listFor, ...
  • formMixin which is the problematic part. It deals with the edit mode, it has custom methods to render the buttons. It handles the submit of the form, it renders the form and exposes renderContent.

Example

const FormExample = React.createClass({
    displayName: 'FormExample',
    mixins: [formMixin],
    stores: [{  // store behaviour + storeChangeBehaviour
        store: contactStore,
        properties: ['contact', 'commandes']
    }],
    definitionPath: 'contact', // definitionBehaviour
    action: action, // actionBehaviour
    referenceNames: ['papas', 'monkeys'], // referenceBehaviour
    renderContent() { // formMixin
        return (
            <Panel actions={this._renderActions} title="Fiche de l'utilisateur">
                {this.fieldFor('firstName')}
                {this.fieldFor('papaCode', {listName: 'papas'})}
                {this.fieldFor('monkeyCode', {listName: 'monkeys', valueKey: 'myCustomCode', labelKey: 'myCustomLabel' })}
                {this.fieldFor('lopezCode', {values: [{code: 'JOE', label: 'Joe Lopez'}, {code: 'DAVE', label: 'David Lopez'}]})}
                {this.fieldFor('bio')}
                {this.fieldFor('isNice')}
                {this.textFor('birthDate', {formatter: date => 'formatted date' + date})}
                {this.fieldFor('birthDate')}
            </Panel>
        );
    }
});

The problem

  • The formMixin should only be a composition of mixins and it shouldn't add specific code.
  • When you have an entity which is splitted in two Blocks, even if a block can be connected to multiple store, it is hard to build: the webservices are asymetric between load and save. Its unclear wwhich block load the data.
  • The form blocks has all the actions and they are too corelated to it. Actions should no be a part of the form.
  • The formMixin has been used for almost every page on each projects. It shouldn't be the case. We thought it will be used as a preset and projects could have customize which part of the formMixin they want in their own presets.
  • The formComponent has the state from the store and its sometimes problematic
  • The form shouldn't call loading actions

Proposed evolution

  • All the mixins composing the store will be pure, there will be no specific code in the formMixin. The formMixin is composed of the mixins described in the beginning of this document.

The main goal is to be able to build components without the formMixin. A form-presets will be published in order to have no regression.

  • Actions are decorelated from the components

Solves the problem of an entity

  • Fields are stateless and get read it from the parent. The state is located in the parent and only in the parent.

Solves the problem of corelated fields and imporve the testabiliy of the components.

  • The connection to the stores will be a wrapper around the component which contains the data.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment