Custom Widgets

In addition to the built-in React-Toolbox widget types, mobx-schema-form exposes a Higher Order Component (HOC) - asSchemaField which encapsulates all the necessary MobX observer, default value handling, data-type conversion and validation machinery. To create a custom component, simply wrap your React component/function in an asSchemaField() call. Your React component can either be a class or a function. Then add the wrapped component to the mapper object passed to MobxSchemaForm, i.e.:

import { MobxSchemaForm, FieldWrapper, asSchemaField } from 'mobx-schema-form';

// The fieldWrapper is optional - don't declare this inside the render method!
const mapper = { fieldWrapper: FieldWrapper, myComponent: asSchemaField(MyComponent) };

<MobxSchemaForm mapper={mapper} ...... />

asSchemaForm will pass the following props to your component. value and onChange are the minimum required props your component must use to have your field controlled by the model.

prop

Data type

Description

name

String

The schema.properties key. Place it into the form field's name property.

value

Any

The current value. May be null, so replace with an empty string for string types. Don't forget that 0 may be a legitimate value at some point in time, so don't replace all falsy values - look specifically for null. Value will never be undefined. asSchemaField already obtains the default value from schema or form metadata, so you don't need to do that.

error

String or null

The validation error message to display under/next to your widget. Make sure to not pass this prop to html elements like input or React will compain. If a React-Toolbox widget doesn't indicate that it accepts such a prop, don't pass it to it or it'll pass it straight to the html tag.

required

Boolean

True if this field is required.

disabled, readOnly

Boolean

True if the field should be disabled and readonly (these props are always the same - per W3C standards, some HTML form elements use one, some the other) - this is driven by the model.status.isReadOnly computed, which can be determined by a function you provide to FormStore constructor.

onChange

Function which accepts either a React Event object as sole argument or the new value in first argument and React Event object in second (React-Toolbox onChange call signature)

value and onChange are the minimum required props your component must use to have your field controlled by the model. In react-schema-form this is called onChangeValidate.

onFocus, onBlur

Function which accepts a React Event object

Optional, only useful for text/textarea fields. Enables intelligent validation and prevents FormStore auto-save from saving in-progress fields.

formField

Specially merged Form Field Metadata and Data Property Schema. In react-schema-form this is somewhat confusingly called just form though it's a completely different structure from the form prop of SchemaForm. Definitely do not pass this prop to form field tags as form as you'll then break many built-in browser behaviors that expect the form property of a field to refer to their parent form element.

Data-type conversion

All HTML attributes, including form field values are actually strings. Therefore, asSchemaField performs data-type conversion of user-entered/selected values from strings to numbers/integers (starting in version 1.1.2) and booleans (starting in version 1.2.1) based on the data property schema. For booleans, asSchemaField treats values of 0 (number or string), f, false, off, no, n as false; NaN, empty string, undefined as null; and everything else as true.

However, it is the responsibility of the custom widget to convert from these data types (and from null) to a string to be passed to the input component. asSchemaField will only convert an undefined value to null before passing it to the widget (the built-in widgets in mobx-schema-form convert nulls to an empty string).

The only exception is while a text input field is in focus, numeric data types are temporarily converted to a string before passing them to the widget to allow it to reflect user-entered characters that are valid in a numeric field but in that particular form will get stripped out on blur (for example. 1. and 1.0).

Currently, it's up to the widget to perform additional reformating (such as two-digit decimals for money) on values.

Compiling without React-Toolbox

If you want to use all-custom widgets without react-toolbox (and postcss and sass loaders) dependency with webpack 2+, it will be necessary to import each component directly from /lib (as opposed to root of mobx-schema-form) and you will also need to use the SchemaForminstead of MobxSchemaFormcomponent with your own widget mapper. MobxSchemaForm wraps SchemaForm with a pre-defined react-toolbox-based mapper, so you need to import at this lower level to bypass webpack pulling in react-toolbox.

Last updated