MobX Forms
  • Introduction
  • Overview
    • MobX Forms
  • FormStore
    • Overview
    • Constructor
    • Observables
    • Methods
      • save
    • Server errors
  • mobx-schema-form
    • Overview
    • MobxSchemaForm
    • Data Property Schema
    • Form Field Metadata
    • Widget Types
    • Styling
    • Custom Widgets
    • Validation
    • SaveButton
    • API
Powered by GitBook
On this page
  • Features
  • Breaking change in Version 2.0
  • Breaking changes in Version 3.0
  • Requirements
  • Installation
  • Minimal Usage Example
  • Example of using FormStore in a React form

Was this helpful?

  1. FormStore

Overview

PreviousMobX FormsNextConstructor

Last updated 3 years ago

Was this helpful?

Instances of FormStore (models) store the data entered by the user into form fields and provide observables for managing validation error messages. They also track changes and provide facilities for (auto-)saving the (changed) data.

Features

  • Tracks changes in each data property and by default saves only the changes.

  • Will not deem a property as changed for string/number, etc datatype changes or different Date objects with the same date or different Arrays (in v1.4.2+) or Objects (in v3.0+) with the same content.

  • Optionally auto-saves incremental changes (if there are any) every X milliseconds (see ).

  • By default, will not (auto-)save data properties that failed validation or that are still being edited by the user (note that FormStore only provides the facilities to track this - validation, etc is done in different components).

  • In a long-running app, can prevent unnecessary server requests to refresh data in the model by limiting them to not occur more often than Y milliseconds (see ).

  • Will auto-save any unsaved data when attempting to refresh to prevent loss of user-entered data.

  • Provides observable properties to drive things like loading indicators, enabling/disabling form or save button, error and confirmation messages, etc.

  • Server to save requests can drive error / validation messaging and discard invalid values.

  • Can differentiate between 'create' and 'update' save operations. A model that has not yet been created on the server will not try to refresh from server (this works right in v2.0+).

  • Saves are queued automatically, never concurrent.

  • (NEW in v1.3) Auto-save can be dynamically configured and enabled or disabled with method

Breaking change in Version 2.0

Previously, server.create() was called (instead of server.set()) only when the property defined as the idProperty in store.data was falsy. This worked well if the idProperty was only returned by the server and was not user-enterable. Now whether server.create() is called is driven by a new store.status.mustCreate property which is true only when the idProperty has not yet been returned by the server / saved even if it already has a value in store.data. Note that v.1.14+ supports a readOnlyCondition property that can be set to "!model.status.mustCreate" to allow an id property to be entered but not modified.

Breaking changes in Version 3.0

  • FormStore now deep-clones (and merges) objects and arrays (plain or observable) when storing data coming from server and in the updates object sent to server.

  • It's no longer published as a webpack-compiled and minified module.

Requirements

Installation

npm install --save mobx-form-store

Minimal Usage Example

myStore.js (a Singleton):

import FormStore from 'mobx-form-store';

const model = new FormStore({
  server: {
    // Example uses ES5 with https://github.com/github/fetch API and Promises
    get: function() {
      return fetch('myServerRefreshUrl').then(function(result) { return result.json() });
    },

    // Example uses ES6, fetch and async await
    set: async (info) => {
      const result = await fetch('myServerSaveUrl', {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(info),
      });
      return await result.json() || {}; // MUST return an object
    }
  },
});

export default model;

IMPORTANT: Your server.get method MUST return an object with ALL properties that need to be rendered in the form. If the model does not yet exist on the server, each property should have a null value but it must exist in the object or it cannot be observed with MobX.

Example of using FormStore in a React form

import React from 'react';
import { observer } from 'mobx-react';
import model from './myStore.js'

@observer class MyForm extends React.Component {
  componentDidMount() {
    model.refresh();
  }

  onChange = (e) => {
    model.data[e.target.name] = e.target.value;
    model.dataErrors[e.target.name] = myCustomValidationPassed ? null : "error message";
  }

  onSaveClick = () => {
    if (!model.status.canSave || !model.status.hasChanges) return;
    if (myCustomValidationPassed) model.save();
  }

  render() {
    return (
      {/* ... more fields / labels ... */}

      <label className={model.dataErrors.myProperty ? 'error' : ''}>My Property</label>
      <input
        type="text"
        name="myProperty"
        className={model.dataErrors.myProperty ? 'error' : ''}
        value={model.data.myProperty || ''}
        readonly={model.status.isReadOnly}
        onChange={this.onChange}
      />
      <p>{model.dataErrors.myProperty}</p>

      <button
        className={(!model.status.canSave || !model.status.hasChanges) ? 'gray' : ''}
        onClick={this.onSaveClick}
      >
        Save
      </button>
    );
  }
}

FormStore only requires 2.2+, 3.x, 4.x or 5.x. MobX strict mode is currently not supported. FormStore does not implement the actual server requests, it only calls methods that you provide with the data to be sent to the server.

myForm.jsx (this is without (with it there is even less code)).

MobX
MobxSchemaForm
autoSaveInterval
minRefreshInterval
responses
MobxSchemaForm
configAutoSave