Prepared new release
This commit is contained in:
parent
dbb0653a2b
commit
a1cf2236df
31
API.md
31
API.md
|
|
@ -12,6 +12,7 @@
|
|||
- [onInvalidSubmit()](#oninvalidsubmit)
|
||||
- [onChange()](#onchange)
|
||||
- [reset()](#resetform)
|
||||
- [preventExternalInvalidation](#preventexternalinvalidation)
|
||||
- [Formsy.Mixin](#formsymixin)
|
||||
- [name](#name)
|
||||
- [value](#value)
|
||||
|
|
@ -136,13 +137,13 @@ Triggers when form is submitted with a valid state. The arguments are the same a
|
|||
```
|
||||
Triggers when form is submitted with an invalid state. The arguments are the same as on `onSubmit`.
|
||||
|
||||
#### <a name="onchange">onChange(currentValues)</a>
|
||||
#### <a name="onchange">onChange(currentValues, isChanged)</a>
|
||||
```html
|
||||
<Formsy.Form onChange={this.saveCurrentValuesToLocalStorage}></Formsy.Form>
|
||||
```
|
||||
"onChange" triggers when setValue is called on your form elements. It is also triggered when dynamic form elements have been added to the form. The "currentValues" is an object where the key is the name of the input and the value is the current value.
|
||||
"onChange" triggers when setValue is called on your form elements. It is also triggered when dynamic form elements have been added to the form. The "currentValues" is an object where the key is the name of the input and the value is the current value. The second argument states if the forms initial values actually has changed.
|
||||
|
||||
#### <a name="resetform">reset()</a>
|
||||
#### <a name="resetform">reset(values)</a>
|
||||
```html
|
||||
var MyForm = React.createClass({
|
||||
resetForm: function () {
|
||||
|
|
@ -157,15 +158,35 @@ var MyForm = React.createClass({
|
|||
}
|
||||
});
|
||||
```
|
||||
Manually reset the form to its pristine state.
|
||||
Manually reset the form to its pristine state. You can also pass an object that inserts new values into the inputs. Keys are name of input and value is of course the value.
|
||||
|
||||
#### <a name="preventExternalInvalidation">preventExternalInvalidation</a>
|
||||
```html
|
||||
var MyForm = React.createClass({
|
||||
onSubmit: function (model, reset, invalidate) {
|
||||
invalidate({
|
||||
foo: 'Got some error'
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onSubmit={this.onSubmit} preventExternalInvalidation>
|
||||
...
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
```
|
||||
With the `preventExternalInvalidation` the input will not be invalidated though it has an error.
|
||||
|
||||
### <a name="formsymixin">Formsy.Mixin</a>
|
||||
|
||||
#### <a name="name">name</a>
|
||||
```html
|
||||
<MyInputComponent name="email"/>
|
||||
<MyInputComponent name="address.street"/>
|
||||
```
|
||||
The name is required to register the form input component in the form.
|
||||
The name is required to register the form input component in the form. You can also use dot notation. This will result in the "form model" being a nested object. `{email: 'value', address: {street: 'value'}}`.
|
||||
|
||||
#### <a name="value">value</a>
|
||||
```html
|
||||
|
|
|
|||
|
|
@ -6,28 +6,29 @@ var Input = React.createClass({
|
|||
mixins: [Formsy.Mixin],
|
||||
|
||||
render: function () {
|
||||
return <input disabled={this.isFormDisabled()} />
|
||||
return (
|
||||
<div>
|
||||
{this.showError()}
|
||||
{this.getErrorMessage()}
|
||||
<input disabled={this.isFormDisabled()} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var FormApp = React.createClass({
|
||||
getInitialState: function () {
|
||||
return {
|
||||
bool: true
|
||||
};
|
||||
},
|
||||
flip: function () {
|
||||
this.setState({
|
||||
bool: !this.state.bool
|
||||
componentDidMount: function () {
|
||||
this.refs.form.updateInputsWithError({
|
||||
'foo.bar': 'hmmm'
|
||||
});
|
||||
},
|
||||
onSubmit: function (model) {
|
||||
console.log('model', model);
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form disabled={this.state.bool}>
|
||||
{this.state.bool ?
|
||||
<Input name="foo" /> :
|
||||
<Input name="bar" />
|
||||
}
|
||||
<Formsy.Form ref="form" onInvalid={this.onInvalid}>
|
||||
<Input name="foo.bar" />
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -558,4 +558,33 @@ it('should allow an undefined value to be updated to a value', function (done) {
|
|||
|
||||
});
|
||||
|
||||
it('should allow for dot notation in name which maps to a deep object', function () {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>
|
||||
}
|
||||
});
|
||||
|
||||
var TestForm = React.createClass({
|
||||
onSubmit: function (model) {
|
||||
expect(model).toEqual({foo: {bar: 'foo', test: 'test'}});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo.bar" value="foo"/>
|
||||
<TestInput name="foo.test" value="test"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
var formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form');
|
||||
TestUtils.Simulate.submit(formEl);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -612,6 +612,20 @@ describe('Formsy', function () {
|
|||
formsyForm.reset();
|
||||
expect(input.getValue()).toBe(true);
|
||||
});
|
||||
|
||||
it("should be able to reset the form using custom data", function() {
|
||||
var form = TestUtils.renderIntoDocument(<TestForm value={ true }/>);
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
var formsyForm = TestUtils.findRenderedComponentWithType(form, Formsy.Form);
|
||||
expect(input.getValue()).toBe(true);
|
||||
form.setProps({value: false});
|
||||
expect(input.getValue()).toBe(false);
|
||||
formsyForm.reset({
|
||||
foo: 'bar'
|
||||
});
|
||||
expect(input.getValue()).toBe('bar');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('.isChanged()', function() {
|
||||
|
|
|
|||
|
|
@ -217,4 +217,65 @@ describe('Validation', function() {
|
|||
|
||||
});
|
||||
|
||||
|
||||
it('should not invalidate inputs on external errors with preventExternalInvalidation prop', function () {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input value={this.getValue()}/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
invalidate: function (model, reset, invalidate) {
|
||||
invalidate({
|
||||
foo: 'bar'
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onSubmit={this.invalidate} preventExternalInvalidation>
|
||||
<TestInput name="foo" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
var formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form');
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
TestUtils.Simulate.submit(formEl);
|
||||
expect(input.isValid()).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
it('should invalidate inputs on external errors without preventExternalInvalidation prop', function () {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input value={this.getValue()}/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
invalidate: function (model, reset, invalidate) {
|
||||
invalidate({
|
||||
foo: 'bar'
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onSubmit={this.invalidate}>
|
||||
<TestInput name="foo" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
var formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form');
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
TestUtils.Simulate.submit(formEl);
|
||||
expect(input.isValid()).toBe(false);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
26
src/main.js
26
src/main.js
|
|
@ -34,7 +34,8 @@ Formsy.Form = React.createClass({
|
|||
onValid: function () {},
|
||||
onInvalid: function () {},
|
||||
onChange: function () {},
|
||||
validationErrors: null
|
||||
validationErrors: null,
|
||||
preventExternalInvalidation: false
|
||||
};
|
||||
},
|
||||
|
||||
|
|
@ -93,7 +94,21 @@ Formsy.Form = React.createClass({
|
|||
},
|
||||
|
||||
mapModel: function () {
|
||||
return this.props.mapping ? this.props.mapping(this.model) : this.model;
|
||||
if (this.props.mapping) {
|
||||
return this.props.mapping(this.model)
|
||||
} else {
|
||||
return Object.keys(this.model).reduce(function (mappedModel, key) {
|
||||
|
||||
var keyArray = key.split('.');
|
||||
while (keyArray.length) {
|
||||
var currentKey = keyArray.shift();
|
||||
mappedModel[currentKey] = keyArray.length ? mappedModel[currentKey] || {} : this.model[key];
|
||||
}
|
||||
|
||||
return mappedModel;
|
||||
|
||||
}.bind(this), {});
|
||||
}
|
||||
},
|
||||
|
||||
// Goes through all registered components and
|
||||
|
|
@ -152,9 +167,8 @@ Formsy.Form = React.createClass({
|
|||
if (!component) {
|
||||
throw new Error('You are trying to update an input that does not exist. Verify errors object with input names. ' + JSON.stringify(errors));
|
||||
}
|
||||
|
||||
var args = [{
|
||||
_isValid: false,
|
||||
_isValid: this.props.preventExternalInvalidation || false,
|
||||
_externalError: errors[name]
|
||||
}];
|
||||
component.setState.apply(component, args);
|
||||
|
|
@ -421,10 +435,10 @@ Formsy.Form = React.createClass({
|
|||
},
|
||||
render: function () {
|
||||
|
||||
return React.DOM.form({
|
||||
return React.DOM.form(utils.extend({}, this.props, {
|
||||
onSubmit: this.submit,
|
||||
className: this.props.className
|
||||
},
|
||||
}),
|
||||
this.traverseChildrenAndRegisterInputs(this.props.children)
|
||||
);
|
||||
|
||||
|
|
|
|||
10
src/utils.js
10
src/utils.js
|
|
@ -37,5 +37,15 @@ module.exports = {
|
|||
}
|
||||
|
||||
return a === b;
|
||||
},
|
||||
extend: function () {
|
||||
var objects = [].slice.call(arguments);
|
||||
var initialObject = objects.shift();
|
||||
return objects.reduce(function (returnedObject, object) {
|
||||
return Object.keys(object).reduce(function (returnedObject, key) {
|
||||
returnedObject[key] = object[key];
|
||||
return returnedObject;
|
||||
}, returnedObject);
|
||||
}, initialObject);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue