Skip to content

Commit

Permalink
REF: Simplify and improve mobx-form api
Browse files Browse the repository at this point in the history
  • Loading branch information
royriojas committed Aug 5, 2019
1 parent e9966c5 commit 8f48e28
Show file tree
Hide file tree
Showing 11 changed files with 1,704 additions and 818 deletions.
153 changes: 77 additions & 76 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,24 @@ npm i --save mobx mobx-form
```javascript
import { createModel } from 'mobx-form';

const model = createModel({
// the fields that will hold the initial data
fieldName: '',
}, {
// the validators by fieldName.
// when calling model.validate(); all the validators are executed sequentially
fieldName: {
// whether validation will happen after first update. Default true.
// sometimes is annoying
interactive: true,
const model = createModel( {
// the field descriptor
// when calling model.validate(); all the validators are executed in parallel
fieldName1: {
// whether validation will happen automatically after first update
autoValidate: true,
// whether validation should wait until the field is blurred at least once
// (meaning the blur event happened at least once in that field). The main
// limitation here is that `onBlur` of the field is required to call the method
// `markBlurredAndValidate();`
// (meaning the blur event happened at least once in that field).
//
// This requires that the component calls `markBlurredAndValidate()` after
// the blur even is raised on the field
waitForBlur: false,
// if this prop has no value validation will fail with an error message
// equal to the prop's value
// if `required` is set. `fn` is optional.
// Very useful flag to just make a field required or not without requiring a validator
// the `required` property can be:
// - a boolean, in which case the error message shown will be `Required`
// - a `string` in which case the string message will be used as the message to show when the field has no value
required: 'This field is required',
// optional, default error message is the function return just true/false
// optional, default error message is the validaor function return just true/false
errorMessage:
// optional, if `required` is defined. Required if not
// the validation function it receive the current field and allFields for
Expand All @@ -53,85 +51,88 @@ const model = createModel({
// return { error: 'some error' };
// return Promise.reject({ error: 'some error' }); // although this should be considered deprecated
// ```.
fn(field/*, allFields*/) {
validator = (field, allFields, model) => {
// do validation
// return true/false
// throw new Error('some error');
// return Promise.reject({ error: 'some error '}).
// return { error: 'some error '};
}
}
})

// To call all validations
await model.validate();

// To check if valid (after awaiting the validate call)
if (model.valid) {
// get the serialized data
// { fieldName: 'value set' }
const obj = model.serializedData;
};

// To reset the initial values
model.restoreInitialValues();
performValidation = async () => {
// To call all validators
await model.validate();

// To reset the validation
model.clearValidations();
// To check if valid (after awaiting the validate call)
if (model.valid) {
// get the serialized data
// { fieldName: 'value set' }
const obj = model.serializedData;

// To get the summary of all the errors
model.summary // Array or error messages

// To know if the model was interacted
model.interacted // true if at least one field has a value set

// To know if all required fields have values
model.requiredAreFilled // true if all fields marked as required are filled

// To know if the data is ready to serialize
model.dataIsReady // true if interacted, requiredAreFilled and valid are true.
// do something with the serializedData
await xhr('/some/endpoint', { method: 'post', payload: obj });
};
};

// to know which fields are required
model.requiredFields // an array with the required fieldNames

// to update values in the form
// by default setting values using this method will reset the interacted flag on the Field and reset the validation error
model.updateFrom({ fieldName: 'new value' }, /* reset = true */);
// to update values in the form.
model.updateFrom({ fieldName1: 'new value' }, /* reset = true */); // by default setting values using this method
// will reset the interacted flag on the Field
// and reset the validation error
```

## Example:

```js
import trim from 'jq-trim';
import { createModel } from 'mobx-form';

const model = this.model = createModel({
email: '', // initial value for email
password: '', // initial value for password
}, {
// validator for email
email: {
interactive: false,
// validator function
fn(field) {
const email = trim(field.value);
// super simple and naive email validation
if (!email || !(email.indexOf('@') > 0)) {
return Promise.reject({
error: 'Please provide an error message'
});
}
const model = createModel({
descriptors: {
name: {
required: 'Name is required',
},
},
// validator for password
password: {
interactive: false,
// validator function
fn(field) {
if (!trim(field.value)) {
return Promise.reject({
error: 'Please provide your password'
});
}
// validator for email
email: {
// validator function
async validator(field) {
const email = trim(field.value);
// super simple and naive email validation
if (!email || !(email.indexOf('@') > 0)) {
throw new Error('Please provide an error message');
}
},
},
// validator for password
password: {
// validator function
async validator(field) {
if (!trim(field.value)) {
throw new Error('Please provide your password');
}
},
},
},
initialState: {
email: '',
password: '',
},
});

const main = async () => {
await model.validate();

console.log('>>>> model.valid', model.valid);
console.log('>>>> model.summary', model.summary);
console.log('>>>> model.requiredFields', model.requiredFields);

// >>>> model.valid false
// >>>> model.summary [ 'Name is required',
// 'Please provide an error message',
// 'Please provide your password' ]
// >>>> model.requiredFields [ 'name' ]
};

main().catch(err => console.error('>>> error', err));
```
1 change: 1 addition & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ module.exports = {
},
],
'@babel/plugin-proposal-object-rest-spread',
'@babel/plugin-proposal-optional-chaining',
],
};
40 changes: 20 additions & 20 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,96 +2,96 @@
# mobx-form - Changelog
## v5.2.2
- **Refactoring**
- Upgrade node_modules and use latest babel - [b795e13]( https://github.com/royriojas/mobx-form/commit/b795e13 ), [Roy Riojas](https://github.com/Roy Riojas), 08/05/2019 00:11:58
- Upgrade node_modules and use latest babel - [b795e13]( https://github.com/royriojas/mobx-form/commit/b795e13 ), [Roy Riojas](https://github.com/Roy Riojas), 08/05/2019 01:11:58

Breaking change as now we transpile 2 versions of the module one for evergreen browsers and one for IE11

## v5.2.1
- **Refactoring**
- Add rest spread support - [48ae905]( https://github.com/royriojas/mobx-form/commit/48ae905 ), [Roy Riojas](https://github.com/Roy Riojas), 13/01/2019 21:58:53
- Add rest spread support - [48ae905]( https://github.com/royriojas/mobx-form/commit/48ae905 ), [Roy Riojas](https://github.com/Roy Riojas), 13/01/2019 23:58:53


## v5.2.0
- **Features**
- Add support to create a form from an array or an object descriptor - [19072dc]( https://github.com/royriojas/mobx-form/commit/19072dc ), [Roy Riojas](https://github.com/Roy Riojas), 13/01/2019 20:51:12
- Add support to create a form from an array or an object descriptor - [19072dc]( https://github.com/royriojas/mobx-form/commit/19072dc ), [Roy Riojas](https://github.com/Roy Riojas), 13/01/2019 22:51:12


## v5.0.3
- **Features**
- pass the model instance to the validators - [f4045c1]( https://github.com/royriojas/mobx-form/commit/f4045c1 ), [Roy Riojas](https://github.com/Roy Riojas), 20/12/2018 04:50:08
- pass the model instance to the validators - [f4045c1]( https://github.com/royriojas/mobx-form/commit/f4045c1 ), [Roy Riojas](https://github.com/Roy Riojas), 20/12/2018 06:50:08


## v5.0.2
- **Refactoring**
- Be compatible with enforceActions option of mobx - [d419fba]( https://github.com/royriojas/mobx-form/commit/d419fba ), [Roy Riojas](https://github.com/Roy Riojas), 17/08/2018 06:10:08
- Be compatible with enforceActions option of mobx - [d419fba]( https://github.com/royriojas/mobx-form/commit/d419fba ), [Roy Riojas](https://github.com/Roy Riojas), 17/08/2018 08:10:08


## v5.0.1
- **Bug Fixes**
- wrong entry point for UMD target - [de06c9d]( https://github.com/royriojas/mobx-form/commit/de06c9d ), [Roy Riojas](https://github.com/Roy Riojas), 09/08/2018 22:28:53
- wrong entry point for UMD target - [de06c9d]( https://github.com/royriojas/mobx-form/commit/de06c9d ), [Roy Riojas](https://github.com/Roy Riojas), 09/08/2018 23:28:53


## v5.0.0
- **Refactoring**
- remove dependency on regenerator - [e8bdbc9]( https://github.com/royriojas/mobx-form/commit/e8bdbc9 ), [Roy Riojas](https://github.com/Roy Riojas), 09/08/2018 22:27:41
- remove dependency on regenerator - [e8bdbc9]( https://github.com/royriojas/mobx-form/commit/e8bdbc9 ), [Roy Riojas](https://github.com/Roy Riojas), 09/08/2018 23:27:41


## v4.0.0
- **Refactoring**
- Create a smaller umd bundle - [81d81e3]( https://github.com/royriojas/mobx-form/commit/81d81e3 ), [Roy Riojas](https://github.com/Roy Riojas), 09/08/2018 22:07:12
- Create a smaller umd bundle - [81d81e3]( https://github.com/royriojas/mobx-form/commit/81d81e3 ), [Roy Riojas](https://github.com/Roy Riojas), 09/08/2018 23:07:12


- **Other changes**
- Update FormModel.test.js - [bff561e]( https://github.com/royriojas/mobx-form/commit/bff561e ), [Roy Riojas](https://github.com/Roy Riojas), 09/08/2018 21:24:08
- Update FormModel.test.js - [bff561e]( https://github.com/royriojas/mobx-form/commit/bff561e ), [Roy Riojas](https://github.com/Roy Riojas), 09/08/2018 22:24:08


## v3.0.2
- **Refactoring**
- Add prepublish script - [f0dde93]( https://github.com/royriojas/mobx-form/commit/f0dde93 ), [Roy Riojas](https://github.com/Roy Riojas), 08/08/2018 21:32:01
- Add prepublish script - [f0dde93]( https://github.com/royriojas/mobx-form/commit/f0dde93 ), [Roy Riojas](https://github.com/Roy Riojas), 08/08/2018 22:32:01


## v3.0.1
- **Refactoring**
- rename the bundle output - [49d010d]( https://github.com/royriojas/mobx-form/commit/49d010d ), [Roy Riojas](https://github.com/Roy Riojas), 08/08/2018 21:24:28
- rename the bundle output - [49d010d]( https://github.com/royriojas/mobx-form/commit/49d010d ), [Roy Riojas](https://github.com/Roy Riojas), 08/08/2018 22:24:28


## v3.0.0
- **Refactoring**
- Use rollup to create umd/esm/cjs bundles - [697d75c]( https://github.com/royriojas/mobx-form/commit/697d75c ), [Roy Riojas](https://github.com/Roy Riojas), 08/08/2018 14:38:47
- Use rollup to create umd/esm/cjs bundles - [697d75c]( https://github.com/royriojas/mobx-form/commit/697d75c ), [Roy Riojas](https://github.com/Roy Riojas), 08/08/2018 15:38:47


## v2.1.1
- **Documentation**
- Fix missing peer dependency - [9feae5e]( https://github.com/royriojas/mobx-form/commit/9feae5e ), [Roy Riojas](https://github.com/Roy Riojas), 08/08/2018 12:57:06
- Fix missing peer dependency - [9feae5e]( https://github.com/royriojas/mobx-form/commit/9feae5e ), [Roy Riojas](https://github.com/Roy Riojas), 08/08/2018 13:57:06


## v2.1.0
- **Documentation**
- update documenation - [7718d79]( https://github.com/royriojas/mobx-form/commit/7718d79 ), [Roy Riojas](https://github.com/Roy Riojas), 08/08/2018 12:16:28
- update documenation - [7718d79]( https://github.com/royriojas/mobx-form/commit/7718d79 ), [Roy Riojas](https://github.com/Roy Riojas), 08/08/2018 13:16:28


## v2.0.0
- **Refactoring**
- Update FormModel to add new features and tests - [4e449d9]( https://github.com/royriojas/mobx-form/commit/4e449d9 ), [Roy Riojas](https://github.com/Roy Riojas), 08/08/2018 10:28:41
- Update FormModel to add new features and tests - [4e449d9]( https://github.com/royriojas/mobx-form/commit/4e449d9 ), [Roy Riojas](https://github.com/Roy Riojas), 08/08/2018 11:28:41


## v1.0.1
- **Build Scripts Changes**
- Add build tasks - [2b36cf5]( https://github.com/royriojas/mobx-form/commit/2b36cf5 ), [Roy Riojas](https://github.com/Roy Riojas), 23/06/2016 20:26:51
- Add build tasks - [2b36cf5]( https://github.com/royriojas/mobx-form/commit/2b36cf5 ), [Roy Riojas](https://github.com/Roy Riojas), 23/06/2016 21:26:51


- **Refactoring**
- Add a helper to improve how fields are set - [c208bc7]( https://github.com/royriojas/mobx-form/commit/c208bc7 ), [Roy Riojas](https://github.com/Roy Riojas), 23/06/2016 20:22:35
- Add a helper to improve how fields are set - [c208bc7]( https://github.com/royriojas/mobx-form/commit/c208bc7 ), [Roy Riojas](https://github.com/Roy Riojas), 23/06/2016 21:22:35


- **Documentation**
- add more documentation - [443d90d]( https://github.com/royriojas/mobx-form/commit/443d90d ), [Roy Riojas](https://github.com/Roy Riojas), 15/06/2016 13:02:55
- add more documentation - [443d90d]( https://github.com/royriojas/mobx-form/commit/443d90d ), [Roy Riojas](https://github.com/Roy Riojas), 15/06/2016 14:02:55


- add missed import - [3da648e]( https://github.com/royriojas/mobx-form/commit/3da648e ), [Roy Riojas](https://github.com/Roy Riojas), 15/06/2016 12:53:32
- add missed import - [3da648e]( https://github.com/royriojas/mobx-form/commit/3da648e ), [Roy Riojas](https://github.com/Roy Riojas), 15/06/2016 13:53:32


- **Features**
- initial version - [02003a4]( https://github.com/royriojas/mobx-form/commit/02003a4 ), [Roy Riojas](https://github.com/Roy Riojas), 15/06/2016 12:49:00
- initial version - [02003a4]( https://github.com/royriojas/mobx-form/commit/02003a4 ), [Roy Riojas](https://github.com/Roy Riojas), 15/06/2016 13:49:00


2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ module.exports = {
verbose: true,
collectCoverage: true,
testEnvironment: 'node',
collectCoverageFrom: ['**/*.{js,jsx}', '!**/node_modules/**', '!**/vendor/**'],
collectCoverageFrom: ['src/**/*.{js,jsx}', '!**/node_modules/**', '!**/vendor/**'],
};
39 changes: 21 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"prepublishOnly": "npm run build",
"build": "rollup -c",
"dev": "rollup -c -w",
"test": "jest --config jest.config.js"
"test": "jest --config jest.config.js",
"smoke:test": "babel-node test.js"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -61,22 +62,24 @@
"mobx": "5.9.4"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-external-helpers": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-transform-runtime": "7.4.4",
"@babel/preset-env": "^7.0.0",
"@redisrupt/eslint-red": "4.0.0",
"changelogx": "2.0.1",
"jest": "24.8.0",
"mobx": "5.9.4",
"rollup": "1.11.3",
"rollup-plugin-babel": "4.3.2",
"rollup-plugin-commonjs": "9.3.4",
"rollup-plugin-node-resolve": "4.2.3",
"rollup-plugin-replace": "2.2.0",
"sleep.async": "1.0.4"
"@babel/core": "^7.5.5",
"@babel/node": "^7.5.5",
"@babel/plugin-external-helpers": "^7.2.0",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/plugin-proposal-decorators": "^7.4.4",
"@babel/plugin-proposal-object-rest-spread": "^7.5.5",
"@babel/plugin-proposal-optional-chaining": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@redisrupt/eslint-red": "^6.0.0",
"changelogx": "^5.0.4",
"jest": "^24.8.0",
"mobx": "^5.13.0",
"rollup": "^1.18.0",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-commonjs": "^10.0.1",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-replace": "^2.2.0",
"sleep.async": "^1.0.4"
}
}
Loading

0 comments on commit 8f48e28

Please sign in to comment.