foxhound87 / mobx-react-form Goto Github PK
View Code? Open in Web Editor NEWReactive MobX Form State Management
Home Page: https://foxhound87.github.io/mobx-react-form
License: MIT License
Reactive MobX Form State Management
Home Page: https://foxhound87.github.io/mobx-react-form
License: MIT License
Hello,
Thanks for this package!
Anyways, for me it seems like the live demo is broken.
Chrome 53, on Ubuntu
Avoid using .constructor.name
to check the name of the Field
Class, which is mangled by uglify.
Ref: foxhound87/rfx-stack#31
ADD THIS TO YOUR WEBPACK CONFIG
In the meantime, in order to keep the package working in a minified production environment
use
webpack -p --keep-fnames
or
new webpack.optimize.UglifyJsPlugin({
mangle: {
keep_fnames: true,
},
}),
If a form is created by separated fields
and values
objects and a value is 0
then a corresponding field will be initialized with ""
:
const MobxReactForm = require("mobx-react-form");
const form = new MobxReactForm({
fields: ["qwerty"],
values: { qwerty: 0 },
});
console.log(form.fields.qwerty.value); // ""
The cause of the bug is incorrect calculating of an initial value here: https://github.com/foxhound87/mobx-react-form/blob/master/src/Field.js#L60
While $value = 0
and $field = ""
the result will be ""
despite the logical priority of $value
's value.
const plugins = { dvr: validatorjs };
const fields = {
email: {
labal: 'Email',
rules: 'required|email|string|between:5,25',
},
password: {
label: 'Password',
rules: 'required|string|between:5,25',
},
};
class LoginForm extends MobxReactForm {
onSuccess(form) {
console.log('Form Values!', form.value());
}
onError(form) {
console.log('All form errors', form.errors());
form.invalidate('This is a generic error message!');
}
}
export default new LoginForm({ fields, plugins });
that 's all the code and it can't work even though I just refer without passing the instance to my component .
and logs :
Uncaught Error: [mobx] Invariant failed: It is not allowed to create or change state outside an "action" when MobX is in strict mode. Wrap the current method in
actionif this state change is intended
Hi, I tried adding an 'Add Members' button on your demo form.
<button type="button" onClick={e => form.$('members').onAdd(e)}>
<i className="fa fa-plus-circle" data-tip="Add Members" />
</button>
I get the following error:
Uncaught Error: The selected field is not defined (firstname)
form.update({ address: { city: null } });
Error trace:
if ((0, _isUndefined3.default)(val.fields)) {
Hello,
I'm trying to run MobX AJV Form, but get these errors:
ERROR in ./~/ajv/lib/refs/json-schema-draft-04.json
Module parse failed: C:\proj\node_modules\ajv\lib\refs\json-schema-draft-04.json Line 2: Unexpected token :
You may need an appropriate loader to handle this file type.
| {
| "id": "http://json-schema.org/draft-04/schema#",
| "$schema": "http://json-schema.org/draft-04/schema#",
| "description": "Core schema meta-schema",
@ ./~/ajv/lib/ajv.js 352:23-66
ERROR in ./~/ajv/lib/refs/json-schema-v5.json
Module parse failed: C:\proj\node_modules\ajv\lib\refs\json-schema-v5.json Line 2: Unexpected token :
You may need an appropriate loader to handle this file type.
| {
| "id": "https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/json-schema-v5.json#",
| "$schema": "http://json-schema.org/draft-04/schema#",
| "description": "Core schema meta-schema (v5 proposals)",
@ ./~/ajv/lib/v5.js 20:21-58
And also warnings Cannot resolve module
:
form.isValid is true when a async validation is executed for a field. The value of field.asyncErrorMessage is "validating..". so the form is still not valid state and i guess form.isValid should be false.
use case:
form.isValid is used to disable the submit button. if there is on going validation (async), want the form submit to be disabled.
currently using the below custom property to workaround the issue.
Form.ts
import { computed } from 'mobx';
import MobxReactForm from 'mobx-react-form';
export default class Form extends MobxReactForm {
@computed
get isValidating(): boolean {
const fields = (this as any).fields;
return Object.keys(fields).some(key => !!(fields[key].asyncErrorMessage));
}
}
Form.tsx
<RaisedButton
type="submit"
onClick={form.handleOnSubmit}
disabled={!form.isValid || form.isValidating}
>Submit</RaisedButton>
Hi. I have the following issue:
Changing validateOnChange option isn't change form validation behavior, if we change it after first form initialization, because this method:
observeFields() {
if (this.$options.validateOnChange === false) return;
// observe and validate each field
_.each(this.fields, (field, key) =>
observe(this.fields[key], '$value', () =>
this.validate({ key, showErrors: true, recursive: true })));
}
that responsible on onChange validation, is called only during form initialization processes.
If form was initialized with validateOnChange
set to false, later updates to true
- won't change field validation mechanism.
And i have two ideas to resolve this issue:
We can change observeFields
method to the following:
observeFields() {
// observe and validate each field
_.each(this.fields, (field, key) =>
observe(this.fields[key], '$value', () => {
if (this.$options.validateOnChange === false) return;
this.validate({ key, showErrors: true, recursive: true });
}));
}
And that will remove the issue. I can create pull request with this fix.
On the other hand, we can call observeFields
method each time when options
method is invoked. But in this case, we have to enable or disable this.fields
observing accordingly to this.$options.validateOnChange
.
To keep dependencies up to date, i suggest using https://greenkeeper.io/ it'll limit manual work :)
It seems .sync
is only setting the value right immediate of what passed into it;
While .update
seems to have much complete checking to the nested fields and update accordingly.
What is the use case for both .sync
and .update
?
I think that checking $value against originalValue is more intuitive.
the redux-form doing like this.
https://github.com/erikras/redux-form/blob/master/src/isPristine.js
I'm having a bit of an issue trying to set the values for an array (nested) field. I have a form that has a "files" field, which is an array. The user uploads a file and I want to append the file names returned in the response to the "files" field. I tried to use both update
and sync
, but with no success:
// Fields defined as separated properties
const fields = [
'files',
'files[]',
// ...
];
// `response` is an array of strings
_handleUploadSuccess = (response) => {
const files = this.props.form.$('files');
const values = files.value.concat(response);
files.update(values);
console.log(values); // ['file1', 'file2', ...]
console.log(files.value); // displays empty array
console.log(this.props.form.values()); // { files: [] ... }
}
Hi, I'm creating import component with table of records, like:
How can I initialize form validation for each row using the same fields? Tried creating array containing Form instances. But it doesn't work (rows values change in the same time).
@observable recordsValidation = [];
recordsValidation.push( new Form({ plugins, fields });
recordsValidation.push( new Form({ plugins, fields });
See HERE for an example.
Scroll to the bottom of the form and click the Green FAB button + to add more clients
click the 'SAVE' button to validate. The additional client fields are validated (after recent update to 1.13.20) but the validation messages don't clear when entering valid data into the additional fields. The validation messages clear as expected on the fields that the form was initialized with.
ValidatorJS allows DVR rules to be defined as an array and not just pipe delimited string.
When defining regex validation its recommend to define as an array such as:
['required', 'regex:/^(19|20)[\d]{2,2}$/']
as the pipe in the regex pattern would cause a problem when splitting if it was pipe delimited.
DVR.js
Change:
{
key: 'rules',
value: function rules(_rules, type) {
var diff = [];
var $rules = (0, _split3.default)(_rules, '|');
if (type === 'sync') diff = (0, _difference3.default)($rules, this.asyncRules);
if (type === 'async') diff = (0, _intersection3.default)($rules, this.asyncRules);
return diff;
}
}
To:
{
key: 'rules',
value: function rules(_rules, type) {
var diff = [];
var $rules = [];
if (typeof _rules === 'string') {
$rules = (0, _split3.default)(_rules, '|');
} else {
$rules = _rules;
}
// var $rules = (0, _split3.default)(_rules, '|');
if (type === 'sync') diff = (0, _difference3.default)($rules, this.asyncRules);
if (type === 'async') diff = (0, _intersection3.default)($rules, this.asyncRules);
return diff;
}
}
const fields = [
'club.name',
'club.city',
'members',
'members[].firstname',
'members[].lastname',
'members[].hobbies',
'members[].hobbies[]',
];
const values = {
club: {
name: 'HELLO',
city: 'NY',
},
members: [{
firstname: 'Clint',
lastname: 'Eastwood',
hobbies: ['Soccer', 'Baseball'],
}, {
firstname: 'Charlie',
lastname: 'Chaplin',
hobbies: ['Golf', 'Basket'],
}],
};
const form = new MobxReactForm({ fields, values });
console.log(form.values())
/* output
{
club: { name: 'HELLO', city: 'NY' },
members: [ { firstname: '', lastname: '', hobbies: '' }, { firstname: '', lastname: '', hobbies: ''],
}
*/
// Not working use .set
form.set(values);
console.log(form.values()) // Output same as above
// Either .init or .update the form
form.update(values); // Or form.init(values);
console.log(form.values()) // Output the exact values
when init a form like:
const fields = {...}
new Form({ options, fields, ... });
the field
parameter is mutated. Form should not mutate state outside the form class. This allow to reuse form definition in differents forms instances.
form.update({ places: ['NY', 'NJ', 'AR'] });
// console.log(form.values()); returns { places: [ 'NY', 'NJ', 'AR' ] }
form.update({ places: ['NY', 'NJ'] });
// console.log(form.values()); returns { places: [ 'NY', 'NJ', 'AR' ] }
this.validator.genericErrorMessage = null;
this line of cod will raise this error
Uncaught Error: [mobx] Invariant failed: It is not allowed to create or change state outside an
action
when MobX is in strict mode. Wrap the current method inaction
if this state change is intended
I work around for now by commenting this line.
const fields = [
'places[]',
];
const values = {
places: [
'NY',
'NJ',
],
};
form = new MobxForm({ fields, values });
// OR
form = new MobxForm({ fields });
form.update(values);
form.$('places').clear(); // no change, form.values() returns { places: [ 'NY', 'NJ' ] }
form.$('places').clear(true); // form.values() returns { places: [ '', '' ] }
Hello. I think that the ability to track the touched state of the field will be very useful.
On the demo branch, after following instructions, I get the error Uncaught TypeError: Cannot read property 'scheme' of null(…)
.
formObject.options({ validateOnChange: true, /*...other options */ });
isn't working.
The problem is in this string, that localted in Form.js:
if (!_.isObject(options)) this.$options.set(options);
- why we use 'not' statement?
I am applying this library to handle form authentication in my app.
On successful validation, I want to call an external library (auth0) to handle authentication and update state in some UI store which is part of my application.
What is the best way to handle this? I am thinking that I should be able to call the auth0 API and the store update function in the onSuccess event handler. In this case how do I pass the auth0 library and the UIStore into the form class? Or there better approach than what I am thinking?
Thanks.
If we init the Form using separated props:
new MobxReactForm({ plugins, values, defaults, rules })
Then using an Array as a value does not work.
However, if initialized with unified props Array as value works:
new MobxReactForm({ fields, plugins })
I was wondering what it would take to use this in my mobx-examples. Everything's straight up ES5. Is there a global hook in the umd files I can hit? Any other gotchas to watch out for?
Thanks!
Hey there, thanks for this great library! Everything worked perfectly so far, except now I have a very strange behavior for a text field that has errors (they are even shown in the form correctly) but still validates to true
and the onSuccess
handler is called on the form.
Here is a screenshot of the console.log output of the form.get
call for this field:
I guess this state (errors are set & displayed but field hasError
is false
) should not be possible?
It worked fine on a form where we used material-ui and now im trying it with react-toolbox although i don't think that is the problem?
I am a bit confused as to why onAdd
is not working. Tried to make sense of this closed issue but no luck: 109
So, how can onAdd
be used as of now?
Can you clarify this statement?
This method is not yet supported for the nested fields. You can use it only for flat arrays for now.
What is the recommended way to disable mobx's strict mode?
Seems like it is decided for us in src/index.js. Why not allow dev's to disable?
Not sure how these are supposed to work, but touched
and focus
are never true. What's the proper usage for these?
How can the disabled value of all fields be set after the form has been initialized?
const form = new MobxReactForm({ fields, plugins })
const setDisabled = (value) => {
// Do something with form and all its fields...
}
onSubmit Validation works fine in 1.13.10 on all fields but after updating to 1.13.17 it only validates top level fields.
I've read the tutorial and most of the documentation. I'm still having a little trouble understanding how mobx-react-form
integrates into an application.
I have an object model and store that I've built with mobx. I'd like to create a form for editing instances of the objects in the mobx store. My current understanding is that I would need to 1) create a form that has all of the fields of my model, 2) pass in a copy of the the object to initialize all of the form field values, and 3) on submit update all the fields in the original source instance.
Since mobx is in the name of this project, I figure I have this wrong and there is a smoother path towards integration. I also looked at the demo but it is a bit complicated. Is there any other simpler examples?
const values = null;
const fields = [
'hotel.name',
'hotel.starRating',
];
const form = new Form({ fields, values });
console.log(form.$('hotel.name').value); // Error
Hello!
We want to use mobx-react-form in our application, but we cannot because we use the old lodash version (3.x) globally on the whole site, so sooner or later we can clash with the some lodash breaking changes (3.x vs 4.x). I think that peer dependency on the lodash is very bad. Probably you need to drop the lodash dependency or include it in the library bundle (drop it from the webpack.config.babel.js/externals section).
Probably the best solution will be cherry picking individual lodash functions, for example:
import intersection from "lodash/intersection"
Also you can use this plugin https://github.com/lodash/babel-plugin-lodash.
I can help with the pull request if you approve.
I think that we need to make MobX the peer dependency. For example, https://github.com/mobxjs/mobx-react/blob/master/package.json#L24
What do you think about it?
Great library so far!
I'm getting a constant stream of resolve warnings clogging up my terminal each time I hot reload. I have to constantly scroll up to see if there are any actual errors.
WARNING in ./~/ajv/lib/compile/index.js
Module not found: Error: Can't resolve 'js-beautify' in '/src/node_modules/ajv/lib/compile'
@ ./~/ajv/lib/compile/index.js 8:42-69
@ ./~/ajv/lib/ajv.js
@ ./~/mobx-ajv-form/lib/form.js
@ ./~/mobx-ajv-form/lib/index.js
@ ./app/containers/LoginPage/index.js
@ ./app/routes.js
@ ./app/app.js
@ multi main
WARNING in ./~/ajv/lib/async.js
Module not found: Error: Can't resolve 'regenerator' in '/src/node_modules/ajv/lib'
@ ./~/ajv/lib/async.js 95:20-47
@ ./~/ajv/lib/ajv.js
@ ./~/mobx-ajv-form/lib/form.js
@ ./~/mobx-ajv-form/lib/index.js
@ ./app/containers/LoginPage/index.js
@ ./app/routes.js
@ ./app/app.js
@ multi main
WARNING in ./~/ajv/lib/async.js
Module not found: Error: Can't resolve 'nodent' in '/src/node_modules/ajv/lib'
@ ./~/ajv/lib/async.js 116:26-48
@ ./~/ajv/lib/ajv.js
@ ./~/mobx-ajv-form/lib/form.js
@ ./~/mobx-ajv-form/lib/index.js
@ ./app/containers/LoginPage/index.js
@ ./app/routes.js
@ ./app/app.js
@ multi main
Any chance of getting these cleared up?
const fields = {
club: 'HELLO',
members: [{
firstname: 'Clint',
lastname: 'Eastwood',
hobbies: ['Soccer', 'Baseball'],
}, {
firstname: 'Charlie',
lastname: 'Chaplin',
hobbies: ['Golf', 'Basket'],
}],
};
...
// Get Charlie's hobbies
console.log(form.$('members[1].hobbies').value) // output: ""
console.log(form.$('members[1].hobbies').values() // output: ["Golf", "Basket"]
I am trying to build mobx-react-form and I am getting this error:
ReferenceError: Unknown plugin "transform-decorators" specified in "C:\\Users\\Veniamin\\Desktop\\mobx-react-form\\.babelrc"
I think that this line is redundant https://github.com/foxhound87/mobx-react-form/blob/master/.babelrc#L5 This babel plugin is not exists.
What is the practice for dealing with complex/nested property if we have property like below:
const attraction = {
name: 'A',
address: {
country: 'B',
streetAddress: 'C',
},
alternateNames: ['D', 'E', 'F'],
geo: {
latitude: 12.3456,
longitude: 23.4567,
},
};
I am trying to define a fairly complex nested field set. Below is an example.
How do I define an array in the field definition?
const fields = [{
name: 'someField',
label: 'Some Field',
rules: 'required|string'
}, {
name: 'clients', // This need to be an array of clients.
label: 'Clients',
fields: [{
name: 'title',
label: 'Title',
rules: 'required|string'
}, {
name: 'firstname',
label: 'Firstname',
rules: 'required|string'
}, {
name: 'surname',
label: 'Surname',
rules: 'required|string'
}],
}];
example JSON:
{
someField: 'value',
clients: [{
title: 'Mr',
firstname: 'John',
surname: 'Smith',
}, {
title: 'Mrs',
firstname: 'Susan',
surname: 'Smith',
}],
}
Just wondering: Would it be possible to post the demo code? Having a bit of trouble following the tutorial. I'm confused about how to get from "Initialize the Form" to "Pass the form to a react component" as it seems as though you're implementing two different approaches. Anyway, thanks either way.
Hello. I think that the word "react" in the package name is misleading. In theory mobx-react-form can be used with any UI library/framework.
What do you think about it?
Hello,
It seems that current version is broken, I can't get fields initialisation to work
import MobxReactForm from 'mobx-react-form';
let fields = {
username: {name: 'username', label: 'Email'},
password: {name: 'password', label: 'Password'}
};
const loginForm = new MobxReactForm({fields});
console.log(loginForm.$('username').label);
it logs undefined
, even inspecting loginForm
in debugger shows that fields are empty.
Hello again ;)
When I try to run form.update() I get an Uncaught TypeError: Cannot read property 'update' of undefined
error... It seems like the package is simply missing the export for update?
Regards,
Lukas
edit: seems like i'm doing sth wrong here as it's even covered in your tests
... ah it actually was my fault. When providing a property inside update() which isn't set inside fields the library errors out. Would it be an option for you to extend https://github.com/foxhound87/mobx-react-form/blob/master/src/Form.js#L189 with a !== check if the field exists before updating it?
Hi,
The confirmed
rule from validatorjs cannot work currently as the validateFieldSync method only passes the field to validate instead of the fields array.
I'll try to submit a PR about this asap
const fields = [
'inventoryLevel.value',
];
const values = {
inventoryLevel: {
value: 2,
},
};
const form = new Form({ fields, values });
console.log(form.$('inventoryLevel')); // Output: 2
console.log(form.$('inventoryLevel.value')); // Error
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.