Extending¶
Creating a skin¶
The inputs and auxiliary elements are created using a set of components. The mapping can be set all together by overriding the skin.
You can take a look at skin.js and components/index.js from any skin to have a glimpse.
There’s an entry in the skin object for every field type. The value of the entry is an object with two attributes like in this example:
string: {
component: Input,
props: {
inputComponent: 'input'
}
},
component¶
The React component used to render the whole HTML for the input, including label and any other wrappers. For the Bootstrap skin the Input
component is used to do the common tasks:
string: {
component: Input
}
The component is also in charge of the field connection with redux form store (the Field
component).
Overriding¶
You can override (or add) specific types or the whole set.
-
setSkin
(skin)¶ Sets the whole skin at once.
Arguments: - skin (object) – Whole skin description
-
addSkinType
(typeName, rendering)¶ Sets the rendering for a specific schema type.
Arguments: - typeName (string) – Type name as it appears in the schema specification.
- rendering (skinTypeMap) – Object with the rendering specification.
Skin component¶
Every input component expects at least these props:
Prop | Type | Use |
---|---|---|
children |
element | Passed to inputComponent |
name |
string | ReduxForm field name |
fieldSchema |
object | Schema specification for the field |
schemaTypeName |
string (required) | Name of the schema that contains the field |
inputComponent |
element | Component used to render the input |
type |
string | Passed to inputComponent |
typeValidator |
function | Validator for the type. See “Override or add type validation” |
There are also other props passed depending on current implementation of renderInput
, the function in charge of choosing the component and render it.
typeValidator
is needed to avoid an error when validating field’s type. If unsure provide value => false
.
Form component¶
The form
component is different in the sense that it’s not rendered after a type. Instead, every form renders a form component in case the UI library requires special form wrapping.
InputWrap¶
It’s a common component used to create all the input structure, including wrappers. You can use it to avoid boilerplate. The final input component used (taken from inputComponent
prop) will be a decorated Field
.
Prop | Type | Use |
---|---|---|
children |
node | (optional) You can use InputWrap to… wrap. |
name |
string | Field name |
inputWrapper |
element | Wrapper for the input. See below for props. |
inputComponent |
element | Component receiving the input. See below for props. |
config |
object | Form configuration |
elementOnly |
boolean | (optional) Asks the wrapper to not decorate the input |
inline |
boolean | (optional) Passed to wrapper |
type |
string | (optional) Passed to input |
schemaTypeName |
string | Name of the schema as created |
onKeyDown |
function | (optional) Passed to input |
onKeyPress |
function | (optional) Passed to input |
labelOverride |
string | (optional) Passed as label to wrapper instead of |
meta |
object | ReduxForm’s meta |
The props passed to the wrapper component (inputWrapper
)
Prop | Type | Use |
---|---|---|
label |
string | Text use as label |
required |
boolean | Field is marked as required |
horizontal |
boolean | Taken from config |
inline |
boolean | Taken from InputWrap props |
errorMessage |
string | To print in red |
warningMessage |
string | To print in orange |
elementOnly |
boolean | Skip wrappings |
The props for the input component are different depending if the inputComponent
is a string, like 'input'
or a React component.
Common input props¶
Prop | Type | Use |
---|---|---|
type |
string | From InputWrap |
onKeyDown |
function | From InputWrap |
onKeyPress |
function | From InputWrap |
autoComplete |
string | Always 'off' |
placeholder |
string | From InputWrap |
Native component (ie. 'input'
)¶
For a component like that only ReduxForm input
object is passed.
Class component (ie. MySlider
)¶
Extra props are passed:
Prop # Type # Use
input
# object # From decorated Field
meta
# object # From decorated Field
config
# object # From InputWrap
from Autoform
autoFocus` # boolean # From ``InputWrap
schemaTypeName` # string # From ``Schema
Rendering¶
To feed InputWrap
with the needed props, two functions can be used:
-
renderInputs
(params)¶ Renders the inputs to make the schema work.
Arguments: - params (object) –
- params.schema (Schema) – Schema instance
- params.config (object) – Rendering configuration
- params.config.arrayMode (string) – ‘panels’ or ‘table’
- params.config.horizontal (boolean) – Labels above inputs
- params.rest (object) – Props passed to each input
Returns: array – React elements with the form and inputs.
-
renderInput
(params)¶ Renders a single field.
Arguments: - params (object) –
- params.field (string) – Name of the field
- params.fieldSchema (object) – Schema specification for the field
- params.parent (string) – Prefix of the field name
- params.schemaTypeName (string) – Name of the schema (first argument while instantiating a schema)
- params.config (object) – Form configuration
- params.rest (object) – props passed to the component
Write your own validators¶
Suppose you have a field schema and you want to add a custom validator:
const vehicles = new Schema('vehicles', {
numberOfWheels: {
type: 'number',
isEven: true
}
})
To add the validation, use
-
addValidator
(validationName, validation)¶ Adds a test creator to the testFactory table, that way you can use your own custom validations.
Arguments: - validationName (string) – The validation name for the test being created.
- validation (validatorConstructor) – Function that takes the entry and creates a validator to be used later.
That is, validation
is a function that returns a function. Outer one creates the validator and the inner one is the validator itself.
The validator returns true
when validation doesn’t pass. It can also return a translatable object or a direct message.
To implement the isEven
test using ES6 arrow functions:
import { addValidator } from 'redux-form-auto'
addValidator('isEven', entry =>
value => {
const expected = entry.isEven ? 0 : 1
return isNaN(value) || value % 2 != expected
}
)
Because the validator takes advantage of the closure from the constructor, it’s useful to write both in that cascade manner.
You can construct translatable objects using translatable()
. See Translatable objects
Override or add type validation¶
To avoid type errors as false positives you can change its behaviour in two ways:
- Adding
typeValidator
in the component definition when you create it. - Calling addSpecialTypeValidator specifying the field and the validation.
The validator has the same signature as others validators: Will receive the field’s value and returns false
for “valid”.
-
addSpecialTypeValidator
(type, validator)¶ Adds a special type validation
Arguments: - type (string) – Type validated
- validator (function) – value => true_to_fail validator