From 818b1defbfaf1cced5d0e602b1d1361e8a785f7e Mon Sep 17 00:00:00 2001 From: christianalfoni Date: Tue, 7 Jul 2015 19:31:14 +0200 Subject: [PATCH 01/24] Initial commit for new version --- README.md | 17 ++++---- build/test.js | 40 +++++++++++++----- package.json | 6 +-- specs/Element-spec.jsx | 39 +++++++++++++++--- specs/Formsy-spec.jsx | 93 +++++++++++++++++++++--------------------- src/Mixin.js | 37 +++++++++++++---- src/main.js | 39 +++++++++++++----- 7 files changed, 181 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index cfb203b..7571ecf 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ A form input builder and validator for React JS ### From version 0.12.0 Formsy only supports React 0.13.1 and up ## Background -I wrote an article on forms and validation with React JS, [Nailing that validation with React JS](http://christianalfoni.github.io/javascript/2014/10/22/nailing-that-validation-with-reactjs.html), the result of that was this extension. +I wrote an article on forms and validation with React JS, [Nailing that validation with React JS](http://christianalfoni.github.io/javascript/2014/10/22/nailing-that-validation-with-reactjs.html), the result of that was this extension. The main concept is that forms, inputs and validation is done very differently across developers and projects. This extension to React JS aims to be that "sweet spot" between flexibility and reusability. @@ -19,12 +19,15 @@ The main concept is that forms, inputs and validation is done very differently a 2. Add validation rules and use them with simple syntax - 3. Use handlers for different states of your form. Ex. "onSubmit", "onError", "onValid" etc. + 3. Use handlers for different states of your form. Ex. "onSubmit", "onError", "onValid" etc. - 4. Server validation errors automatically binds to the correct form input component + 4. Pass external errors to the form to invalidate elements 5. You can dynamically add form elements to your form and they will register/unregister to the form +## Default elements +You can look at examples in this repo or use the [formsy-react-components](https://github.com/twisty/formsy-react-components) project to use bootstrap with formsy-react. + ## Install 1. Download from this REPO and use globally (Formsy) or with requirejs @@ -84,7 +87,7 @@ This code results in a form with a submit button that will run the `submit` meth // Add the Formsy Mixin mixins: [Formsy.Mixin], - // setValue() will set the value of the component, which in + // setValue() will set the value of the component, which in // turn will validate it and the rest of the form changeValue: function (event) { this.setValue(event.currentTarget.value); @@ -92,9 +95,9 @@ This code results in a form with a submit button that will run the `submit` meth render: function () { // Set a specific className based on the validation - // state of this component. showRequired() is true - // when the value is empty and the required prop is - // passed to the input. showError() is true when the + // state of this component. showRequired() is true + // when the value is empty and the required prop is + // passed to the input. showError() is true when the // value typed is invalid var className = this.showRequired() ? 'required' : this.showError() ? 'error' : null; diff --git a/build/test.js b/build/test.js index e8908b0..d39fe80 100644 --- a/build/test.js +++ b/build/test.js @@ -1,37 +1,55 @@ var React = require('react'); +var ReactDOM = require('react-dom'); var Formsy = require('./../src/main.js'); var Input = React.createClass({ mixins: [Formsy.Mixin], - + onChange: function (event) { + this.setValue(event.currentTarget.value); + }, render: function () { return (
- {this.showError()} - {this.getErrorMessage()} - + {this.showRequired() ? 'required' : ''} +
); } }); -var FormApp = React.createClass({ - componentDidMount: function () { - this.refs.form.updateInputsWithError({ - 'foo.bar': 'hmmm' +var SomeComp = React.createClass({ + getInitialState: function () { + return { + isRequired: false + }; + }, + toggleRequired: function () { + this.setState({ + isRequired: !this.state.isRequired }); }, + render: function () { + return ( +
+ + +
+ ) + } +}); + +var FormApp = React.createClass({ onSubmit: function (model) { console.log('model', model); }, render: function () { return ( - - + + ); } }); -React.render(, document.getElementById('app')); \ No newline at end of file +ReactDOM.render(, document.getElementById('app')); diff --git a/package.json b/package.json index ecf2a93..ccd92a3 100644 --- a/package.json +++ b/package.json @@ -28,11 +28,9 @@ "babel-loader": "^5.0.0", "jasmine-node": "^1.14.5", "jsdom": "^3.1.2", - "react": "^0.13.1", + "react": "^0.14.0-beta1", + "react-dom": "^0.14.0-beta1", "webpack": "^1.7.3", "webpack-dev-server": "^1.7.0" - }, - "peerDependencies": { - "react": "^0.13.1" } } diff --git a/specs/Element-spec.jsx b/specs/Element-spec.jsx index d517f37..ec2d3f2 100644 --- a/specs/Element-spec.jsx +++ b/specs/Element-spec.jsx @@ -22,9 +22,9 @@ describe('Element', function() { ); var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - expect(input.getDOMNode().value).toBe('foo'); + expect(input.value).toBe('foo'); TestUtils.Simulate.change(input, {target: {value: 'foobar'}}); - expect(input.getDOMNode().value).toBe('foobar'); + expect(input.value).toBe('foobar'); }); @@ -52,7 +52,7 @@ describe('Element', function() { var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); TestUtils.Simulate.change(input, {target: {value: 'foobar'}}); reset(); - expect(input.getDOMNode().value).toBe('foo'); + expect(input.value).toBe('foo'); }); @@ -226,7 +226,7 @@ it('should allow an undefined value to be updated to a value', function (done) { form.changeValue(); var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); setTimeout(function () { - expect(input.getDOMNode().value).toBe('foo'); + expect(input.value).toBe('foo'); done(); }, 0); }); @@ -573,7 +573,7 @@ it('should allow an undefined value to be updated to a value', function (done) { }, render: function () { return ( - + @@ -587,4 +587,33 @@ it('should allow an undefined value to be updated to a value', function (done) { }); + it('should allow for application/x-www-form-urlencoded syntax and convert to object', function () { + + var TestInput = React.createClass({ + mixins: [Formsy.Mixin], + render: function () { + return + } + }); + + var TestForm = React.createClass({ + onSubmit: function (model) { + expect(model).toEqual({foo: ['foo', 'bar']}); + }, + render: function () { + return ( + + + + + ); + } + }); + + var form = TestUtils.renderIntoDocument(); + var formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); + TestUtils.Simulate.submit(formEl); + + }); + }); diff --git a/specs/Formsy-spec.jsx b/specs/Formsy-spec.jsx index 5f74041..5d51f43 100755 --- a/specs/Formsy-spec.jsx +++ b/specs/Formsy-spec.jsx @@ -8,12 +8,12 @@ describe('Formsy', function () { it('should render a form into the document', function () { var form = TestUtils.renderIntoDocument( ); - expect(form.getDOMNode().tagName).toEqual('FORM'); + expect(React.findDOMNode(form).tagName).toEqual('FORM'); }); it('should set a class name if passed', function () { var form = TestUtils.renderIntoDocument( ); - expect(form.getDOMNode().className).toEqual('foo'); + expect(React.findDOMNode(form).className).toEqual('foo'); }); it('should allow for null/undefined children', function (done) { @@ -46,7 +46,7 @@ describe('Formsy', function () { var form = TestUtils.renderIntoDocument(); setTimeout(function () { - TestUtils.Simulate.submit(form.getDOMNode()); + TestUtils.Simulate.submit(React.findDOMNode(form)); expect(model).toEqual({name: 'foo'}); done(); }, 10); @@ -71,14 +71,14 @@ describe('Formsy', function () { model = formModel; }, render: function () { - return ( - + return ( + {inputs} ); } }); - var form = TestUtils.renderIntoDocument( - + var form = TestUtils.renderIntoDocument( + ); // Wait before adding the input @@ -89,7 +89,7 @@ describe('Formsy', function () { forceUpdate(function () { // Wait for next event loop, as that does the form setTimeout(function () { - TestUtils.Simulate.submit(form.getDOMNode()); + TestUtils.Simulate.submit(React.findDOMNode(form)); expect(model.test).toBeDefined(); done(); }, 0); @@ -122,14 +122,14 @@ describe('Formsy', function () { model = formModel; }, render: function () { - return ( - + return ( + {inputs} ); } }); - var form = TestUtils.renderIntoDocument( - + var form = TestUtils.renderIntoDocument( + ); // Wait before adding the input @@ -142,7 +142,7 @@ describe('Formsy', function () { // Wait for next event loop, as that does the form setTimeout(function () { TestUtils.Simulate.change(TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'), {target: {value: 'foo'}}); - TestUtils.Simulate.submit(form.getDOMNode()); + TestUtils.Simulate.submit(React.findDOMNode(form)); expect(model.test).toBe('foo'); done(); }, 0); @@ -188,12 +188,13 @@ describe('Formsy', function () { // Wait before changing the input setTimeout(function () { - form.setProps({value: 'bar'}); + + form = TestUtils.renderIntoDocument(); forceUpdate(function () { // Wait for next event loop, as that does the form setTimeout(function () { - TestUtils.Simulate.submit(form.getDOMNode()); + TestUtils.Simulate.submit(React.findDOMNode(form)); expect(model.test).toBe('bar'); done(); }, 0); @@ -253,7 +254,7 @@ describe('Formsy', function () { it('should run when the input changes', function() { var form = TestUtils.renderIntoDocument(); var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(input.getDOMNode(), {target: {value: 'bar'}}); + TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); expect(CheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true); expect(OtherCheckValid).not.toHaveBeenCalled(); }); @@ -262,7 +263,7 @@ describe('Formsy', function () { var form = TestUtils.renderIntoDocument(); form.setProps({inputs: [{name: 'one', validations: 'OtherCheckValid', value: 'foo'}] }); var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(input.getDOMNode(), {target: {value: 'bar'}}); + TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); expect(OtherCheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true); }); @@ -297,7 +298,7 @@ describe('Formsy', function () { it('runs multiple validations', function() { var form = TestUtils.renderIntoDocument(); var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(input.getDOMNode(), {target: {value: 'bar'}}); + TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); expect(CheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true); expect(OtherCheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true); }); @@ -366,14 +367,14 @@ describe('Formsy', function () { hasChanged(); }, render: function () { - return ( - + return ( + {inputs} ); } }); - var form = TestUtils.renderIntoDocument( - + var form = TestUtils.renderIntoDocument( + ); // Wait before adding the input @@ -413,14 +414,14 @@ describe('Formsy', function () { }); }, render: function () { - return ( - + return ( + ); } }); - var form = TestUtils.renderIntoDocument( - + var form = TestUtils.renderIntoDocument( + ); var input = TestUtils.findRenderedComponentWithType(form, TestInput); @@ -461,14 +462,14 @@ describe('Formsy', function () { } }, render: function () { - return ( - + return ( + ); } }); - var form = TestUtils.renderIntoDocument( - + var form = TestUtils.renderIntoDocument( + ); // Wait for update @@ -501,18 +502,18 @@ describe('Formsy', function () { isCalled = true; }, render: function () { - return ( - + return ( + ); } }); - var form = TestUtils.renderIntoDocument( - + var form = TestUtils.renderIntoDocument( + ); var TestForm = TestUtils.findRenderedComponentWithType(form, TestForm); - TestUtils.Simulate.submit(TestForm.getDOMNode()); + TestUtils.Simulate.submit(React.findDOMNode(TestForm)); expect(isCalled).toBe(true); }); @@ -531,18 +532,18 @@ describe('Formsy', function () { isCalled = true; }, render: function () { - return ( - + return ( + ); } }); - var form = TestUtils.renderIntoDocument( - + var form = TestUtils.renderIntoDocument( + ); var TestForm = TestUtils.findRenderedComponentWithType(form, TestForm); - TestUtils.Simulate.submit(TestForm.getDOMNode()); + TestUtils.Simulate.submit(React.findDOMNode(TestForm)); expect(isCalled).toBe(true); }); @@ -583,14 +584,14 @@ describe('Formsy', function () { it("should call onSubmit correctly", function() { var form = TestUtils.renderIntoDocument(); - TestUtils.Simulate.submit(form.getDOMNode()); + TestUtils.Simulate.submit(React.findDOMNode(form)); expect(onSubmit).toHaveBeenCalledWith({foo: false}); }); it("should allow dynamic changes to false", function() { var form = TestUtils.renderIntoDocument(); form.setProps({value: false}); - TestUtils.Simulate.submit(form.getDOMNode()); + TestUtils.Simulate.submit(React.findDOMNode(form)); expect(onSubmit).toHaveBeenCalledWith({foo: false}); }); @@ -598,7 +599,7 @@ describe('Formsy', function () { var form = TestUtils.renderIntoDocument(); var input = TestUtils.findRenderedComponentWithType(form, TestInput); expect(input.isFormSubmitted()).toBe(false); - TestUtils.Simulate.submit(form.getDOMNode()); + TestUtils.Simulate.submit(React.findDOMNode(form)); expect(input.isFormSubmitted()).toBe(true); }); @@ -673,7 +674,7 @@ describe('Formsy', function () { it('returns true when changed', function() { var form = TestUtils.renderIntoDocument(); var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(input.getDOMNode(), {target: {value: 'bar'}}); + TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); expect(form.refs.formsy.isChanged()).toEqual(true); expect(onChange).toHaveBeenCalledWith({one: 'bar'}, true); }); @@ -681,9 +682,9 @@ describe('Formsy', function () { it('returns false if changes are undone', function() { var form = TestUtils.renderIntoDocument(); var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(input.getDOMNode(), {target: {value: 'bar'}}); + TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); expect(onChange).toHaveBeenCalledWith({one: 'bar'}, true); - TestUtils.Simulate.change(input.getDOMNode(), {target: {value: 'foo'}}); + TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'foo'}}); expect(form.refs.formsy.isChanged()).toEqual(false); expect(onChange).toHaveBeenCalledWith({one: 'foo'}, false); }); diff --git a/src/Mixin.js b/src/Mixin.js index a6ae2ee..df655d7 100644 --- a/src/Mixin.js +++ b/src/Mixin.js @@ -1,4 +1,5 @@ var utils = require('./utils.js'); +var React = global.React || require('react'); var convertValidationsToObject = function (validations) { @@ -37,11 +38,14 @@ module.exports = { _isValid: true, _isPristine: true, _pristineValue: this.props.value, - _validationError: '', + _validationError: [], _externalError: null, _formSubmitted: false }; }, + contextTypes: { + formsy: React.PropTypes.object // What about required? + }, getDefaultProps: function () { return { validationError: '', @@ -52,13 +56,17 @@ module.exports = { componentWillMount: function () { var configure = function () { this.setValidations(this.props.validations, this.props.required); - this.props._attachToForm(this); + + // Pass a function instead? + this.context.formsy.attachToForm(this); + //this.props._attachToForm(this); }.bind(this); if (!this.props.name) { throw new Error('Form Input requires a name property when used'); } + /* if (!this.props._attachToForm) { return setTimeout(function () { if (!this.isMounted()) return; @@ -68,12 +76,14 @@ module.exports = { configure(); }.bind(this), 0); } + */ configure(); }, // We have to make the validate method is kept when new props are added componentWillReceiveProps: function (nextProps) { this.setValidations(nextProps.validations, nextProps.required); + }, componentDidUpdate: function (prevProps) { @@ -83,11 +93,17 @@ module.exports = { if (!utils.isSame(this.props.value, prevProps.value)) { this.setValue(this.props.value); } + + // If validations or required is changed, run a new validation + if (!utils.isSame(this.props.validations, prevProps.validations) || !utils.isSame(this.props.required, prevProps.required)) { + this.context.formsy.validate(this); + } }, // Detach it when component unmounts componentWillUnmount: function () { - this.props._detachFromForm(this); + this.context.formsy.detachFromForm(this); + //this.props._detachFromForm(this); }, setValidations: function (validations, required) { @@ -104,7 +120,8 @@ module.exports = { _value: value, _isPristine: false }, function () { - this.props._validate(this); + this.context.formsy.validate(this); + //this.props._validate(this); }.bind(this)); }, resetValue: function () { @@ -112,7 +129,8 @@ module.exports = { _value: this.state._pristineValue, _isPristine: true }, function () { - this.props._validate(this); + this.context.formsy.validate(this); + //this.props._validate(this); }); }, getValue: function () { @@ -122,10 +140,14 @@ module.exports = { return this.state._value !== ''; }, getErrorMessage: function () { + return this.getErrorMessages() && this.getErrorMessages()[0]; + }, + getErrorMessages: function () { return !this.isValid() || this.showRequired() ? (this.state._externalError || this.state._validationError) : null; }, isFormDisabled: function () { - return this.props._isFormDisabled(); + return this.context.formsy.isFormDisabled(); + //return this.props._isFormDisabled(); }, isValid: function () { return this.state._isValid; @@ -146,6 +168,7 @@ module.exports = { return !this.showRequired() && !this.isValid(); }, isValidValue: function (value) { - return this.props._isValidValue.call(null, this, value); + return this.context.formsy.isValidValue.call(null, this, value); + //return this.props._isValidValue.call(null, this, value); } }; diff --git a/src/main.js b/src/main.js index 7689b99..b37165d 100644 --- a/src/main.js +++ b/src/main.js @@ -1,6 +1,7 @@ var React = global.React || require('react'); var Formsy = {}; var validationRules = require('./validationRules.js'); +var formDataToObject = require('form-data-to-object'); var utils = require('./utils.js'); var Mixin = require('./Mixin.js'); var options = {}; @@ -39,6 +40,23 @@ Formsy.Form = React.createClass({ }; }, + childContextTypes: { + formsy: React.PropTypes.object + }, + getChildContext: function () { + return { + formsy: { + attachToForm: this.attachToForm, + detachFromForm: this.detachFromForm, + validate: this.validate, + isFormDisabled: this.isFormDisabled, + isValidValue: function (component, value) { + return this.runValidation(component, value).isValid; + }.bind(this) + } + } + }, + // Add a map to store the inputs of the form, a model to store // the values of the form and register child inputs componentWillMount: function () { @@ -97,7 +115,7 @@ Formsy.Form = React.createClass({ if (this.props.mapping) { return this.props.mapping(this.model) } else { - return Object.keys(this.model).reduce(function (mappedModel, key) { + return formDataToObject(Object.keys(this.model).reduce(function (mappedModel, key) { var keyArray = key.split('.'); var base = mappedModel; @@ -108,7 +126,7 @@ Formsy.Form = React.createClass({ return mappedModel; - }.bind(this), {}); + }.bind(this), {})); } }, @@ -138,7 +156,7 @@ Formsy.Form = React.createClass({ var component = this.inputs[name]; var args = [{ _isValid: !(name in errors), - _validationError: errors[name] + _validationError: typeof errors[name] === 'string' ? [errors[name]] : errors[name] }]; component.setState.apply(component, args); }.bind(this)); @@ -170,7 +188,7 @@ Formsy.Form = React.createClass({ } var args = [{ _isValid: this.props.preventExternalInvalidation || false, - _externalError: errors[name] + _externalError: typeof errors[name] === 'string' ? [errors[name]] : errors[name] }]; component.setState.apply(component, args); }.bind(this)); @@ -287,23 +305,23 @@ Formsy.Form = React.createClass({ error: (function () { if (isValid && !isRequired) { - return ''; + return []; } if (validationResults.errors.length) { - return validationResults.errors[0]; + return validationResults.errors; } if (this.props.validationErrors && this.props.validationErrors[component.props.name]) { - return this.props.validationErrors[component.props.name]; + return typeof this.props.validationErrors[component.props.name] === 'string' ? [this.props.validationErrors[component.props.name]] : this.props.validationErrors[component.props.name]; } if (isRequired) { - return validationErrors[requiredResults.success[0]] || null; + return [validationErrors[requiredResults.success[0]]] || null; } if (!isValid) { - return validationErrors[validationResults.failed[0]] || validationError; + return [validationError]; } }.call(this)) @@ -438,7 +456,8 @@ Formsy.Form = React.createClass({ return (
- {this.traverseChildrenAndRegisterInputs(this.props.children)} + {this.props.children} + {/*this.traverseChildrenAndRegisterInputs(this.props.children)*/}
); From 9e5723c5545dfc8874ea25e1be63ca2606f25598 Mon Sep 17 00:00:00 2001 From: Dmitry Semigradsky Date: Tue, 7 Jul 2015 22:21:04 +0300 Subject: [PATCH 02/24] Update package.json Added missed dependencies --- package.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/package.json b/package.json index ccd92a3..d74bf42 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,12 @@ "validation", "react-component" ], + "dependencies": { + "form-data-to-object": "^0.1.0" + }, + "peerDependencies": { + "react": "^0.14.0-beta1" + }, "devDependencies": { "babel": "^5.6.4", "babel-core": "^5.1.11", From 89759fefdedcd013fca45b248f4d12232123f3bb Mon Sep 17 00:00:00 2001 From: Semigradsky Date: Thu, 9 Jul 2015 11:35:52 +0300 Subject: [PATCH 03/24] Fix showing multiple error messages --- src/main.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main.js b/src/main.js index b37165d..7cf016e 100644 --- a/src/main.js +++ b/src/main.js @@ -320,8 +320,13 @@ Formsy.Form = React.createClass({ return [validationErrors[requiredResults.success[0]]] || null; } - if (!isValid) { - return [validationError]; + if (validationResults.failed.length) { + return validationResults.failed.map(function(failed) { + return validationErrors[failed] ? validationErrors[failed] : validationError; + }).filter(function(x, pos, arr) { + // Remove duplicates + return arr.indexOf(x) === pos; + }); } }.call(this)) From 357f4adf715a58b17faa3b6094aef6b8f7de4391 Mon Sep 17 00:00:00 2001 From: Semigradsky Date: Thu, 9 Jul 2015 12:53:26 +0300 Subject: [PATCH 04/24] `getErrorMessages` should return empty array when there are no errors --- src/Mixin.js | 5 +++-- src/main.js | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Mixin.js b/src/Mixin.js index df655d7..d615fc7 100644 --- a/src/Mixin.js +++ b/src/Mixin.js @@ -140,10 +140,11 @@ module.exports = { return this.state._value !== ''; }, getErrorMessage: function () { - return this.getErrorMessages() && this.getErrorMessages()[0]; + var messages = this.getErrorMessages(); + return messages.length ? messages[0] : null; }, getErrorMessages: function () { - return !this.isValid() || this.showRequired() ? (this.state._externalError || this.state._validationError) : null; + return !this.isValid() || this.showRequired() ? (this.state._externalError || this.state._validationError || []) : []; }, isFormDisabled: function () { return this.context.formsy.isFormDisabled(); diff --git a/src/main.js b/src/main.js index 7cf016e..c0924a4 100644 --- a/src/main.js +++ b/src/main.js @@ -317,7 +317,8 @@ Formsy.Form = React.createClass({ } if (isRequired) { - return [validationErrors[requiredResults.success[0]]] || null; + var error = validationErrors[requiredResults.success[0]]; + return error ? [error] : null; } if (validationResults.failed.length) { From 82edabde1510131e8996d04b0092789f7a31541f Mon Sep 17 00:00:00 2001 From: christianalfoni Date: Sun, 26 Jul 2015 15:06:46 +0200 Subject: [PATCH 05/24] added HOC and decorators --- build/test.js | 10 +++++----- src/Decorator.js | 28 ++++++++++++++++++++++++++++ src/HOC.js | 26 ++++++++++++++++++++++++++ src/main.js | 4 ++++ 4 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 src/Decorator.js create mode 100644 src/HOC.js diff --git a/build/test.js b/build/test.js index d39fe80..39c8722 100644 --- a/build/test.js +++ b/build/test.js @@ -3,21 +3,21 @@ var ReactDOM = require('react-dom'); var Formsy = require('./../src/main.js'); var Input = React.createClass({ - - mixins: [Formsy.Mixin], onChange: function (event) { - this.setValue(event.currentTarget.value); + this.props.setValue(event.currentTarget.value); }, render: function () { return (
- {this.showRequired() ? 'required' : ''} - + {this.props.showRequired() ? 'required' : ''} +
); } }); +Input = Formsy.HOC(Input); + var SomeComp = React.createClass({ getInitialState: function () { return { diff --git a/src/Decorator.js b/src/Decorator.js new file mode 100644 index 0000000..e4c61cc --- /dev/null +++ b/src/Decorator.js @@ -0,0 +1,28 @@ +var React = global.React || require('react'); +var Mixin = require('./Mixin.js'); +module.exports = function () { + return function (Component) { + return React.createClass({ + mixins: [Mixin], + render: function () { + return React.createElement(Component, { + setValidations: this.setValidations, + setValue: this.setValue, + resetValue: this.resetValue, + getValue: this.getValue, + hasValue: this.hasValue, + getErrorMessage: this.getErrorMessage, + getErrorMessages: this.getErrorMessages, + isFormDisabled: this.isFormDisabled, + isValid: this.isValid, + isPristine: this.isPristine, + isFormSubmitted: this.isFormSubmitted, + isRequired: this.isRequired, + showRequired: this.showRequired, + showError: this.showError, + isValidValue: this.isValidValue + }); + } + }); + }; +}; diff --git a/src/HOC.js b/src/HOC.js new file mode 100644 index 0000000..acbffa9 --- /dev/null +++ b/src/HOC.js @@ -0,0 +1,26 @@ +var React = global.React || require('react'); +var Mixin = require('./Mixin.js'); +module.exports = function (Component) { + return React.createClass({ + mixins: [Mixin], + render: function () { + return React.createElement(Component, { + setValidations: this.setValidations, + setValue: this.setValue, + resetValue: this.resetValue, + getValue: this.getValue, + hasValue: this.hasValue, + getErrorMessage: this.getErrorMessage, + getErrorMessages: this.getErrorMessages, + isFormDisabled: this.isFormDisabled, + isValid: this.isValid, + isPristine: this.isPristine, + isFormSubmitted: this.isFormSubmitted, + isRequired: this.isRequired, + showRequired: this.showRequired, + showError: this.showError, + isValidValue: this.isValidValue + }); + } + }); +}; diff --git a/src/main.js b/src/main.js index b37165d..4218979 100644 --- a/src/main.js +++ b/src/main.js @@ -4,9 +4,13 @@ var validationRules = require('./validationRules.js'); var formDataToObject = require('form-data-to-object'); var utils = require('./utils.js'); var Mixin = require('./Mixin.js'); +var HOC = require('./HOC.js'); +var Decorator = require('./Decorator.js'); var options = {}; Formsy.Mixin = Mixin; +Formsy.HOC = HOC; +Formsy.Decorator = Decorator; Formsy.defaults = function (passedOptions) { options = passedOptions; From dda96c46f60863a56223eb39b834d5f06505a244 Mon Sep 17 00:00:00 2001 From: christianalfoni Date: Sun, 26 Jul 2015 15:09:23 +0200 Subject: [PATCH 06/24] updated docs --- API.md | 49 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/API.md b/API.md index c356e15..2bbb8f1 100644 --- a/API.md +++ b/API.md @@ -35,6 +35,8 @@ - [isFormSubmitted()](#isformsubmitted) - [validate](#validate) - [formNoValidate](#formnovalidate) +- [Formsy.HOC](#formsyhoc) +- [Formsy.Decorator](#formsydecorator) - [Formsy.addValidationRule](#formsyaddvalidationrule) - [Validators](#validators) @@ -109,7 +111,7 @@ var Form = React.createClass({ ```html ``` -Takes a function to run when the submit button has been clicked. +Takes a function to run when the submit button has been clicked. The first argument is the data of the form. The second argument will reset the form. The third argument will invalidate the form by taking an object that maps to inputs. E.g. `{email: "This email is taken"}`. Resetting or invalidating the form will cause **setState** to run on the form element component. @@ -226,12 +228,12 @@ The message that will show when the form input component is invalid. It will be #### validationErrors ```html -showRequired() ```javascript @@ -424,7 +426,7 @@ var MyInput = React.createClass({ } }); ``` -Lets you check if the form input component should indicate if it is a required field. This happens when the form input component value is empty and the required prop has been passed. +Lets you check if the form input component should indicate if it is a required field. This happens when the form input component value is empty and the required prop has been passed. #### showError() ```javascript @@ -539,6 +541,41 @@ var MyInput = React.createClass({ }); ``` +### Formsy.HOC +The same methods as the mixin are exposed to the HOC version of the element component, though through the `props`, not on the instance. +```js +import {HOC} from 'formsy-react'; + +class MyInput extends React.Component { + render() { + return ( +
+ this.props.setValue(e.target.value)}/> +
+ ); + } +}; +export default HOC(MyInput); +``` + +### Formsy.Decorator +The same methods as the mixin are exposed to the decorator version of the element component, though through the `props`, not on the instance. +```js +import {Decorator as FormsyElement} from 'formsy-react'; + +@FormsyElement() +class MyInput extends React.Component { + render() { + return ( +
+ this.props.setValue(e.target.value)}/> +
+ ); + } +}; +export default MyInput +``` + ### Formsy.addValidationRule(name, ruleFunc) An example: ```javascript From 338ceb853ae2753893337bb27f04a6b0169936b5 Mon Sep 17 00:00:00 2001 From: iwangu Date: Sun, 16 Aug 2015 21:48:13 +0200 Subject: [PATCH 07/24] Update app.js --- examples/custom-validation/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/custom-validation/app.js b/examples/custom-validation/app.js index bd5fd32..6bf31f0 100644 --- a/examples/custom-validation/app.js +++ b/examples/custom-validation/app.js @@ -20,7 +20,7 @@ var validators = { Formsy.addValidationRule('isYearOfBirth', function (values, value) { value = parseInt(value); - if (typeof value !== 'number' || value !== value) { + if (typeof value !== 'number') { return false; } return value < currentYear && value > currentYear - 130; From d623d9ddf1619440641d81493517a1e3ad151e9c Mon Sep 17 00:00:00 2001 From: David Blurton Date: Mon, 31 Aug 2015 11:22:11 +0000 Subject: [PATCH 08/24] Depend on beta version of React --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 344fe77..907493d 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,6 @@ "webpack-dev-server": "^1.7.0" }, "peerDependencies": { - "react": "0.13.x" + "react": "^0.14.0-beta3" } } From 3258545a5500b11fb37f8e8d9c0fbb587b376606 Mon Sep 17 00:00:00 2001 From: David Blurton Date: Mon, 31 Aug 2015 13:17:34 +0000 Subject: [PATCH 09/24] Fix package.json --- package.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/package.json b/package.json index 703ad46..2094847 100644 --- a/package.json +++ b/package.json @@ -25,16 +25,13 @@ "dependencies": { "form-data-to-object": "^0.1.0" }, - "peerDependencies": { - "react": "^0.14.0-beta1" - }, "devDependencies": { "babel": "^5.6.4", "babel-core": "^5.1.11", "babel-loader": "^5.0.0", "jasmine-node": "^1.14.5", "jsdom": "^3.1.2", - "react": "^0.14.0-beta3" + "react": "^0.14.0-beta3", "react-dom": "^0.14.0-beta3", "webpack": "^1.7.3", "webpack-dev-server": "^1.7.0" From 712f38883b7018ed806374bfc020ad3f123b7661 Mon Sep 17 00:00:00 2001 From: David Blurton Date: Mon, 31 Aug 2015 13:17:58 +0000 Subject: [PATCH 10/24] Use react-dom --- examples/custom-validation/app.js | 3 ++- examples/login/app.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/custom-validation/app.js b/examples/custom-validation/app.js index bd5fd32..03a5b9a 100644 --- a/examples/custom-validation/app.js +++ b/examples/custom-validation/app.js @@ -1,4 +1,5 @@ var React = require('react'); +var ReactDOM = require('react-dom'); var Formsy = require('formsy-react'); var currentYear = new Date().getFullYear(); @@ -120,4 +121,4 @@ var Validations = React.createClass({ } }); -React.render(, document.getElementById('example')); +ReactDOM.render(, document.getElementById('example')); diff --git a/examples/login/app.js b/examples/login/app.js index 24439c2..d6e0da8 100644 --- a/examples/login/app.js +++ b/examples/login/app.js @@ -1,4 +1,5 @@ var React = require('react'); +var ReactDOM = require('react-dom'); var Formsy = require('formsy-react'); var App = React.createClass({ @@ -62,4 +63,4 @@ var MyOwnInput = React.createClass({ } }); -React.render(, document.getElementById('example')); +ReactDOM.render(, document.getElementById('example')); From 87f14ae418ad0226eeae599c97ac52132cb10f86 Mon Sep 17 00:00:00 2001 From: David Blurton Date: Mon, 31 Aug 2015 13:18:12 +0000 Subject: [PATCH 11/24] Fix warnings --- examples/custom-validation/app.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/custom-validation/app.js b/examples/custom-validation/app.js index 03a5b9a..beef629 100644 --- a/examples/custom-validation/app.js +++ b/examples/custom-validation/app.js @@ -108,13 +108,13 @@ var Validations = React.createClass({
Validation Type
- Time + Time
- Decimal + Decimal
- Binary + Binary
); From 575321d2e21c40a33ab542e81e5b05f58167293b Mon Sep 17 00:00:00 2001 From: christianalfoni Date: Mon, 31 Aug 2015 15:33:04 +0200 Subject: [PATCH 12/24] Bumped version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2094847..20a9961 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "formsy-react", - "version": "0.14.1", + "version": "0.15.0", "description": "A form input builder and validator for React JS", "repository": { "type": "git", From 2a1be46ffec2170307767799e825f33a08bd32c0 Mon Sep 17 00:00:00 2001 From: David Blurton Date: Mon, 31 Aug 2015 13:49:21 +0000 Subject: [PATCH 13/24] Add release files --- release/formsy-react.js | 2 +- release/formsy-react.js.map | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/release/formsy-react.js b/release/formsy-react.js index 032fee8..ab389bc 100644 --- a/release/formsy-react.js +++ b/release/formsy-react.js @@ -1,2 +1,2 @@ -!function(t,i){"object"==typeof exports&&"object"==typeof module?module.exports=i(require("react")):"function"==typeof define&&define.amd?define(["react"],i):"object"==typeof exports?exports.Formsy=i(require("react")):t.Formsy=i(t.react)}(this,function(t){return function(t){function i(r){if(e[r])return e[r].exports;var n=e[r]={exports:{},id:r,loaded:!1};return t[r].call(n.exports,n,n.exports,i),n.loaded=!0,n.exports}var e={};return i.m=t,i.c=e,i.p="",i(0)}([function(t,i,e){(function(i){"use strict";var r=i.React||e(4),n={},s=e(3),u=e(1),o=e(2),a={};n.Mixin=o,n.defaults=function(t){a=t},n.addValidationRule=function(t,i){s[t]=i},n.Form=r.createClass({displayName:"Form",getInitialState:function(){return{isValid:!0,isSubmitting:!1,canChange:!1}},getDefaultProps:function(){return{onSuccess:function(){},onError:function(){},onSubmit:function(){},onValidSubmit:function(){},onInvalidSubmit:function(){},onSubmitted:function(){},onValid:function(){},onInvalid:function(){},onChange:function(){},validationErrors:null,preventExternalInvalidation:!1}},componentWillMount:function(){this.inputs={},this.model={}},componentDidMount:function(){this.validateForm()},componentWillUpdate:function(){this.prevInputKeys=Object.keys(this.inputs)},componentDidUpdate:function(){this.props.validationErrors&&this.setInputValidationErrors(this.props.validationErrors);var t=Object.keys(this.inputs);u.arraysDiffer(this.prevInputKeys,t)&&this.validateForm()},reset:function(t){this.setFormPristine(!0),this.resetModel(t)},submit:function(t){t&&t.preventDefault(),this.setFormPristine(!1),this.updateModel();var i=this.mapModel();this.props.onSubmit(i,this.resetModel,this.updateInputsWithError),this.state.isValid?this.props.onValidSubmit(i,this.resetModel,this.updateInputsWithError):this.props.onInvalidSubmit(i,this.resetModel,this.updateInputsWithError)},mapModel:function(){return this.props.mapping?this.props.mapping(this.model):Object.keys(this.model).reduce(function(t,i){for(var e=i.split("."),r=t;e.length;){var n=e.shift();r=r[n]=e.length?r[n]||{}:this.model[i]}return t}.bind(this),{})},updateModel:function(){Object.keys(this.inputs).forEach(function(t){var i=this.inputs[t];this.model[t]=i.state._value}.bind(this))},resetModel:function(t){Object.keys(this.inputs).forEach(function(i){t&&t[i]?this.inputs[i].setValue(t[i]):this.inputs[i].resetValue()}.bind(this)),this.validateForm()},setInputValidationErrors:function(t){Object.keys(this.inputs).forEach(function(i,e){var r=this.inputs[i],n=[{_isValid:!(i in t),_validationError:t[i]}];r.setState.apply(r,n)}.bind(this))},isChanged:function(){return!u.isSame(this.getPristineValues(),this.getCurrentValues())},getPristineValues:function(){var t=this.inputs;return Object.keys(t).reduce(function(i,e){var r=t[e];return i[e]=r.props.value,i},{})},updateInputsWithError:function(t){Object.keys(t).forEach(function(i,e){var r=this.inputs[i];if(!r)throw new Error("You are trying to update an input that does not exist. Verify errors object with input names. "+JSON.stringify(t));var n=[{_isValid:this.props.preventExternalInvalidation||!1,_externalError:t[i]}];r.setState.apply(r,n)}.bind(this))},traverseChildrenAndRegisterInputs:function(t){return"object"!=typeof t||null===t?t:r.Children.map(t,function(t){return"object"!=typeof t||null===t?t:t.props&&t.props.name?r.cloneElement(t,{_attachToForm:this.attachToForm,_detachFromForm:this.detachFromForm,_validate:this.validate,_isFormDisabled:this.isFormDisabled,_isValidValue:function(t,i){return this.runValidation(t,i).isValid}.bind(this)},t.props&&t.props.children):r.cloneElement(t,{},this.traverseChildrenAndRegisterInputs(t.props&&t.props.children))},this)},isFormDisabled:function(){return this.props.disabled},getCurrentValues:function(){return Object.keys(this.inputs).reduce(function(t,i){var e=this.inputs[i];return t[i]=e.state._value,t}.bind(this),{})},setFormPristine:function(t){var i=this.inputs,e=Object.keys(i);this.setState({_formSubmitted:!t}),e.forEach(function(e,r){var n=i[e];n.setState({_formSubmitted:!t,_isPristine:t})}.bind(this))},validate:function(t){this.state.canChange&&this.props.onChange(this.getCurrentValues(),this.isChanged());var i=this.runValidation(t);t.setState({_isValid:i.isValid,_isRequired:i.isRequired,_validationError:i.error,_externalError:null},this.validateForm)},runValidation:function(t,i){var e=this.getCurrentValues(),r=t.props.validationErrors,n=t.props.validationError;i=2===arguments.length?i:t.state._value;var s=this.runRules(i,e,t._validations),u=this.runRules(i,e,t._requiredValidations);"function"==typeof t.validate&&(s.failed=t.validate()?[]:["failed"]);var o=Object.keys(t._requiredValidations).length?!!u.success.length:!1,a=!(s.failed.length||this.props.validationErrors&&this.props.validationErrors[t.props.name]);return{isRequired:o,isValid:o?!1:a,error:function(){return a&&!o?"":s.errors.length?s.errors[0]:this.props.validationErrors&&this.props.validationErrors[t.props.name]?this.props.validationErrors[t.props.name]:o?r[u.success[0]]||null:a?void 0:r[s.failed[0]]||n}.call(this)}},runRules:function(t,i,e){var r={errors:[],failed:[],success:[]};return Object.keys(e).length&&Object.keys(e).forEach(function(n){if(s[n]&&"function"==typeof e[n])throw new Error("Formsy does not allow you to override default validations: "+n);if(!s[n]&&"function"!=typeof e[n])throw new Error("Formsy does not have the validation rule: "+n);if("function"==typeof e[n]){var u=e[n](i,t);return void("string"==typeof u?(r.errors.push(u),r.failed.push(n)):u||r.failed.push(n))}if("function"!=typeof e[n]){var u=s[n](i,t,e[n]);return void("string"==typeof u?(r.errors.push(u),r.failed.push(n)):u?r.success.push(n):r.failed.push(n))}return r.success.push(n)}),r},validateForm:function(){var t=!0,i=this.inputs,e=Object.keys(i),r=function(){e.forEach(function(e){i[e].state._isValid||(t=!1)}.bind(this)),this.setState({isValid:t}),t?this.props.onValid():this.props.onInvalid(),this.setState({canChange:!0})}.bind(this);e.forEach(function(t,n){var s=i[t],u=this.runValidation(s);u.isValid&&s.state._externalError&&(u.isValid=!1),s.setState({_isValid:u.isValid,_isRequired:u.isRequired,_validationError:u.error,_externalError:!u.isValid&&s.state._externalError?s.state._externalError:null},n===e.length-1?r:null)}.bind(this)),!e.length&&this.isMounted()&&this.setState({canChange:!0})},attachToForm:function(t){this.inputs[t.props.name]=t,this.model[t.props.name]=t.state._value,this.validate(t)},detachFromForm:function(t){delete this.inputs[t.props.name],delete this.model[t.props.name]},render:function(){return r.DOM.form({onSubmit:this.submit,className:this.props.className,autoComplete:this.props.autoComplete},this.traverseChildrenAndRegisterInputs(this.props.children))}}),i.exports||i.module||i.define&&i.define.amd||(i.Formsy=n),t.exports=n}).call(i,function(){return this}())},function(t,i){"use strict";t.exports={arraysDiffer:function(t,i){var e=!1;return t.length!==i.length?e=!0:t.forEach(function(t,r){this.isSame(t,i[r])||(e=!0)},this),e},objectsDiffer:function(t,i){var e=!1;return Object.keys(t).length!==Object.keys(i).length?e=!0:Object.keys(t).forEach(function(r){this.isSame(t[r],i[r])||(e=!0)},this),e},isSame:function(t,i){return typeof t!=typeof i?!1:Array.isArray(t)?!this.arraysDiffer(t,i):"object"==typeof t&&null!==t&&null!==i?!this.objectsDiffer(t,i):t===i}}},function(t,i,e){"use strict";var r=e(1),n=function(t){return"string"==typeof t?t.split(/\,(?![^{\[]*[}\]])/g).reduce(function(t,i){var e=i.split(":"),r=e.shift();if(e=e.map(function(t){try{return JSON.parse(t)}catch(i){return t}}),e.length>1)throw new Error("Formsy does not support multiple args on string validations. Use object format of validations instead.");return t[r]=e.length?e[0]:!0,t},{}):t||{}};t.exports={getInitialState:function(){return{_value:this.props.value,_isRequired:!1,_isValid:!0,_isPristine:!0,_pristineValue:this.props.value,_validationError:"",_externalError:null,_formSubmitted:!1}},getDefaultProps:function(){return{validationError:"",validationErrors:{}}},componentWillMount:function(){var t=function(){this.setValidations(this.props.validations,this.props.required),this.props._attachToForm(this)}.bind(this);if(!this.props.name)throw new Error("Form Input requires a name property when used");return this.props._attachToForm?void t():setTimeout(function(){if(this.isMounted()){if(!this.props._attachToForm)throw new Error("Form Mixin requires component to be nested in a Form");t()}}.bind(this),0)},componentWillReceiveProps:function(t){this.setValidations(t.validations,t.required)},componentDidUpdate:function(t){r.isSame(this.props.value,t.value)||this.setValue(this.props.value)},componentWillUnmount:function(){this.props._detachFromForm(this)},setValidations:function(t,i){this._validations=n(t)||{},this._requiredValidations=i===!0?{isDefaultRequiredValue:!0}:n(i)},setValue:function(t){this.setState({_value:t,_isPristine:!1},function(){this.props._validate(this)}.bind(this))},resetValue:function(){this.setState({_value:this.state._pristineValue,_isPristine:!0},function(){this.props._validate(this)})},getValue:function(){return this.state._value},hasValue:function(){return""!==this.state._value},getErrorMessage:function(){return!this.isValid()||this.showRequired()?this.state._externalError||this.state._validationError:null},isFormDisabled:function(){return this.props._isFormDisabled()},isValid:function(){return this.state._isValid},isPristine:function(){return this.state._isPristine},isFormSubmitted:function(){return this.state._formSubmitted},isRequired:function(){return!!this.props.required},showRequired:function(){return this.state._isRequired},showError:function(){return!this.showRequired()&&!this.isValid()},isValidValue:function(t){return this.props._isValidValue.call(null,this,t)}}},function(t,i){"use strict";var e=function(t){return null!==t&&void 0!==t},r=function(t){return""===t},n={isDefaultRequiredValue:function(t,i){return void 0===i||""===i},isExisty:function(t,i){return e(i)},matchRegexp:function(t,i,n){return!e(i)||r(i)||n.test(i)},isUndefined:function(t,i){return void 0===i},isEmptyString:function(t,i){return r(i)},isEmail:function(t,i){return n.matchRegexp(t,i,/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i)},isUrl:function(t,i){return n.matchRegexp(t,i,/^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i)},isTrue:function(t,i){return i===!0},isFalse:function(t,i){return i===!1},isNumeric:function(t,i){return"number"==typeof i?!0:n.matchRegexp(t,i,/^[-+]?(\d*[.])?\d+$/)},isAlpha:function(t,i){return n.matchRegexp(t,i,/^[a-zA-Z]+$/)},isWords:function(t,i){return n.matchRegexp(t,i,/^[a-zA-Z\s]+$/)},isSpecialWords:function(t,i){return n.matchRegexp(t,i,/^[a-zA-Z\s\u00C0-\u017F]+$/)},isLength:function(t,i,n){return!e(i)||r(i)||i.length===n},equals:function(t,i,n){return!e(i)||r(i)||i==n},equalsField:function(t,i,e){return i==t[e]},maxLength:function(t,i,r){return!e(i)||i.length<=r},minLength:function(t,i,n){return!e(i)||r(i)||i.length>=n}};t.exports=n},function(i,e){i.exports=t}])}); +!function(t,i){"object"==typeof exports&&"object"==typeof module?module.exports=i(require("react")):"function"==typeof define&&define.amd?define(["react"],i):"object"==typeof exports?exports.Formsy=i(require("react")):t.Formsy=i(t.react)}(this,function(t){return function(t){function i(r){if(e[r])return e[r].exports;var s=e[r]={exports:{},id:r,loaded:!1};return t[r].call(s.exports,s,s.exports,i),s.loaded=!0,s.exports}var e={};return i.m=t,i.c=e,i.p="",i(0)}([function(t,i,e){(function(i){"use strict";var r=Object.assign||function(t){for(var i=1;i1)throw new Error("Formsy does not support multiple args on string validations. Use object format of validations instead.");return t[r]=e.length?e[0]:!0,t},{}):t||{}};t.exports={getInitialState:function(){return{_value:this.props.value,_isRequired:!1,_isValid:!0,_isPristine:!0,_pristineValue:this.props.value,_validationError:[],_externalError:null,_formSubmitted:!1}},contextTypes:{formsy:s.PropTypes.object},getDefaultProps:function(){return{validationError:"",validationErrors:{}}},componentWillMount:function(){var t=function(){this.setValidations(this.props.validations,this.props.required),this.context.formsy.attachToForm(this)}.bind(this);if(!this.props.name)throw new Error("Form Input requires a name property when used");t()},componentWillReceiveProps:function(t){this.setValidations(t.validations,t.required)},componentDidUpdate:function(t){r.isSame(this.props.value,t.value)||this.setValue(this.props.value),r.isSame(this.props.validations,t.validations)&&r.isSame(this.props.required,t.required)||this.context.formsy.validate(this)},componentWillUnmount:function(){this.context.formsy.detachFromForm(this)},setValidations:function(t,i){this._validations=n(t)||{},this._requiredValidations=i===!0?{isDefaultRequiredValue:!0}:n(i)},setValue:function(t){this.setState({_value:t,_isPristine:!1},function(){this.context.formsy.validate(this)}.bind(this))},resetValue:function(){this.setState({_value:this.state._pristineValue,_isPristine:!0},function(){this.context.formsy.validate(this)})},getValue:function(){return this.state._value},hasValue:function(){return""!==this.state._value},getErrorMessage:function(){var t=this.getErrorMessages();return t.length?t[0]:null},getErrorMessages:function(){return!this.isValid()||this.showRequired()?this.state._externalError||this.state._validationError||[]:[]},isFormDisabled:function(){return this.context.formsy.isFormDisabled()},isValid:function(){return this.state._isValid},isPristine:function(){return this.state._isPristine},isFormSubmitted:function(){return this.state._formSubmitted},isRequired:function(){return!!this.props.required},showRequired:function(){return this.state._isRequired},showError:function(){return!this.showRequired()&&!this.isValid()},isValidValue:function(t){return this.context.formsy.isValidValue.call(null,this,t)}}}).call(i,function(){return this}())},function(t,i){"use strict";t.exports={arraysDiffer:function(t,i){var e=!1;return t.length!==i.length?e=!0:t.forEach(function(t,r){this.isSame(t,i[r])||(e=!0)},this),e},objectsDiffer:function(t,i){var e=!1;return Object.keys(t).length!==Object.keys(i).length?e=!0:Object.keys(t).forEach(function(r){this.isSame(t[r],i[r])||(e=!0)},this),e},isSame:function(t,i){return typeof t!=typeof i?!1:Array.isArray(t)?!this.arraysDiffer(t,i):"object"==typeof t&&null!==t&&null!==i?!this.objectsDiffer(t,i):t===i}}},function(t,i,e){(function(i){"use strict";var r=i.React||e(1),s=e(2);t.exports=function(){return function(t){return r.createClass({mixins:[s],render:function(){return r.createElement(t,{setValidations:this.setValidations,setValue:this.setValue,resetValue:this.resetValue,getValue:this.getValue,hasValue:this.hasValue,getErrorMessage:this.getErrorMessage,getErrorMessages:this.getErrorMessages,isFormDisabled:this.isFormDisabled,isValid:this.isValid,isPristine:this.isPristine,isFormSubmitted:this.isFormSubmitted,isRequired:this.isRequired,showRequired:this.showRequired,showError:this.showError,isValidValue:this.isValidValue})}})}}}).call(i,function(){return this}())},function(t,i,e){(function(i){"use strict";var r=i.React||e(1),s=e(2);t.exports=function(t){return r.createClass({mixins:[s],render:function(){return r.createElement(t,{setValidations:this.setValidations,setValue:this.setValue,resetValue:this.resetValue,getValue:this.getValue,hasValue:this.hasValue,getErrorMessage:this.getErrorMessage,getErrorMessages:this.getErrorMessages,isFormDisabled:this.isFormDisabled,isValid:this.isValid,isPristine:this.isPristine,isFormSubmitted:this.isFormSubmitted,isRequired:this.isRequired,showRequired:this.showRequired,showError:this.showError,isValidValue:this.isValidValue})}})}}).call(i,function(){return this}())},function(t,i){"use strict";var e=function(t){return null!==t&&void 0!==t},r=function(t){return""===t},s={isDefaultRequiredValue:function(t,i){return void 0===i||""===i},isExisty:function(t,i){return e(i)},matchRegexp:function(t,i,s){return!e(i)||r(i)||s.test(i)},isUndefined:function(t,i){return void 0===i},isEmptyString:function(t,i){return r(i)},isEmail:function(t,i){return s.matchRegexp(t,i,/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i)},isUrl:function(t,i){return s.matchRegexp(t,i,/^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i)},isTrue:function(t,i){return i===!0},isFalse:function(t,i){return i===!1},isNumeric:function(t,i){return"number"==typeof i?!0:s.matchRegexp(t,i,/^[-+]?(\d*[.])?\d+$/)},isAlpha:function(t,i){return s.matchRegexp(t,i,/^[a-zA-Z]+$/)},isWords:function(t,i){return s.matchRegexp(t,i,/^[a-zA-Z\s]+$/)},isSpecialWords:function(t,i){return s.matchRegexp(t,i,/^[a-zA-Z\s\u00C0-\u017F]+$/)},isLength:function(t,i,s){return!e(i)||r(i)||i.length===s},equals:function(t,i,s){return!e(i)||r(i)||i==s},equalsField:function(t,i,e){return i==t[e]},maxLength:function(t,i,r){return!e(i)||i.length<=r},minLength:function(t,i,s){return!e(i)||r(i)||i.length>=s}};t.exports=s},function(t,i){t.exports=function(t){return Object.keys(t).reduce(function(i,e){var r=e.match(/[^\[]*/i),s=e.match(/\[.*?\]/g)||[];s=[r[0]].concat(s).map(function(t){return t.replace(/\[|\]/g,"")});for(var n=i;s.length;){var u=s.shift();u in n?n=n[u]:(n[u]=s.length?isNaN(s[0])?{}:[]:t[e],n=n[u])}return i},{})}}])}); //# sourceMappingURL=formsy-react.js.map \ No newline at end of file diff --git a/release/formsy-react.js.map b/release/formsy-react.js.map index 6bb89b7..ca10ee3 100644 --- a/release/formsy-react.js.map +++ b/release/formsy-react.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///formsy-react.js","webpack:///webpack/bootstrap 4695461acb66117350c3","webpack:///./src/main.js","webpack:///./src/utils.js","webpack:///./src/Mixin.js","webpack:///./src/validationRules.js","webpack:///external \"react\""],"names":["root","factory","exports","module","require","define","amd","this","__WEBPACK_EXTERNAL_MODULE_4__","modules","__webpack_require__","moduleId","installedModules","id","loaded","call","m","c","p","global","React","Formsy","validationRules","utils","Mixin","options","defaults","passedOptions","addValidationRule","name","func","Form","createClass","displayName","getInitialState","isValid","isSubmitting","canChange","getDefaultProps","onSuccess","onError","onSubmit","onValidSubmit","onInvalidSubmit","onSubmitted","onValid","onInvalid","onChange","validationErrors","preventExternalInvalidation","componentWillMount","inputs","model","componentDidMount","validateForm","componentWillUpdate","prevInputKeys","Object","keys","componentDidUpdate","props","setInputValidationErrors","newInputKeys","arraysDiffer","reset","data","setFormPristine","resetModel","submit","event","preventDefault","updateModel","mapModel","updateInputsWithError","state","mapping","reduce","mappedModel","key","keyArray","split","base","length","currentKey","shift","bind","forEach","component","_value","setValue","resetValue","errors","index","args","_isValid","_validationError","setState","apply","isChanged","isSame","getPristineValues","getCurrentValues","value","Error","JSON","stringify","_externalError","traverseChildrenAndRegisterInputs","children","Children","map","child","cloneElement","_attachToForm","attachToForm","_detachFromForm","detachFromForm","_validate","validate","_isFormDisabled","isFormDisabled","_isValidValue","runValidation","disabled","isPristine","inputKeys","_formSubmitted","_isPristine","validation","_isRequired","isRequired","error","currentValues","validationError","arguments","validationResults","runRules","_validations","requiredResults","_requiredValidations","failed","success","validations","results","validationMethod","push","allIsValid","onValidationComplete","isMounted","render","DOM","form","className","autoComplete","a","b","isDifferent","item","objectsDiffer","Array","isArray","convertValidationsToObject","validateMethod","arg","parse","e","_pristineValue","configure","setValidations","required","setTimeout","componentWillReceiveProps","nextProps","prevProps","componentWillUnmount","isDefaultRequiredValue","getValue","hasValue","getErrorMessage","showRequired","isFormSubmitted","showError","isValidValue","_isExisty","undefined","isEmpty","values","isExisty","matchRegexp","regexp","test","isUndefined","isEmptyString","isEmail","isUrl","isTrue","isFalse","isNumeric","isAlpha","isWords","isSpecialWords","isLength","equals","eql","equalsField","field","maxLength","minLength"],"mappings":"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","file":"formsy-react.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Formsy\"] = factory(require(\"react\"));\n\telse\n\t\troot[\"Formsy\"] = factory(root[\"react\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_4__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Formsy\"] = factory(require(\"react\"));\n\telse\n\t\troot[\"Formsy\"] = factory(root[\"react\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_4__) {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global) {'use strict';\n\t\n\tvar React = global.React || __webpack_require__(4);\n\tvar Formsy = {};\n\tvar validationRules = __webpack_require__(3);\n\tvar utils = __webpack_require__(1);\n\tvar Mixin = __webpack_require__(2);\n\tvar options = {};\n\t\n\tFormsy.Mixin = Mixin;\n\t\n\tFormsy.defaults = function (passedOptions) {\n\t options = passedOptions;\n\t};\n\t\n\tFormsy.addValidationRule = function (name, func) {\n\t validationRules[name] = func;\n\t};\n\t\n\tFormsy.Form = React.createClass({\n\t displayName: 'Form',\n\t\n\t getInitialState: function getInitialState() {\n\t return {\n\t isValid: true,\n\t isSubmitting: false,\n\t canChange: false\n\t };\n\t },\n\t getDefaultProps: function getDefaultProps() {\n\t return {\n\t onSuccess: function onSuccess() {},\n\t onError: function onError() {},\n\t onSubmit: function onSubmit() {},\n\t onValidSubmit: function onValidSubmit() {},\n\t onInvalidSubmit: function onInvalidSubmit() {},\n\t onSubmitted: function onSubmitted() {},\n\t onValid: function onValid() {},\n\t onInvalid: function onInvalid() {},\n\t onChange: function onChange() {},\n\t validationErrors: null,\n\t preventExternalInvalidation: false\n\t };\n\t },\n\t\n\t // Add a map to store the inputs of the form, a model to store\n\t // the values of the form and register child inputs\n\t componentWillMount: function componentWillMount() {\n\t this.inputs = {};\n\t this.model = {};\n\t },\n\t\n\t componentDidMount: function componentDidMount() {\n\t this.validateForm();\n\t },\n\t\n\t componentWillUpdate: function componentWillUpdate() {\n\t\n\t // Keep a reference to input keys before form updates,\n\t // to check if inputs has changed after render\n\t this.prevInputKeys = Object.keys(this.inputs);\n\t },\n\t\n\t componentDidUpdate: function componentDidUpdate() {\n\t\n\t if (this.props.validationErrors) {\n\t this.setInputValidationErrors(this.props.validationErrors);\n\t }\n\t\n\t var newInputKeys = Object.keys(this.inputs);\n\t if (utils.arraysDiffer(this.prevInputKeys, newInputKeys)) {\n\t this.validateForm();\n\t }\n\t },\n\t\n\t // Allow resetting to specified data\n\t reset: function reset(data) {\n\t this.setFormPristine(true);\n\t this.resetModel(data);\n\t },\n\t\n\t // Update model, submit to url prop and send the model\n\t submit: function submit(event) {\n\t\n\t event && event.preventDefault();\n\t\n\t // Trigger form as not pristine.\n\t // If any inputs have not been touched yet this will make them dirty\n\t // so validation becomes visible (if based on isPristine)\n\t this.setFormPristine(false);\n\t this.updateModel();\n\t var model = this.mapModel();\n\t this.props.onSubmit(model, this.resetModel, this.updateInputsWithError);\n\t this.state.isValid ? this.props.onValidSubmit(model, this.resetModel, this.updateInputsWithError) : this.props.onInvalidSubmit(model, this.resetModel, this.updateInputsWithError);\n\t },\n\t\n\t mapModel: function mapModel() {\n\t if (this.props.mapping) {\n\t return this.props.mapping(this.model);\n\t } else {\n\t return Object.keys(this.model).reduce((function (mappedModel, key) {\n\t\n\t var keyArray = key.split('.');\n\t var base = mappedModel;\n\t while (keyArray.length) {\n\t var currentKey = keyArray.shift();\n\t base = base[currentKey] = keyArray.length ? base[currentKey] || {} : this.model[key];\n\t }\n\t\n\t return mappedModel;\n\t }).bind(this), {});\n\t }\n\t },\n\t\n\t // Goes through all registered components and\n\t // updates the model values\n\t updateModel: function updateModel() {\n\t Object.keys(this.inputs).forEach((function (name) {\n\t var component = this.inputs[name];\n\t this.model[name] = component.state._value;\n\t }).bind(this));\n\t },\n\t\n\t // Reset each key in the model to the original / initial / specified value\n\t resetModel: function resetModel(data) {\n\t Object.keys(this.inputs).forEach((function (name) {\n\t if (data && data[name]) {\n\t this.inputs[name].setValue(data[name]);\n\t } else {\n\t this.inputs[name].resetValue();\n\t }\n\t }).bind(this));\n\t this.validateForm();\n\t },\n\t\n\t setInputValidationErrors: function setInputValidationErrors(errors) {\n\t Object.keys(this.inputs).forEach((function (name, index) {\n\t var component = this.inputs[name];\n\t var args = [{\n\t _isValid: !(name in errors),\n\t _validationError: errors[name]\n\t }];\n\t component.setState.apply(component, args);\n\t }).bind(this));\n\t },\n\t\n\t // Checks if the values have changed from their initial value\n\t isChanged: function isChanged() {\n\t return !utils.isSame(this.getPristineValues(), this.getCurrentValues());\n\t },\n\t\n\t getPristineValues: function getPristineValues() {\n\t var inputs = this.inputs;\n\t return Object.keys(inputs).reduce(function (data, name) {\n\t var component = inputs[name];\n\t data[name] = component.props.value;\n\t return data;\n\t }, {});\n\t },\n\t\n\t // Go through errors from server and grab the components\n\t // stored in the inputs map. Change their state to invalid\n\t // and set the serverError message\n\t updateInputsWithError: function updateInputsWithError(errors) {\n\t Object.keys(errors).forEach((function (name, index) {\n\t var component = this.inputs[name];\n\t\n\t if (!component) {\n\t throw new Error('You are trying to update an input that does not exist. Verify errors object with input names. ' + JSON.stringify(errors));\n\t }\n\t var args = [{\n\t _isValid: this.props.preventExternalInvalidation || false,\n\t _externalError: errors[name]\n\t }];\n\t component.setState.apply(component, args);\n\t }).bind(this));\n\t },\n\t\n\t // Traverse the children and children of children to find\n\t // all inputs by checking the name prop. Maybe do a better\n\t // check here\n\t traverseChildrenAndRegisterInputs: function traverseChildrenAndRegisterInputs(children) {\n\t\n\t if (typeof children !== 'object' || children === null) {\n\t return children;\n\t }\n\t return React.Children.map(children, function (child) {\n\t\n\t if (typeof child !== 'object' || child === null) {\n\t return child;\n\t }\n\t\n\t if (child.props && child.props.name) {\n\t\n\t return React.cloneElement(child, {\n\t _attachToForm: this.attachToForm,\n\t _detachFromForm: this.detachFromForm,\n\t _validate: this.validate,\n\t _isFormDisabled: this.isFormDisabled,\n\t _isValidValue: (function (component, value) {\n\t return this.runValidation(component, value).isValid;\n\t }).bind(this)\n\t }, child.props && child.props.children);\n\t } else {\n\t return React.cloneElement(child, {}, this.traverseChildrenAndRegisterInputs(child.props && child.props.children));\n\t }\n\t }, this);\n\t },\n\t\n\t isFormDisabled: function isFormDisabled() {\n\t return this.props.disabled;\n\t },\n\t\n\t getCurrentValues: function getCurrentValues() {\n\t return Object.keys(this.inputs).reduce((function (data, name) {\n\t var component = this.inputs[name];\n\t data[name] = component.state._value;\n\t return data;\n\t }).bind(this), {});\n\t },\n\t\n\t setFormPristine: function setFormPristine(isPristine) {\n\t var inputs = this.inputs;\n\t var inputKeys = Object.keys(inputs);\n\t\n\t this.setState({\n\t _formSubmitted: !isPristine\n\t });\n\t\n\t // Iterate through each component and set it as pristine\n\t // or \"dirty\".\n\t inputKeys.forEach((function (name, index) {\n\t var component = inputs[name];\n\t component.setState({\n\t _formSubmitted: !isPristine,\n\t _isPristine: isPristine\n\t });\n\t }).bind(this));\n\t },\n\t\n\t // Use the binded values and the actual input value to\n\t // validate the input and set its state. Then check the\n\t // state of the form itself\n\t validate: function validate(component) {\n\t\n\t // Trigger onChange\n\t if (this.state.canChange) {\n\t this.props.onChange(this.getCurrentValues(), this.isChanged());\n\t }\n\t\n\t var validation = this.runValidation(component);\n\t // Run through the validations, split them up and call\n\t // the validator IF there is a value or it is required\n\t component.setState({\n\t _isValid: validation.isValid,\n\t _isRequired: validation.isRequired,\n\t _validationError: validation.error,\n\t _externalError: null\n\t }, this.validateForm);\n\t },\n\t\n\t // Checks validation on current value or a passed value\n\t runValidation: function runValidation(component, value) {\n\t\n\t var currentValues = this.getCurrentValues();\n\t var validationErrors = component.props.validationErrors;\n\t var validationError = component.props.validationError;\n\t value = arguments.length === 2 ? value : component.state._value;\n\t\n\t var validationResults = this.runRules(value, currentValues, component._validations);\n\t var requiredResults = this.runRules(value, currentValues, component._requiredValidations);\n\t\n\t // the component defines an explicit validate function\n\t if (typeof component.validate === 'function') {\n\t validationResults.failed = component.validate() ? [] : ['failed'];\n\t }\n\t\n\t var isRequired = Object.keys(component._requiredValidations).length ? !!requiredResults.success.length : false;\n\t var isValid = !validationResults.failed.length && !(this.props.validationErrors && this.props.validationErrors[component.props.name]);\n\t\n\t return {\n\t isRequired: isRequired,\n\t isValid: isRequired ? false : isValid,\n\t error: (function () {\n\t\n\t if (isValid && !isRequired) {\n\t return '';\n\t }\n\t\n\t if (validationResults.errors.length) {\n\t return validationResults.errors[0];\n\t }\n\t\n\t if (this.props.validationErrors && this.props.validationErrors[component.props.name]) {\n\t return this.props.validationErrors[component.props.name];\n\t }\n\t\n\t if (isRequired) {\n\t return validationErrors[requiredResults.success[0]] || null;\n\t }\n\t\n\t if (!isValid) {\n\t return validationErrors[validationResults.failed[0]] || validationError;\n\t }\n\t }).call(this)\n\t };\n\t },\n\t\n\t runRules: function runRules(value, currentValues, validations) {\n\t\n\t var results = {\n\t errors: [],\n\t failed: [],\n\t success: []\n\t };\n\t if (Object.keys(validations).length) {\n\t Object.keys(validations).forEach(function (validationMethod) {\n\t\n\t if (validationRules[validationMethod] && typeof validations[validationMethod] === 'function') {\n\t throw new Error('Formsy does not allow you to override default validations: ' + validationMethod);\n\t }\n\t\n\t if (!validationRules[validationMethod] && typeof validations[validationMethod] !== 'function') {\n\t throw new Error('Formsy does not have the validation rule: ' + validationMethod);\n\t }\n\t\n\t if (typeof validations[validationMethod] === 'function') {\n\t var validation = validations[validationMethod](currentValues, value);\n\t if (typeof validation === 'string') {\n\t results.errors.push(validation);\n\t results.failed.push(validationMethod);\n\t } else if (!validation) {\n\t results.failed.push(validationMethod);\n\t }\n\t return;\n\t } else if (typeof validations[validationMethod] !== 'function') {\n\t var validation = validationRules[validationMethod](currentValues, value, validations[validationMethod]);\n\t if (typeof validation === 'string') {\n\t results.errors.push(validation);\n\t results.failed.push(validationMethod);\n\t } else if (!validation) {\n\t results.failed.push(validationMethod);\n\t } else {\n\t results.success.push(validationMethod);\n\t }\n\t return;\n\t }\n\t\n\t return results.success.push(validationMethod);\n\t });\n\t }\n\t\n\t return results;\n\t },\n\t\n\t // Validate the form by going through all child input components\n\t // and check their state\n\t validateForm: function validateForm() {\n\t var allIsValid = true;\n\t var inputs = this.inputs;\n\t var inputKeys = Object.keys(inputs);\n\t\n\t // We need a callback as we are validating all inputs again. This will\n\t // run when the last component has set its state\n\t var onValidationComplete = (function () {\n\t inputKeys.forEach((function (name) {\n\t if (!inputs[name].state._isValid) {\n\t allIsValid = false;\n\t }\n\t }).bind(this));\n\t\n\t this.setState({\n\t isValid: allIsValid\n\t });\n\t\n\t if (allIsValid) {\n\t this.props.onValid();\n\t } else {\n\t this.props.onInvalid();\n\t }\n\t\n\t // Tell the form that it can start to trigger change events\n\t this.setState({\n\t canChange: true\n\t });\n\t }).bind(this);\n\t\n\t // Run validation again in case affected by other inputs. The\n\t // last component validated will run the onValidationComplete callback\n\t inputKeys.forEach((function (name, index) {\n\t var component = inputs[name];\n\t var validation = this.runValidation(component);\n\t if (validation.isValid && component.state._externalError) {\n\t validation.isValid = false;\n\t }\n\t component.setState({\n\t _isValid: validation.isValid,\n\t _isRequired: validation.isRequired,\n\t _validationError: validation.error,\n\t _externalError: !validation.isValid && component.state._externalError ? component.state._externalError : null\n\t }, index === inputKeys.length - 1 ? onValidationComplete : null);\n\t }).bind(this));\n\t\n\t // If there are no inputs, set state where form is ready to trigger\n\t // change event. New inputs might be added later\n\t if (!inputKeys.length && this.isMounted()) {\n\t this.setState({\n\t canChange: true\n\t });\n\t }\n\t },\n\t\n\t // Method put on each input component to register\n\t // itself to the form\n\t attachToForm: function attachToForm(component) {\n\t this.inputs[component.props.name] = component;\n\t this.model[component.props.name] = component.state._value;\n\t this.validate(component);\n\t },\n\t\n\t // Method put on each input component to unregister\n\t // itself from the form\n\t detachFromForm: function detachFromForm(component) {\n\t delete this.inputs[component.props.name];\n\t delete this.model[component.props.name];\n\t },\n\t render: function render() {\n\t\n\t return React.DOM.form({\n\t onSubmit: this.submit,\n\t className: this.props.className,\n\t autoComplete: this.props.autoComplete\n\t }, this.traverseChildrenAndRegisterInputs(this.props.children));\n\t }\n\t});\n\t\n\tif (!global.exports && !global.module && (!global.define || !global.define.amd)) {\n\t global.Formsy = Formsy;\n\t}\n\t\n\tmodule.exports = Formsy;\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n\n/***/ },\n/* 1 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = {\n\t arraysDiffer: function arraysDiffer(a, b) {\n\t var isDifferent = false;\n\t if (a.length !== b.length) {\n\t isDifferent = true;\n\t } else {\n\t a.forEach(function (item, index) {\n\t if (!this.isSame(item, b[index])) {\n\t isDifferent = true;\n\t }\n\t }, this);\n\t }\n\t return isDifferent;\n\t },\n\t\n\t objectsDiffer: function objectsDiffer(a, b) {\n\t var isDifferent = false;\n\t if (Object.keys(a).length !== Object.keys(b).length) {\n\t isDifferent = true;\n\t } else {\n\t Object.keys(a).forEach(function (key) {\n\t if (!this.isSame(a[key], b[key])) {\n\t isDifferent = true;\n\t }\n\t }, this);\n\t }\n\t return isDifferent;\n\t },\n\t\n\t isSame: function isSame(a, b) {\n\t if (typeof a !== typeof b) {\n\t return false;\n\t } else if (Array.isArray(a)) {\n\t return !this.arraysDiffer(a, b);\n\t } else if (typeof a === 'object' && a !== null && b !== null) {\n\t return !this.objectsDiffer(a, b);\n\t }\n\t\n\t return a === b;\n\t }\n\t};\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(1);\n\t\n\tvar convertValidationsToObject = function convertValidationsToObject(validations) {\n\t\n\t if (typeof validations === 'string') {\n\t\n\t return validations.split(/\\,(?![^{\\[]*[}\\]])/g).reduce(function (validations, validation) {\n\t var args = validation.split(':');\n\t var validateMethod = args.shift();\n\t\n\t args = args.map(function (arg) {\n\t try {\n\t return JSON.parse(arg);\n\t } catch (e) {\n\t return arg; // It is a string if it can not parse it\n\t }\n\t });\n\t\n\t if (args.length > 1) {\n\t throw new Error('Formsy does not support multiple args on string validations. Use object format of validations instead.');\n\t }\n\t\n\t validations[validateMethod] = args.length ? args[0] : true;\n\t return validations;\n\t }, {});\n\t }\n\t\n\t return validations || {};\n\t};\n\t\n\tmodule.exports = {\n\t getInitialState: function getInitialState() {\n\t return {\n\t _value: this.props.value,\n\t _isRequired: false,\n\t _isValid: true,\n\t _isPristine: true,\n\t _pristineValue: this.props.value,\n\t _validationError: '',\n\t _externalError: null,\n\t _formSubmitted: false\n\t };\n\t },\n\t getDefaultProps: function getDefaultProps() {\n\t return {\n\t validationError: '',\n\t validationErrors: {}\n\t };\n\t },\n\t\n\t componentWillMount: function componentWillMount() {\n\t var configure = (function () {\n\t this.setValidations(this.props.validations, this.props.required);\n\t this.props._attachToForm(this);\n\t }).bind(this);\n\t\n\t if (!this.props.name) {\n\t throw new Error('Form Input requires a name property when used');\n\t }\n\t\n\t if (!this.props._attachToForm) {\n\t return setTimeout((function () {\n\t if (!this.isMounted()) return;\n\t if (!this.props._attachToForm) {\n\t throw new Error('Form Mixin requires component to be nested in a Form');\n\t }\n\t configure();\n\t }).bind(this), 0);\n\t }\n\t configure();\n\t },\n\t\n\t // We have to make the validate method is kept when new props are added\n\t componentWillReceiveProps: function componentWillReceiveProps(nextProps) {\n\t this.setValidations(nextProps.validations, nextProps.required);\n\t },\n\t\n\t componentDidUpdate: function componentDidUpdate(prevProps) {\n\t\n\t // If the value passed has changed, set it. If value is not passed it will\n\t // internally update, and this will never run\n\t if (!utils.isSame(this.props.value, prevProps.value)) {\n\t this.setValue(this.props.value);\n\t }\n\t },\n\t\n\t // Detach it when component unmounts\n\t componentWillUnmount: function componentWillUnmount() {\n\t this.props._detachFromForm(this);\n\t },\n\t\n\t setValidations: function setValidations(validations, required) {\n\t\n\t // Add validations to the store itself as the props object can not be modified\n\t this._validations = convertValidationsToObject(validations) || {};\n\t this._requiredValidations = required === true ? { isDefaultRequiredValue: true } : convertValidationsToObject(required);\n\t },\n\t\n\t // We validate after the value has been set\n\t setValue: function setValue(value) {\n\t this.setState({\n\t _value: value,\n\t _isPristine: false\n\t }, (function () {\n\t this.props._validate(this);\n\t }).bind(this));\n\t },\n\t resetValue: function resetValue() {\n\t this.setState({\n\t _value: this.state._pristineValue,\n\t _isPristine: true\n\t }, function () {\n\t this.props._validate(this);\n\t });\n\t },\n\t getValue: function getValue() {\n\t return this.state._value;\n\t },\n\t hasValue: function hasValue() {\n\t return this.state._value !== '';\n\t },\n\t getErrorMessage: function getErrorMessage() {\n\t return !this.isValid() || this.showRequired() ? this.state._externalError || this.state._validationError : null;\n\t },\n\t isFormDisabled: function isFormDisabled() {\n\t return this.props._isFormDisabled();\n\t },\n\t isValid: function isValid() {\n\t return this.state._isValid;\n\t },\n\t isPristine: function isPristine() {\n\t return this.state._isPristine;\n\t },\n\t isFormSubmitted: function isFormSubmitted() {\n\t return this.state._formSubmitted;\n\t },\n\t isRequired: function isRequired() {\n\t return !!this.props.required;\n\t },\n\t showRequired: function showRequired() {\n\t return this.state._isRequired;\n\t },\n\t showError: function showError() {\n\t return !this.showRequired() && !this.isValid();\n\t },\n\t isValidValue: function isValidValue(value) {\n\t return this.props._isValidValue.call(null, this, value);\n\t }\n\t};\n\n/***/ },\n/* 3 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tvar _isExisty = function _isExisty(value) {\n\t return value !== null && value !== undefined;\n\t};\n\t\n\tvar isEmpty = function isEmpty(value) {\n\t return value === '';\n\t};\n\t\n\tvar validations = {\n\t isDefaultRequiredValue: function isDefaultRequiredValue(values, value) {\n\t return value === undefined || value === '';\n\t },\n\t isExisty: function isExisty(values, value) {\n\t return _isExisty(value);\n\t },\n\t matchRegexp: function matchRegexp(values, value, regexp) {\n\t return !_isExisty(value) || isEmpty(value) || regexp.test(value);\n\t },\n\t isUndefined: function isUndefined(values, value) {\n\t return value === undefined;\n\t },\n\t isEmptyString: function isEmptyString(values, value) {\n\t return isEmpty(value);\n\t },\n\t isEmail: function isEmail(values, value) {\n\t return validations.matchRegexp(values, value, /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i);\n\t },\n\t isUrl: function isUrl(values, value) {\n\t return validations.matchRegexp(values, value, /^(https?|s?ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i);\n\t },\n\t isTrue: function isTrue(values, value) {\n\t return value === true;\n\t },\n\t isFalse: function isFalse(values, value) {\n\t return value === false;\n\t },\n\t isNumeric: function isNumeric(values, value) {\n\t if (typeof value === 'number') {\n\t return true;\n\t }\n\t return validations.matchRegexp(values, value, /^[-+]?(\\d*[.])?\\d+$/);\n\t },\n\t isAlpha: function isAlpha(values, value) {\n\t return validations.matchRegexp(values, value, /^[a-zA-Z]+$/);\n\t },\n\t isWords: function isWords(values, value) {\n\t return validations.matchRegexp(values, value, /^[a-zA-Z\\s]+$/);\n\t },\n\t isSpecialWords: function isSpecialWords(values, value) {\n\t return validations.matchRegexp(values, value, /^[a-zA-Z\\s\\u00C0-\\u017F]+$/);\n\t },\n\t isLength: function isLength(values, value, length) {\n\t return !_isExisty(value) || isEmpty(value) || value.length === length;\n\t },\n\t equals: function equals(values, value, eql) {\n\t return !_isExisty(value) || isEmpty(value) || value == eql;\n\t },\n\t equalsField: function equalsField(values, value, field) {\n\t return value == values[field];\n\t },\n\t maxLength: function maxLength(values, value, length) {\n\t return !_isExisty(value) || value.length <= length;\n\t },\n\t minLength: function minLength(values, value, length) {\n\t return !_isExisty(value) || isEmpty(value) || value.length >= length;\n\t }\n\t};\n\t\n\tmodule.exports = validations;\n\n/***/ },\n/* 4 */\n/***/ function(module, exports) {\n\n\tmodule.exports = __WEBPACK_EXTERNAL_MODULE_4__;\n\n/***/ }\n/******/ ])\n});\n;\n\n\n/** WEBPACK FOOTER **\n ** formsy-react.js\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 4695461acb66117350c3\n **/","var React = global.React || require('react');\nvar Formsy = {};\nvar validationRules = require('./validationRules.js');\nvar utils = require('./utils.js');\nvar Mixin = require('./Mixin.js');\nvar options = {};\n\nFormsy.Mixin = Mixin;\n\nFormsy.defaults = function (passedOptions) {\n options = passedOptions;\n};\n\nFormsy.addValidationRule = function (name, func) {\n validationRules[name] = func;\n};\n\nFormsy.Form = React.createClass({\n getInitialState: function () {\n return {\n isValid: true,\n isSubmitting: false,\n canChange: false\n };\n },\n getDefaultProps: function () {\n return {\n onSuccess: function () {},\n onError: function () {},\n onSubmit: function () {},\n onValidSubmit: function () {},\n onInvalidSubmit: function () {},\n onSubmitted: function () {},\n onValid: function () {},\n onInvalid: function () {},\n onChange: function () {},\n validationErrors: null,\n preventExternalInvalidation: false\n };\n },\n\n // Add a map to store the inputs of the form, a model to store\n // the values of the form and register child inputs\n componentWillMount: function () {\n this.inputs = {};\n this.model = {};\n },\n\n componentDidMount: function () {\n this.validateForm();\n },\n\n componentWillUpdate: function () {\n\n // Keep a reference to input keys before form updates,\n // to check if inputs has changed after render\n this.prevInputKeys = Object.keys(this.inputs);\n\n },\n\n componentDidUpdate: function () {\n\n if (this.props.validationErrors) {\n this.setInputValidationErrors(this.props.validationErrors);\n }\n\n var newInputKeys = Object.keys(this.inputs);\n if (utils.arraysDiffer(this.prevInputKeys, newInputKeys)) {\n this.validateForm();\n }\n\n },\n\n // Allow resetting to specified data\n reset: function (data) {\n this.setFormPristine(true);\n this.resetModel(data);\n },\n\n // Update model, submit to url prop and send the model\n submit: function (event) {\n\n event && event.preventDefault();\n\n // Trigger form as not pristine.\n // If any inputs have not been touched yet this will make them dirty\n // so validation becomes visible (if based on isPristine)\n this.setFormPristine(false);\n this.updateModel();\n var model = this.mapModel();\n this.props.onSubmit(model, this.resetModel, this.updateInputsWithError);\n this.state.isValid ? this.props.onValidSubmit(model, this.resetModel, this.updateInputsWithError) : this.props.onInvalidSubmit(model, this.resetModel, this.updateInputsWithError);\n\n },\n\n mapModel: function () {\n if (this.props.mapping) {\n return this.props.mapping(this.model)\n } else {\n return Object.keys(this.model).reduce(function (mappedModel, key) {\n\n var keyArray = key.split('.');\n var base = mappedModel;\n while (keyArray.length) {\n var currentKey = keyArray.shift();\n base = (base[currentKey] = keyArray.length ? base[currentKey] || {} : this.model[key]);\n }\n\n return mappedModel;\n\n }.bind(this), {});\n }\n },\n\n // Goes through all registered components and\n // updates the model values\n updateModel: function () {\n Object.keys(this.inputs).forEach(function (name) {\n var component = this.inputs[name];\n this.model[name] = component.state._value;\n }.bind(this));\n },\n\n // Reset each key in the model to the original / initial / specified value\n resetModel: function (data) {\n Object.keys(this.inputs).forEach(function (name) {\n if (data && data[name]) {\n this.inputs[name].setValue(data[name]);\n } else {\n this.inputs[name].resetValue();\n }\n }.bind(this));\n this.validateForm();\n },\n\n setInputValidationErrors: function (errors) {\n Object.keys(this.inputs).forEach(function (name, index) {\n var component = this.inputs[name];\n var args = [{\n _isValid: !(name in errors),\n _validationError: errors[name]\n }];\n component.setState.apply(component, args);\n }.bind(this));\n },\n\n // Checks if the values have changed from their initial value\n isChanged: function() {\n return !utils.isSame(this.getPristineValues(), this.getCurrentValues());\n },\n\n getPristineValues: function() {\n var inputs = this.inputs;\n return Object.keys(inputs).reduce(function (data, name) {\n var component = inputs[name];\n data[name] = component.props.value;\n return data;\n }, {});\n },\n\n // Go through errors from server and grab the components\n // stored in the inputs map. Change their state to invalid\n // and set the serverError message\n updateInputsWithError: function (errors) {\n Object.keys(errors).forEach(function (name, index) {\n var component = this.inputs[name];\n\n if (!component) {\n throw new Error('You are trying to update an input that does not exist. Verify errors object with input names. ' + JSON.stringify(errors));\n }\n var args = [{\n _isValid: this.props.preventExternalInvalidation || false,\n _externalError: errors[name]\n }];\n component.setState.apply(component, args);\n }.bind(this));\n },\n\n // Traverse the children and children of children to find\n // all inputs by checking the name prop. Maybe do a better\n // check here\n traverseChildrenAndRegisterInputs: function (children) {\n\n if (typeof children !== 'object' || children === null) {\n return children;\n }\n return React.Children.map(children, function (child) {\n\n if (typeof child !== 'object' || child === null) {\n return child;\n }\n\n if (child.props && child.props.name) {\n\n return React.cloneElement(child, {\n _attachToForm: this.attachToForm,\n _detachFromForm: this.detachFromForm,\n _validate: this.validate,\n _isFormDisabled: this.isFormDisabled,\n _isValidValue: function (component, value) {\n return this.runValidation(component, value).isValid;\n }.bind(this)\n }, child.props && child.props.children);\n } else {\n return React.cloneElement(child, {}, this.traverseChildrenAndRegisterInputs(child.props && child.props.children));\n }\n\n }, this);\n\n },\n\n isFormDisabled: function () {\n return this.props.disabled;\n },\n\n getCurrentValues: function () {\n return Object.keys(this.inputs).reduce(function (data, name) {\n var component = this.inputs[name];\n data[name] = component.state._value;\n return data;\n }.bind(this), {});\n },\n\n setFormPristine: function (isPristine) {\n var inputs = this.inputs;\n var inputKeys = Object.keys(inputs);\n\n this.setState({\n _formSubmitted: !isPristine\n })\n\n // Iterate through each component and set it as pristine\n // or \"dirty\".\n inputKeys.forEach(function (name, index) {\n var component = inputs[name];\n component.setState({\n _formSubmitted: !isPristine,\n _isPristine: isPristine\n });\n }.bind(this));\n },\n\n // Use the binded values and the actual input value to\n // validate the input and set its state. Then check the\n // state of the form itself\n validate: function (component) {\n\n // Trigger onChange\n if (this.state.canChange) {\n this.props.onChange(this.getCurrentValues(), this.isChanged());\n }\n\n var validation = this.runValidation(component);\n // Run through the validations, split them up and call\n // the validator IF there is a value or it is required\n component.setState({\n _isValid: validation.isValid,\n _isRequired: validation.isRequired,\n _validationError: validation.error,\n _externalError: null\n }, this.validateForm);\n\n },\n\n // Checks validation on current value or a passed value\n runValidation: function (component, value) {\n\n var currentValues = this.getCurrentValues();\n var validationErrors = component.props.validationErrors;\n var validationError = component.props.validationError;\n value = arguments.length === 2 ? value : component.state._value;\n\n var validationResults = this.runRules(value, currentValues, component._validations);\n var requiredResults = this.runRules(value, currentValues, component._requiredValidations);\n\n // the component defines an explicit validate function\n if (typeof component.validate === \"function\") {\n validationResults.failed = component.validate() ? [] : ['failed'];\n }\n\n var isRequired = Object.keys(component._requiredValidations).length ? !!requiredResults.success.length : false;\n var isValid = !validationResults.failed.length && !(this.props.validationErrors && this.props.validationErrors[component.props.name]);\n\n return {\n isRequired: isRequired,\n isValid: isRequired ? false : isValid,\n error: (function () {\n\n if (isValid && !isRequired) {\n return '';\n }\n\n if (validationResults.errors.length) {\n return validationResults.errors[0];\n }\n\n if (this.props.validationErrors && this.props.validationErrors[component.props.name]) {\n return this.props.validationErrors[component.props.name];\n }\n\n if (isRequired) {\n return validationErrors[requiredResults.success[0]] || null;\n }\n\n if (!isValid) {\n return validationErrors[validationResults.failed[0]] || validationError;\n }\n\n }.call(this))\n };\n\n },\n\n runRules: function (value, currentValues, validations) {\n\n var results = {\n errors: [],\n failed: [],\n success: []\n };\n if (Object.keys(validations).length) {\n Object.keys(validations).forEach(function (validationMethod) {\n\n if (validationRules[validationMethod] && typeof validations[validationMethod] === 'function') {\n throw new Error('Formsy does not allow you to override default validations: ' + validationMethod);\n }\n\n if (!validationRules[validationMethod] && typeof validations[validationMethod] !== 'function') {\n throw new Error('Formsy does not have the validation rule: ' + validationMethod);\n }\n\n if (typeof validations[validationMethod] === 'function') {\n var validation = validations[validationMethod](currentValues, value);\n if (typeof validation === 'string') {\n results.errors.push(validation);\n results.failed.push(validationMethod);\n } else if (!validation) {\n results.failed.push(validationMethod);\n }\n return;\n\n } else if (typeof validations[validationMethod] !== 'function') {\n var validation = validationRules[validationMethod](currentValues, value, validations[validationMethod]);\n if (typeof validation === 'string') {\n results.errors.push(validation);\n results.failed.push(validationMethod);\n } else if (!validation) {\n results.failed.push(validationMethod);\n } else {\n results.success.push(validationMethod);\n }\n return;\n\n }\n\n return results.success.push(validationMethod);\n\n });\n }\n\n return results;\n\n },\n\n // Validate the form by going through all child input components\n // and check their state\n validateForm: function () {\n var allIsValid = true;\n var inputs = this.inputs;\n var inputKeys = Object.keys(inputs);\n\n // We need a callback as we are validating all inputs again. This will\n // run when the last component has set its state\n var onValidationComplete = function () {\n inputKeys.forEach(function (name) {\n if (!inputs[name].state._isValid) {\n allIsValid = false;\n }\n }.bind(this));\n\n this.setState({\n isValid: allIsValid\n });\n\n if (allIsValid) {\n this.props.onValid();\n } else {\n this.props.onInvalid();\n }\n\n // Tell the form that it can start to trigger change events\n this.setState({\n canChange: true\n });\n\n }.bind(this);\n\n // Run validation again in case affected by other inputs. The\n // last component validated will run the onValidationComplete callback\n inputKeys.forEach(function (name, index) {\n var component = inputs[name];\n var validation = this.runValidation(component);\n if (validation.isValid && component.state._externalError) {\n validation.isValid = false;\n }\n component.setState({\n _isValid: validation.isValid,\n _isRequired: validation.isRequired,\n _validationError: validation.error,\n _externalError: !validation.isValid && component.state._externalError ? component.state._externalError : null\n }, index === inputKeys.length - 1 ? onValidationComplete : null);\n }.bind(this));\n\n // If there are no inputs, set state where form is ready to trigger\n // change event. New inputs might be added later\n if (!inputKeys.length && this.isMounted()) {\n this.setState({\n canChange: true\n });\n }\n },\n\n // Method put on each input component to register\n // itself to the form\n attachToForm: function (component) {\n this.inputs[component.props.name] = component;\n this.model[component.props.name] = component.state._value;\n this.validate(component);\n },\n\n // Method put on each input component to unregister\n // itself from the form\n detachFromForm: function (component) {\n delete this.inputs[component.props.name];\n delete this.model[component.props.name];\n },\n render: function () {\n\n return React.DOM.form({\n onSubmit: this.submit,\n className: this.props.className,\n autoComplete: this.props.autoComplete\n },\n this.traverseChildrenAndRegisterInputs(this.props.children)\n );\n\n }\n});\n\nif (!global.exports && !global.module && (!global.define || !global.define.amd)) {\n global.Formsy = Formsy;\n}\n\nmodule.exports = Formsy;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/main.js\n **/","module.exports = {\n arraysDiffer: function (a, b) {\n var isDifferent = false;\n if (a.length !== b.length) {\n isDifferent = true;\n } else {\n a.forEach(function (item, index) {\n if (!this.isSame(item, b[index])) {\n isDifferent = true;\n }\n }, this);\n }\n return isDifferent;\n },\n\n objectsDiffer: function (a, b) {\n var isDifferent = false;\n if (Object.keys(a).length !== Object.keys(b).length) {\n isDifferent = true;\n } else {\n Object.keys(a).forEach(function (key) {\n if (!this.isSame(a[key], b[key])) {\n isDifferent = true;\n }\n }, this);\n }\n return isDifferent;\n },\n\n isSame: function (a, b) {\n if (typeof a !== typeof b) {\n return false;\n } else if (Array.isArray(a)) {\n return !this.arraysDiffer(a, b);\n } else if (typeof a === 'object' && a !== null && b !== null) {\n return !this.objectsDiffer(a, b);\n }\n\n return a === b;\n }\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/utils.js\n **/","var utils = require('./utils.js');\n\nvar convertValidationsToObject = function (validations) {\n\n if (typeof validations === 'string') {\n\n return validations.split(/\\,(?![^{\\[]*[}\\]])/g).reduce(function (validations, validation) {\n var args = validation.split(':');\n var validateMethod = args.shift();\n\n args = args.map(function (arg) {\n try {\n return JSON.parse(arg);\n } catch (e) {\n return arg; // It is a string if it can not parse it\n }\n });\n\n if (args.length > 1) {\n throw new Error('Formsy does not support multiple args on string validations. Use object format of validations instead.');\n }\n\n validations[validateMethod] = args.length ? args[0] : true;\n return validations;\n }, {});\n\n }\n\n return validations || {};\n};\n\nmodule.exports = {\n getInitialState: function () {\n return {\n _value: this.props.value,\n _isRequired: false,\n _isValid: true,\n _isPristine: true,\n _pristineValue: this.props.value,\n _validationError: '',\n _externalError: null,\n _formSubmitted: false\n };\n },\n getDefaultProps: function () {\n return {\n validationError: '',\n validationErrors: {}\n };\n },\n\n componentWillMount: function () {\n var configure = function () {\n this.setValidations(this.props.validations, this.props.required);\n this.props._attachToForm(this);\n }.bind(this);\n\n if (!this.props.name) {\n throw new Error('Form Input requires a name property when used');\n }\n\n if (!this.props._attachToForm) {\n return setTimeout(function () {\n if (!this.isMounted()) return;\n if (!this.props._attachToForm) {\n throw new Error('Form Mixin requires component to be nested in a Form');\n }\n configure();\n }.bind(this), 0);\n }\n configure();\n },\n\n // We have to make the validate method is kept when new props are added\n componentWillReceiveProps: function (nextProps) {\n this.setValidations(nextProps.validations, nextProps.required);\n },\n\n componentDidUpdate: function (prevProps) {\n\n // If the value passed has changed, set it. If value is not passed it will\n // internally update, and this will never run\n if (!utils.isSame(this.props.value, prevProps.value)) {\n this.setValue(this.props.value);\n }\n },\n\n // Detach it when component unmounts\n componentWillUnmount: function () {\n this.props._detachFromForm(this);\n },\n\n setValidations: function (validations, required) {\n\n // Add validations to the store itself as the props object can not be modified\n this._validations = convertValidationsToObject(validations) || {};\n this._requiredValidations = required === true ? {isDefaultRequiredValue: true} : convertValidationsToObject(required);\n\n },\n\n // We validate after the value has been set\n setValue: function (value) {\n this.setState({\n _value: value,\n _isPristine: false\n }, function () {\n this.props._validate(this);\n }.bind(this));\n },\n resetValue: function () {\n this.setState({\n _value: this.state._pristineValue,\n _isPristine: true\n }, function () {\n this.props._validate(this);\n });\n },\n getValue: function () {\n return this.state._value;\n },\n hasValue: function () {\n return this.state._value !== '';\n },\n getErrorMessage: function () {\n return !this.isValid() || this.showRequired() ? (this.state._externalError || this.state._validationError) : null;\n },\n isFormDisabled: function () {\n return this.props._isFormDisabled();\n },\n isValid: function () {\n return this.state._isValid;\n },\n isPristine: function () {\n return this.state._isPristine;\n },\n isFormSubmitted: function () {\n return this.state._formSubmitted;\n },\n isRequired: function () {\n return !!this.props.required;\n },\n showRequired: function () {\n return this.state._isRequired;\n },\n showError: function () {\n return !this.showRequired() && !this.isValid();\n },\n isValidValue: function (value) {\n return this.props._isValidValue.call(null, this, value);\n }\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/Mixin.js\n **/","var isExisty = function (value) {\n return value !== null && value !== undefined;\n};\n\nvar isEmpty = function (value) {\n return value === '';\n};\n\nvar validations = {\n isDefaultRequiredValue: function (values, value) {\n return value === undefined || value === '';\n },\n isExisty: function (values, value) {\n return isExisty(value);\n },\n matchRegexp: function (values, value, regexp) {\n return !isExisty(value) || isEmpty(value) || regexp.test(value);\n },\n isUndefined: function (values, value) {\n return value === undefined;\n },\n isEmptyString: function (values, value) {\n return isEmpty(value);\n },\n isEmail: function (values, value) {\n return validations.matchRegexp(values, value, /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i);\n },\n isUrl: function (values, value) {\n return validations.matchRegexp(values, value, /^(https?|s?ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i);\n },\n isTrue: function (values, value) {\n return value === true;\n },\n isFalse: function (values, value) {\n return value === false;\n },\n isNumeric: function (values, value) {\n if (typeof value === 'number') {\n return true;\n }\n return validations.matchRegexp(values, value, /^[-+]?(\\d*[.])?\\d+$/);\n },\n isAlpha: function (values, value) {\n return validations.matchRegexp(values, value, /^[a-zA-Z]+$/);\n },\n isWords: function (values, value) {\n return validations.matchRegexp(values, value, /^[a-zA-Z\\s]+$/);\n },\n isSpecialWords: function (values, value) {\n return validations.matchRegexp(values, value, /^[a-zA-Z\\s\\u00C0-\\u017F]+$/);\n },\n isLength: function (values, value, length) {\n return !isExisty(value) || isEmpty(value) || value.length === length;\n },\n equals: function (values, value, eql) {\n return !isExisty(value) || isEmpty(value) || value == eql;\n },\n equalsField: function (values, value, field) {\n return value == values[field];\n },\n maxLength: function (values, value, length) {\n return !isExisty(value) || value.length <= length;\n },\n minLength: function (values, value, length) {\n return !isExisty(value) || isEmpty(value) || value.length >= length;\n }\n};\n\nmodule.exports = validations;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/validationRules.js\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_4__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external \"react\"\n ** module id = 4\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///formsy-react.js","webpack:///webpack/bootstrap 24399d79821c570f3424","webpack:///./src/main.js","webpack:///external \"react\"","webpack:///./src/Mixin.js","webpack:///./src/utils.js","webpack:///./src/Decorator.js","webpack:///./src/HOC.js","webpack:///./src/validationRules.js","webpack:///./~/form-data-to-object/index.js"],"names":["root","factory","exports","module","require","define","amd","this","__WEBPACK_EXTERNAL_MODULE_1__","modules","__webpack_require__","moduleId","installedModules","id","loaded","call","m","c","p","global","_extends","Object","assign","target","i","arguments","length","source","key","prototype","hasOwnProperty","React","Formsy","validationRules","formDataToObject","utils","Mixin","HOC","Decorator","options","defaults","passedOptions","addValidationRule","name","func","Form","createClass","displayName","getInitialState","isValid","isSubmitting","canChange","getDefaultProps","onSuccess","onError","onSubmit","onValidSubmit","onInvalidSubmit","onSubmitted","onValid","onInvalid","onChange","validationErrors","preventExternalInvalidation","childContextTypes","formsy","PropTypes","object","getChildContext","attachToForm","detachFromForm","validate","isFormDisabled","isValidValue","component","value","runValidation","bind","componentWillMount","inputs","model","componentDidMount","validateForm","componentWillUpdate","prevInputKeys","keys","componentDidUpdate","props","setInputValidationErrors","newInputKeys","arraysDiffer","reset","data","setFormPristine","resetModel","submit","event","preventDefault","updateModel","mapModel","updateInputsWithError","state","mapping","reduce","mappedModel","keyArray","split","base","currentKey","shift","forEach","_value","setValue","resetValue","errors","index","args","_isValid","_validationError","setState","apply","isChanged","isSame","getPristineValues","getCurrentValues","Error","JSON","stringify","_externalError","traverseChildrenAndRegisterInputs","children","Children","map","child","cloneElement","_attachToForm","_detachFromForm","_validate","_isFormDisabled","_isValidValue","disabled","isPristine","inputKeys","_formSubmitted","_isPristine","validation","_isRequired","isRequired","error","currentValues","validationError","validationResults","runRules","_validations","requiredResults","_requiredValidations","failed","success","filter","x","pos","arr","indexOf","validations","results","validationMethod","push","allIsValid","onValidationComplete","every","isMounted","render","createElement","convertValidationsToObject","validateMethod","arg","parse","e","_pristineValue","contextTypes","configure","setValidations","required","context","componentWillReceiveProps","nextProps","prevProps","componentWillUnmount","isDefaultRequiredValue","getValue","hasValue","getErrorMessage","messages","getErrorMessages","showRequired","isFormSubmitted","showError","a","b","isDifferent","item","objectsDiffer","Array","isArray","Component","mixins","_isExisty","undefined","isEmpty","values","isExisty","matchRegexp","regexp","test","isUndefined","isEmptyString","isEmail","isUrl","isTrue","isFalse","isNumeric","isAlpha","isWords","isSpecialWords","isLength","equals","eql","equalsField","field","maxLength","minLength","output","parentKey","match","paths","concat","replace","currentPath","pathKey","isNaN"],"mappings":"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","file":"formsy-react.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Formsy\"] = factory(require(\"react\"));\n\telse\n\t\troot[\"Formsy\"] = factory(root[\"react\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Formsy\"] = factory(require(\"react\"));\n\telse\n\t\troot[\"Formsy\"] = factory(root[\"react\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global) {'use strict';\n\t\n\tvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\t\n\tvar React = global.React || __webpack_require__(1);\n\tvar Formsy = {};\n\tvar validationRules = __webpack_require__(6);\n\tvar formDataToObject = __webpack_require__(7);\n\tvar utils = __webpack_require__(3);\n\tvar Mixin = __webpack_require__(2);\n\tvar HOC = __webpack_require__(5);\n\tvar Decorator = __webpack_require__(4);\n\tvar options = {};\n\t\n\tFormsy.Mixin = Mixin;\n\tFormsy.HOC = HOC;\n\tFormsy.Decorator = Decorator;\n\t\n\tFormsy.defaults = function (passedOptions) {\n\t options = passedOptions;\n\t};\n\t\n\tFormsy.addValidationRule = function (name, func) {\n\t validationRules[name] = func;\n\t};\n\t\n\tFormsy.Form = React.createClass({\n\t displayName: 'Form',\n\t\n\t getInitialState: function getInitialState() {\n\t return {\n\t isValid: true,\n\t isSubmitting: false,\n\t canChange: false\n\t };\n\t },\n\t getDefaultProps: function getDefaultProps() {\n\t return {\n\t onSuccess: function onSuccess() {},\n\t onError: function onError() {},\n\t onSubmit: function onSubmit() {},\n\t onValidSubmit: function onValidSubmit() {},\n\t onInvalidSubmit: function onInvalidSubmit() {},\n\t onSubmitted: function onSubmitted() {},\n\t onValid: function onValid() {},\n\t onInvalid: function onInvalid() {},\n\t onChange: function onChange() {},\n\t validationErrors: null,\n\t preventExternalInvalidation: false\n\t };\n\t },\n\t\n\t childContextTypes: {\n\t formsy: React.PropTypes.object\n\t },\n\t getChildContext: function getChildContext() {\n\t return {\n\t formsy: {\n\t attachToForm: this.attachToForm,\n\t detachFromForm: this.detachFromForm,\n\t validate: this.validate,\n\t isFormDisabled: this.isFormDisabled,\n\t isValidValue: (function (component, value) {\n\t return this.runValidation(component, value).isValid;\n\t }).bind(this)\n\t }\n\t };\n\t },\n\t\n\t // Add a map to store the inputs of the form, a model to store\n\t // the values of the form and register child inputs\n\t componentWillMount: function componentWillMount() {\n\t this.inputs = {};\n\t this.model = {};\n\t },\n\t\n\t componentDidMount: function componentDidMount() {\n\t this.validateForm();\n\t },\n\t\n\t componentWillUpdate: function componentWillUpdate() {\n\t\n\t // Keep a reference to input keys before form updates,\n\t // to check if inputs has changed after render\n\t this.prevInputKeys = Object.keys(this.inputs);\n\t },\n\t\n\t componentDidUpdate: function componentDidUpdate() {\n\t\n\t if (this.props.validationErrors) {\n\t this.setInputValidationErrors(this.props.validationErrors);\n\t }\n\t\n\t var newInputKeys = Object.keys(this.inputs);\n\t if (utils.arraysDiffer(this.prevInputKeys, newInputKeys)) {\n\t this.validateForm();\n\t }\n\t },\n\t\n\t // Allow resetting to specified data\n\t reset: function reset(data) {\n\t this.setFormPristine(true);\n\t this.resetModel(data);\n\t },\n\t\n\t // Update model, submit to url prop and send the model\n\t submit: function submit(event) {\n\t\n\t event && event.preventDefault();\n\t\n\t // Trigger form as not pristine.\n\t // If any inputs have not been touched yet this will make them dirty\n\t // so validation becomes visible (if based on isPristine)\n\t this.setFormPristine(false);\n\t this.updateModel();\n\t var model = this.mapModel();\n\t this.props.onSubmit(model, this.resetModel, this.updateInputsWithError);\n\t this.state.isValid ? this.props.onValidSubmit(model, this.resetModel, this.updateInputsWithError) : this.props.onInvalidSubmit(model, this.resetModel, this.updateInputsWithError);\n\t },\n\t\n\t mapModel: function mapModel() {\n\t if (this.props.mapping) {\n\t return this.props.mapping(this.model);\n\t } else {\n\t return formDataToObject(Object.keys(this.model).reduce((function (mappedModel, key) {\n\t\n\t var keyArray = key.split('.');\n\t var base = mappedModel;\n\t while (keyArray.length) {\n\t var currentKey = keyArray.shift();\n\t base = base[currentKey] = keyArray.length ? base[currentKey] || {} : this.model[key];\n\t }\n\t\n\t return mappedModel;\n\t }).bind(this), {}));\n\t }\n\t },\n\t\n\t // Goes through all registered components and\n\t // updates the model values\n\t updateModel: function updateModel() {\n\t Object.keys(this.inputs).forEach((function (name) {\n\t var component = this.inputs[name];\n\t this.model[name] = component.state._value;\n\t }).bind(this));\n\t },\n\t\n\t // Reset each key in the model to the original / initial / specified value\n\t resetModel: function resetModel(data) {\n\t Object.keys(this.inputs).forEach((function (name) {\n\t if (data && data[name]) {\n\t this.inputs[name].setValue(data[name]);\n\t } else {\n\t this.inputs[name].resetValue();\n\t }\n\t }).bind(this));\n\t this.validateForm();\n\t },\n\t\n\t setInputValidationErrors: function setInputValidationErrors(errors) {\n\t Object.keys(this.inputs).forEach((function (name, index) {\n\t var component = this.inputs[name];\n\t var args = [{\n\t _isValid: !(name in errors),\n\t _validationError: typeof errors[name] === 'string' ? [errors[name]] : errors[name]\n\t }];\n\t component.setState.apply(component, args);\n\t }).bind(this));\n\t },\n\t\n\t // Checks if the values have changed from their initial value\n\t isChanged: function isChanged() {\n\t return !utils.isSame(this.getPristineValues(), this.getCurrentValues());\n\t },\n\t\n\t getPristineValues: function getPristineValues() {\n\t var inputs = this.inputs;\n\t return Object.keys(inputs).reduce(function (data, name) {\n\t var component = inputs[name];\n\t data[name] = component.props.value;\n\t return data;\n\t }, {});\n\t },\n\t\n\t // Go through errors from server and grab the components\n\t // stored in the inputs map. Change their state to invalid\n\t // and set the serverError message\n\t updateInputsWithError: function updateInputsWithError(errors) {\n\t Object.keys(errors).forEach((function (name, index) {\n\t var component = this.inputs[name];\n\t\n\t if (!component) {\n\t throw new Error('You are trying to update an input that does not exist. Verify errors object with input names. ' + JSON.stringify(errors));\n\t }\n\t var args = [{\n\t _isValid: this.props.preventExternalInvalidation || false,\n\t _externalError: typeof errors[name] === 'string' ? [errors[name]] : errors[name]\n\t }];\n\t component.setState.apply(component, args);\n\t }).bind(this));\n\t },\n\t\n\t // Traverse the children and children of children to find\n\t // all inputs by checking the name prop. Maybe do a better\n\t // check here\n\t traverseChildrenAndRegisterInputs: function traverseChildrenAndRegisterInputs(children) {\n\t\n\t if (typeof children !== 'object' || children === null) {\n\t return children;\n\t }\n\t return React.Children.map(children, function (child) {\n\t\n\t if (typeof child !== 'object' || child === null) {\n\t return child;\n\t }\n\t\n\t if (child.props && child.props.name) {\n\t\n\t return React.cloneElement(child, {\n\t _attachToForm: this.attachToForm,\n\t _detachFromForm: this.detachFromForm,\n\t _validate: this.validate,\n\t _isFormDisabled: this.isFormDisabled,\n\t _isValidValue: (function (component, value) {\n\t return this.runValidation(component, value).isValid;\n\t }).bind(this)\n\t }, child.props && child.props.children);\n\t } else {\n\t return React.cloneElement(child, {}, this.traverseChildrenAndRegisterInputs(child.props && child.props.children));\n\t }\n\t }, this);\n\t },\n\t\n\t isFormDisabled: function isFormDisabled() {\n\t return this.props.disabled;\n\t },\n\t\n\t getCurrentValues: function getCurrentValues() {\n\t return Object.keys(this.inputs).reduce((function (data, name) {\n\t var component = this.inputs[name];\n\t data[name] = component.state._value;\n\t return data;\n\t }).bind(this), {});\n\t },\n\t\n\t setFormPristine: function setFormPristine(isPristine) {\n\t var inputs = this.inputs;\n\t var inputKeys = Object.keys(inputs);\n\t\n\t this.setState({\n\t _formSubmitted: !isPristine\n\t });\n\t\n\t // Iterate through each component and set it as pristine\n\t // or \"dirty\".\n\t inputKeys.forEach((function (name, index) {\n\t var component = inputs[name];\n\t component.setState({\n\t _formSubmitted: !isPristine,\n\t _isPristine: isPristine\n\t });\n\t }).bind(this));\n\t },\n\t\n\t // Use the binded values and the actual input value to\n\t // validate the input and set its state. Then check the\n\t // state of the form itself\n\t validate: function validate(component) {\n\t\n\t // Trigger onChange\n\t if (this.state.canChange) {\n\t this.props.onChange(this.getCurrentValues(), this.isChanged());\n\t }\n\t\n\t var validation = this.runValidation(component);\n\t // Run through the validations, split them up and call\n\t // the validator IF there is a value or it is required\n\t component.setState({\n\t _isValid: validation.isValid,\n\t _isRequired: validation.isRequired,\n\t _validationError: validation.error,\n\t _externalError: null\n\t }, this.validateForm);\n\t },\n\t\n\t // Checks validation on current value or a passed value\n\t runValidation: function runValidation(component, value) {\n\t\n\t var currentValues = this.getCurrentValues();\n\t var validationErrors = component.props.validationErrors;\n\t var validationError = component.props.validationError;\n\t value = arguments.length === 2 ? value : component.state._value;\n\t\n\t var validationResults = this.runRules(value, currentValues, component._validations);\n\t var requiredResults = this.runRules(value, currentValues, component._requiredValidations);\n\t\n\t // the component defines an explicit validate function\n\t if (typeof component.validate === \"function\") {\n\t validationResults.failed = component.validate() ? [] : ['failed'];\n\t }\n\t\n\t var isRequired = Object.keys(component._requiredValidations).length ? !!requiredResults.success.length : false;\n\t var isValid = !validationResults.failed.length && !(this.props.validationErrors && this.props.validationErrors[component.props.name]);\n\t\n\t return {\n\t isRequired: isRequired,\n\t isValid: isRequired ? false : isValid,\n\t error: (function () {\n\t\n\t if (isValid && !isRequired) {\n\t return [];\n\t }\n\t\n\t if (validationResults.errors.length) {\n\t return validationResults.errors;\n\t }\n\t\n\t if (this.props.validationErrors && this.props.validationErrors[component.props.name]) {\n\t return typeof this.props.validationErrors[component.props.name] === 'string' ? [this.props.validationErrors[component.props.name]] : this.props.validationErrors[component.props.name];\n\t }\n\t\n\t if (isRequired) {\n\t var error = validationErrors[requiredResults.success[0]];\n\t return error ? [error] : null;\n\t }\n\t\n\t if (validationResults.failed.length) {\n\t return validationResults.failed.map(function (failed) {\n\t return validationErrors[failed] ? validationErrors[failed] : validationError;\n\t }).filter(function (x, pos, arr) {\n\t // Remove duplicates\n\t return arr.indexOf(x) === pos;\n\t });\n\t }\n\t }).call(this)\n\t };\n\t },\n\t\n\t runRules: function runRules(value, currentValues, validations) {\n\t\n\t var results = {\n\t errors: [],\n\t failed: [],\n\t success: []\n\t };\n\t if (Object.keys(validations).length) {\n\t Object.keys(validations).forEach(function (validationMethod) {\n\t\n\t if (validationRules[validationMethod] && typeof validations[validationMethod] === 'function') {\n\t throw new Error('Formsy does not allow you to override default validations: ' + validationMethod);\n\t }\n\t\n\t if (!validationRules[validationMethod] && typeof validations[validationMethod] !== 'function') {\n\t throw new Error('Formsy does not have the validation rule: ' + validationMethod);\n\t }\n\t\n\t if (typeof validations[validationMethod] === 'function') {\n\t var validation = validations[validationMethod](currentValues, value);\n\t if (typeof validation === 'string') {\n\t results.errors.push(validation);\n\t results.failed.push(validationMethod);\n\t } else if (!validation) {\n\t results.failed.push(validationMethod);\n\t }\n\t return;\n\t } else if (typeof validations[validationMethod] !== 'function') {\n\t var validation = validationRules[validationMethod](currentValues, value, validations[validationMethod]);\n\t if (typeof validation === 'string') {\n\t results.errors.push(validation);\n\t results.failed.push(validationMethod);\n\t } else if (!validation) {\n\t results.failed.push(validationMethod);\n\t } else {\n\t results.success.push(validationMethod);\n\t }\n\t return;\n\t }\n\t\n\t return results.success.push(validationMethod);\n\t });\n\t }\n\t\n\t return results;\n\t },\n\t\n\t // Validate the form by going through all child input components\n\t // and check their state\n\t validateForm: function validateForm() {\n\t var allIsValid;\n\t var inputs = this.inputs;\n\t var inputKeys = Object.keys(inputs);\n\t\n\t // We need a callback as we are validating all inputs again. This will\n\t // run when the last component has set its state\n\t var onValidationComplete = (function () {\n\t allIsValid = inputKeys.every((function (name) {\n\t return inputs[name].state._isValid;\n\t }).bind(this));\n\t\n\t this.setState({\n\t isValid: allIsValid\n\t });\n\t\n\t if (allIsValid) {\n\t this.props.onValid();\n\t } else {\n\t this.props.onInvalid();\n\t }\n\t\n\t // Tell the form that it can start to trigger change events\n\t this.setState({\n\t canChange: true\n\t });\n\t }).bind(this);\n\t\n\t // Run validation again in case affected by other inputs. The\n\t // last component validated will run the onValidationComplete callback\n\t inputKeys.forEach((function (name, index) {\n\t var component = inputs[name];\n\t var validation = this.runValidation(component);\n\t if (validation.isValid && component.state._externalError) {\n\t validation.isValid = false;\n\t }\n\t component.setState({\n\t _isValid: validation.isValid,\n\t _isRequired: validation.isRequired,\n\t _validationError: validation.error,\n\t _externalError: !validation.isValid && component.state._externalError ? component.state._externalError : null\n\t }, index === inputKeys.length - 1 ? onValidationComplete : null);\n\t }).bind(this));\n\t\n\t // If there are no inputs, set state where form is ready to trigger\n\t // change event. New inputs might be added later\n\t if (!inputKeys.length && this.isMounted()) {\n\t this.setState({\n\t canChange: true\n\t });\n\t }\n\t },\n\t\n\t // Method put on each input component to register\n\t // itself to the form\n\t attachToForm: function attachToForm(component) {\n\t this.inputs[component.props.name] = component;\n\t this.model[component.props.name] = component.state._value;\n\t this.validate(component);\n\t },\n\t\n\t // Method put on each input component to unregister\n\t // itself from the form\n\t detachFromForm: function detachFromForm(component) {\n\t delete this.inputs[component.props.name];\n\t delete this.model[component.props.name];\n\t },\n\t render: function render() {\n\t\n\t return React.createElement(\n\t 'form',\n\t _extends({}, this.props, { onSubmit: this.submit }),\n\t this.props.children\n\t );\n\t }\n\t});\n\t\n\tif (!global.exports && !global.module && (!global.define || !global.define.amd)) {\n\t global.Formsy = Formsy;\n\t}\n\t\n\tmodule.exports = Formsy;\n\t/*this.traverseChildrenAndRegisterInputs(this.props.children)*/\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n\n/***/ },\n/* 1 */\n/***/ function(module, exports) {\n\n\tmodule.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global) {'use strict';\n\t\n\tvar utils = __webpack_require__(3);\n\tvar React = global.React || __webpack_require__(1);\n\t\n\tvar convertValidationsToObject = function convertValidationsToObject(validations) {\n\t\n\t if (typeof validations === 'string') {\n\t\n\t return validations.split(/\\,(?![^{\\[]*[}\\]])/g).reduce(function (validations, validation) {\n\t var args = validation.split(':');\n\t var validateMethod = args.shift();\n\t\n\t args = args.map(function (arg) {\n\t try {\n\t return JSON.parse(arg);\n\t } catch (e) {\n\t return arg; // It is a string if it can not parse it\n\t }\n\t });\n\t\n\t if (args.length > 1) {\n\t throw new Error('Formsy does not support multiple args on string validations. Use object format of validations instead.');\n\t }\n\t\n\t validations[validateMethod] = args.length ? args[0] : true;\n\t return validations;\n\t }, {});\n\t }\n\t\n\t return validations || {};\n\t};\n\t\n\tmodule.exports = {\n\t getInitialState: function getInitialState() {\n\t return {\n\t _value: this.props.value,\n\t _isRequired: false,\n\t _isValid: true,\n\t _isPristine: true,\n\t _pristineValue: this.props.value,\n\t _validationError: [],\n\t _externalError: null,\n\t _formSubmitted: false\n\t };\n\t },\n\t contextTypes: {\n\t formsy: React.PropTypes.object // What about required?\n\t },\n\t getDefaultProps: function getDefaultProps() {\n\t return {\n\t validationError: '',\n\t validationErrors: {}\n\t };\n\t },\n\t\n\t componentWillMount: function componentWillMount() {\n\t var configure = (function () {\n\t this.setValidations(this.props.validations, this.props.required);\n\t\n\t // Pass a function instead?\n\t this.context.formsy.attachToForm(this);\n\t //this.props._attachToForm(this);\n\t }).bind(this);\n\t\n\t if (!this.props.name) {\n\t throw new Error('Form Input requires a name property when used');\n\t }\n\t\n\t /*\n\t if (!this.props._attachToForm) {\n\t return setTimeout(function () {\n\t if (!this.isMounted()) return;\n\t if (!this.props._attachToForm) {\n\t throw new Error('Form Mixin requires component to be nested in a Form');\n\t }\n\t configure();\n\t }.bind(this), 0);\n\t }\n\t */\n\t configure();\n\t },\n\t\n\t // We have to make the validate method is kept when new props are added\n\t componentWillReceiveProps: function componentWillReceiveProps(nextProps) {\n\t this.setValidations(nextProps.validations, nextProps.required);\n\t },\n\t\n\t componentDidUpdate: function componentDidUpdate(prevProps) {\n\t\n\t // If the value passed has changed, set it. If value is not passed it will\n\t // internally update, and this will never run\n\t if (!utils.isSame(this.props.value, prevProps.value)) {\n\t this.setValue(this.props.value);\n\t }\n\t\n\t // If validations or required is changed, run a new validation\n\t if (!utils.isSame(this.props.validations, prevProps.validations) || !utils.isSame(this.props.required, prevProps.required)) {\n\t this.context.formsy.validate(this);\n\t }\n\t },\n\t\n\t // Detach it when component unmounts\n\t componentWillUnmount: function componentWillUnmount() {\n\t this.context.formsy.detachFromForm(this);\n\t //this.props._detachFromForm(this);\n\t },\n\t\n\t setValidations: function setValidations(validations, required) {\n\t\n\t // Add validations to the store itself as the props object can not be modified\n\t this._validations = convertValidationsToObject(validations) || {};\n\t this._requiredValidations = required === true ? { isDefaultRequiredValue: true } : convertValidationsToObject(required);\n\t },\n\t\n\t // We validate after the value has been set\n\t setValue: function setValue(value) {\n\t this.setState({\n\t _value: value,\n\t _isPristine: false\n\t }, (function () {\n\t this.context.formsy.validate(this);\n\t //this.props._validate(this);\n\t }).bind(this));\n\t },\n\t resetValue: function resetValue() {\n\t this.setState({\n\t _value: this.state._pristineValue,\n\t _isPristine: true\n\t }, function () {\n\t this.context.formsy.validate(this);\n\t //this.props._validate(this);\n\t });\n\t },\n\t getValue: function getValue() {\n\t return this.state._value;\n\t },\n\t hasValue: function hasValue() {\n\t return this.state._value !== '';\n\t },\n\t getErrorMessage: function getErrorMessage() {\n\t var messages = this.getErrorMessages();\n\t return messages.length ? messages[0] : null;\n\t },\n\t getErrorMessages: function getErrorMessages() {\n\t return !this.isValid() || this.showRequired() ? this.state._externalError || this.state._validationError || [] : [];\n\t },\n\t isFormDisabled: function isFormDisabled() {\n\t return this.context.formsy.isFormDisabled();\n\t //return this.props._isFormDisabled();\n\t },\n\t isValid: function isValid() {\n\t return this.state._isValid;\n\t },\n\t isPristine: function isPristine() {\n\t return this.state._isPristine;\n\t },\n\t isFormSubmitted: function isFormSubmitted() {\n\t return this.state._formSubmitted;\n\t },\n\t isRequired: function isRequired() {\n\t return !!this.props.required;\n\t },\n\t showRequired: function showRequired() {\n\t return this.state._isRequired;\n\t },\n\t showError: function showError() {\n\t return !this.showRequired() && !this.isValid();\n\t },\n\t isValidValue: function isValidValue(value) {\n\t return this.context.formsy.isValidValue.call(null, this, value);\n\t //return this.props._isValidValue.call(null, this, value);\n\t }\n\t};\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n\n/***/ },\n/* 3 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = {\n\t arraysDiffer: function arraysDiffer(a, b) {\n\t var isDifferent = false;\n\t if (a.length !== b.length) {\n\t isDifferent = true;\n\t } else {\n\t a.forEach(function (item, index) {\n\t if (!this.isSame(item, b[index])) {\n\t isDifferent = true;\n\t }\n\t }, this);\n\t }\n\t return isDifferent;\n\t },\n\t\n\t objectsDiffer: function objectsDiffer(a, b) {\n\t var isDifferent = false;\n\t if (Object.keys(a).length !== Object.keys(b).length) {\n\t isDifferent = true;\n\t } else {\n\t Object.keys(a).forEach(function (key) {\n\t if (!this.isSame(a[key], b[key])) {\n\t isDifferent = true;\n\t }\n\t }, this);\n\t }\n\t return isDifferent;\n\t },\n\t\n\t isSame: function isSame(a, b) {\n\t if (typeof a !== typeof b) {\n\t return false;\n\t } else if (Array.isArray(a)) {\n\t return !this.arraysDiffer(a, b);\n\t } else if (typeof a === 'object' && a !== null && b !== null) {\n\t return !this.objectsDiffer(a, b);\n\t }\n\t\n\t return a === b;\n\t }\n\t};\n\n/***/ },\n/* 4 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global) {'use strict';\n\t\n\tvar React = global.React || __webpack_require__(1);\n\tvar Mixin = __webpack_require__(2);\n\tmodule.exports = function () {\n\t return function (Component) {\n\t return React.createClass({\n\t mixins: [Mixin],\n\t render: function render() {\n\t return React.createElement(Component, {\n\t setValidations: this.setValidations,\n\t setValue: this.setValue,\n\t resetValue: this.resetValue,\n\t getValue: this.getValue,\n\t hasValue: this.hasValue,\n\t getErrorMessage: this.getErrorMessage,\n\t getErrorMessages: this.getErrorMessages,\n\t isFormDisabled: this.isFormDisabled,\n\t isValid: this.isValid,\n\t isPristine: this.isPristine,\n\t isFormSubmitted: this.isFormSubmitted,\n\t isRequired: this.isRequired,\n\t showRequired: this.showRequired,\n\t showError: this.showError,\n\t isValidValue: this.isValidValue\n\t });\n\t }\n\t });\n\t };\n\t};\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n\n/***/ },\n/* 5 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global) {'use strict';\n\t\n\tvar React = global.React || __webpack_require__(1);\n\tvar Mixin = __webpack_require__(2);\n\tmodule.exports = function (Component) {\n\t return React.createClass({\n\t mixins: [Mixin],\n\t render: function render() {\n\t return React.createElement(Component, {\n\t setValidations: this.setValidations,\n\t setValue: this.setValue,\n\t resetValue: this.resetValue,\n\t getValue: this.getValue,\n\t hasValue: this.hasValue,\n\t getErrorMessage: this.getErrorMessage,\n\t getErrorMessages: this.getErrorMessages,\n\t isFormDisabled: this.isFormDisabled,\n\t isValid: this.isValid,\n\t isPristine: this.isPristine,\n\t isFormSubmitted: this.isFormSubmitted,\n\t isRequired: this.isRequired,\n\t showRequired: this.showRequired,\n\t showError: this.showError,\n\t isValidValue: this.isValidValue\n\t });\n\t }\n\t });\n\t};\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n\n/***/ },\n/* 6 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tvar _isExisty = function _isExisty(value) {\n\t return value !== null && value !== undefined;\n\t};\n\t\n\tvar isEmpty = function isEmpty(value) {\n\t return value === '';\n\t};\n\t\n\tvar validations = {\n\t isDefaultRequiredValue: function isDefaultRequiredValue(values, value) {\n\t return value === undefined || value === '';\n\t },\n\t isExisty: function isExisty(values, value) {\n\t return _isExisty(value);\n\t },\n\t matchRegexp: function matchRegexp(values, value, regexp) {\n\t return !_isExisty(value) || isEmpty(value) || regexp.test(value);\n\t },\n\t isUndefined: function isUndefined(values, value) {\n\t return value === undefined;\n\t },\n\t isEmptyString: function isEmptyString(values, value) {\n\t return isEmpty(value);\n\t },\n\t isEmail: function isEmail(values, value) {\n\t return validations.matchRegexp(values, value, /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i);\n\t },\n\t isUrl: function isUrl(values, value) {\n\t return validations.matchRegexp(values, value, /^(https?|s?ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i);\n\t },\n\t isTrue: function isTrue(values, value) {\n\t return value === true;\n\t },\n\t isFalse: function isFalse(values, value) {\n\t return value === false;\n\t },\n\t isNumeric: function isNumeric(values, value) {\n\t if (typeof value === 'number') {\n\t return true;\n\t }\n\t return validations.matchRegexp(values, value, /^[-+]?(\\d*[.])?\\d+$/);\n\t },\n\t isAlpha: function isAlpha(values, value) {\n\t return validations.matchRegexp(values, value, /^[a-zA-Z]+$/);\n\t },\n\t isWords: function isWords(values, value) {\n\t return validations.matchRegexp(values, value, /^[a-zA-Z\\s]+$/);\n\t },\n\t isSpecialWords: function isSpecialWords(values, value) {\n\t return validations.matchRegexp(values, value, /^[a-zA-Z\\s\\u00C0-\\u017F]+$/);\n\t },\n\t isLength: function isLength(values, value, length) {\n\t return !_isExisty(value) || isEmpty(value) || value.length === length;\n\t },\n\t equals: function equals(values, value, eql) {\n\t return !_isExisty(value) || isEmpty(value) || value == eql;\n\t },\n\t equalsField: function equalsField(values, value, field) {\n\t return value == values[field];\n\t },\n\t maxLength: function maxLength(values, value, length) {\n\t return !_isExisty(value) || value.length <= length;\n\t },\n\t minLength: function minLength(values, value, length) {\n\t return !_isExisty(value) || isEmpty(value) || value.length >= length;\n\t }\n\t};\n\t\n\tmodule.exports = validations;\n\n/***/ },\n/* 7 */\n/***/ function(module, exports) {\n\n\tmodule.exports = function (source) {\n\t\n\t\n\t // \"foo[0]\"\n\t return Object.keys(source).reduce(function (output, key) {\n\t\n\t var parentKey = key.match(/[^\\[]*/i);\n\t var paths = key.match(/\\[.*?\\]/g) || [];\n\t paths = [parentKey[0]].concat(paths).map(function (key) {\n\t return key.replace(/\\[|\\]/g, '');\n\t });\n\t\n\t var currentPath = output;\n\t while (paths.length) {\n\t\n\t var pathKey = paths.shift();\n\t\n\t if (pathKey in currentPath) {\n\t currentPath = currentPath[pathKey];\n\t } else {\n\t currentPath[pathKey] = paths.length ? isNaN(paths[0]) ? {} : [] : source[key];\n\t currentPath = currentPath[pathKey];\n\t }\n\t\n\t }\n\t\n\t return output;\n\t\n\t }, {});\n\t\n\t};\n\n\n/***/ }\n/******/ ])\n});\n;\n\n\n/** WEBPACK FOOTER **\n ** formsy-react.js\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 24399d79821c570f3424\n **/","var React = global.React || require('react');\nvar Formsy = {};\nvar validationRules = require('./validationRules.js');\nvar formDataToObject = require('form-data-to-object');\nvar utils = require('./utils.js');\nvar Mixin = require('./Mixin.js');\nvar HOC = require('./HOC.js');\nvar Decorator = require('./Decorator.js');\nvar options = {};\n\nFormsy.Mixin = Mixin;\nFormsy.HOC = HOC;\nFormsy.Decorator = Decorator;\n\nFormsy.defaults = function (passedOptions) {\n options = passedOptions;\n};\n\nFormsy.addValidationRule = function (name, func) {\n validationRules[name] = func;\n};\n\nFormsy.Form = React.createClass({\n getInitialState: function () {\n return {\n isValid: true,\n isSubmitting: false,\n canChange: false\n };\n },\n getDefaultProps: function () {\n return {\n onSuccess: function () {},\n onError: function () {},\n onSubmit: function () {},\n onValidSubmit: function () {},\n onInvalidSubmit: function () {},\n onSubmitted: function () {},\n onValid: function () {},\n onInvalid: function () {},\n onChange: function () {},\n validationErrors: null,\n preventExternalInvalidation: false\n };\n },\n\n childContextTypes: {\n formsy: React.PropTypes.object\n },\n getChildContext: function () {\n return {\n formsy: {\n attachToForm: this.attachToForm,\n detachFromForm: this.detachFromForm,\n validate: this.validate,\n isFormDisabled: this.isFormDisabled,\n isValidValue: function (component, value) {\n return this.runValidation(component, value).isValid;\n }.bind(this)\n }\n }\n },\n\n // Add a map to store the inputs of the form, a model to store\n // the values of the form and register child inputs\n componentWillMount: function () {\n this.inputs = {};\n this.model = {};\n },\n\n componentDidMount: function () {\n this.validateForm();\n },\n\n componentWillUpdate: function () {\n\n // Keep a reference to input keys before form updates,\n // to check if inputs has changed after render\n this.prevInputKeys = Object.keys(this.inputs);\n\n },\n\n componentDidUpdate: function () {\n\n if (this.props.validationErrors) {\n this.setInputValidationErrors(this.props.validationErrors);\n }\n\n var newInputKeys = Object.keys(this.inputs);\n if (utils.arraysDiffer(this.prevInputKeys, newInputKeys)) {\n this.validateForm();\n }\n\n },\n\n // Allow resetting to specified data\n reset: function (data) {\n this.setFormPristine(true);\n this.resetModel(data);\n },\n\n // Update model, submit to url prop and send the model\n submit: function (event) {\n\n event && event.preventDefault();\n\n // Trigger form as not pristine.\n // If any inputs have not been touched yet this will make them dirty\n // so validation becomes visible (if based on isPristine)\n this.setFormPristine(false);\n this.updateModel();\n var model = this.mapModel();\n this.props.onSubmit(model, this.resetModel, this.updateInputsWithError);\n this.state.isValid ? this.props.onValidSubmit(model, this.resetModel, this.updateInputsWithError) : this.props.onInvalidSubmit(model, this.resetModel, this.updateInputsWithError);\n\n },\n\n mapModel: function () {\n if (this.props.mapping) {\n return this.props.mapping(this.model)\n } else {\n return formDataToObject(Object.keys(this.model).reduce(function (mappedModel, key) {\n\n var keyArray = key.split('.');\n var base = mappedModel;\n while (keyArray.length) {\n var currentKey = keyArray.shift();\n base = (base[currentKey] = keyArray.length ? base[currentKey] || {} : this.model[key]);\n }\n\n return mappedModel;\n\n }.bind(this), {}));\n }\n },\n\n // Goes through all registered components and\n // updates the model values\n updateModel: function () {\n Object.keys(this.inputs).forEach(function (name) {\n var component = this.inputs[name];\n this.model[name] = component.state._value;\n }.bind(this));\n },\n\n // Reset each key in the model to the original / initial / specified value\n resetModel: function (data) {\n Object.keys(this.inputs).forEach(function (name) {\n if (data && data[name]) {\n this.inputs[name].setValue(data[name]);\n } else {\n this.inputs[name].resetValue();\n }\n }.bind(this));\n this.validateForm();\n },\n\n setInputValidationErrors: function (errors) {\n Object.keys(this.inputs).forEach(function (name, index) {\n var component = this.inputs[name];\n var args = [{\n _isValid: !(name in errors),\n _validationError: typeof errors[name] === 'string' ? [errors[name]] : errors[name]\n }];\n component.setState.apply(component, args);\n }.bind(this));\n },\n\n // Checks if the values have changed from their initial value\n isChanged: function() {\n return !utils.isSame(this.getPristineValues(), this.getCurrentValues());\n },\n\n getPristineValues: function() {\n var inputs = this.inputs;\n return Object.keys(inputs).reduce(function (data, name) {\n var component = inputs[name];\n data[name] = component.props.value;\n return data;\n }, {});\n },\n\n // Go through errors from server and grab the components\n // stored in the inputs map. Change their state to invalid\n // and set the serverError message\n updateInputsWithError: function (errors) {\n Object.keys(errors).forEach(function (name, index) {\n var component = this.inputs[name];\n\n if (!component) {\n throw new Error('You are trying to update an input that does not exist. Verify errors object with input names. ' + JSON.stringify(errors));\n }\n var args = [{\n _isValid: this.props.preventExternalInvalidation || false,\n _externalError: typeof errors[name] === 'string' ? [errors[name]] : errors[name]\n }];\n component.setState.apply(component, args);\n }.bind(this));\n },\n\n // Traverse the children and children of children to find\n // all inputs by checking the name prop. Maybe do a better\n // check here\n traverseChildrenAndRegisterInputs: function (children) {\n\n if (typeof children !== 'object' || children === null) {\n return children;\n }\n return React.Children.map(children, function (child) {\n\n if (typeof child !== 'object' || child === null) {\n return child;\n }\n\n if (child.props && child.props.name) {\n\n return React.cloneElement(child, {\n _attachToForm: this.attachToForm,\n _detachFromForm: this.detachFromForm,\n _validate: this.validate,\n _isFormDisabled: this.isFormDisabled,\n _isValidValue: function (component, value) {\n return this.runValidation(component, value).isValid;\n }.bind(this)\n }, child.props && child.props.children);\n } else {\n return React.cloneElement(child, {}, this.traverseChildrenAndRegisterInputs(child.props && child.props.children));\n }\n\n }, this);\n\n },\n\n isFormDisabled: function () {\n return this.props.disabled;\n },\n\n getCurrentValues: function () {\n return Object.keys(this.inputs).reduce(function (data, name) {\n var component = this.inputs[name];\n data[name] = component.state._value;\n return data;\n }.bind(this), {});\n },\n\n setFormPristine: function (isPristine) {\n var inputs = this.inputs;\n var inputKeys = Object.keys(inputs);\n\n this.setState({\n _formSubmitted: !isPristine\n })\n\n // Iterate through each component and set it as pristine\n // or \"dirty\".\n inputKeys.forEach(function (name, index) {\n var component = inputs[name];\n component.setState({\n _formSubmitted: !isPristine,\n _isPristine: isPristine\n });\n }.bind(this));\n },\n\n // Use the binded values and the actual input value to\n // validate the input and set its state. Then check the\n // state of the form itself\n validate: function (component) {\n\n // Trigger onChange\n if (this.state.canChange) {\n this.props.onChange(this.getCurrentValues(), this.isChanged());\n }\n\n var validation = this.runValidation(component);\n // Run through the validations, split them up and call\n // the validator IF there is a value or it is required\n component.setState({\n _isValid: validation.isValid,\n _isRequired: validation.isRequired,\n _validationError: validation.error,\n _externalError: null\n }, this.validateForm);\n\n },\n\n // Checks validation on current value or a passed value\n runValidation: function (component, value) {\n\n var currentValues = this.getCurrentValues();\n var validationErrors = component.props.validationErrors;\n var validationError = component.props.validationError;\n value = arguments.length === 2 ? value : component.state._value;\n\n var validationResults = this.runRules(value, currentValues, component._validations);\n var requiredResults = this.runRules(value, currentValues, component._requiredValidations);\n\n // the component defines an explicit validate function\n if (typeof component.validate === \"function\") {\n validationResults.failed = component.validate() ? [] : ['failed'];\n }\n\n var isRequired = Object.keys(component._requiredValidations).length ? !!requiredResults.success.length : false;\n var isValid = !validationResults.failed.length && !(this.props.validationErrors && this.props.validationErrors[component.props.name]);\n\n return {\n isRequired: isRequired,\n isValid: isRequired ? false : isValid,\n error: (function () {\n\n if (isValid && !isRequired) {\n return [];\n }\n\n if (validationResults.errors.length) {\n return validationResults.errors;\n }\n\n if (this.props.validationErrors && this.props.validationErrors[component.props.name]) {\n return typeof this.props.validationErrors[component.props.name] === 'string' ? [this.props.validationErrors[component.props.name]] : this.props.validationErrors[component.props.name];\n }\n\n if (isRequired) {\n var error = validationErrors[requiredResults.success[0]];\n return error ? [error] : null;\n }\n\n if (validationResults.failed.length) {\n return validationResults.failed.map(function(failed) {\n return validationErrors[failed] ? validationErrors[failed] : validationError;\n }).filter(function(x, pos, arr) {\n // Remove duplicates\n return arr.indexOf(x) === pos;\n });\n }\n\n }.call(this))\n };\n\n },\n\n runRules: function (value, currentValues, validations) {\n\n var results = {\n errors: [],\n failed: [],\n success: []\n };\n if (Object.keys(validations).length) {\n Object.keys(validations).forEach(function (validationMethod) {\n\n if (validationRules[validationMethod] && typeof validations[validationMethod] === 'function') {\n throw new Error('Formsy does not allow you to override default validations: ' + validationMethod);\n }\n\n if (!validationRules[validationMethod] && typeof validations[validationMethod] !== 'function') {\n throw new Error('Formsy does not have the validation rule: ' + validationMethod);\n }\n\n if (typeof validations[validationMethod] === 'function') {\n var validation = validations[validationMethod](currentValues, value);\n if (typeof validation === 'string') {\n results.errors.push(validation);\n results.failed.push(validationMethod);\n } else if (!validation) {\n results.failed.push(validationMethod);\n }\n return;\n\n } else if (typeof validations[validationMethod] !== 'function') {\n var validation = validationRules[validationMethod](currentValues, value, validations[validationMethod]);\n if (typeof validation === 'string') {\n results.errors.push(validation);\n results.failed.push(validationMethod);\n } else if (!validation) {\n results.failed.push(validationMethod);\n } else {\n results.success.push(validationMethod);\n }\n return;\n\n }\n\n return results.success.push(validationMethod);\n\n });\n }\n\n return results;\n\n },\n\n // Validate the form by going through all child input components\n // and check their state\n validateForm: function () {\n var allIsValid;\n var inputs = this.inputs;\n var inputKeys = Object.keys(inputs);\n\n // We need a callback as we are validating all inputs again. This will\n // run when the last component has set its state\n var onValidationComplete = function () {\n allIsValid = inputKeys.every(function (name) {\n return inputs[name].state._isValid;\n }.bind(this));\n\n this.setState({\n isValid: allIsValid\n });\n\n if (allIsValid) {\n this.props.onValid();\n } else {\n this.props.onInvalid();\n }\n\n // Tell the form that it can start to trigger change events\n this.setState({\n canChange: true\n });\n\n }.bind(this);\n\n // Run validation again in case affected by other inputs. The\n // last component validated will run the onValidationComplete callback\n inputKeys.forEach(function (name, index) {\n var component = inputs[name];\n var validation = this.runValidation(component);\n if (validation.isValid && component.state._externalError) {\n validation.isValid = false;\n }\n component.setState({\n _isValid: validation.isValid,\n _isRequired: validation.isRequired,\n _validationError: validation.error,\n _externalError: !validation.isValid && component.state._externalError ? component.state._externalError : null\n }, index === inputKeys.length - 1 ? onValidationComplete : null);\n }.bind(this));\n\n // If there are no inputs, set state where form is ready to trigger\n // change event. New inputs might be added later\n if (!inputKeys.length && this.isMounted()) {\n this.setState({\n canChange: true\n });\n }\n },\n\n // Method put on each input component to register\n // itself to the form\n attachToForm: function (component) {\n this.inputs[component.props.name] = component;\n this.model[component.props.name] = component.state._value;\n this.validate(component);\n },\n\n // Method put on each input component to unregister\n // itself from the form\n detachFromForm: function (component) {\n delete this.inputs[component.props.name];\n delete this.model[component.props.name];\n },\n render: function () {\n\n return (\n
\n {this.props.children}\n {/*this.traverseChildrenAndRegisterInputs(this.props.children)*/}\n
\n );\n\n }\n});\n\nif (!global.exports && !global.module && (!global.define || !global.define.amd)) {\n global.Formsy = Formsy;\n}\n\nmodule.exports = Formsy;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/main.js\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external \"react\"\n ** module id = 1\n ** module chunks = 0\n **/","var utils = require('./utils.js');\nvar React = global.React || require('react');\n\nvar convertValidationsToObject = function (validations) {\n\n if (typeof validations === 'string') {\n\n return validations.split(/\\,(?![^{\\[]*[}\\]])/g).reduce(function (validations, validation) {\n var args = validation.split(':');\n var validateMethod = args.shift();\n\n args = args.map(function (arg) {\n try {\n return JSON.parse(arg);\n } catch (e) {\n return arg; // It is a string if it can not parse it\n }\n });\n\n if (args.length > 1) {\n throw new Error('Formsy does not support multiple args on string validations. Use object format of validations instead.');\n }\n\n validations[validateMethod] = args.length ? args[0] : true;\n return validations;\n }, {});\n\n }\n\n return validations || {};\n};\n\nmodule.exports = {\n getInitialState: function () {\n return {\n _value: this.props.value,\n _isRequired: false,\n _isValid: true,\n _isPristine: true,\n _pristineValue: this.props.value,\n _validationError: [],\n _externalError: null,\n _formSubmitted: false\n };\n },\n contextTypes: {\n formsy: React.PropTypes.object // What about required?\n },\n getDefaultProps: function () {\n return {\n validationError: '',\n validationErrors: {}\n };\n },\n\n componentWillMount: function () {\n var configure = function () {\n this.setValidations(this.props.validations, this.props.required);\n\n // Pass a function instead?\n this.context.formsy.attachToForm(this);\n //this.props._attachToForm(this);\n }.bind(this);\n\n if (!this.props.name) {\n throw new Error('Form Input requires a name property when used');\n }\n\n /*\n if (!this.props._attachToForm) {\n return setTimeout(function () {\n if (!this.isMounted()) return;\n if (!this.props._attachToForm) {\n throw new Error('Form Mixin requires component to be nested in a Form');\n }\n configure();\n }.bind(this), 0);\n }\n */\n configure();\n },\n\n // We have to make the validate method is kept when new props are added\n componentWillReceiveProps: function (nextProps) {\n this.setValidations(nextProps.validations, nextProps.required);\n\n },\n\n componentDidUpdate: function (prevProps) {\n\n // If the value passed has changed, set it. If value is not passed it will\n // internally update, and this will never run\n if (!utils.isSame(this.props.value, prevProps.value)) {\n this.setValue(this.props.value);\n }\n\n // If validations or required is changed, run a new validation\n if (!utils.isSame(this.props.validations, prevProps.validations) || !utils.isSame(this.props.required, prevProps.required)) {\n this.context.formsy.validate(this);\n }\n },\n\n // Detach it when component unmounts\n componentWillUnmount: function () {\n this.context.formsy.detachFromForm(this);\n //this.props._detachFromForm(this);\n },\n\n setValidations: function (validations, required) {\n\n // Add validations to the store itself as the props object can not be modified\n this._validations = convertValidationsToObject(validations) || {};\n this._requiredValidations = required === true ? {isDefaultRequiredValue: true} : convertValidationsToObject(required);\n\n },\n\n // We validate after the value has been set\n setValue: function (value) {\n this.setState({\n _value: value,\n _isPristine: false\n }, function () {\n this.context.formsy.validate(this);\n //this.props._validate(this);\n }.bind(this));\n },\n resetValue: function () {\n this.setState({\n _value: this.state._pristineValue,\n _isPristine: true\n }, function () {\n this.context.formsy.validate(this);\n //this.props._validate(this);\n });\n },\n getValue: function () {\n return this.state._value;\n },\n hasValue: function () {\n return this.state._value !== '';\n },\n getErrorMessage: function () {\n var messages = this.getErrorMessages();\n return messages.length ? messages[0] : null;\n },\n getErrorMessages: function () {\n return !this.isValid() || this.showRequired() ? (this.state._externalError || this.state._validationError || []) : [];\n },\n isFormDisabled: function () {\n return this.context.formsy.isFormDisabled();\n //return this.props._isFormDisabled();\n },\n isValid: function () {\n return this.state._isValid;\n },\n isPristine: function () {\n return this.state._isPristine;\n },\n isFormSubmitted: function () {\n return this.state._formSubmitted;\n },\n isRequired: function () {\n return !!this.props.required;\n },\n showRequired: function () {\n return this.state._isRequired;\n },\n showError: function () {\n return !this.showRequired() && !this.isValid();\n },\n isValidValue: function (value) {\n return this.context.formsy.isValidValue.call(null, this, value);\n //return this.props._isValidValue.call(null, this, value);\n }\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/Mixin.js\n **/","module.exports = {\n arraysDiffer: function (a, b) {\n var isDifferent = false;\n if (a.length !== b.length) {\n isDifferent = true;\n } else {\n a.forEach(function (item, index) {\n if (!this.isSame(item, b[index])) {\n isDifferent = true;\n }\n }, this);\n }\n return isDifferent;\n },\n\n objectsDiffer: function (a, b) {\n var isDifferent = false;\n if (Object.keys(a).length !== Object.keys(b).length) {\n isDifferent = true;\n } else {\n Object.keys(a).forEach(function (key) {\n if (!this.isSame(a[key], b[key])) {\n isDifferent = true;\n }\n }, this);\n }\n return isDifferent;\n },\n\n isSame: function (a, b) {\n if (typeof a !== typeof b) {\n return false;\n } else if (Array.isArray(a)) {\n return !this.arraysDiffer(a, b);\n } else if (typeof a === 'object' && a !== null && b !== null) {\n return !this.objectsDiffer(a, b);\n }\n\n return a === b;\n }\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/utils.js\n **/","var React = global.React || require('react');\nvar Mixin = require('./Mixin.js');\nmodule.exports = function () {\n return function (Component) {\n return React.createClass({\n mixins: [Mixin],\n render: function () {\n return React.createElement(Component, {\n setValidations: this.setValidations,\n setValue: this.setValue,\n resetValue: this.resetValue,\n getValue: this.getValue,\n hasValue: this.hasValue,\n getErrorMessage: this.getErrorMessage,\n getErrorMessages: this.getErrorMessages,\n isFormDisabled: this.isFormDisabled,\n isValid: this.isValid,\n isPristine: this.isPristine,\n isFormSubmitted: this.isFormSubmitted,\n isRequired: this.isRequired,\n showRequired: this.showRequired,\n showError: this.showError,\n isValidValue: this.isValidValue\n });\n }\n });\n };\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/Decorator.js\n **/","var React = global.React || require('react');\nvar Mixin = require('./Mixin.js');\nmodule.exports = function (Component) {\n return React.createClass({\n mixins: [Mixin],\n render: function () {\n return React.createElement(Component, {\n setValidations: this.setValidations,\n setValue: this.setValue,\n resetValue: this.resetValue,\n getValue: this.getValue,\n hasValue: this.hasValue,\n getErrorMessage: this.getErrorMessage,\n getErrorMessages: this.getErrorMessages,\n isFormDisabled: this.isFormDisabled,\n isValid: this.isValid,\n isPristine: this.isPristine,\n isFormSubmitted: this.isFormSubmitted,\n isRequired: this.isRequired,\n showRequired: this.showRequired,\n showError: this.showError,\n isValidValue: this.isValidValue\n });\n }\n });\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/HOC.js\n **/","var isExisty = function (value) {\n return value !== null && value !== undefined;\n};\n\nvar isEmpty = function (value) {\n return value === '';\n};\n\nvar validations = {\n isDefaultRequiredValue: function (values, value) {\n return value === undefined || value === '';\n },\n isExisty: function (values, value) {\n return isExisty(value);\n },\n matchRegexp: function (values, value, regexp) {\n return !isExisty(value) || isEmpty(value) || regexp.test(value);\n },\n isUndefined: function (values, value) {\n return value === undefined;\n },\n isEmptyString: function (values, value) {\n return isEmpty(value);\n },\n isEmail: function (values, value) {\n return validations.matchRegexp(values, value, /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i);\n },\n isUrl: function (values, value) {\n return validations.matchRegexp(values, value, /^(https?|s?ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i);\n },\n isTrue: function (values, value) {\n return value === true;\n },\n isFalse: function (values, value) {\n return value === false;\n },\n isNumeric: function (values, value) {\n if (typeof value === 'number') {\n return true;\n }\n return validations.matchRegexp(values, value, /^[-+]?(\\d*[.])?\\d+$/);\n },\n isAlpha: function (values, value) {\n return validations.matchRegexp(values, value, /^[a-zA-Z]+$/);\n },\n isWords: function (values, value) {\n return validations.matchRegexp(values, value, /^[a-zA-Z\\s]+$/);\n },\n isSpecialWords: function (values, value) {\n return validations.matchRegexp(values, value, /^[a-zA-Z\\s\\u00C0-\\u017F]+$/);\n },\n isLength: function (values, value, length) {\n return !isExisty(value) || isEmpty(value) || value.length === length;\n },\n equals: function (values, value, eql) {\n return !isExisty(value) || isEmpty(value) || value == eql;\n },\n equalsField: function (values, value, field) {\n return value == values[field];\n },\n maxLength: function (values, value, length) {\n return !isExisty(value) || value.length <= length;\n },\n minLength: function (values, value, length) {\n return !isExisty(value) || isEmpty(value) || value.length >= length;\n }\n};\n\nmodule.exports = validations;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/validationRules.js\n **/","module.exports = function (source) {\n\n\n // \"foo[0]\"\n return Object.keys(source).reduce(function (output, key) {\n\n var parentKey = key.match(/[^\\[]*/i);\n var paths = key.match(/\\[.*?\\]/g) || [];\n paths = [parentKey[0]].concat(paths).map(function (key) {\n return key.replace(/\\[|\\]/g, '');\n });\n\n var currentPath = output;\n while (paths.length) {\n\n var pathKey = paths.shift();\n\n if (pathKey in currentPath) {\n currentPath = currentPath[pathKey];\n } else {\n currentPath[pathKey] = paths.length ? isNaN(paths[0]) ? {} : [] : source[key];\n currentPath = currentPath[pathKey];\n }\n\n }\n\n return output;\n\n }, {});\n\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/form-data-to-object/index.js\n ** module id = 7\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file From 0acaf5e14c2ee216e81627b25dcc309fd7676986 Mon Sep 17 00:00:00 2001 From: christianalfoni Date: Mon, 31 Aug 2015 15:57:01 +0200 Subject: [PATCH 14/24] bumped version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 20a9961..2221fce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "formsy-react", - "version": "0.15.0", + "version": "0.15.1", "description": "A form input builder and validator for React JS", "repository": { "type": "git", From 882eaa1801d9a108a97263575639e33ad12df605 Mon Sep 17 00:00:00 2001 From: Bret Little Date: Tue, 1 Sep 2015 17:53:22 -0600 Subject: [PATCH 15/24] Pass through props inside the decorator This allows custom properties on inputs. Example: The property label is now available within a custom input: export default class Input extends React.Component { render() { return (
) } } --- src/Decorator.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Decorator.js b/src/Decorator.js index e4c61cc..f9a4b35 100644 --- a/src/Decorator.js +++ b/src/Decorator.js @@ -20,7 +20,8 @@ module.exports = function () { isRequired: this.isRequired, showRequired: this.showRequired, showError: this.showError, - isValidValue: this.isValidValue + isValidValue: this.isValidValue, + ...this.props }); } }); From b1275d813e9563f65ba0480bcc52f9ef3941a0ff Mon Sep 17 00:00:00 2001 From: Bret Little Date: Thu, 3 Sep 2015 18:16:16 -0600 Subject: [PATCH 16/24] Add built files --- release/formsy-react.js | 2 +- release/formsy-react.js.map | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/release/formsy-react.js b/release/formsy-react.js index ab389bc..8b5a92b 100644 --- a/release/formsy-react.js +++ b/release/formsy-react.js @@ -1,2 +1,2 @@ -!function(t,i){"object"==typeof exports&&"object"==typeof module?module.exports=i(require("react")):"function"==typeof define&&define.amd?define(["react"],i):"object"==typeof exports?exports.Formsy=i(require("react")):t.Formsy=i(t.react)}(this,function(t){return function(t){function i(r){if(e[r])return e[r].exports;var s=e[r]={exports:{},id:r,loaded:!1};return t[r].call(s.exports,s,s.exports,i),s.loaded=!0,s.exports}var e={};return i.m=t,i.c=e,i.p="",i(0)}([function(t,i,e){(function(i){"use strict";var r=Object.assign||function(t){for(var i=1;i1)throw new Error("Formsy does not support multiple args on string validations. Use object format of validations instead.");return t[r]=e.length?e[0]:!0,t},{}):t||{}};t.exports={getInitialState:function(){return{_value:this.props.value,_isRequired:!1,_isValid:!0,_isPristine:!0,_pristineValue:this.props.value,_validationError:[],_externalError:null,_formSubmitted:!1}},contextTypes:{formsy:s.PropTypes.object},getDefaultProps:function(){return{validationError:"",validationErrors:{}}},componentWillMount:function(){var t=function(){this.setValidations(this.props.validations,this.props.required),this.context.formsy.attachToForm(this)}.bind(this);if(!this.props.name)throw new Error("Form Input requires a name property when used");t()},componentWillReceiveProps:function(t){this.setValidations(t.validations,t.required)},componentDidUpdate:function(t){r.isSame(this.props.value,t.value)||this.setValue(this.props.value),r.isSame(this.props.validations,t.validations)&&r.isSame(this.props.required,t.required)||this.context.formsy.validate(this)},componentWillUnmount:function(){this.context.formsy.detachFromForm(this)},setValidations:function(t,i){this._validations=n(t)||{},this._requiredValidations=i===!0?{isDefaultRequiredValue:!0}:n(i)},setValue:function(t){this.setState({_value:t,_isPristine:!1},function(){this.context.formsy.validate(this)}.bind(this))},resetValue:function(){this.setState({_value:this.state._pristineValue,_isPristine:!0},function(){this.context.formsy.validate(this)})},getValue:function(){return this.state._value},hasValue:function(){return""!==this.state._value},getErrorMessage:function(){var t=this.getErrorMessages();return t.length?t[0]:null},getErrorMessages:function(){return!this.isValid()||this.showRequired()?this.state._externalError||this.state._validationError||[]:[]},isFormDisabled:function(){return this.context.formsy.isFormDisabled()},isValid:function(){return this.state._isValid},isPristine:function(){return this.state._isPristine},isFormSubmitted:function(){return this.state._formSubmitted},isRequired:function(){return!!this.props.required},showRequired:function(){return this.state._isRequired},showError:function(){return!this.showRequired()&&!this.isValid()},isValidValue:function(t){return this.context.formsy.isValidValue.call(null,this,t)}}}).call(i,function(){return this}())},function(t,i){"use strict";t.exports={arraysDiffer:function(t,i){var e=!1;return t.length!==i.length?e=!0:t.forEach(function(t,r){this.isSame(t,i[r])||(e=!0)},this),e},objectsDiffer:function(t,i){var e=!1;return Object.keys(t).length!==Object.keys(i).length?e=!0:Object.keys(t).forEach(function(r){this.isSame(t[r],i[r])||(e=!0)},this),e},isSame:function(t,i){return typeof t!=typeof i?!1:Array.isArray(t)?!this.arraysDiffer(t,i):"object"==typeof t&&null!==t&&null!==i?!this.objectsDiffer(t,i):t===i}}},function(t,i,e){(function(i){"use strict";var r=i.React||e(1),s=e(2);t.exports=function(){return function(t){return r.createClass({mixins:[s],render:function(){return r.createElement(t,{setValidations:this.setValidations,setValue:this.setValue,resetValue:this.resetValue,getValue:this.getValue,hasValue:this.hasValue,getErrorMessage:this.getErrorMessage,getErrorMessages:this.getErrorMessages,isFormDisabled:this.isFormDisabled,isValid:this.isValid,isPristine:this.isPristine,isFormSubmitted:this.isFormSubmitted,isRequired:this.isRequired,showRequired:this.showRequired,showError:this.showError,isValidValue:this.isValidValue})}})}}}).call(i,function(){return this}())},function(t,i,e){(function(i){"use strict";var r=i.React||e(1),s=e(2);t.exports=function(t){return r.createClass({mixins:[s],render:function(){return r.createElement(t,{setValidations:this.setValidations,setValue:this.setValue,resetValue:this.resetValue,getValue:this.getValue,hasValue:this.hasValue,getErrorMessage:this.getErrorMessage,getErrorMessages:this.getErrorMessages,isFormDisabled:this.isFormDisabled,isValid:this.isValid,isPristine:this.isPristine,isFormSubmitted:this.isFormSubmitted,isRequired:this.isRequired,showRequired:this.showRequired,showError:this.showError,isValidValue:this.isValidValue})}})}}).call(i,function(){return this}())},function(t,i){"use strict";var e=function(t){return null!==t&&void 0!==t},r=function(t){return""===t},s={isDefaultRequiredValue:function(t,i){return void 0===i||""===i},isExisty:function(t,i){return e(i)},matchRegexp:function(t,i,s){return!e(i)||r(i)||s.test(i)},isUndefined:function(t,i){return void 0===i},isEmptyString:function(t,i){return r(i)},isEmail:function(t,i){return s.matchRegexp(t,i,/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i)},isUrl:function(t,i){return s.matchRegexp(t,i,/^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i)},isTrue:function(t,i){return i===!0},isFalse:function(t,i){return i===!1},isNumeric:function(t,i){return"number"==typeof i?!0:s.matchRegexp(t,i,/^[-+]?(\d*[.])?\d+$/)},isAlpha:function(t,i){return s.matchRegexp(t,i,/^[a-zA-Z]+$/)},isWords:function(t,i){return s.matchRegexp(t,i,/^[a-zA-Z\s]+$/)},isSpecialWords:function(t,i){return s.matchRegexp(t,i,/^[a-zA-Z\s\u00C0-\u017F]+$/)},isLength:function(t,i,s){return!e(i)||r(i)||i.length===s},equals:function(t,i,s){return!e(i)||r(i)||i==s},equalsField:function(t,i,e){return i==t[e]},maxLength:function(t,i,r){return!e(i)||i.length<=r},minLength:function(t,i,s){return!e(i)||r(i)||i.length>=s}};t.exports=s},function(t,i){t.exports=function(t){return Object.keys(t).reduce(function(i,e){var r=e.match(/[^\[]*/i),s=e.match(/\[.*?\]/g)||[];s=[r[0]].concat(s).map(function(t){return t.replace(/\[|\]/g,"")});for(var n=i;s.length;){var u=s.shift();u in n?n=n[u]:(n[u]=s.length?isNaN(s[0])?{}:[]:t[e],n=n[u])}return i},{})}}])}); +!function(t,i){"object"==typeof exports&&"object"==typeof module?module.exports=i(require("react")):"function"==typeof define&&define.amd?define(["react"],i):"object"==typeof exports?exports.Formsy=i(require("react")):t.Formsy=i(t.react)}(this,function(t){return function(t){function i(r){if(e[r])return e[r].exports;var s=e[r]={exports:{},id:r,loaded:!1};return t[r].call(s.exports,s,s.exports,i),s.loaded=!0,s.exports}var e={};return i.m=t,i.c=e,i.p="",i(0)}([function(t,i,e){(function(i){"use strict";var r=Object.assign||function(t){for(var i=1;i1)throw new Error("Formsy does not support multiple args on string validations. Use object format of validations instead.");return t[r]=e.length?e[0]:!0,t},{}):t||{}};t.exports={getInitialState:function(){return{_value:this.props.value,_isRequired:!1,_isValid:!0,_isPristine:!0,_pristineValue:this.props.value,_validationError:[],_externalError:null,_formSubmitted:!1}},contextTypes:{formsy:s.PropTypes.object},getDefaultProps:function(){return{validationError:"",validationErrors:{}}},componentWillMount:function(){var t=function(){this.setValidations(this.props.validations,this.props.required),this.context.formsy.attachToForm(this)}.bind(this);if(!this.props.name)throw new Error("Form Input requires a name property when used");t()},componentWillReceiveProps:function(t){this.setValidations(t.validations,t.required)},componentDidUpdate:function(t){r.isSame(this.props.value,t.value)||this.setValue(this.props.value),r.isSame(this.props.validations,t.validations)&&r.isSame(this.props.required,t.required)||this.context.formsy.validate(this)},componentWillUnmount:function(){this.context.formsy.detachFromForm(this)},setValidations:function(t,i){this._validations=n(t)||{},this._requiredValidations=i===!0?{isDefaultRequiredValue:!0}:n(i)},setValue:function(t){this.setState({_value:t,_isPristine:!1},function(){this.context.formsy.validate(this)}.bind(this))},resetValue:function(){this.setState({_value:this.state._pristineValue,_isPristine:!0},function(){this.context.formsy.validate(this)})},getValue:function(){return this.state._value},hasValue:function(){return""!==this.state._value},getErrorMessage:function(){var t=this.getErrorMessages();return t.length?t[0]:null},getErrorMessages:function(){return!this.isValid()||this.showRequired()?this.state._externalError||this.state._validationError||[]:[]},isFormDisabled:function(){return this.context.formsy.isFormDisabled()},isValid:function(){return this.state._isValid},isPristine:function(){return this.state._isPristine},isFormSubmitted:function(){return this.state._formSubmitted},isRequired:function(){return!!this.props.required},showRequired:function(){return this.state._isRequired},showError:function(){return!this.showRequired()&&!this.isValid()},isValidValue:function(t){return this.context.formsy.isValidValue.call(null,this,t)}}}).call(i,function(){return this}())},function(t,i){"use strict";t.exports={arraysDiffer:function(t,i){var e=!1;return t.length!==i.length?e=!0:t.forEach(function(t,r){this.isSame(t,i[r])||(e=!0)},this),e},objectsDiffer:function(t,i){var e=!1;return Object.keys(t).length!==Object.keys(i).length?e=!0:Object.keys(t).forEach(function(r){this.isSame(t[r],i[r])||(e=!0)},this),e},isSame:function(t,i){return typeof t!=typeof i?!1:Array.isArray(t)?!this.arraysDiffer(t,i):"object"==typeof t&&null!==t&&null!==i?!this.objectsDiffer(t,i):t===i}}},function(t,i,e){(function(i){"use strict";var r=Object.assign||function(t){for(var i=1;i=s}};t.exports=s},function(t,i){t.exports=function(t){return Object.keys(t).reduce(function(i,e){var r=e.match(/[^\[]*/i),s=e.match(/\[.*?\]/g)||[];s=[r[0]].concat(s).map(function(t){return t.replace(/\[|\]/g,"")});for(var n=i;s.length;){var u=s.shift();u in n?n=n[u]:(n[u]=s.length?isNaN(s[0])?{}:[]:t[e],n=n[u])}return i},{})}}])}); //# sourceMappingURL=formsy-react.js.map \ No newline at end of file diff --git a/release/formsy-react.js.map b/release/formsy-react.js.map index ca10ee3..f8f1525 100644 --- a/release/formsy-react.js.map +++ b/release/formsy-react.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///formsy-react.js","webpack:///webpack/bootstrap 24399d79821c570f3424","webpack:///./src/main.js","webpack:///external \"react\"","webpack:///./src/Mixin.js","webpack:///./src/utils.js","webpack:///./src/Decorator.js","webpack:///./src/HOC.js","webpack:///./src/validationRules.js","webpack:///./~/form-data-to-object/index.js"],"names":["root","factory","exports","module","require","define","amd","this","__WEBPACK_EXTERNAL_MODULE_1__","modules","__webpack_require__","moduleId","installedModules","id","loaded","call","m","c","p","global","_extends","Object","assign","target","i","arguments","length","source","key","prototype","hasOwnProperty","React","Formsy","validationRules","formDataToObject","utils","Mixin","HOC","Decorator","options","defaults","passedOptions","addValidationRule","name","func","Form","createClass","displayName","getInitialState","isValid","isSubmitting","canChange","getDefaultProps","onSuccess","onError","onSubmit","onValidSubmit","onInvalidSubmit","onSubmitted","onValid","onInvalid","onChange","validationErrors","preventExternalInvalidation","childContextTypes","formsy","PropTypes","object","getChildContext","attachToForm","detachFromForm","validate","isFormDisabled","isValidValue","component","value","runValidation","bind","componentWillMount","inputs","model","componentDidMount","validateForm","componentWillUpdate","prevInputKeys","keys","componentDidUpdate","props","setInputValidationErrors","newInputKeys","arraysDiffer","reset","data","setFormPristine","resetModel","submit","event","preventDefault","updateModel","mapModel","updateInputsWithError","state","mapping","reduce","mappedModel","keyArray","split","base","currentKey","shift","forEach","_value","setValue","resetValue","errors","index","args","_isValid","_validationError","setState","apply","isChanged","isSame","getPristineValues","getCurrentValues","Error","JSON","stringify","_externalError","traverseChildrenAndRegisterInputs","children","Children","map","child","cloneElement","_attachToForm","_detachFromForm","_validate","_isFormDisabled","_isValidValue","disabled","isPristine","inputKeys","_formSubmitted","_isPristine","validation","_isRequired","isRequired","error","currentValues","validationError","validationResults","runRules","_validations","requiredResults","_requiredValidations","failed","success","filter","x","pos","arr","indexOf","validations","results","validationMethod","push","allIsValid","onValidationComplete","every","isMounted","render","createElement","convertValidationsToObject","validateMethod","arg","parse","e","_pristineValue","contextTypes","configure","setValidations","required","context","componentWillReceiveProps","nextProps","prevProps","componentWillUnmount","isDefaultRequiredValue","getValue","hasValue","getErrorMessage","messages","getErrorMessages","showRequired","isFormSubmitted","showError","a","b","isDifferent","item","objectsDiffer","Array","isArray","Component","mixins","_isExisty","undefined","isEmpty","values","isExisty","matchRegexp","regexp","test","isUndefined","isEmptyString","isEmail","isUrl","isTrue","isFalse","isNumeric","isAlpha","isWords","isSpecialWords","isLength","equals","eql","equalsField","field","maxLength","minLength","output","parentKey","match","paths","concat","replace","currentPath","pathKey","isNaN"],"mappings":"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","file":"formsy-react.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Formsy\"] = factory(require(\"react\"));\n\telse\n\t\troot[\"Formsy\"] = factory(root[\"react\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Formsy\"] = factory(require(\"react\"));\n\telse\n\t\troot[\"Formsy\"] = factory(root[\"react\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global) {'use strict';\n\t\n\tvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\t\n\tvar React = global.React || __webpack_require__(1);\n\tvar Formsy = {};\n\tvar validationRules = __webpack_require__(6);\n\tvar formDataToObject = __webpack_require__(7);\n\tvar utils = __webpack_require__(3);\n\tvar Mixin = __webpack_require__(2);\n\tvar HOC = __webpack_require__(5);\n\tvar Decorator = __webpack_require__(4);\n\tvar options = {};\n\t\n\tFormsy.Mixin = Mixin;\n\tFormsy.HOC = HOC;\n\tFormsy.Decorator = Decorator;\n\t\n\tFormsy.defaults = function (passedOptions) {\n\t options = passedOptions;\n\t};\n\t\n\tFormsy.addValidationRule = function (name, func) {\n\t validationRules[name] = func;\n\t};\n\t\n\tFormsy.Form = React.createClass({\n\t displayName: 'Form',\n\t\n\t getInitialState: function getInitialState() {\n\t return {\n\t isValid: true,\n\t isSubmitting: false,\n\t canChange: false\n\t };\n\t },\n\t getDefaultProps: function getDefaultProps() {\n\t return {\n\t onSuccess: function onSuccess() {},\n\t onError: function onError() {},\n\t onSubmit: function onSubmit() {},\n\t onValidSubmit: function onValidSubmit() {},\n\t onInvalidSubmit: function onInvalidSubmit() {},\n\t onSubmitted: function onSubmitted() {},\n\t onValid: function onValid() {},\n\t onInvalid: function onInvalid() {},\n\t onChange: function onChange() {},\n\t validationErrors: null,\n\t preventExternalInvalidation: false\n\t };\n\t },\n\t\n\t childContextTypes: {\n\t formsy: React.PropTypes.object\n\t },\n\t getChildContext: function getChildContext() {\n\t return {\n\t formsy: {\n\t attachToForm: this.attachToForm,\n\t detachFromForm: this.detachFromForm,\n\t validate: this.validate,\n\t isFormDisabled: this.isFormDisabled,\n\t isValidValue: (function (component, value) {\n\t return this.runValidation(component, value).isValid;\n\t }).bind(this)\n\t }\n\t };\n\t },\n\t\n\t // Add a map to store the inputs of the form, a model to store\n\t // the values of the form and register child inputs\n\t componentWillMount: function componentWillMount() {\n\t this.inputs = {};\n\t this.model = {};\n\t },\n\t\n\t componentDidMount: function componentDidMount() {\n\t this.validateForm();\n\t },\n\t\n\t componentWillUpdate: function componentWillUpdate() {\n\t\n\t // Keep a reference to input keys before form updates,\n\t // to check if inputs has changed after render\n\t this.prevInputKeys = Object.keys(this.inputs);\n\t },\n\t\n\t componentDidUpdate: function componentDidUpdate() {\n\t\n\t if (this.props.validationErrors) {\n\t this.setInputValidationErrors(this.props.validationErrors);\n\t }\n\t\n\t var newInputKeys = Object.keys(this.inputs);\n\t if (utils.arraysDiffer(this.prevInputKeys, newInputKeys)) {\n\t this.validateForm();\n\t }\n\t },\n\t\n\t // Allow resetting to specified data\n\t reset: function reset(data) {\n\t this.setFormPristine(true);\n\t this.resetModel(data);\n\t },\n\t\n\t // Update model, submit to url prop and send the model\n\t submit: function submit(event) {\n\t\n\t event && event.preventDefault();\n\t\n\t // Trigger form as not pristine.\n\t // If any inputs have not been touched yet this will make them dirty\n\t // so validation becomes visible (if based on isPristine)\n\t this.setFormPristine(false);\n\t this.updateModel();\n\t var model = this.mapModel();\n\t this.props.onSubmit(model, this.resetModel, this.updateInputsWithError);\n\t this.state.isValid ? this.props.onValidSubmit(model, this.resetModel, this.updateInputsWithError) : this.props.onInvalidSubmit(model, this.resetModel, this.updateInputsWithError);\n\t },\n\t\n\t mapModel: function mapModel() {\n\t if (this.props.mapping) {\n\t return this.props.mapping(this.model);\n\t } else {\n\t return formDataToObject(Object.keys(this.model).reduce((function (mappedModel, key) {\n\t\n\t var keyArray = key.split('.');\n\t var base = mappedModel;\n\t while (keyArray.length) {\n\t var currentKey = keyArray.shift();\n\t base = base[currentKey] = keyArray.length ? base[currentKey] || {} : this.model[key];\n\t }\n\t\n\t return mappedModel;\n\t }).bind(this), {}));\n\t }\n\t },\n\t\n\t // Goes through all registered components and\n\t // updates the model values\n\t updateModel: function updateModel() {\n\t Object.keys(this.inputs).forEach((function (name) {\n\t var component = this.inputs[name];\n\t this.model[name] = component.state._value;\n\t }).bind(this));\n\t },\n\t\n\t // Reset each key in the model to the original / initial / specified value\n\t resetModel: function resetModel(data) {\n\t Object.keys(this.inputs).forEach((function (name) {\n\t if (data && data[name]) {\n\t this.inputs[name].setValue(data[name]);\n\t } else {\n\t this.inputs[name].resetValue();\n\t }\n\t }).bind(this));\n\t this.validateForm();\n\t },\n\t\n\t setInputValidationErrors: function setInputValidationErrors(errors) {\n\t Object.keys(this.inputs).forEach((function (name, index) {\n\t var component = this.inputs[name];\n\t var args = [{\n\t _isValid: !(name in errors),\n\t _validationError: typeof errors[name] === 'string' ? [errors[name]] : errors[name]\n\t }];\n\t component.setState.apply(component, args);\n\t }).bind(this));\n\t },\n\t\n\t // Checks if the values have changed from their initial value\n\t isChanged: function isChanged() {\n\t return !utils.isSame(this.getPristineValues(), this.getCurrentValues());\n\t },\n\t\n\t getPristineValues: function getPristineValues() {\n\t var inputs = this.inputs;\n\t return Object.keys(inputs).reduce(function (data, name) {\n\t var component = inputs[name];\n\t data[name] = component.props.value;\n\t return data;\n\t }, {});\n\t },\n\t\n\t // Go through errors from server and grab the components\n\t // stored in the inputs map. Change their state to invalid\n\t // and set the serverError message\n\t updateInputsWithError: function updateInputsWithError(errors) {\n\t Object.keys(errors).forEach((function (name, index) {\n\t var component = this.inputs[name];\n\t\n\t if (!component) {\n\t throw new Error('You are trying to update an input that does not exist. Verify errors object with input names. ' + JSON.stringify(errors));\n\t }\n\t var args = [{\n\t _isValid: this.props.preventExternalInvalidation || false,\n\t _externalError: typeof errors[name] === 'string' ? [errors[name]] : errors[name]\n\t }];\n\t component.setState.apply(component, args);\n\t }).bind(this));\n\t },\n\t\n\t // Traverse the children and children of children to find\n\t // all inputs by checking the name prop. Maybe do a better\n\t // check here\n\t traverseChildrenAndRegisterInputs: function traverseChildrenAndRegisterInputs(children) {\n\t\n\t if (typeof children !== 'object' || children === null) {\n\t return children;\n\t }\n\t return React.Children.map(children, function (child) {\n\t\n\t if (typeof child !== 'object' || child === null) {\n\t return child;\n\t }\n\t\n\t if (child.props && child.props.name) {\n\t\n\t return React.cloneElement(child, {\n\t _attachToForm: this.attachToForm,\n\t _detachFromForm: this.detachFromForm,\n\t _validate: this.validate,\n\t _isFormDisabled: this.isFormDisabled,\n\t _isValidValue: (function (component, value) {\n\t return this.runValidation(component, value).isValid;\n\t }).bind(this)\n\t }, child.props && child.props.children);\n\t } else {\n\t return React.cloneElement(child, {}, this.traverseChildrenAndRegisterInputs(child.props && child.props.children));\n\t }\n\t }, this);\n\t },\n\t\n\t isFormDisabled: function isFormDisabled() {\n\t return this.props.disabled;\n\t },\n\t\n\t getCurrentValues: function getCurrentValues() {\n\t return Object.keys(this.inputs).reduce((function (data, name) {\n\t var component = this.inputs[name];\n\t data[name] = component.state._value;\n\t return data;\n\t }).bind(this), {});\n\t },\n\t\n\t setFormPristine: function setFormPristine(isPristine) {\n\t var inputs = this.inputs;\n\t var inputKeys = Object.keys(inputs);\n\t\n\t this.setState({\n\t _formSubmitted: !isPristine\n\t });\n\t\n\t // Iterate through each component and set it as pristine\n\t // or \"dirty\".\n\t inputKeys.forEach((function (name, index) {\n\t var component = inputs[name];\n\t component.setState({\n\t _formSubmitted: !isPristine,\n\t _isPristine: isPristine\n\t });\n\t }).bind(this));\n\t },\n\t\n\t // Use the binded values and the actual input value to\n\t // validate the input and set its state. Then check the\n\t // state of the form itself\n\t validate: function validate(component) {\n\t\n\t // Trigger onChange\n\t if (this.state.canChange) {\n\t this.props.onChange(this.getCurrentValues(), this.isChanged());\n\t }\n\t\n\t var validation = this.runValidation(component);\n\t // Run through the validations, split them up and call\n\t // the validator IF there is a value or it is required\n\t component.setState({\n\t _isValid: validation.isValid,\n\t _isRequired: validation.isRequired,\n\t _validationError: validation.error,\n\t _externalError: null\n\t }, this.validateForm);\n\t },\n\t\n\t // Checks validation on current value or a passed value\n\t runValidation: function runValidation(component, value) {\n\t\n\t var currentValues = this.getCurrentValues();\n\t var validationErrors = component.props.validationErrors;\n\t var validationError = component.props.validationError;\n\t value = arguments.length === 2 ? value : component.state._value;\n\t\n\t var validationResults = this.runRules(value, currentValues, component._validations);\n\t var requiredResults = this.runRules(value, currentValues, component._requiredValidations);\n\t\n\t // the component defines an explicit validate function\n\t if (typeof component.validate === \"function\") {\n\t validationResults.failed = component.validate() ? [] : ['failed'];\n\t }\n\t\n\t var isRequired = Object.keys(component._requiredValidations).length ? !!requiredResults.success.length : false;\n\t var isValid = !validationResults.failed.length && !(this.props.validationErrors && this.props.validationErrors[component.props.name]);\n\t\n\t return {\n\t isRequired: isRequired,\n\t isValid: isRequired ? false : isValid,\n\t error: (function () {\n\t\n\t if (isValid && !isRequired) {\n\t return [];\n\t }\n\t\n\t if (validationResults.errors.length) {\n\t return validationResults.errors;\n\t }\n\t\n\t if (this.props.validationErrors && this.props.validationErrors[component.props.name]) {\n\t return typeof this.props.validationErrors[component.props.name] === 'string' ? [this.props.validationErrors[component.props.name]] : this.props.validationErrors[component.props.name];\n\t }\n\t\n\t if (isRequired) {\n\t var error = validationErrors[requiredResults.success[0]];\n\t return error ? [error] : null;\n\t }\n\t\n\t if (validationResults.failed.length) {\n\t return validationResults.failed.map(function (failed) {\n\t return validationErrors[failed] ? validationErrors[failed] : validationError;\n\t }).filter(function (x, pos, arr) {\n\t // Remove duplicates\n\t return arr.indexOf(x) === pos;\n\t });\n\t }\n\t }).call(this)\n\t };\n\t },\n\t\n\t runRules: function runRules(value, currentValues, validations) {\n\t\n\t var results = {\n\t errors: [],\n\t failed: [],\n\t success: []\n\t };\n\t if (Object.keys(validations).length) {\n\t Object.keys(validations).forEach(function (validationMethod) {\n\t\n\t if (validationRules[validationMethod] && typeof validations[validationMethod] === 'function') {\n\t throw new Error('Formsy does not allow you to override default validations: ' + validationMethod);\n\t }\n\t\n\t if (!validationRules[validationMethod] && typeof validations[validationMethod] !== 'function') {\n\t throw new Error('Formsy does not have the validation rule: ' + validationMethod);\n\t }\n\t\n\t if (typeof validations[validationMethod] === 'function') {\n\t var validation = validations[validationMethod](currentValues, value);\n\t if (typeof validation === 'string') {\n\t results.errors.push(validation);\n\t results.failed.push(validationMethod);\n\t } else if (!validation) {\n\t results.failed.push(validationMethod);\n\t }\n\t return;\n\t } else if (typeof validations[validationMethod] !== 'function') {\n\t var validation = validationRules[validationMethod](currentValues, value, validations[validationMethod]);\n\t if (typeof validation === 'string') {\n\t results.errors.push(validation);\n\t results.failed.push(validationMethod);\n\t } else if (!validation) {\n\t results.failed.push(validationMethod);\n\t } else {\n\t results.success.push(validationMethod);\n\t }\n\t return;\n\t }\n\t\n\t return results.success.push(validationMethod);\n\t });\n\t }\n\t\n\t return results;\n\t },\n\t\n\t // Validate the form by going through all child input components\n\t // and check their state\n\t validateForm: function validateForm() {\n\t var allIsValid;\n\t var inputs = this.inputs;\n\t var inputKeys = Object.keys(inputs);\n\t\n\t // We need a callback as we are validating all inputs again. This will\n\t // run when the last component has set its state\n\t var onValidationComplete = (function () {\n\t allIsValid = inputKeys.every((function (name) {\n\t return inputs[name].state._isValid;\n\t }).bind(this));\n\t\n\t this.setState({\n\t isValid: allIsValid\n\t });\n\t\n\t if (allIsValid) {\n\t this.props.onValid();\n\t } else {\n\t this.props.onInvalid();\n\t }\n\t\n\t // Tell the form that it can start to trigger change events\n\t this.setState({\n\t canChange: true\n\t });\n\t }).bind(this);\n\t\n\t // Run validation again in case affected by other inputs. The\n\t // last component validated will run the onValidationComplete callback\n\t inputKeys.forEach((function (name, index) {\n\t var component = inputs[name];\n\t var validation = this.runValidation(component);\n\t if (validation.isValid && component.state._externalError) {\n\t validation.isValid = false;\n\t }\n\t component.setState({\n\t _isValid: validation.isValid,\n\t _isRequired: validation.isRequired,\n\t _validationError: validation.error,\n\t _externalError: !validation.isValid && component.state._externalError ? component.state._externalError : null\n\t }, index === inputKeys.length - 1 ? onValidationComplete : null);\n\t }).bind(this));\n\t\n\t // If there are no inputs, set state where form is ready to trigger\n\t // change event. New inputs might be added later\n\t if (!inputKeys.length && this.isMounted()) {\n\t this.setState({\n\t canChange: true\n\t });\n\t }\n\t },\n\t\n\t // Method put on each input component to register\n\t // itself to the form\n\t attachToForm: function attachToForm(component) {\n\t this.inputs[component.props.name] = component;\n\t this.model[component.props.name] = component.state._value;\n\t this.validate(component);\n\t },\n\t\n\t // Method put on each input component to unregister\n\t // itself from the form\n\t detachFromForm: function detachFromForm(component) {\n\t delete this.inputs[component.props.name];\n\t delete this.model[component.props.name];\n\t },\n\t render: function render() {\n\t\n\t return React.createElement(\n\t 'form',\n\t _extends({}, this.props, { onSubmit: this.submit }),\n\t this.props.children\n\t );\n\t }\n\t});\n\t\n\tif (!global.exports && !global.module && (!global.define || !global.define.amd)) {\n\t global.Formsy = Formsy;\n\t}\n\t\n\tmodule.exports = Formsy;\n\t/*this.traverseChildrenAndRegisterInputs(this.props.children)*/\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n\n/***/ },\n/* 1 */\n/***/ function(module, exports) {\n\n\tmodule.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global) {'use strict';\n\t\n\tvar utils = __webpack_require__(3);\n\tvar React = global.React || __webpack_require__(1);\n\t\n\tvar convertValidationsToObject = function convertValidationsToObject(validations) {\n\t\n\t if (typeof validations === 'string') {\n\t\n\t return validations.split(/\\,(?![^{\\[]*[}\\]])/g).reduce(function (validations, validation) {\n\t var args = validation.split(':');\n\t var validateMethod = args.shift();\n\t\n\t args = args.map(function (arg) {\n\t try {\n\t return JSON.parse(arg);\n\t } catch (e) {\n\t return arg; // It is a string if it can not parse it\n\t }\n\t });\n\t\n\t if (args.length > 1) {\n\t throw new Error('Formsy does not support multiple args on string validations. Use object format of validations instead.');\n\t }\n\t\n\t validations[validateMethod] = args.length ? args[0] : true;\n\t return validations;\n\t }, {});\n\t }\n\t\n\t return validations || {};\n\t};\n\t\n\tmodule.exports = {\n\t getInitialState: function getInitialState() {\n\t return {\n\t _value: this.props.value,\n\t _isRequired: false,\n\t _isValid: true,\n\t _isPristine: true,\n\t _pristineValue: this.props.value,\n\t _validationError: [],\n\t _externalError: null,\n\t _formSubmitted: false\n\t };\n\t },\n\t contextTypes: {\n\t formsy: React.PropTypes.object // What about required?\n\t },\n\t getDefaultProps: function getDefaultProps() {\n\t return {\n\t validationError: '',\n\t validationErrors: {}\n\t };\n\t },\n\t\n\t componentWillMount: function componentWillMount() {\n\t var configure = (function () {\n\t this.setValidations(this.props.validations, this.props.required);\n\t\n\t // Pass a function instead?\n\t this.context.formsy.attachToForm(this);\n\t //this.props._attachToForm(this);\n\t }).bind(this);\n\t\n\t if (!this.props.name) {\n\t throw new Error('Form Input requires a name property when used');\n\t }\n\t\n\t /*\n\t if (!this.props._attachToForm) {\n\t return setTimeout(function () {\n\t if (!this.isMounted()) return;\n\t if (!this.props._attachToForm) {\n\t throw new Error('Form Mixin requires component to be nested in a Form');\n\t }\n\t configure();\n\t }.bind(this), 0);\n\t }\n\t */\n\t configure();\n\t },\n\t\n\t // We have to make the validate method is kept when new props are added\n\t componentWillReceiveProps: function componentWillReceiveProps(nextProps) {\n\t this.setValidations(nextProps.validations, nextProps.required);\n\t },\n\t\n\t componentDidUpdate: function componentDidUpdate(prevProps) {\n\t\n\t // If the value passed has changed, set it. If value is not passed it will\n\t // internally update, and this will never run\n\t if (!utils.isSame(this.props.value, prevProps.value)) {\n\t this.setValue(this.props.value);\n\t }\n\t\n\t // If validations or required is changed, run a new validation\n\t if (!utils.isSame(this.props.validations, prevProps.validations) || !utils.isSame(this.props.required, prevProps.required)) {\n\t this.context.formsy.validate(this);\n\t }\n\t },\n\t\n\t // Detach it when component unmounts\n\t componentWillUnmount: function componentWillUnmount() {\n\t this.context.formsy.detachFromForm(this);\n\t //this.props._detachFromForm(this);\n\t },\n\t\n\t setValidations: function setValidations(validations, required) {\n\t\n\t // Add validations to the store itself as the props object can not be modified\n\t this._validations = convertValidationsToObject(validations) || {};\n\t this._requiredValidations = required === true ? { isDefaultRequiredValue: true } : convertValidationsToObject(required);\n\t },\n\t\n\t // We validate after the value has been set\n\t setValue: function setValue(value) {\n\t this.setState({\n\t _value: value,\n\t _isPristine: false\n\t }, (function () {\n\t this.context.formsy.validate(this);\n\t //this.props._validate(this);\n\t }).bind(this));\n\t },\n\t resetValue: function resetValue() {\n\t this.setState({\n\t _value: this.state._pristineValue,\n\t _isPristine: true\n\t }, function () {\n\t this.context.formsy.validate(this);\n\t //this.props._validate(this);\n\t });\n\t },\n\t getValue: function getValue() {\n\t return this.state._value;\n\t },\n\t hasValue: function hasValue() {\n\t return this.state._value !== '';\n\t },\n\t getErrorMessage: function getErrorMessage() {\n\t var messages = this.getErrorMessages();\n\t return messages.length ? messages[0] : null;\n\t },\n\t getErrorMessages: function getErrorMessages() {\n\t return !this.isValid() || this.showRequired() ? this.state._externalError || this.state._validationError || [] : [];\n\t },\n\t isFormDisabled: function isFormDisabled() {\n\t return this.context.formsy.isFormDisabled();\n\t //return this.props._isFormDisabled();\n\t },\n\t isValid: function isValid() {\n\t return this.state._isValid;\n\t },\n\t isPristine: function isPristine() {\n\t return this.state._isPristine;\n\t },\n\t isFormSubmitted: function isFormSubmitted() {\n\t return this.state._formSubmitted;\n\t },\n\t isRequired: function isRequired() {\n\t return !!this.props.required;\n\t },\n\t showRequired: function showRequired() {\n\t return this.state._isRequired;\n\t },\n\t showError: function showError() {\n\t return !this.showRequired() && !this.isValid();\n\t },\n\t isValidValue: function isValidValue(value) {\n\t return this.context.formsy.isValidValue.call(null, this, value);\n\t //return this.props._isValidValue.call(null, this, value);\n\t }\n\t};\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n\n/***/ },\n/* 3 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = {\n\t arraysDiffer: function arraysDiffer(a, b) {\n\t var isDifferent = false;\n\t if (a.length !== b.length) {\n\t isDifferent = true;\n\t } else {\n\t a.forEach(function (item, index) {\n\t if (!this.isSame(item, b[index])) {\n\t isDifferent = true;\n\t }\n\t }, this);\n\t }\n\t return isDifferent;\n\t },\n\t\n\t objectsDiffer: function objectsDiffer(a, b) {\n\t var isDifferent = false;\n\t if (Object.keys(a).length !== Object.keys(b).length) {\n\t isDifferent = true;\n\t } else {\n\t Object.keys(a).forEach(function (key) {\n\t if (!this.isSame(a[key], b[key])) {\n\t isDifferent = true;\n\t }\n\t }, this);\n\t }\n\t return isDifferent;\n\t },\n\t\n\t isSame: function isSame(a, b) {\n\t if (typeof a !== typeof b) {\n\t return false;\n\t } else if (Array.isArray(a)) {\n\t return !this.arraysDiffer(a, b);\n\t } else if (typeof a === 'object' && a !== null && b !== null) {\n\t return !this.objectsDiffer(a, b);\n\t }\n\t\n\t return a === b;\n\t }\n\t};\n\n/***/ },\n/* 4 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global) {'use strict';\n\t\n\tvar React = global.React || __webpack_require__(1);\n\tvar Mixin = __webpack_require__(2);\n\tmodule.exports = function () {\n\t return function (Component) {\n\t return React.createClass({\n\t mixins: [Mixin],\n\t render: function render() {\n\t return React.createElement(Component, {\n\t setValidations: this.setValidations,\n\t setValue: this.setValue,\n\t resetValue: this.resetValue,\n\t getValue: this.getValue,\n\t hasValue: this.hasValue,\n\t getErrorMessage: this.getErrorMessage,\n\t getErrorMessages: this.getErrorMessages,\n\t isFormDisabled: this.isFormDisabled,\n\t isValid: this.isValid,\n\t isPristine: this.isPristine,\n\t isFormSubmitted: this.isFormSubmitted,\n\t isRequired: this.isRequired,\n\t showRequired: this.showRequired,\n\t showError: this.showError,\n\t isValidValue: this.isValidValue\n\t });\n\t }\n\t });\n\t };\n\t};\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n\n/***/ },\n/* 5 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global) {'use strict';\n\t\n\tvar React = global.React || __webpack_require__(1);\n\tvar Mixin = __webpack_require__(2);\n\tmodule.exports = function (Component) {\n\t return React.createClass({\n\t mixins: [Mixin],\n\t render: function render() {\n\t return React.createElement(Component, {\n\t setValidations: this.setValidations,\n\t setValue: this.setValue,\n\t resetValue: this.resetValue,\n\t getValue: this.getValue,\n\t hasValue: this.hasValue,\n\t getErrorMessage: this.getErrorMessage,\n\t getErrorMessages: this.getErrorMessages,\n\t isFormDisabled: this.isFormDisabled,\n\t isValid: this.isValid,\n\t isPristine: this.isPristine,\n\t isFormSubmitted: this.isFormSubmitted,\n\t isRequired: this.isRequired,\n\t showRequired: this.showRequired,\n\t showError: this.showError,\n\t isValidValue: this.isValidValue\n\t });\n\t }\n\t });\n\t};\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n\n/***/ },\n/* 6 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tvar _isExisty = function _isExisty(value) {\n\t return value !== null && value !== undefined;\n\t};\n\t\n\tvar isEmpty = function isEmpty(value) {\n\t return value === '';\n\t};\n\t\n\tvar validations = {\n\t isDefaultRequiredValue: function isDefaultRequiredValue(values, value) {\n\t return value === undefined || value === '';\n\t },\n\t isExisty: function isExisty(values, value) {\n\t return _isExisty(value);\n\t },\n\t matchRegexp: function matchRegexp(values, value, regexp) {\n\t return !_isExisty(value) || isEmpty(value) || regexp.test(value);\n\t },\n\t isUndefined: function isUndefined(values, value) {\n\t return value === undefined;\n\t },\n\t isEmptyString: function isEmptyString(values, value) {\n\t return isEmpty(value);\n\t },\n\t isEmail: function isEmail(values, value) {\n\t return validations.matchRegexp(values, value, /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i);\n\t },\n\t isUrl: function isUrl(values, value) {\n\t return validations.matchRegexp(values, value, /^(https?|s?ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i);\n\t },\n\t isTrue: function isTrue(values, value) {\n\t return value === true;\n\t },\n\t isFalse: function isFalse(values, value) {\n\t return value === false;\n\t },\n\t isNumeric: function isNumeric(values, value) {\n\t if (typeof value === 'number') {\n\t return true;\n\t }\n\t return validations.matchRegexp(values, value, /^[-+]?(\\d*[.])?\\d+$/);\n\t },\n\t isAlpha: function isAlpha(values, value) {\n\t return validations.matchRegexp(values, value, /^[a-zA-Z]+$/);\n\t },\n\t isWords: function isWords(values, value) {\n\t return validations.matchRegexp(values, value, /^[a-zA-Z\\s]+$/);\n\t },\n\t isSpecialWords: function isSpecialWords(values, value) {\n\t return validations.matchRegexp(values, value, /^[a-zA-Z\\s\\u00C0-\\u017F]+$/);\n\t },\n\t isLength: function isLength(values, value, length) {\n\t return !_isExisty(value) || isEmpty(value) || value.length === length;\n\t },\n\t equals: function equals(values, value, eql) {\n\t return !_isExisty(value) || isEmpty(value) || value == eql;\n\t },\n\t equalsField: function equalsField(values, value, field) {\n\t return value == values[field];\n\t },\n\t maxLength: function maxLength(values, value, length) {\n\t return !_isExisty(value) || value.length <= length;\n\t },\n\t minLength: function minLength(values, value, length) {\n\t return !_isExisty(value) || isEmpty(value) || value.length >= length;\n\t }\n\t};\n\t\n\tmodule.exports = validations;\n\n/***/ },\n/* 7 */\n/***/ function(module, exports) {\n\n\tmodule.exports = function (source) {\n\t\n\t\n\t // \"foo[0]\"\n\t return Object.keys(source).reduce(function (output, key) {\n\t\n\t var parentKey = key.match(/[^\\[]*/i);\n\t var paths = key.match(/\\[.*?\\]/g) || [];\n\t paths = [parentKey[0]].concat(paths).map(function (key) {\n\t return key.replace(/\\[|\\]/g, '');\n\t });\n\t\n\t var currentPath = output;\n\t while (paths.length) {\n\t\n\t var pathKey = paths.shift();\n\t\n\t if (pathKey in currentPath) {\n\t currentPath = currentPath[pathKey];\n\t } else {\n\t currentPath[pathKey] = paths.length ? isNaN(paths[0]) ? {} : [] : source[key];\n\t currentPath = currentPath[pathKey];\n\t }\n\t\n\t }\n\t\n\t return output;\n\t\n\t }, {});\n\t\n\t};\n\n\n/***/ }\n/******/ ])\n});\n;\n\n\n/** WEBPACK FOOTER **\n ** formsy-react.js\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 24399d79821c570f3424\n **/","var React = global.React || require('react');\nvar Formsy = {};\nvar validationRules = require('./validationRules.js');\nvar formDataToObject = require('form-data-to-object');\nvar utils = require('./utils.js');\nvar Mixin = require('./Mixin.js');\nvar HOC = require('./HOC.js');\nvar Decorator = require('./Decorator.js');\nvar options = {};\n\nFormsy.Mixin = Mixin;\nFormsy.HOC = HOC;\nFormsy.Decorator = Decorator;\n\nFormsy.defaults = function (passedOptions) {\n options = passedOptions;\n};\n\nFormsy.addValidationRule = function (name, func) {\n validationRules[name] = func;\n};\n\nFormsy.Form = React.createClass({\n getInitialState: function () {\n return {\n isValid: true,\n isSubmitting: false,\n canChange: false\n };\n },\n getDefaultProps: function () {\n return {\n onSuccess: function () {},\n onError: function () {},\n onSubmit: function () {},\n onValidSubmit: function () {},\n onInvalidSubmit: function () {},\n onSubmitted: function () {},\n onValid: function () {},\n onInvalid: function () {},\n onChange: function () {},\n validationErrors: null,\n preventExternalInvalidation: false\n };\n },\n\n childContextTypes: {\n formsy: React.PropTypes.object\n },\n getChildContext: function () {\n return {\n formsy: {\n attachToForm: this.attachToForm,\n detachFromForm: this.detachFromForm,\n validate: this.validate,\n isFormDisabled: this.isFormDisabled,\n isValidValue: function (component, value) {\n return this.runValidation(component, value).isValid;\n }.bind(this)\n }\n }\n },\n\n // Add a map to store the inputs of the form, a model to store\n // the values of the form and register child inputs\n componentWillMount: function () {\n this.inputs = {};\n this.model = {};\n },\n\n componentDidMount: function () {\n this.validateForm();\n },\n\n componentWillUpdate: function () {\n\n // Keep a reference to input keys before form updates,\n // to check if inputs has changed after render\n this.prevInputKeys = Object.keys(this.inputs);\n\n },\n\n componentDidUpdate: function () {\n\n if (this.props.validationErrors) {\n this.setInputValidationErrors(this.props.validationErrors);\n }\n\n var newInputKeys = Object.keys(this.inputs);\n if (utils.arraysDiffer(this.prevInputKeys, newInputKeys)) {\n this.validateForm();\n }\n\n },\n\n // Allow resetting to specified data\n reset: function (data) {\n this.setFormPristine(true);\n this.resetModel(data);\n },\n\n // Update model, submit to url prop and send the model\n submit: function (event) {\n\n event && event.preventDefault();\n\n // Trigger form as not pristine.\n // If any inputs have not been touched yet this will make them dirty\n // so validation becomes visible (if based on isPristine)\n this.setFormPristine(false);\n this.updateModel();\n var model = this.mapModel();\n this.props.onSubmit(model, this.resetModel, this.updateInputsWithError);\n this.state.isValid ? this.props.onValidSubmit(model, this.resetModel, this.updateInputsWithError) : this.props.onInvalidSubmit(model, this.resetModel, this.updateInputsWithError);\n\n },\n\n mapModel: function () {\n if (this.props.mapping) {\n return this.props.mapping(this.model)\n } else {\n return formDataToObject(Object.keys(this.model).reduce(function (mappedModel, key) {\n\n var keyArray = key.split('.');\n var base = mappedModel;\n while (keyArray.length) {\n var currentKey = keyArray.shift();\n base = (base[currentKey] = keyArray.length ? base[currentKey] || {} : this.model[key]);\n }\n\n return mappedModel;\n\n }.bind(this), {}));\n }\n },\n\n // Goes through all registered components and\n // updates the model values\n updateModel: function () {\n Object.keys(this.inputs).forEach(function (name) {\n var component = this.inputs[name];\n this.model[name] = component.state._value;\n }.bind(this));\n },\n\n // Reset each key in the model to the original / initial / specified value\n resetModel: function (data) {\n Object.keys(this.inputs).forEach(function (name) {\n if (data && data[name]) {\n this.inputs[name].setValue(data[name]);\n } else {\n this.inputs[name].resetValue();\n }\n }.bind(this));\n this.validateForm();\n },\n\n setInputValidationErrors: function (errors) {\n Object.keys(this.inputs).forEach(function (name, index) {\n var component = this.inputs[name];\n var args = [{\n _isValid: !(name in errors),\n _validationError: typeof errors[name] === 'string' ? [errors[name]] : errors[name]\n }];\n component.setState.apply(component, args);\n }.bind(this));\n },\n\n // Checks if the values have changed from their initial value\n isChanged: function() {\n return !utils.isSame(this.getPristineValues(), this.getCurrentValues());\n },\n\n getPristineValues: function() {\n var inputs = this.inputs;\n return Object.keys(inputs).reduce(function (data, name) {\n var component = inputs[name];\n data[name] = component.props.value;\n return data;\n }, {});\n },\n\n // Go through errors from server and grab the components\n // stored in the inputs map. Change their state to invalid\n // and set the serverError message\n updateInputsWithError: function (errors) {\n Object.keys(errors).forEach(function (name, index) {\n var component = this.inputs[name];\n\n if (!component) {\n throw new Error('You are trying to update an input that does not exist. Verify errors object with input names. ' + JSON.stringify(errors));\n }\n var args = [{\n _isValid: this.props.preventExternalInvalidation || false,\n _externalError: typeof errors[name] === 'string' ? [errors[name]] : errors[name]\n }];\n component.setState.apply(component, args);\n }.bind(this));\n },\n\n // Traverse the children and children of children to find\n // all inputs by checking the name prop. Maybe do a better\n // check here\n traverseChildrenAndRegisterInputs: function (children) {\n\n if (typeof children !== 'object' || children === null) {\n return children;\n }\n return React.Children.map(children, function (child) {\n\n if (typeof child !== 'object' || child === null) {\n return child;\n }\n\n if (child.props && child.props.name) {\n\n return React.cloneElement(child, {\n _attachToForm: this.attachToForm,\n _detachFromForm: this.detachFromForm,\n _validate: this.validate,\n _isFormDisabled: this.isFormDisabled,\n _isValidValue: function (component, value) {\n return this.runValidation(component, value).isValid;\n }.bind(this)\n }, child.props && child.props.children);\n } else {\n return React.cloneElement(child, {}, this.traverseChildrenAndRegisterInputs(child.props && child.props.children));\n }\n\n }, this);\n\n },\n\n isFormDisabled: function () {\n return this.props.disabled;\n },\n\n getCurrentValues: function () {\n return Object.keys(this.inputs).reduce(function (data, name) {\n var component = this.inputs[name];\n data[name] = component.state._value;\n return data;\n }.bind(this), {});\n },\n\n setFormPristine: function (isPristine) {\n var inputs = this.inputs;\n var inputKeys = Object.keys(inputs);\n\n this.setState({\n _formSubmitted: !isPristine\n })\n\n // Iterate through each component and set it as pristine\n // or \"dirty\".\n inputKeys.forEach(function (name, index) {\n var component = inputs[name];\n component.setState({\n _formSubmitted: !isPristine,\n _isPristine: isPristine\n });\n }.bind(this));\n },\n\n // Use the binded values and the actual input value to\n // validate the input and set its state. Then check the\n // state of the form itself\n validate: function (component) {\n\n // Trigger onChange\n if (this.state.canChange) {\n this.props.onChange(this.getCurrentValues(), this.isChanged());\n }\n\n var validation = this.runValidation(component);\n // Run through the validations, split them up and call\n // the validator IF there is a value or it is required\n component.setState({\n _isValid: validation.isValid,\n _isRequired: validation.isRequired,\n _validationError: validation.error,\n _externalError: null\n }, this.validateForm);\n\n },\n\n // Checks validation on current value or a passed value\n runValidation: function (component, value) {\n\n var currentValues = this.getCurrentValues();\n var validationErrors = component.props.validationErrors;\n var validationError = component.props.validationError;\n value = arguments.length === 2 ? value : component.state._value;\n\n var validationResults = this.runRules(value, currentValues, component._validations);\n var requiredResults = this.runRules(value, currentValues, component._requiredValidations);\n\n // the component defines an explicit validate function\n if (typeof component.validate === \"function\") {\n validationResults.failed = component.validate() ? [] : ['failed'];\n }\n\n var isRequired = Object.keys(component._requiredValidations).length ? !!requiredResults.success.length : false;\n var isValid = !validationResults.failed.length && !(this.props.validationErrors && this.props.validationErrors[component.props.name]);\n\n return {\n isRequired: isRequired,\n isValid: isRequired ? false : isValid,\n error: (function () {\n\n if (isValid && !isRequired) {\n return [];\n }\n\n if (validationResults.errors.length) {\n return validationResults.errors;\n }\n\n if (this.props.validationErrors && this.props.validationErrors[component.props.name]) {\n return typeof this.props.validationErrors[component.props.name] === 'string' ? [this.props.validationErrors[component.props.name]] : this.props.validationErrors[component.props.name];\n }\n\n if (isRequired) {\n var error = validationErrors[requiredResults.success[0]];\n return error ? [error] : null;\n }\n\n if (validationResults.failed.length) {\n return validationResults.failed.map(function(failed) {\n return validationErrors[failed] ? validationErrors[failed] : validationError;\n }).filter(function(x, pos, arr) {\n // Remove duplicates\n return arr.indexOf(x) === pos;\n });\n }\n\n }.call(this))\n };\n\n },\n\n runRules: function (value, currentValues, validations) {\n\n var results = {\n errors: [],\n failed: [],\n success: []\n };\n if (Object.keys(validations).length) {\n Object.keys(validations).forEach(function (validationMethod) {\n\n if (validationRules[validationMethod] && typeof validations[validationMethod] === 'function') {\n throw new Error('Formsy does not allow you to override default validations: ' + validationMethod);\n }\n\n if (!validationRules[validationMethod] && typeof validations[validationMethod] !== 'function') {\n throw new Error('Formsy does not have the validation rule: ' + validationMethod);\n }\n\n if (typeof validations[validationMethod] === 'function') {\n var validation = validations[validationMethod](currentValues, value);\n if (typeof validation === 'string') {\n results.errors.push(validation);\n results.failed.push(validationMethod);\n } else if (!validation) {\n results.failed.push(validationMethod);\n }\n return;\n\n } else if (typeof validations[validationMethod] !== 'function') {\n var validation = validationRules[validationMethod](currentValues, value, validations[validationMethod]);\n if (typeof validation === 'string') {\n results.errors.push(validation);\n results.failed.push(validationMethod);\n } else if (!validation) {\n results.failed.push(validationMethod);\n } else {\n results.success.push(validationMethod);\n }\n return;\n\n }\n\n return results.success.push(validationMethod);\n\n });\n }\n\n return results;\n\n },\n\n // Validate the form by going through all child input components\n // and check their state\n validateForm: function () {\n var allIsValid;\n var inputs = this.inputs;\n var inputKeys = Object.keys(inputs);\n\n // We need a callback as we are validating all inputs again. This will\n // run when the last component has set its state\n var onValidationComplete = function () {\n allIsValid = inputKeys.every(function (name) {\n return inputs[name].state._isValid;\n }.bind(this));\n\n this.setState({\n isValid: allIsValid\n });\n\n if (allIsValid) {\n this.props.onValid();\n } else {\n this.props.onInvalid();\n }\n\n // Tell the form that it can start to trigger change events\n this.setState({\n canChange: true\n });\n\n }.bind(this);\n\n // Run validation again in case affected by other inputs. The\n // last component validated will run the onValidationComplete callback\n inputKeys.forEach(function (name, index) {\n var component = inputs[name];\n var validation = this.runValidation(component);\n if (validation.isValid && component.state._externalError) {\n validation.isValid = false;\n }\n component.setState({\n _isValid: validation.isValid,\n _isRequired: validation.isRequired,\n _validationError: validation.error,\n _externalError: !validation.isValid && component.state._externalError ? component.state._externalError : null\n }, index === inputKeys.length - 1 ? onValidationComplete : null);\n }.bind(this));\n\n // If there are no inputs, set state where form is ready to trigger\n // change event. New inputs might be added later\n if (!inputKeys.length && this.isMounted()) {\n this.setState({\n canChange: true\n });\n }\n },\n\n // Method put on each input component to register\n // itself to the form\n attachToForm: function (component) {\n this.inputs[component.props.name] = component;\n this.model[component.props.name] = component.state._value;\n this.validate(component);\n },\n\n // Method put on each input component to unregister\n // itself from the form\n detachFromForm: function (component) {\n delete this.inputs[component.props.name];\n delete this.model[component.props.name];\n },\n render: function () {\n\n return (\n
\n {this.props.children}\n {/*this.traverseChildrenAndRegisterInputs(this.props.children)*/}\n
\n );\n\n }\n});\n\nif (!global.exports && !global.module && (!global.define || !global.define.amd)) {\n global.Formsy = Formsy;\n}\n\nmodule.exports = Formsy;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/main.js\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external \"react\"\n ** module id = 1\n ** module chunks = 0\n **/","var utils = require('./utils.js');\nvar React = global.React || require('react');\n\nvar convertValidationsToObject = function (validations) {\n\n if (typeof validations === 'string') {\n\n return validations.split(/\\,(?![^{\\[]*[}\\]])/g).reduce(function (validations, validation) {\n var args = validation.split(':');\n var validateMethod = args.shift();\n\n args = args.map(function (arg) {\n try {\n return JSON.parse(arg);\n } catch (e) {\n return arg; // It is a string if it can not parse it\n }\n });\n\n if (args.length > 1) {\n throw new Error('Formsy does not support multiple args on string validations. Use object format of validations instead.');\n }\n\n validations[validateMethod] = args.length ? args[0] : true;\n return validations;\n }, {});\n\n }\n\n return validations || {};\n};\n\nmodule.exports = {\n getInitialState: function () {\n return {\n _value: this.props.value,\n _isRequired: false,\n _isValid: true,\n _isPristine: true,\n _pristineValue: this.props.value,\n _validationError: [],\n _externalError: null,\n _formSubmitted: false\n };\n },\n contextTypes: {\n formsy: React.PropTypes.object // What about required?\n },\n getDefaultProps: function () {\n return {\n validationError: '',\n validationErrors: {}\n };\n },\n\n componentWillMount: function () {\n var configure = function () {\n this.setValidations(this.props.validations, this.props.required);\n\n // Pass a function instead?\n this.context.formsy.attachToForm(this);\n //this.props._attachToForm(this);\n }.bind(this);\n\n if (!this.props.name) {\n throw new Error('Form Input requires a name property when used');\n }\n\n /*\n if (!this.props._attachToForm) {\n return setTimeout(function () {\n if (!this.isMounted()) return;\n if (!this.props._attachToForm) {\n throw new Error('Form Mixin requires component to be nested in a Form');\n }\n configure();\n }.bind(this), 0);\n }\n */\n configure();\n },\n\n // We have to make the validate method is kept when new props are added\n componentWillReceiveProps: function (nextProps) {\n this.setValidations(nextProps.validations, nextProps.required);\n\n },\n\n componentDidUpdate: function (prevProps) {\n\n // If the value passed has changed, set it. If value is not passed it will\n // internally update, and this will never run\n if (!utils.isSame(this.props.value, prevProps.value)) {\n this.setValue(this.props.value);\n }\n\n // If validations or required is changed, run a new validation\n if (!utils.isSame(this.props.validations, prevProps.validations) || !utils.isSame(this.props.required, prevProps.required)) {\n this.context.formsy.validate(this);\n }\n },\n\n // Detach it when component unmounts\n componentWillUnmount: function () {\n this.context.formsy.detachFromForm(this);\n //this.props._detachFromForm(this);\n },\n\n setValidations: function (validations, required) {\n\n // Add validations to the store itself as the props object can not be modified\n this._validations = convertValidationsToObject(validations) || {};\n this._requiredValidations = required === true ? {isDefaultRequiredValue: true} : convertValidationsToObject(required);\n\n },\n\n // We validate after the value has been set\n setValue: function (value) {\n this.setState({\n _value: value,\n _isPristine: false\n }, function () {\n this.context.formsy.validate(this);\n //this.props._validate(this);\n }.bind(this));\n },\n resetValue: function () {\n this.setState({\n _value: this.state._pristineValue,\n _isPristine: true\n }, function () {\n this.context.formsy.validate(this);\n //this.props._validate(this);\n });\n },\n getValue: function () {\n return this.state._value;\n },\n hasValue: function () {\n return this.state._value !== '';\n },\n getErrorMessage: function () {\n var messages = this.getErrorMessages();\n return messages.length ? messages[0] : null;\n },\n getErrorMessages: function () {\n return !this.isValid() || this.showRequired() ? (this.state._externalError || this.state._validationError || []) : [];\n },\n isFormDisabled: function () {\n return this.context.formsy.isFormDisabled();\n //return this.props._isFormDisabled();\n },\n isValid: function () {\n return this.state._isValid;\n },\n isPristine: function () {\n return this.state._isPristine;\n },\n isFormSubmitted: function () {\n return this.state._formSubmitted;\n },\n isRequired: function () {\n return !!this.props.required;\n },\n showRequired: function () {\n return this.state._isRequired;\n },\n showError: function () {\n return !this.showRequired() && !this.isValid();\n },\n isValidValue: function (value) {\n return this.context.formsy.isValidValue.call(null, this, value);\n //return this.props._isValidValue.call(null, this, value);\n }\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/Mixin.js\n **/","module.exports = {\n arraysDiffer: function (a, b) {\n var isDifferent = false;\n if (a.length !== b.length) {\n isDifferent = true;\n } else {\n a.forEach(function (item, index) {\n if (!this.isSame(item, b[index])) {\n isDifferent = true;\n }\n }, this);\n }\n return isDifferent;\n },\n\n objectsDiffer: function (a, b) {\n var isDifferent = false;\n if (Object.keys(a).length !== Object.keys(b).length) {\n isDifferent = true;\n } else {\n Object.keys(a).forEach(function (key) {\n if (!this.isSame(a[key], b[key])) {\n isDifferent = true;\n }\n }, this);\n }\n return isDifferent;\n },\n\n isSame: function (a, b) {\n if (typeof a !== typeof b) {\n return false;\n } else if (Array.isArray(a)) {\n return !this.arraysDiffer(a, b);\n } else if (typeof a === 'object' && a !== null && b !== null) {\n return !this.objectsDiffer(a, b);\n }\n\n return a === b;\n }\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/utils.js\n **/","var React = global.React || require('react');\nvar Mixin = require('./Mixin.js');\nmodule.exports = function () {\n return function (Component) {\n return React.createClass({\n mixins: [Mixin],\n render: function () {\n return React.createElement(Component, {\n setValidations: this.setValidations,\n setValue: this.setValue,\n resetValue: this.resetValue,\n getValue: this.getValue,\n hasValue: this.hasValue,\n getErrorMessage: this.getErrorMessage,\n getErrorMessages: this.getErrorMessages,\n isFormDisabled: this.isFormDisabled,\n isValid: this.isValid,\n isPristine: this.isPristine,\n isFormSubmitted: this.isFormSubmitted,\n isRequired: this.isRequired,\n showRequired: this.showRequired,\n showError: this.showError,\n isValidValue: this.isValidValue\n });\n }\n });\n };\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/Decorator.js\n **/","var React = global.React || require('react');\nvar Mixin = require('./Mixin.js');\nmodule.exports = function (Component) {\n return React.createClass({\n mixins: [Mixin],\n render: function () {\n return React.createElement(Component, {\n setValidations: this.setValidations,\n setValue: this.setValue,\n resetValue: this.resetValue,\n getValue: this.getValue,\n hasValue: this.hasValue,\n getErrorMessage: this.getErrorMessage,\n getErrorMessages: this.getErrorMessages,\n isFormDisabled: this.isFormDisabled,\n isValid: this.isValid,\n isPristine: this.isPristine,\n isFormSubmitted: this.isFormSubmitted,\n isRequired: this.isRequired,\n showRequired: this.showRequired,\n showError: this.showError,\n isValidValue: this.isValidValue\n });\n }\n });\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/HOC.js\n **/","var isExisty = function (value) {\n return value !== null && value !== undefined;\n};\n\nvar isEmpty = function (value) {\n return value === '';\n};\n\nvar validations = {\n isDefaultRequiredValue: function (values, value) {\n return value === undefined || value === '';\n },\n isExisty: function (values, value) {\n return isExisty(value);\n },\n matchRegexp: function (values, value, regexp) {\n return !isExisty(value) || isEmpty(value) || regexp.test(value);\n },\n isUndefined: function (values, value) {\n return value === undefined;\n },\n isEmptyString: function (values, value) {\n return isEmpty(value);\n },\n isEmail: function (values, value) {\n return validations.matchRegexp(values, value, /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i);\n },\n isUrl: function (values, value) {\n return validations.matchRegexp(values, value, /^(https?|s?ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i);\n },\n isTrue: function (values, value) {\n return value === true;\n },\n isFalse: function (values, value) {\n return value === false;\n },\n isNumeric: function (values, value) {\n if (typeof value === 'number') {\n return true;\n }\n return validations.matchRegexp(values, value, /^[-+]?(\\d*[.])?\\d+$/);\n },\n isAlpha: function (values, value) {\n return validations.matchRegexp(values, value, /^[a-zA-Z]+$/);\n },\n isWords: function (values, value) {\n return validations.matchRegexp(values, value, /^[a-zA-Z\\s]+$/);\n },\n isSpecialWords: function (values, value) {\n return validations.matchRegexp(values, value, /^[a-zA-Z\\s\\u00C0-\\u017F]+$/);\n },\n isLength: function (values, value, length) {\n return !isExisty(value) || isEmpty(value) || value.length === length;\n },\n equals: function (values, value, eql) {\n return !isExisty(value) || isEmpty(value) || value == eql;\n },\n equalsField: function (values, value, field) {\n return value == values[field];\n },\n maxLength: function (values, value, length) {\n return !isExisty(value) || value.length <= length;\n },\n minLength: function (values, value, length) {\n return !isExisty(value) || isEmpty(value) || value.length >= length;\n }\n};\n\nmodule.exports = validations;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/validationRules.js\n **/","module.exports = function (source) {\n\n\n // \"foo[0]\"\n return Object.keys(source).reduce(function (output, key) {\n\n var parentKey = key.match(/[^\\[]*/i);\n var paths = key.match(/\\[.*?\\]/g) || [];\n paths = [parentKey[0]].concat(paths).map(function (key) {\n return key.replace(/\\[|\\]/g, '');\n });\n\n var currentPath = output;\n while (paths.length) {\n\n var pathKey = paths.shift();\n\n if (pathKey in currentPath) {\n currentPath = currentPath[pathKey];\n } else {\n currentPath[pathKey] = paths.length ? isNaN(paths[0]) ? {} : [] : source[key];\n currentPath = currentPath[pathKey];\n }\n\n }\n\n return output;\n\n }, {});\n\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/form-data-to-object/index.js\n ** module id = 7\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///formsy-react.js","webpack:///webpack/bootstrap b470bfbf32881c25245e","webpack:///./src/main.js","webpack:///external \"react\"","webpack:///./src/Mixin.js","webpack:///./src/utils.js","webpack:///./src/Decorator.js","webpack:///./src/HOC.js","webpack:///./src/validationRules.js","webpack:///./~/form-data-to-object/index.js"],"names":["root","factory","exports","module","require","define","amd","this","__WEBPACK_EXTERNAL_MODULE_1__","modules","__webpack_require__","moduleId","installedModules","id","loaded","call","m","c","p","global","_extends","Object","assign","target","i","arguments","length","source","key","prototype","hasOwnProperty","React","Formsy","validationRules","formDataToObject","utils","Mixin","HOC","Decorator","options","defaults","passedOptions","addValidationRule","name","func","Form","createClass","displayName","getInitialState","isValid","isSubmitting","canChange","getDefaultProps","onSuccess","onError","onSubmit","onValidSubmit","onInvalidSubmit","onSubmitted","onValid","onInvalid","onChange","validationErrors","preventExternalInvalidation","childContextTypes","formsy","PropTypes","object","getChildContext","attachToForm","detachFromForm","validate","isFormDisabled","isValidValue","component","value","runValidation","bind","componentWillMount","inputs","model","componentDidMount","validateForm","componentWillUpdate","prevInputKeys","keys","componentDidUpdate","props","setInputValidationErrors","newInputKeys","arraysDiffer","reset","data","setFormPristine","resetModel","submit","event","preventDefault","updateModel","mapModel","updateInputsWithError","state","mapping","reduce","mappedModel","keyArray","split","base","currentKey","shift","forEach","_value","setValue","resetValue","errors","index","args","_isValid","_validationError","setState","apply","isChanged","isSame","getPristineValues","getCurrentValues","Error","JSON","stringify","_externalError","traverseChildrenAndRegisterInputs","children","Children","map","child","cloneElement","_attachToForm","_detachFromForm","_validate","_isFormDisabled","_isValidValue","disabled","isPristine","inputKeys","_formSubmitted","_isPristine","validation","_isRequired","isRequired","error","currentValues","validationError","validationResults","runRules","_validations","requiredResults","_requiredValidations","failed","success","filter","x","pos","arr","indexOf","validations","results","validationMethod","push","allIsValid","onValidationComplete","every","isMounted","render","createElement","convertValidationsToObject","validateMethod","arg","parse","e","_pristineValue","contextTypes","configure","setValidations","required","context","componentWillReceiveProps","nextProps","prevProps","componentWillUnmount","isDefaultRequiredValue","getValue","hasValue","getErrorMessage","messages","getErrorMessages","showRequired","isFormSubmitted","showError","a","b","isDifferent","item","objectsDiffer","Array","isArray","Component","mixins","_isExisty","undefined","isEmpty","values","isExisty","matchRegexp","regexp","test","isUndefined","isEmptyString","isEmail","isUrl","isTrue","isFalse","isNumeric","isAlpha","isWords","isSpecialWords","isLength","equals","eql","equalsField","field","maxLength","minLength","output","parentKey","match","paths","concat","replace","currentPath","pathKey","isNaN"],"mappings":"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","file":"formsy-react.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Formsy\"] = factory(require(\"react\"));\n\telse\n\t\troot[\"Formsy\"] = factory(root[\"react\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Formsy\"] = factory(require(\"react\"));\n\telse\n\t\troot[\"Formsy\"] = factory(root[\"react\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global) {'use strict';\n\t\n\tvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\t\n\tvar React = global.React || __webpack_require__(1);\n\tvar Formsy = {};\n\tvar validationRules = __webpack_require__(6);\n\tvar formDataToObject = __webpack_require__(7);\n\tvar utils = __webpack_require__(3);\n\tvar Mixin = __webpack_require__(2);\n\tvar HOC = __webpack_require__(5);\n\tvar Decorator = __webpack_require__(4);\n\tvar options = {};\n\t\n\tFormsy.Mixin = Mixin;\n\tFormsy.HOC = HOC;\n\tFormsy.Decorator = Decorator;\n\t\n\tFormsy.defaults = function (passedOptions) {\n\t options = passedOptions;\n\t};\n\t\n\tFormsy.addValidationRule = function (name, func) {\n\t validationRules[name] = func;\n\t};\n\t\n\tFormsy.Form = React.createClass({\n\t displayName: 'Form',\n\t\n\t getInitialState: function getInitialState() {\n\t return {\n\t isValid: true,\n\t isSubmitting: false,\n\t canChange: false\n\t };\n\t },\n\t getDefaultProps: function getDefaultProps() {\n\t return {\n\t onSuccess: function onSuccess() {},\n\t onError: function onError() {},\n\t onSubmit: function onSubmit() {},\n\t onValidSubmit: function onValidSubmit() {},\n\t onInvalidSubmit: function onInvalidSubmit() {},\n\t onSubmitted: function onSubmitted() {},\n\t onValid: function onValid() {},\n\t onInvalid: function onInvalid() {},\n\t onChange: function onChange() {},\n\t validationErrors: null,\n\t preventExternalInvalidation: false\n\t };\n\t },\n\t\n\t childContextTypes: {\n\t formsy: React.PropTypes.object\n\t },\n\t getChildContext: function getChildContext() {\n\t return {\n\t formsy: {\n\t attachToForm: this.attachToForm,\n\t detachFromForm: this.detachFromForm,\n\t validate: this.validate,\n\t isFormDisabled: this.isFormDisabled,\n\t isValidValue: (function (component, value) {\n\t return this.runValidation(component, value).isValid;\n\t }).bind(this)\n\t }\n\t };\n\t },\n\t\n\t // Add a map to store the inputs of the form, a model to store\n\t // the values of the form and register child inputs\n\t componentWillMount: function componentWillMount() {\n\t this.inputs = {};\n\t this.model = {};\n\t },\n\t\n\t componentDidMount: function componentDidMount() {\n\t this.validateForm();\n\t },\n\t\n\t componentWillUpdate: function componentWillUpdate() {\n\t\n\t // Keep a reference to input keys before form updates,\n\t // to check if inputs has changed after render\n\t this.prevInputKeys = Object.keys(this.inputs);\n\t },\n\t\n\t componentDidUpdate: function componentDidUpdate() {\n\t\n\t if (this.props.validationErrors) {\n\t this.setInputValidationErrors(this.props.validationErrors);\n\t }\n\t\n\t var newInputKeys = Object.keys(this.inputs);\n\t if (utils.arraysDiffer(this.prevInputKeys, newInputKeys)) {\n\t this.validateForm();\n\t }\n\t },\n\t\n\t // Allow resetting to specified data\n\t reset: function reset(data) {\n\t this.setFormPristine(true);\n\t this.resetModel(data);\n\t },\n\t\n\t // Update model, submit to url prop and send the model\n\t submit: function submit(event) {\n\t\n\t event && event.preventDefault();\n\t\n\t // Trigger form as not pristine.\n\t // If any inputs have not been touched yet this will make them dirty\n\t // so validation becomes visible (if based on isPristine)\n\t this.setFormPristine(false);\n\t this.updateModel();\n\t var model = this.mapModel();\n\t this.props.onSubmit(model, this.resetModel, this.updateInputsWithError);\n\t this.state.isValid ? this.props.onValidSubmit(model, this.resetModel, this.updateInputsWithError) : this.props.onInvalidSubmit(model, this.resetModel, this.updateInputsWithError);\n\t },\n\t\n\t mapModel: function mapModel() {\n\t if (this.props.mapping) {\n\t return this.props.mapping(this.model);\n\t } else {\n\t return formDataToObject(Object.keys(this.model).reduce((function (mappedModel, key) {\n\t\n\t var keyArray = key.split('.');\n\t var base = mappedModel;\n\t while (keyArray.length) {\n\t var currentKey = keyArray.shift();\n\t base = base[currentKey] = keyArray.length ? base[currentKey] || {} : this.model[key];\n\t }\n\t\n\t return mappedModel;\n\t }).bind(this), {}));\n\t }\n\t },\n\t\n\t // Goes through all registered components and\n\t // updates the model values\n\t updateModel: function updateModel() {\n\t Object.keys(this.inputs).forEach((function (name) {\n\t var component = this.inputs[name];\n\t this.model[name] = component.state._value;\n\t }).bind(this));\n\t },\n\t\n\t // Reset each key in the model to the original / initial / specified value\n\t resetModel: function resetModel(data) {\n\t Object.keys(this.inputs).forEach((function (name) {\n\t if (data && data[name]) {\n\t this.inputs[name].setValue(data[name]);\n\t } else {\n\t this.inputs[name].resetValue();\n\t }\n\t }).bind(this));\n\t this.validateForm();\n\t },\n\t\n\t setInputValidationErrors: function setInputValidationErrors(errors) {\n\t Object.keys(this.inputs).forEach((function (name, index) {\n\t var component = this.inputs[name];\n\t var args = [{\n\t _isValid: !(name in errors),\n\t _validationError: typeof errors[name] === 'string' ? [errors[name]] : errors[name]\n\t }];\n\t component.setState.apply(component, args);\n\t }).bind(this));\n\t },\n\t\n\t // Checks if the values have changed from their initial value\n\t isChanged: function isChanged() {\n\t return !utils.isSame(this.getPristineValues(), this.getCurrentValues());\n\t },\n\t\n\t getPristineValues: function getPristineValues() {\n\t var inputs = this.inputs;\n\t return Object.keys(inputs).reduce(function (data, name) {\n\t var component = inputs[name];\n\t data[name] = component.props.value;\n\t return data;\n\t }, {});\n\t },\n\t\n\t // Go through errors from server and grab the components\n\t // stored in the inputs map. Change their state to invalid\n\t // and set the serverError message\n\t updateInputsWithError: function updateInputsWithError(errors) {\n\t Object.keys(errors).forEach((function (name, index) {\n\t var component = this.inputs[name];\n\t\n\t if (!component) {\n\t throw new Error('You are trying to update an input that does not exist. Verify errors object with input names. ' + JSON.stringify(errors));\n\t }\n\t var args = [{\n\t _isValid: this.props.preventExternalInvalidation || false,\n\t _externalError: typeof errors[name] === 'string' ? [errors[name]] : errors[name]\n\t }];\n\t component.setState.apply(component, args);\n\t }).bind(this));\n\t },\n\t\n\t // Traverse the children and children of children to find\n\t // all inputs by checking the name prop. Maybe do a better\n\t // check here\n\t traverseChildrenAndRegisterInputs: function traverseChildrenAndRegisterInputs(children) {\n\t\n\t if (typeof children !== 'object' || children === null) {\n\t return children;\n\t }\n\t return React.Children.map(children, function (child) {\n\t\n\t if (typeof child !== 'object' || child === null) {\n\t return child;\n\t }\n\t\n\t if (child.props && child.props.name) {\n\t\n\t return React.cloneElement(child, {\n\t _attachToForm: this.attachToForm,\n\t _detachFromForm: this.detachFromForm,\n\t _validate: this.validate,\n\t _isFormDisabled: this.isFormDisabled,\n\t _isValidValue: (function (component, value) {\n\t return this.runValidation(component, value).isValid;\n\t }).bind(this)\n\t }, child.props && child.props.children);\n\t } else {\n\t return React.cloneElement(child, {}, this.traverseChildrenAndRegisterInputs(child.props && child.props.children));\n\t }\n\t }, this);\n\t },\n\t\n\t isFormDisabled: function isFormDisabled() {\n\t return this.props.disabled;\n\t },\n\t\n\t getCurrentValues: function getCurrentValues() {\n\t return Object.keys(this.inputs).reduce((function (data, name) {\n\t var component = this.inputs[name];\n\t data[name] = component.state._value;\n\t return data;\n\t }).bind(this), {});\n\t },\n\t\n\t setFormPristine: function setFormPristine(isPristine) {\n\t var inputs = this.inputs;\n\t var inputKeys = Object.keys(inputs);\n\t\n\t this.setState({\n\t _formSubmitted: !isPristine\n\t });\n\t\n\t // Iterate through each component and set it as pristine\n\t // or \"dirty\".\n\t inputKeys.forEach((function (name, index) {\n\t var component = inputs[name];\n\t component.setState({\n\t _formSubmitted: !isPristine,\n\t _isPristine: isPristine\n\t });\n\t }).bind(this));\n\t },\n\t\n\t // Use the binded values and the actual input value to\n\t // validate the input and set its state. Then check the\n\t // state of the form itself\n\t validate: function validate(component) {\n\t\n\t // Trigger onChange\n\t if (this.state.canChange) {\n\t this.props.onChange(this.getCurrentValues(), this.isChanged());\n\t }\n\t\n\t var validation = this.runValidation(component);\n\t // Run through the validations, split them up and call\n\t // the validator IF there is a value or it is required\n\t component.setState({\n\t _isValid: validation.isValid,\n\t _isRequired: validation.isRequired,\n\t _validationError: validation.error,\n\t _externalError: null\n\t }, this.validateForm);\n\t },\n\t\n\t // Checks validation on current value or a passed value\n\t runValidation: function runValidation(component, value) {\n\t\n\t var currentValues = this.getCurrentValues();\n\t var validationErrors = component.props.validationErrors;\n\t var validationError = component.props.validationError;\n\t value = arguments.length === 2 ? value : component.state._value;\n\t\n\t var validationResults = this.runRules(value, currentValues, component._validations);\n\t var requiredResults = this.runRules(value, currentValues, component._requiredValidations);\n\t\n\t // the component defines an explicit validate function\n\t if (typeof component.validate === \"function\") {\n\t validationResults.failed = component.validate() ? [] : ['failed'];\n\t }\n\t\n\t var isRequired = Object.keys(component._requiredValidations).length ? !!requiredResults.success.length : false;\n\t var isValid = !validationResults.failed.length && !(this.props.validationErrors && this.props.validationErrors[component.props.name]);\n\t\n\t return {\n\t isRequired: isRequired,\n\t isValid: isRequired ? false : isValid,\n\t error: (function () {\n\t\n\t if (isValid && !isRequired) {\n\t return [];\n\t }\n\t\n\t if (validationResults.errors.length) {\n\t return validationResults.errors;\n\t }\n\t\n\t if (this.props.validationErrors && this.props.validationErrors[component.props.name]) {\n\t return typeof this.props.validationErrors[component.props.name] === 'string' ? [this.props.validationErrors[component.props.name]] : this.props.validationErrors[component.props.name];\n\t }\n\t\n\t if (isRequired) {\n\t var error = validationErrors[requiredResults.success[0]];\n\t return error ? [error] : null;\n\t }\n\t\n\t if (validationResults.failed.length) {\n\t return validationResults.failed.map(function (failed) {\n\t return validationErrors[failed] ? validationErrors[failed] : validationError;\n\t }).filter(function (x, pos, arr) {\n\t // Remove duplicates\n\t return arr.indexOf(x) === pos;\n\t });\n\t }\n\t }).call(this)\n\t };\n\t },\n\t\n\t runRules: function runRules(value, currentValues, validations) {\n\t\n\t var results = {\n\t errors: [],\n\t failed: [],\n\t success: []\n\t };\n\t if (Object.keys(validations).length) {\n\t Object.keys(validations).forEach(function (validationMethod) {\n\t\n\t if (validationRules[validationMethod] && typeof validations[validationMethod] === 'function') {\n\t throw new Error('Formsy does not allow you to override default validations: ' + validationMethod);\n\t }\n\t\n\t if (!validationRules[validationMethod] && typeof validations[validationMethod] !== 'function') {\n\t throw new Error('Formsy does not have the validation rule: ' + validationMethod);\n\t }\n\t\n\t if (typeof validations[validationMethod] === 'function') {\n\t var validation = validations[validationMethod](currentValues, value);\n\t if (typeof validation === 'string') {\n\t results.errors.push(validation);\n\t results.failed.push(validationMethod);\n\t } else if (!validation) {\n\t results.failed.push(validationMethod);\n\t }\n\t return;\n\t } else if (typeof validations[validationMethod] !== 'function') {\n\t var validation = validationRules[validationMethod](currentValues, value, validations[validationMethod]);\n\t if (typeof validation === 'string') {\n\t results.errors.push(validation);\n\t results.failed.push(validationMethod);\n\t } else if (!validation) {\n\t results.failed.push(validationMethod);\n\t } else {\n\t results.success.push(validationMethod);\n\t }\n\t return;\n\t }\n\t\n\t return results.success.push(validationMethod);\n\t });\n\t }\n\t\n\t return results;\n\t },\n\t\n\t // Validate the form by going through all child input components\n\t // and check their state\n\t validateForm: function validateForm() {\n\t var allIsValid;\n\t var inputs = this.inputs;\n\t var inputKeys = Object.keys(inputs);\n\t\n\t // We need a callback as we are validating all inputs again. This will\n\t // run when the last component has set its state\n\t var onValidationComplete = (function () {\n\t allIsValid = inputKeys.every((function (name) {\n\t return inputs[name].state._isValid;\n\t }).bind(this));\n\t\n\t this.setState({\n\t isValid: allIsValid\n\t });\n\t\n\t if (allIsValid) {\n\t this.props.onValid();\n\t } else {\n\t this.props.onInvalid();\n\t }\n\t\n\t // Tell the form that it can start to trigger change events\n\t this.setState({\n\t canChange: true\n\t });\n\t }).bind(this);\n\t\n\t // Run validation again in case affected by other inputs. The\n\t // last component validated will run the onValidationComplete callback\n\t inputKeys.forEach((function (name, index) {\n\t var component = inputs[name];\n\t var validation = this.runValidation(component);\n\t if (validation.isValid && component.state._externalError) {\n\t validation.isValid = false;\n\t }\n\t component.setState({\n\t _isValid: validation.isValid,\n\t _isRequired: validation.isRequired,\n\t _validationError: validation.error,\n\t _externalError: !validation.isValid && component.state._externalError ? component.state._externalError : null\n\t }, index === inputKeys.length - 1 ? onValidationComplete : null);\n\t }).bind(this));\n\t\n\t // If there are no inputs, set state where form is ready to trigger\n\t // change event. New inputs might be added later\n\t if (!inputKeys.length && this.isMounted()) {\n\t this.setState({\n\t canChange: true\n\t });\n\t }\n\t },\n\t\n\t // Method put on each input component to register\n\t // itself to the form\n\t attachToForm: function attachToForm(component) {\n\t this.inputs[component.props.name] = component;\n\t this.model[component.props.name] = component.state._value;\n\t this.validate(component);\n\t },\n\t\n\t // Method put on each input component to unregister\n\t // itself from the form\n\t detachFromForm: function detachFromForm(component) {\n\t delete this.inputs[component.props.name];\n\t delete this.model[component.props.name];\n\t },\n\t render: function render() {\n\t\n\t return React.createElement(\n\t 'form',\n\t _extends({}, this.props, { onSubmit: this.submit }),\n\t this.props.children\n\t );\n\t }\n\t});\n\t\n\tif (!global.exports && !global.module && (!global.define || !global.define.amd)) {\n\t global.Formsy = Formsy;\n\t}\n\t\n\tmodule.exports = Formsy;\n\t/*this.traverseChildrenAndRegisterInputs(this.props.children)*/\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n\n/***/ },\n/* 1 */\n/***/ function(module, exports) {\n\n\tmodule.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global) {'use strict';\n\t\n\tvar utils = __webpack_require__(3);\n\tvar React = global.React || __webpack_require__(1);\n\t\n\tvar convertValidationsToObject = function convertValidationsToObject(validations) {\n\t\n\t if (typeof validations === 'string') {\n\t\n\t return validations.split(/\\,(?![^{\\[]*[}\\]])/g).reduce(function (validations, validation) {\n\t var args = validation.split(':');\n\t var validateMethod = args.shift();\n\t\n\t args = args.map(function (arg) {\n\t try {\n\t return JSON.parse(arg);\n\t } catch (e) {\n\t return arg; // It is a string if it can not parse it\n\t }\n\t });\n\t\n\t if (args.length > 1) {\n\t throw new Error('Formsy does not support multiple args on string validations. Use object format of validations instead.');\n\t }\n\t\n\t validations[validateMethod] = args.length ? args[0] : true;\n\t return validations;\n\t }, {});\n\t }\n\t\n\t return validations || {};\n\t};\n\t\n\tmodule.exports = {\n\t getInitialState: function getInitialState() {\n\t return {\n\t _value: this.props.value,\n\t _isRequired: false,\n\t _isValid: true,\n\t _isPristine: true,\n\t _pristineValue: this.props.value,\n\t _validationError: [],\n\t _externalError: null,\n\t _formSubmitted: false\n\t };\n\t },\n\t contextTypes: {\n\t formsy: React.PropTypes.object // What about required?\n\t },\n\t getDefaultProps: function getDefaultProps() {\n\t return {\n\t validationError: '',\n\t validationErrors: {}\n\t };\n\t },\n\t\n\t componentWillMount: function componentWillMount() {\n\t var configure = (function () {\n\t this.setValidations(this.props.validations, this.props.required);\n\t\n\t // Pass a function instead?\n\t this.context.formsy.attachToForm(this);\n\t //this.props._attachToForm(this);\n\t }).bind(this);\n\t\n\t if (!this.props.name) {\n\t throw new Error('Form Input requires a name property when used');\n\t }\n\t\n\t /*\n\t if (!this.props._attachToForm) {\n\t return setTimeout(function () {\n\t if (!this.isMounted()) return;\n\t if (!this.props._attachToForm) {\n\t throw new Error('Form Mixin requires component to be nested in a Form');\n\t }\n\t configure();\n\t }.bind(this), 0);\n\t }\n\t */\n\t configure();\n\t },\n\t\n\t // We have to make the validate method is kept when new props are added\n\t componentWillReceiveProps: function componentWillReceiveProps(nextProps) {\n\t this.setValidations(nextProps.validations, nextProps.required);\n\t },\n\t\n\t componentDidUpdate: function componentDidUpdate(prevProps) {\n\t\n\t // If the value passed has changed, set it. If value is not passed it will\n\t // internally update, and this will never run\n\t if (!utils.isSame(this.props.value, prevProps.value)) {\n\t this.setValue(this.props.value);\n\t }\n\t\n\t // If validations or required is changed, run a new validation\n\t if (!utils.isSame(this.props.validations, prevProps.validations) || !utils.isSame(this.props.required, prevProps.required)) {\n\t this.context.formsy.validate(this);\n\t }\n\t },\n\t\n\t // Detach it when component unmounts\n\t componentWillUnmount: function componentWillUnmount() {\n\t this.context.formsy.detachFromForm(this);\n\t //this.props._detachFromForm(this);\n\t },\n\t\n\t setValidations: function setValidations(validations, required) {\n\t\n\t // Add validations to the store itself as the props object can not be modified\n\t this._validations = convertValidationsToObject(validations) || {};\n\t this._requiredValidations = required === true ? { isDefaultRequiredValue: true } : convertValidationsToObject(required);\n\t },\n\t\n\t // We validate after the value has been set\n\t setValue: function setValue(value) {\n\t this.setState({\n\t _value: value,\n\t _isPristine: false\n\t }, (function () {\n\t this.context.formsy.validate(this);\n\t //this.props._validate(this);\n\t }).bind(this));\n\t },\n\t resetValue: function resetValue() {\n\t this.setState({\n\t _value: this.state._pristineValue,\n\t _isPristine: true\n\t }, function () {\n\t this.context.formsy.validate(this);\n\t //this.props._validate(this);\n\t });\n\t },\n\t getValue: function getValue() {\n\t return this.state._value;\n\t },\n\t hasValue: function hasValue() {\n\t return this.state._value !== '';\n\t },\n\t getErrorMessage: function getErrorMessage() {\n\t var messages = this.getErrorMessages();\n\t return messages.length ? messages[0] : null;\n\t },\n\t getErrorMessages: function getErrorMessages() {\n\t return !this.isValid() || this.showRequired() ? this.state._externalError || this.state._validationError || [] : [];\n\t },\n\t isFormDisabled: function isFormDisabled() {\n\t return this.context.formsy.isFormDisabled();\n\t //return this.props._isFormDisabled();\n\t },\n\t isValid: function isValid() {\n\t return this.state._isValid;\n\t },\n\t isPristine: function isPristine() {\n\t return this.state._isPristine;\n\t },\n\t isFormSubmitted: function isFormSubmitted() {\n\t return this.state._formSubmitted;\n\t },\n\t isRequired: function isRequired() {\n\t return !!this.props.required;\n\t },\n\t showRequired: function showRequired() {\n\t return this.state._isRequired;\n\t },\n\t showError: function showError() {\n\t return !this.showRequired() && !this.isValid();\n\t },\n\t isValidValue: function isValidValue(value) {\n\t return this.context.formsy.isValidValue.call(null, this, value);\n\t //return this.props._isValidValue.call(null, this, value);\n\t }\n\t};\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n\n/***/ },\n/* 3 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = {\n\t arraysDiffer: function arraysDiffer(a, b) {\n\t var isDifferent = false;\n\t if (a.length !== b.length) {\n\t isDifferent = true;\n\t } else {\n\t a.forEach(function (item, index) {\n\t if (!this.isSame(item, b[index])) {\n\t isDifferent = true;\n\t }\n\t }, this);\n\t }\n\t return isDifferent;\n\t },\n\t\n\t objectsDiffer: function objectsDiffer(a, b) {\n\t var isDifferent = false;\n\t if (Object.keys(a).length !== Object.keys(b).length) {\n\t isDifferent = true;\n\t } else {\n\t Object.keys(a).forEach(function (key) {\n\t if (!this.isSame(a[key], b[key])) {\n\t isDifferent = true;\n\t }\n\t }, this);\n\t }\n\t return isDifferent;\n\t },\n\t\n\t isSame: function isSame(a, b) {\n\t if (typeof a !== typeof b) {\n\t return false;\n\t } else if (Array.isArray(a)) {\n\t return !this.arraysDiffer(a, b);\n\t } else if (typeof a === 'object' && a !== null && b !== null) {\n\t return !this.objectsDiffer(a, b);\n\t }\n\t\n\t return a === b;\n\t }\n\t};\n\n/***/ },\n/* 4 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global) {'use strict';\n\t\n\tvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\t\n\tvar React = global.React || __webpack_require__(1);\n\tvar Mixin = __webpack_require__(2);\n\tmodule.exports = function () {\n\t return function (Component) {\n\t return React.createClass({\n\t mixins: [Mixin],\n\t render: function render() {\n\t return React.createElement(Component, _extends({\n\t setValidations: this.setValidations,\n\t setValue: this.setValue,\n\t resetValue: this.resetValue,\n\t getValue: this.getValue,\n\t hasValue: this.hasValue,\n\t getErrorMessage: this.getErrorMessage,\n\t getErrorMessages: this.getErrorMessages,\n\t isFormDisabled: this.isFormDisabled,\n\t isValid: this.isValid,\n\t isPristine: this.isPristine,\n\t isFormSubmitted: this.isFormSubmitted,\n\t isRequired: this.isRequired,\n\t showRequired: this.showRequired,\n\t showError: this.showError,\n\t isValidValue: this.isValidValue\n\t }, this.props));\n\t }\n\t });\n\t };\n\t};\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n\n/***/ },\n/* 5 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global) {'use strict';\n\t\n\tvar React = global.React || __webpack_require__(1);\n\tvar Mixin = __webpack_require__(2);\n\tmodule.exports = function (Component) {\n\t return React.createClass({\n\t mixins: [Mixin],\n\t render: function render() {\n\t return React.createElement(Component, {\n\t setValidations: this.setValidations,\n\t setValue: this.setValue,\n\t resetValue: this.resetValue,\n\t getValue: this.getValue,\n\t hasValue: this.hasValue,\n\t getErrorMessage: this.getErrorMessage,\n\t getErrorMessages: this.getErrorMessages,\n\t isFormDisabled: this.isFormDisabled,\n\t isValid: this.isValid,\n\t isPristine: this.isPristine,\n\t isFormSubmitted: this.isFormSubmitted,\n\t isRequired: this.isRequired,\n\t showRequired: this.showRequired,\n\t showError: this.showError,\n\t isValidValue: this.isValidValue\n\t });\n\t }\n\t });\n\t};\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n\n/***/ },\n/* 6 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tvar _isExisty = function _isExisty(value) {\n\t return value !== null && value !== undefined;\n\t};\n\t\n\tvar isEmpty = function isEmpty(value) {\n\t return value === '';\n\t};\n\t\n\tvar validations = {\n\t isDefaultRequiredValue: function isDefaultRequiredValue(values, value) {\n\t return value === undefined || value === '';\n\t },\n\t isExisty: function isExisty(values, value) {\n\t return _isExisty(value);\n\t },\n\t matchRegexp: function matchRegexp(values, value, regexp) {\n\t return !_isExisty(value) || isEmpty(value) || regexp.test(value);\n\t },\n\t isUndefined: function isUndefined(values, value) {\n\t return value === undefined;\n\t },\n\t isEmptyString: function isEmptyString(values, value) {\n\t return isEmpty(value);\n\t },\n\t isEmail: function isEmail(values, value) {\n\t return validations.matchRegexp(values, value, /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i);\n\t },\n\t isUrl: function isUrl(values, value) {\n\t return validations.matchRegexp(values, value, /^(https?|s?ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i);\n\t },\n\t isTrue: function isTrue(values, value) {\n\t return value === true;\n\t },\n\t isFalse: function isFalse(values, value) {\n\t return value === false;\n\t },\n\t isNumeric: function isNumeric(values, value) {\n\t if (typeof value === 'number') {\n\t return true;\n\t }\n\t return validations.matchRegexp(values, value, /^[-+]?(\\d*[.])?\\d+$/);\n\t },\n\t isAlpha: function isAlpha(values, value) {\n\t return validations.matchRegexp(values, value, /^[a-zA-Z]+$/);\n\t },\n\t isWords: function isWords(values, value) {\n\t return validations.matchRegexp(values, value, /^[a-zA-Z\\s]+$/);\n\t },\n\t isSpecialWords: function isSpecialWords(values, value) {\n\t return validations.matchRegexp(values, value, /^[a-zA-Z\\s\\u00C0-\\u017F]+$/);\n\t },\n\t isLength: function isLength(values, value, length) {\n\t return !_isExisty(value) || isEmpty(value) || value.length === length;\n\t },\n\t equals: function equals(values, value, eql) {\n\t return !_isExisty(value) || isEmpty(value) || value == eql;\n\t },\n\t equalsField: function equalsField(values, value, field) {\n\t return value == values[field];\n\t },\n\t maxLength: function maxLength(values, value, length) {\n\t return !_isExisty(value) || value.length <= length;\n\t },\n\t minLength: function minLength(values, value, length) {\n\t return !_isExisty(value) || isEmpty(value) || value.length >= length;\n\t }\n\t};\n\t\n\tmodule.exports = validations;\n\n/***/ },\n/* 7 */\n/***/ function(module, exports) {\n\n\tmodule.exports = function (source) {\n\t\n\t\n\t // \"foo[0]\"\n\t return Object.keys(source).reduce(function (output, key) {\n\t\n\t var parentKey = key.match(/[^\\[]*/i);\n\t var paths = key.match(/\\[.*?\\]/g) || [];\n\t paths = [parentKey[0]].concat(paths).map(function (key) {\n\t return key.replace(/\\[|\\]/g, '');\n\t });\n\t\n\t var currentPath = output;\n\t while (paths.length) {\n\t\n\t var pathKey = paths.shift();\n\t\n\t if (pathKey in currentPath) {\n\t currentPath = currentPath[pathKey];\n\t } else {\n\t currentPath[pathKey] = paths.length ? isNaN(paths[0]) ? {} : [] : source[key];\n\t currentPath = currentPath[pathKey];\n\t }\n\t\n\t }\n\t\n\t return output;\n\t\n\t }, {});\n\t\n\t};\n\n\n/***/ }\n/******/ ])\n});\n;\n\n\n/** WEBPACK FOOTER **\n ** formsy-react.js\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap b470bfbf32881c25245e\n **/","var React = global.React || require('react');\nvar Formsy = {};\nvar validationRules = require('./validationRules.js');\nvar formDataToObject = require('form-data-to-object');\nvar utils = require('./utils.js');\nvar Mixin = require('./Mixin.js');\nvar HOC = require('./HOC.js');\nvar Decorator = require('./Decorator.js');\nvar options = {};\n\nFormsy.Mixin = Mixin;\nFormsy.HOC = HOC;\nFormsy.Decorator = Decorator;\n\nFormsy.defaults = function (passedOptions) {\n options = passedOptions;\n};\n\nFormsy.addValidationRule = function (name, func) {\n validationRules[name] = func;\n};\n\nFormsy.Form = React.createClass({\n getInitialState: function () {\n return {\n isValid: true,\n isSubmitting: false,\n canChange: false\n };\n },\n getDefaultProps: function () {\n return {\n onSuccess: function () {},\n onError: function () {},\n onSubmit: function () {},\n onValidSubmit: function () {},\n onInvalidSubmit: function () {},\n onSubmitted: function () {},\n onValid: function () {},\n onInvalid: function () {},\n onChange: function () {},\n validationErrors: null,\n preventExternalInvalidation: false\n };\n },\n\n childContextTypes: {\n formsy: React.PropTypes.object\n },\n getChildContext: function () {\n return {\n formsy: {\n attachToForm: this.attachToForm,\n detachFromForm: this.detachFromForm,\n validate: this.validate,\n isFormDisabled: this.isFormDisabled,\n isValidValue: function (component, value) {\n return this.runValidation(component, value).isValid;\n }.bind(this)\n }\n }\n },\n\n // Add a map to store the inputs of the form, a model to store\n // the values of the form and register child inputs\n componentWillMount: function () {\n this.inputs = {};\n this.model = {};\n },\n\n componentDidMount: function () {\n this.validateForm();\n },\n\n componentWillUpdate: function () {\n\n // Keep a reference to input keys before form updates,\n // to check if inputs has changed after render\n this.prevInputKeys = Object.keys(this.inputs);\n\n },\n\n componentDidUpdate: function () {\n\n if (this.props.validationErrors) {\n this.setInputValidationErrors(this.props.validationErrors);\n }\n\n var newInputKeys = Object.keys(this.inputs);\n if (utils.arraysDiffer(this.prevInputKeys, newInputKeys)) {\n this.validateForm();\n }\n\n },\n\n // Allow resetting to specified data\n reset: function (data) {\n this.setFormPristine(true);\n this.resetModel(data);\n },\n\n // Update model, submit to url prop and send the model\n submit: function (event) {\n\n event && event.preventDefault();\n\n // Trigger form as not pristine.\n // If any inputs have not been touched yet this will make them dirty\n // so validation becomes visible (if based on isPristine)\n this.setFormPristine(false);\n this.updateModel();\n var model = this.mapModel();\n this.props.onSubmit(model, this.resetModel, this.updateInputsWithError);\n this.state.isValid ? this.props.onValidSubmit(model, this.resetModel, this.updateInputsWithError) : this.props.onInvalidSubmit(model, this.resetModel, this.updateInputsWithError);\n\n },\n\n mapModel: function () {\n if (this.props.mapping) {\n return this.props.mapping(this.model)\n } else {\n return formDataToObject(Object.keys(this.model).reduce(function (mappedModel, key) {\n\n var keyArray = key.split('.');\n var base = mappedModel;\n while (keyArray.length) {\n var currentKey = keyArray.shift();\n base = (base[currentKey] = keyArray.length ? base[currentKey] || {} : this.model[key]);\n }\n\n return mappedModel;\n\n }.bind(this), {}));\n }\n },\n\n // Goes through all registered components and\n // updates the model values\n updateModel: function () {\n Object.keys(this.inputs).forEach(function (name) {\n var component = this.inputs[name];\n this.model[name] = component.state._value;\n }.bind(this));\n },\n\n // Reset each key in the model to the original / initial / specified value\n resetModel: function (data) {\n Object.keys(this.inputs).forEach(function (name) {\n if (data && data[name]) {\n this.inputs[name].setValue(data[name]);\n } else {\n this.inputs[name].resetValue();\n }\n }.bind(this));\n this.validateForm();\n },\n\n setInputValidationErrors: function (errors) {\n Object.keys(this.inputs).forEach(function (name, index) {\n var component = this.inputs[name];\n var args = [{\n _isValid: !(name in errors),\n _validationError: typeof errors[name] === 'string' ? [errors[name]] : errors[name]\n }];\n component.setState.apply(component, args);\n }.bind(this));\n },\n\n // Checks if the values have changed from their initial value\n isChanged: function() {\n return !utils.isSame(this.getPristineValues(), this.getCurrentValues());\n },\n\n getPristineValues: function() {\n var inputs = this.inputs;\n return Object.keys(inputs).reduce(function (data, name) {\n var component = inputs[name];\n data[name] = component.props.value;\n return data;\n }, {});\n },\n\n // Go through errors from server and grab the components\n // stored in the inputs map. Change their state to invalid\n // and set the serverError message\n updateInputsWithError: function (errors) {\n Object.keys(errors).forEach(function (name, index) {\n var component = this.inputs[name];\n\n if (!component) {\n throw new Error('You are trying to update an input that does not exist. Verify errors object with input names. ' + JSON.stringify(errors));\n }\n var args = [{\n _isValid: this.props.preventExternalInvalidation || false,\n _externalError: typeof errors[name] === 'string' ? [errors[name]] : errors[name]\n }];\n component.setState.apply(component, args);\n }.bind(this));\n },\n\n // Traverse the children and children of children to find\n // all inputs by checking the name prop. Maybe do a better\n // check here\n traverseChildrenAndRegisterInputs: function (children) {\n\n if (typeof children !== 'object' || children === null) {\n return children;\n }\n return React.Children.map(children, function (child) {\n\n if (typeof child !== 'object' || child === null) {\n return child;\n }\n\n if (child.props && child.props.name) {\n\n return React.cloneElement(child, {\n _attachToForm: this.attachToForm,\n _detachFromForm: this.detachFromForm,\n _validate: this.validate,\n _isFormDisabled: this.isFormDisabled,\n _isValidValue: function (component, value) {\n return this.runValidation(component, value).isValid;\n }.bind(this)\n }, child.props && child.props.children);\n } else {\n return React.cloneElement(child, {}, this.traverseChildrenAndRegisterInputs(child.props && child.props.children));\n }\n\n }, this);\n\n },\n\n isFormDisabled: function () {\n return this.props.disabled;\n },\n\n getCurrentValues: function () {\n return Object.keys(this.inputs).reduce(function (data, name) {\n var component = this.inputs[name];\n data[name] = component.state._value;\n return data;\n }.bind(this), {});\n },\n\n setFormPristine: function (isPristine) {\n var inputs = this.inputs;\n var inputKeys = Object.keys(inputs);\n\n this.setState({\n _formSubmitted: !isPristine\n })\n\n // Iterate through each component and set it as pristine\n // or \"dirty\".\n inputKeys.forEach(function (name, index) {\n var component = inputs[name];\n component.setState({\n _formSubmitted: !isPristine,\n _isPristine: isPristine\n });\n }.bind(this));\n },\n\n // Use the binded values and the actual input value to\n // validate the input and set its state. Then check the\n // state of the form itself\n validate: function (component) {\n\n // Trigger onChange\n if (this.state.canChange) {\n this.props.onChange(this.getCurrentValues(), this.isChanged());\n }\n\n var validation = this.runValidation(component);\n // Run through the validations, split them up and call\n // the validator IF there is a value or it is required\n component.setState({\n _isValid: validation.isValid,\n _isRequired: validation.isRequired,\n _validationError: validation.error,\n _externalError: null\n }, this.validateForm);\n\n },\n\n // Checks validation on current value or a passed value\n runValidation: function (component, value) {\n\n var currentValues = this.getCurrentValues();\n var validationErrors = component.props.validationErrors;\n var validationError = component.props.validationError;\n value = arguments.length === 2 ? value : component.state._value;\n\n var validationResults = this.runRules(value, currentValues, component._validations);\n var requiredResults = this.runRules(value, currentValues, component._requiredValidations);\n\n // the component defines an explicit validate function\n if (typeof component.validate === \"function\") {\n validationResults.failed = component.validate() ? [] : ['failed'];\n }\n\n var isRequired = Object.keys(component._requiredValidations).length ? !!requiredResults.success.length : false;\n var isValid = !validationResults.failed.length && !(this.props.validationErrors && this.props.validationErrors[component.props.name]);\n\n return {\n isRequired: isRequired,\n isValid: isRequired ? false : isValid,\n error: (function () {\n\n if (isValid && !isRequired) {\n return [];\n }\n\n if (validationResults.errors.length) {\n return validationResults.errors;\n }\n\n if (this.props.validationErrors && this.props.validationErrors[component.props.name]) {\n return typeof this.props.validationErrors[component.props.name] === 'string' ? [this.props.validationErrors[component.props.name]] : this.props.validationErrors[component.props.name];\n }\n\n if (isRequired) {\n var error = validationErrors[requiredResults.success[0]];\n return error ? [error] : null;\n }\n\n if (validationResults.failed.length) {\n return validationResults.failed.map(function(failed) {\n return validationErrors[failed] ? validationErrors[failed] : validationError;\n }).filter(function(x, pos, arr) {\n // Remove duplicates\n return arr.indexOf(x) === pos;\n });\n }\n\n }.call(this))\n };\n\n },\n\n runRules: function (value, currentValues, validations) {\n\n var results = {\n errors: [],\n failed: [],\n success: []\n };\n if (Object.keys(validations).length) {\n Object.keys(validations).forEach(function (validationMethod) {\n\n if (validationRules[validationMethod] && typeof validations[validationMethod] === 'function') {\n throw new Error('Formsy does not allow you to override default validations: ' + validationMethod);\n }\n\n if (!validationRules[validationMethod] && typeof validations[validationMethod] !== 'function') {\n throw new Error('Formsy does not have the validation rule: ' + validationMethod);\n }\n\n if (typeof validations[validationMethod] === 'function') {\n var validation = validations[validationMethod](currentValues, value);\n if (typeof validation === 'string') {\n results.errors.push(validation);\n results.failed.push(validationMethod);\n } else if (!validation) {\n results.failed.push(validationMethod);\n }\n return;\n\n } else if (typeof validations[validationMethod] !== 'function') {\n var validation = validationRules[validationMethod](currentValues, value, validations[validationMethod]);\n if (typeof validation === 'string') {\n results.errors.push(validation);\n results.failed.push(validationMethod);\n } else if (!validation) {\n results.failed.push(validationMethod);\n } else {\n results.success.push(validationMethod);\n }\n return;\n\n }\n\n return results.success.push(validationMethod);\n\n });\n }\n\n return results;\n\n },\n\n // Validate the form by going through all child input components\n // and check their state\n validateForm: function () {\n var allIsValid;\n var inputs = this.inputs;\n var inputKeys = Object.keys(inputs);\n\n // We need a callback as we are validating all inputs again. This will\n // run when the last component has set its state\n var onValidationComplete = function () {\n allIsValid = inputKeys.every(function (name) {\n return inputs[name].state._isValid;\n }.bind(this));\n\n this.setState({\n isValid: allIsValid\n });\n\n if (allIsValid) {\n this.props.onValid();\n } else {\n this.props.onInvalid();\n }\n\n // Tell the form that it can start to trigger change events\n this.setState({\n canChange: true\n });\n\n }.bind(this);\n\n // Run validation again in case affected by other inputs. The\n // last component validated will run the onValidationComplete callback\n inputKeys.forEach(function (name, index) {\n var component = inputs[name];\n var validation = this.runValidation(component);\n if (validation.isValid && component.state._externalError) {\n validation.isValid = false;\n }\n component.setState({\n _isValid: validation.isValid,\n _isRequired: validation.isRequired,\n _validationError: validation.error,\n _externalError: !validation.isValid && component.state._externalError ? component.state._externalError : null\n }, index === inputKeys.length - 1 ? onValidationComplete : null);\n }.bind(this));\n\n // If there are no inputs, set state where form is ready to trigger\n // change event. New inputs might be added later\n if (!inputKeys.length && this.isMounted()) {\n this.setState({\n canChange: true\n });\n }\n },\n\n // Method put on each input component to register\n // itself to the form\n attachToForm: function (component) {\n this.inputs[component.props.name] = component;\n this.model[component.props.name] = component.state._value;\n this.validate(component);\n },\n\n // Method put on each input component to unregister\n // itself from the form\n detachFromForm: function (component) {\n delete this.inputs[component.props.name];\n delete this.model[component.props.name];\n },\n render: function () {\n\n return (\n
\n {this.props.children}\n {/*this.traverseChildrenAndRegisterInputs(this.props.children)*/}\n
\n );\n\n }\n});\n\nif (!global.exports && !global.module && (!global.define || !global.define.amd)) {\n global.Formsy = Formsy;\n}\n\nmodule.exports = Formsy;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/main.js\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external \"react\"\n ** module id = 1\n ** module chunks = 0\n **/","var utils = require('./utils.js');\nvar React = global.React || require('react');\n\nvar convertValidationsToObject = function (validations) {\n\n if (typeof validations === 'string') {\n\n return validations.split(/\\,(?![^{\\[]*[}\\]])/g).reduce(function (validations, validation) {\n var args = validation.split(':');\n var validateMethod = args.shift();\n\n args = args.map(function (arg) {\n try {\n return JSON.parse(arg);\n } catch (e) {\n return arg; // It is a string if it can not parse it\n }\n });\n\n if (args.length > 1) {\n throw new Error('Formsy does not support multiple args on string validations. Use object format of validations instead.');\n }\n\n validations[validateMethod] = args.length ? args[0] : true;\n return validations;\n }, {});\n\n }\n\n return validations || {};\n};\n\nmodule.exports = {\n getInitialState: function () {\n return {\n _value: this.props.value,\n _isRequired: false,\n _isValid: true,\n _isPristine: true,\n _pristineValue: this.props.value,\n _validationError: [],\n _externalError: null,\n _formSubmitted: false\n };\n },\n contextTypes: {\n formsy: React.PropTypes.object // What about required?\n },\n getDefaultProps: function () {\n return {\n validationError: '',\n validationErrors: {}\n };\n },\n\n componentWillMount: function () {\n var configure = function () {\n this.setValidations(this.props.validations, this.props.required);\n\n // Pass a function instead?\n this.context.formsy.attachToForm(this);\n //this.props._attachToForm(this);\n }.bind(this);\n\n if (!this.props.name) {\n throw new Error('Form Input requires a name property when used');\n }\n\n /*\n if (!this.props._attachToForm) {\n return setTimeout(function () {\n if (!this.isMounted()) return;\n if (!this.props._attachToForm) {\n throw new Error('Form Mixin requires component to be nested in a Form');\n }\n configure();\n }.bind(this), 0);\n }\n */\n configure();\n },\n\n // We have to make the validate method is kept when new props are added\n componentWillReceiveProps: function (nextProps) {\n this.setValidations(nextProps.validations, nextProps.required);\n\n },\n\n componentDidUpdate: function (prevProps) {\n\n // If the value passed has changed, set it. If value is not passed it will\n // internally update, and this will never run\n if (!utils.isSame(this.props.value, prevProps.value)) {\n this.setValue(this.props.value);\n }\n\n // If validations or required is changed, run a new validation\n if (!utils.isSame(this.props.validations, prevProps.validations) || !utils.isSame(this.props.required, prevProps.required)) {\n this.context.formsy.validate(this);\n }\n },\n\n // Detach it when component unmounts\n componentWillUnmount: function () {\n this.context.formsy.detachFromForm(this);\n //this.props._detachFromForm(this);\n },\n\n setValidations: function (validations, required) {\n\n // Add validations to the store itself as the props object can not be modified\n this._validations = convertValidationsToObject(validations) || {};\n this._requiredValidations = required === true ? {isDefaultRequiredValue: true} : convertValidationsToObject(required);\n\n },\n\n // We validate after the value has been set\n setValue: function (value) {\n this.setState({\n _value: value,\n _isPristine: false\n }, function () {\n this.context.formsy.validate(this);\n //this.props._validate(this);\n }.bind(this));\n },\n resetValue: function () {\n this.setState({\n _value: this.state._pristineValue,\n _isPristine: true\n }, function () {\n this.context.formsy.validate(this);\n //this.props._validate(this);\n });\n },\n getValue: function () {\n return this.state._value;\n },\n hasValue: function () {\n return this.state._value !== '';\n },\n getErrorMessage: function () {\n var messages = this.getErrorMessages();\n return messages.length ? messages[0] : null;\n },\n getErrorMessages: function () {\n return !this.isValid() || this.showRequired() ? (this.state._externalError || this.state._validationError || []) : [];\n },\n isFormDisabled: function () {\n return this.context.formsy.isFormDisabled();\n //return this.props._isFormDisabled();\n },\n isValid: function () {\n return this.state._isValid;\n },\n isPristine: function () {\n return this.state._isPristine;\n },\n isFormSubmitted: function () {\n return this.state._formSubmitted;\n },\n isRequired: function () {\n return !!this.props.required;\n },\n showRequired: function () {\n return this.state._isRequired;\n },\n showError: function () {\n return !this.showRequired() && !this.isValid();\n },\n isValidValue: function (value) {\n return this.context.formsy.isValidValue.call(null, this, value);\n //return this.props._isValidValue.call(null, this, value);\n }\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/Mixin.js\n **/","module.exports = {\n arraysDiffer: function (a, b) {\n var isDifferent = false;\n if (a.length !== b.length) {\n isDifferent = true;\n } else {\n a.forEach(function (item, index) {\n if (!this.isSame(item, b[index])) {\n isDifferent = true;\n }\n }, this);\n }\n return isDifferent;\n },\n\n objectsDiffer: function (a, b) {\n var isDifferent = false;\n if (Object.keys(a).length !== Object.keys(b).length) {\n isDifferent = true;\n } else {\n Object.keys(a).forEach(function (key) {\n if (!this.isSame(a[key], b[key])) {\n isDifferent = true;\n }\n }, this);\n }\n return isDifferent;\n },\n\n isSame: function (a, b) {\n if (typeof a !== typeof b) {\n return false;\n } else if (Array.isArray(a)) {\n return !this.arraysDiffer(a, b);\n } else if (typeof a === 'object' && a !== null && b !== null) {\n return !this.objectsDiffer(a, b);\n }\n\n return a === b;\n }\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/utils.js\n **/","var React = global.React || require('react');\nvar Mixin = require('./Mixin.js');\nmodule.exports = function () {\n return function (Component) {\n return React.createClass({\n mixins: [Mixin],\n render: function () {\n return React.createElement(Component, {\n setValidations: this.setValidations,\n setValue: this.setValue,\n resetValue: this.resetValue,\n getValue: this.getValue,\n hasValue: this.hasValue,\n getErrorMessage: this.getErrorMessage,\n getErrorMessages: this.getErrorMessages,\n isFormDisabled: this.isFormDisabled,\n isValid: this.isValid,\n isPristine: this.isPristine,\n isFormSubmitted: this.isFormSubmitted,\n isRequired: this.isRequired,\n showRequired: this.showRequired,\n showError: this.showError,\n isValidValue: this.isValidValue,\n ...this.props\n });\n }\n });\n };\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/Decorator.js\n **/","var React = global.React || require('react');\nvar Mixin = require('./Mixin.js');\nmodule.exports = function (Component) {\n return React.createClass({\n mixins: [Mixin],\n render: function () {\n return React.createElement(Component, {\n setValidations: this.setValidations,\n setValue: this.setValue,\n resetValue: this.resetValue,\n getValue: this.getValue,\n hasValue: this.hasValue,\n getErrorMessage: this.getErrorMessage,\n getErrorMessages: this.getErrorMessages,\n isFormDisabled: this.isFormDisabled,\n isValid: this.isValid,\n isPristine: this.isPristine,\n isFormSubmitted: this.isFormSubmitted,\n isRequired: this.isRequired,\n showRequired: this.showRequired,\n showError: this.showError,\n isValidValue: this.isValidValue\n });\n }\n });\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/HOC.js\n **/","var isExisty = function (value) {\n return value !== null && value !== undefined;\n};\n\nvar isEmpty = function (value) {\n return value === '';\n};\n\nvar validations = {\n isDefaultRequiredValue: function (values, value) {\n return value === undefined || value === '';\n },\n isExisty: function (values, value) {\n return isExisty(value);\n },\n matchRegexp: function (values, value, regexp) {\n return !isExisty(value) || isEmpty(value) || regexp.test(value);\n },\n isUndefined: function (values, value) {\n return value === undefined;\n },\n isEmptyString: function (values, value) {\n return isEmpty(value);\n },\n isEmail: function (values, value) {\n return validations.matchRegexp(values, value, /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i);\n },\n isUrl: function (values, value) {\n return validations.matchRegexp(values, value, /^(https?|s?ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i);\n },\n isTrue: function (values, value) {\n return value === true;\n },\n isFalse: function (values, value) {\n return value === false;\n },\n isNumeric: function (values, value) {\n if (typeof value === 'number') {\n return true;\n }\n return validations.matchRegexp(values, value, /^[-+]?(\\d*[.])?\\d+$/);\n },\n isAlpha: function (values, value) {\n return validations.matchRegexp(values, value, /^[a-zA-Z]+$/);\n },\n isWords: function (values, value) {\n return validations.matchRegexp(values, value, /^[a-zA-Z\\s]+$/);\n },\n isSpecialWords: function (values, value) {\n return validations.matchRegexp(values, value, /^[a-zA-Z\\s\\u00C0-\\u017F]+$/);\n },\n isLength: function (values, value, length) {\n return !isExisty(value) || isEmpty(value) || value.length === length;\n },\n equals: function (values, value, eql) {\n return !isExisty(value) || isEmpty(value) || value == eql;\n },\n equalsField: function (values, value, field) {\n return value == values[field];\n },\n maxLength: function (values, value, length) {\n return !isExisty(value) || value.length <= length;\n },\n minLength: function (values, value, length) {\n return !isExisty(value) || isEmpty(value) || value.length >= length;\n }\n};\n\nmodule.exports = validations;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/validationRules.js\n **/","module.exports = function (source) {\n\n\n // \"foo[0]\"\n return Object.keys(source).reduce(function (output, key) {\n\n var parentKey = key.match(/[^\\[]*/i);\n var paths = key.match(/\\[.*?\\]/g) || [];\n paths = [parentKey[0]].concat(paths).map(function (key) {\n return key.replace(/\\[|\\]/g, '');\n });\n\n var currentPath = output;\n while (paths.length) {\n\n var pathKey = paths.shift();\n\n if (pathKey in currentPath) {\n currentPath = currentPath[pathKey];\n } else {\n currentPath[pathKey] = paths.length ? isNaN(paths[0]) ? {} : [] : source[key];\n currentPath = currentPath[pathKey];\n }\n\n }\n\n return output;\n\n }, {});\n\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/form-data-to-object/index.js\n ** module id = 7\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file From cfb3a5af6f5284c6986c836cee4c3abcf4ed7021 Mon Sep 17 00:00:00 2001 From: Semigradsky Date: Wed, 9 Sep 2015 11:03:19 +0300 Subject: [PATCH 17/24] Removed unnecessary NodeJS versions --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e616d52..cc6db79 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,4 @@ language: node_js node_js: - - 'iojs' - '0.12' - - '0.11' - '0.10' From 7ab78f9603cdf0a9dc312a0021e8d6b02cc04688 Mon Sep 17 00:00:00 2001 From: Semigradsky Date: Wed, 9 Sep 2015 12:45:44 +0300 Subject: [PATCH 18/24] Moved tests to es2015 --- package.json | 1 + specs/Element-spec.js | 478 ++++++++++++ specs/Element-spec.jsx | 622 ---------------- specs/Formsy-spec.js | 519 +++++++++++++ specs/Formsy-spec.jsx | 693 ------------------ specs/Rules-equals-spec.js | 60 ++ specs/Rules-equals-spec.jsx | 62 -- specs/Rules-isAlpha-spec.js | 60 ++ specs/Rules-isAlpha-spec.jsx | 62 -- specs/Rules-isEmail-spec.js | 60 ++ specs/Rules-isEmail-spec.jsx | 62 -- specs/Rules-isEmptyString-spec.js | 60 ++ specs/Rules-isEmptyString-spec.jsx | 62 -- specs/Rules-isExisty-spec.js | 60 ++ specs/Rules-isExisty-spec.jsx | 62 -- ...Length-spec.jsx => Rules-isLength-spec.js} | 52 +- ...meric-spec.jsx => Rules-isNumeric-spec.js} | 42 +- specs/Rules-isUrl-spec.js | 60 ++ specs/Rules-isUrl-spec.jsx | 62 -- specs/Rules-isWords-spec.js | 60 ++ specs/Rules-isWords-spec.jsx | 62 -- ...ength-spec.jsx => Rules-maxLength-spec.js} | 42 +- ...ength-spec.jsx => Rules-minLength-spec.js} | 52 +- specs/{Utils-spec.jsx => Utils-spec.js} | 21 +- specs/Validation-spec.js | 202 +++++ specs/Validation-spec.jsx | 281 ------- specs/utils/TestInput.js | 22 + specs/utils/immediate.js | 3 + testrunner.js | 7 +- 29 files changed, 1748 insertions(+), 2143 deletions(-) create mode 100644 specs/Element-spec.js delete mode 100644 specs/Element-spec.jsx create mode 100755 specs/Formsy-spec.js delete mode 100755 specs/Formsy-spec.jsx create mode 100644 specs/Rules-equals-spec.js delete mode 100644 specs/Rules-equals-spec.jsx create mode 100644 specs/Rules-isAlpha-spec.js delete mode 100644 specs/Rules-isAlpha-spec.jsx create mode 100644 specs/Rules-isEmail-spec.js delete mode 100644 specs/Rules-isEmail-spec.jsx create mode 100644 specs/Rules-isEmptyString-spec.js delete mode 100644 specs/Rules-isEmptyString-spec.jsx create mode 100644 specs/Rules-isExisty-spec.js delete mode 100644 specs/Rules-isExisty-spec.jsx rename specs/{Rules-isLength-spec.jsx => Rules-isLength-spec.js} (57%) rename specs/{Rules-isNumeric-spec.jsx => Rules-isNumeric-spec.js} (53%) create mode 100644 specs/Rules-isUrl-spec.js delete mode 100644 specs/Rules-isUrl-spec.jsx create mode 100644 specs/Rules-isWords-spec.js delete mode 100644 specs/Rules-isWords-spec.jsx rename specs/{Rules-maxLength-spec.jsx => Rules-maxLength-spec.js} (50%) rename specs/{Rules-minLength-spec.jsx => Rules-minLength-spec.js} (57%) rename specs/{Utils-spec.jsx => Utils-spec.js} (55%) create mode 100644 specs/Validation-spec.js delete mode 100644 specs/Validation-spec.jsx create mode 100644 specs/utils/TestInput.js create mode 100644 specs/utils/immediate.js diff --git a/package.json b/package.json index 2221fce..b125879 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "jasmine-node": "^1.14.5", "jsdom": "^3.1.2", "react": "^0.14.0-beta3", + "react-addons-test-utils": "^0.14.0-beta3", "react-dom": "^0.14.0-beta3", "webpack": "^1.7.3", "webpack-dev-server": "^1.7.0" diff --git a/specs/Element-spec.js b/specs/Element-spec.js new file mode 100644 index 0000000..3bdd548 --- /dev/null +++ b/specs/Element-spec.js @@ -0,0 +1,478 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import TestInput, { customizeInput } from './utils/TestInput'; +import immediate from './utils/immediate'; + +describe('Element', function () { + + it('should return passed and setValue() value when using getValue()', function () { + + const form = TestUtils.renderIntoDocument( + + + + ); + + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + expect(input.value).toBe('foo'); + TestUtils.Simulate.change(input, {target: {value: 'foobar'}}); + expect(input.value).toBe('foobar'); + + }); + + it('should set back to pristine value when running reset', function () { + + let reset = null; + const Input = customizeInput({ + componentDidMount() { + reset = this.resetValue; + } + }); + const form = TestUtils.renderIntoDocument( + + + + ); + + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + TestUtils.Simulate.change(input, {target: {value: 'foobar'}}); + reset(); + expect(input.value).toBe('foo'); + + }); + + it('should return error message passed when calling getErrorMessage()', function () { + + let getErrorMessage = null; + const Input = customizeInput({ + componentDidMount() { + getErrorMessage = this.getErrorMessage; + } + }); + TestUtils.renderIntoDocument( + + + + ); + + expect(getErrorMessage()).toBe('Has to be email'); + + }); + + it('should return true or false when calling isValid() depending on valid state', function () { + + let isValid = null; + const Input = customizeInput({ + componentDidMount() { + isValid = this.isValid; + } + }); + const form = TestUtils.renderIntoDocument( + + + + ); + + expect(isValid()).toBe(false); + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + TestUtils.Simulate.change(input, {target: {value: 'foo@foo.com'}}); + expect(isValid()).toBe(true); + + }); + + it('should return true or false when calling isRequired() depending on passed required attribute', function () { + + const isRequireds = []; + const Input = customizeInput({ + componentDidMount() { + isRequireds.push(this.isRequired); + } + }); + TestUtils.renderIntoDocument( + + + + + + ); + + expect(isRequireds[0]()).toBe(false); + expect(isRequireds[1]()).toBe(true); + expect(isRequireds[2]()).toBe(true); + + }); + + it('should return true or false when calling showRequired() depending on input being empty and required is passed, or not', function () { + + const showRequireds = []; + const Input = customizeInput({ + componentDidMount() { + showRequireds.push(this.showRequired); + } + }); + TestUtils.renderIntoDocument( + + + + + + ); + + expect(showRequireds[0]()).toBe(false); + expect(showRequireds[1]()).toBe(true); + expect(showRequireds[2]()).toBe(false); + + }); + + it('should return true or false when calling isPristine() depending on input has been "touched" or not', function () { + + let isPristine = null; + const Input = customizeInput({ + componentDidMount() { + isPristine = this.isPristine; + } + }); + const form = TestUtils.renderIntoDocument( + + + + ); + + expect(isPristine()).toBe(true); + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + TestUtils.Simulate.change(input, {target: {value: 'foo'}}); + expect(isPristine()).toBe(false); + + }); + +it('should allow an undefined value to be updated to a value', function (done) { + + const TestForm = React.createClass({ + getInitialState() { + return {value: undefined}; + }, + changeValue() { + this.setState({ + value: 'foo' + }); + }, + render() { + return ( + + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + form.changeValue(); + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + immediate(() => { + expect(input.value).toBe('foo'); + done(); + }); + + }); + + it('should be able to test a values validity', function () { + + const TestForm = React.createClass({ + render() { + return ( + + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + expect(input.isValidValue('foo@bar.com')).toBe(true); + expect(input.isValidValue('foo@bar')).toBe(false); + + }); + + it('should be able to use an object as validations property', function () { + + const TestForm = React.createClass({ + render() { + return ( + + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + expect(input.isValidValue('foo@bar.com')).toBe(true); + expect(input.isValidValue('foo@bar')).toBe(false); + + }); + + it('should be able to pass complex values to a validation rule', function () { + + const TestForm = React.createClass({ + render() { + return ( + + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); + expect(inputComponent.isValid()).toBe(true); + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + TestUtils.Simulate.change(input, {target: {value: 'bar'}}); + expect(inputComponent.isValid()).toBe(false); + + }); + + it('should be able to run a function to validate', function () { + + const TestForm = React.createClass({ + customValidationA(values, value) { + return value === 'foo'; + }, + customValidationB(values, value) { + return value === 'foo' && values.A === 'foo'; + }, + render() { + return ( + + + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + const inputComponent = TestUtils.scryRenderedComponentsWithType(form, TestInput); + expect(inputComponent[0].isValid()).toBe(true); + expect(inputComponent[1].isValid()).toBe(true); + const input = TestUtils.scryRenderedDOMComponentsWithTag(form, 'INPUT'); + TestUtils.Simulate.change(input[0], {target: {value: 'bar'}}); + expect(inputComponent[0].isValid()).toBe(false); + expect(inputComponent[1].isValid()).toBe(false); + + }); + + it('should override all error messages with error messages passed by form', function () { + + const TestForm = React.createClass({ + render() { + return ( + + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); + expect(inputComponent.getErrorMessage()).toBe('bar'); + + }); + + it('should override validation rules with required rules', function () { + + const TestForm = React.createClass({ + render() { + return ( + + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); + expect(inputComponent.getErrorMessage()).toBe('bar3'); + + }); + + it('should fall back to default error message when non exist in validationErrors map', function () { + + const TestForm = React.createClass({ + render() { + return ( + + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); + expect(inputComponent.getErrorMessage()).toBe('bar'); + + }); + + it('should not be valid if it is required and required rule is true', function () { + + const TestForm = React.createClass({ + render() { + return ( + + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); + expect(inputComponent.isValid()).toBe(false); + + }); + + it('should handle objects and arrays as values', function () { + + const TestForm = React.createClass({ + getInitialState() { + return { + foo: {foo: 'bar'}, + bar: ['foo'] + }; + }, + render() { + return ( + + + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + form.setState({ + foo: {foo: 'foo'}, + bar: ['bar'] + }); + + const inputs = TestUtils.scryRenderedComponentsWithType(form, TestInput); + expect(inputs[0].getValue()).toEqual({foo: 'foo'}); + expect(inputs[1].getValue()).toEqual(['bar']); + + }); + + it('should handle isFormDisabled with dynamic inputs', function () { + + const TestForm = React.createClass({ + getInitialState() { + return { + bool: true + }; + }, + flip() { + this.setState({ + bool: !this.state.bool + }); + }, + render() { + return ( + + {this.state.bool ? + : + + } + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + expect(input.isFormDisabled()).toBe(true); + form.flip(); + expect(input.isFormDisabled()).toBe(false); + + }); + + it('should allow for dot notation in name which maps to a deep object', function () { + + const TestForm = React.createClass({ + onSubmit(model) { + expect(model).toEqual({foo: {bar: 'foo', test: 'test'}}); + }, + render() { + return ( + + + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); + TestUtils.Simulate.submit(formEl); + + }); + + it('should allow for application/x-www-form-urlencoded syntax and convert to object', function () { + + const TestForm = React.createClass({ + onSubmit(model) { + expect(model).toEqual({foo: ['foo', 'bar']}); + }, + render() { + return ( + + + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); + TestUtils.Simulate.submit(formEl); + + }); + +}); diff --git a/specs/Element-spec.jsx b/specs/Element-spec.jsx deleted file mode 100644 index d09746d..0000000 --- a/specs/Element-spec.jsx +++ /dev/null @@ -1,622 +0,0 @@ -var React = require('react/addons'); -var TestUtils = React.addons.TestUtils; -var Formsy = require('./../src/main.js'); - -describe('Element', function() { - - it('should return passed and setValue() value when using getValue()', function () { - - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var form = TestUtils.renderIntoDocument( - - - - ); - - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - expect(input.value).toBe('foo'); - TestUtils.Simulate.change(input, {target: {value: 'foobar'}}); - expect(input.value).toBe('foobar'); - - }); - - it('should set back to pristine value when running reset', function () { - - var reset = null; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - componentDidMount: function () { - reset = this.resetValue; - }, - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var form = TestUtils.renderIntoDocument( - - - - ); - - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - TestUtils.Simulate.change(input, {target: {value: 'foobar'}}); - reset(); - expect(input.value).toBe('foo'); - - }); - - it('should return error message passed when calling getErrorMessage()', function () { - - var getErrorMessage = null; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - componentDidMount: function () { - getErrorMessage = this.getErrorMessage; - }, - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var form = TestUtils.renderIntoDocument( - - - - ); - - expect(getErrorMessage()).toBe('Has to be email'); - - }); - - it('should return true or false when calling isValid() depending on valid state', function () { - - var isValid = null; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - componentDidMount: function () { - isValid = this.isValid; - }, - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var form = TestUtils.renderIntoDocument( - - - - ); - - expect(isValid()).toBe(false); - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - TestUtils.Simulate.change(input, {target: {value: 'foo@foo.com'}}); - expect(isValid()).toBe(true); - - }); - - it('should return true or false when calling isRequired() depending on passed required attribute', function () { - - var isRequireds = []; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - componentDidMount: function () { - isRequireds.push(this.isRequired); - }, - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var form = TestUtils.renderIntoDocument( - - - - - - ); - - expect(isRequireds[0]()).toBe(false); - expect(isRequireds[1]()).toBe(true); - expect(isRequireds[2]()).toBe(true); - - }); - - it('should return true or false when calling showRequired() depending on input being empty and required is passed, or not', function () { - - var showRequireds = []; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - componentDidMount: function () { - showRequireds.push(this.showRequired); - }, - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var form = TestUtils.renderIntoDocument( - - - - - - ); - - expect(showRequireds[0]()).toBe(false); - expect(showRequireds[1]()).toBe(true); - expect(showRequireds[2]()).toBe(false); - - }); - - it('should return true or false when calling isPristine() depending on input has been "touched" or not', function () { - - var isPristine = null; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - componentDidMount: function () { - isPristine = this.isPristine; - }, - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var form = TestUtils.renderIntoDocument( - - - - ); - - expect(isPristine()).toBe(true); - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - TestUtils.Simulate.change(input, {target: {value: 'foo'}}); - expect(isPristine()).toBe(false); - - }); - -it('should allow an undefined value to be updated to a value', function (done) { - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - changeValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var TestForm = React.createClass({ - getInitialState: function () { - return {value: undefined}; - }, - changeValue: function () { - this.setState({ - value: 'foo' - }); - }, - render: function () { - return ( - - - - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - form.changeValue(); - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - setTimeout(function () { - expect(input.value).toBe('foo'); - done(); - }, 0); - }); - - it('should be able to test a values validity', function () { - - var isInvalid = false; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return - } - }); - var TestForm = React.createClass({ - render: function () { - return ( - - - - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - var input = TestUtils.findRenderedComponentWithType(form, TestInput); - expect(input.isValidValue('foo@bar.com')).toBe(true); - expect(input.isValidValue('foo@bar')).toBe(false); - - }); - - it('should be able to use an object as validations property', function () { - - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return - } - }); - var TestForm = React.createClass({ - render: function () { - return ( - - - - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - var input = TestUtils.findRenderedComponentWithType(form, TestInput); - expect(input.isValidValue('foo@bar.com')).toBe(true); - expect(input.isValidValue('foo@bar')).toBe(false); - }); - - it('should be able to pass complex values to a validation rule', function () { - - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - changeValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var TestForm = React.createClass({ - render: function () { - return ( - - - - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - var inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - expect(inputComponent.isValid()).toBe(true); - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - TestUtils.Simulate.change(input, {target: {value: 'bar'}}); - expect(inputComponent.isValid()).toBe(false); - }); - - it('should be able to run a function to validate', function () { - - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - changeValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var TestForm = React.createClass({ - customValidationA: function (values, value) { - return value === 'foo'; - }, - customValidationB: function (values, value) { - return value === 'foo' && values.A === 'foo'; - }, - render: function () { - return ( - - - - - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - var inputComponent = TestUtils.scryRenderedComponentsWithType(form, TestInput); - expect(inputComponent[0].isValid()).toBe(true); - expect(inputComponent[1].isValid()).toBe(true); - var input = TestUtils.scryRenderedDOMComponentsWithTag(form, 'INPUT'); - TestUtils.Simulate.change(input[0], {target: {value: 'bar'}}); - expect(inputComponent[0].isValid()).toBe(false); - expect(inputComponent[1].isValid()).toBe(false); - }); - - it('should override all error messages with error messages passed by form', function () { - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return - } - }); - var TestForm = React.createClass({ - render: function () { - return ( - - - - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - var inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - expect(inputComponent.getErrorMessage()).toBe('bar'); - }); - - it('should override validation rules with required rules', function () { - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return - } - }); - var TestForm = React.createClass({ - render: function () { - return ( - - - - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - var inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - expect(inputComponent.getErrorMessage()).toBe('bar3'); - }); - - it('should fall back to default error message when non exist in validationErrors map', function () { - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return - } - }); - var TestForm = React.createClass({ - render: function () { - return ( - - - - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - var inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - expect(inputComponent.getErrorMessage()).toBe('bar'); - }); - - it('should not be valid if it is required and required rule is true', function () { - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return - } - }); - var TestForm = React.createClass({ - render: function () { - return ( - - - - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - var inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - expect(inputComponent.isValid()).toBe(false); - }); - - it('should handle objects and arrays as values', function () { - - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return
{JSON.stringify(this.getValue())}
- } - }); - var TestForm = React.createClass({ - getInitialState: function () { - return { - foo: {foo: 'bar'}, - bar: ['foo'] - }; - }, - render: function () { - return ( - - - - - ); - } - }); - var form = TestUtils.renderIntoDocument(); - - form.setState({ - foo: {foo: 'foo'}, - bar: ['bar'] - }); - - var inputs = TestUtils.scryRenderedComponentsWithType(form, TestInput); - expect(inputs[0].getValue()).toEqual({foo: 'foo'}); - expect(inputs[1].getValue()).toEqual(['bar']); - - }); - - it('should handle isFormDisabled with dynamic inputs', function () { - - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return - } - }); - - var TestForm = React.createClass({ - getInitialState: function () { - return { - bool: true - }; - }, - flip: function () { - this.setState({ - bool: !this.state.bool - }); - }, - render: function () { - return ( - - {this.state.bool ? - : - - } - - ); - } - }); - - var form = TestUtils.renderIntoDocument(); - var input = TestUtils.findRenderedComponentWithType(form, TestInput); - expect(input.isFormDisabled()).toBe(true); - form.flip(); - expect(input.isFormDisabled()).toBe(false); - - }); - - 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 - } - }); - - var TestForm = React.createClass({ - onSubmit: function (model) { - expect(model).toEqual({foo: {bar: 'foo', test: 'test'}}); - }, - render: function () { - return ( - - - - - ); - } - }); - - var form = TestUtils.renderIntoDocument(); - var formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); - TestUtils.Simulate.submit(formEl); - - }); - - it('should allow for application/x-www-form-urlencoded syntax and convert to object', function () { - - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return - } - }); - - var TestForm = React.createClass({ - onSubmit: function (model) { - expect(model).toEqual({foo: ['foo', 'bar']}); - }, - render: function () { - return ( - - - - - ); - } - }); - - var form = TestUtils.renderIntoDocument(); - var formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); - TestUtils.Simulate.submit(formEl); - - }); - -}); diff --git a/specs/Formsy-spec.js b/specs/Formsy-spec.js new file mode 100755 index 0000000..211eae2 --- /dev/null +++ b/specs/Formsy-spec.js @@ -0,0 +1,519 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import TestInput from './utils/TestInput'; +import immediate from './utils/immediate'; + +describe('Formsy', function () { + + describe('Setting up a form', function () { + + it('should render a form into the document', function () { + const form = TestUtils.renderIntoDocument(); + expect(React.findDOMNode(form).tagName).toEqual('FORM'); + }); + + it('should set a class name if passed', function () { + const form = TestUtils.renderIntoDocument( ); + expect(React.findDOMNode(form).className).toEqual('foo'); + }); + + it('should allow for null/undefined children', function (done) { + + let model = null; + const TestForm = React.createClass({ + render() { + return ( + (model = formModel)}> +

Test

+ { null } + { undefined } + +
+ ); + } + }); + + const form = TestUtils.renderIntoDocument(); + immediate(() => { + TestUtils.Simulate.submit(React.findDOMNode(form)); + expect(model).toEqual({name: 'foo'}); + done(); + }); + + }); + + it('should allow for inputs being added dynamically', function (done) { + + const inputs = []; + let forceUpdate = null; + let model = null; + const TestForm = React.createClass({ + componentWillMount() { + forceUpdate = this.forceUpdate.bind(this); + }, + render() { + return ( + (model = formModel)}> + {inputs} + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + // Wait before adding the input + setTimeout(() => { + inputs.push(); + + forceUpdate(() => { + // Wait for next event loop, as that does the form + immediate(() => { + TestUtils.Simulate.submit(React.findDOMNode(form)); + expect(model.test).toBeDefined(); + done(); + }); + + }); + + }, 10); + + }); + + it('should allow dynamically added inputs to update the form-model', function (done) { + + const inputs = []; + let forceUpdate = null; + let model = null; + const TestForm = React.createClass({ + componentWillMount() { + forceUpdate = this.forceUpdate.bind(this); + }, + render() { + return ( + (model = formModel)}> + {inputs} + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + // Wait before adding the input + immediate(() => { + inputs.push(); + + forceUpdate(() => { + + // Wait for next event loop, as that does the form + immediate(() => { + TestUtils.Simulate.change(TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'), {target: {value: 'foo'}}); + TestUtils.Simulate.submit(React.findDOMNode(form)); + expect(model.test).toBe('foo'); + done(); + }); + + }); + + }); + + }); + + it('should allow a dynamically updated input to update the form-model', function (done) { + + let forceUpdate = null; + let model = null; + + const TestForm = React.createClass({ + componentWillMount() { + forceUpdate = this.forceUpdate.bind(this); + }, + render() { + const input = ; + + return ( + (model = formModel)}> + {input} + ); + } + }); + let form = TestUtils.renderIntoDocument(); + + // Wait before changing the input + immediate(() => { + form = TestUtils.renderIntoDocument(); + + forceUpdate(() => { + // Wait for next event loop, as that does the form + immediate(() => { + TestUtils.Simulate.submit(React.findDOMNode(form)); + expect(model.test).toBe('bar'); + done(); + }); + + }); + + }); + + }); + + describe('validations', function () { + let CheckValid, onSubmit, OtherCheckValid; + let isValid; + + const TestForm = React.createClass({ + getDefaultProps() { + return { inputs: [] }; + }, + render() { + const builtInputs = this.props.inputs.map((input) => ); + return ( + onSubmit(arg1)} + onValid={() => (isValid = true)} + onInvalid={() => (isValid = false)}> + { builtInputs } + + ); + } + }); + + beforeEach(() => { + isValid = true; + CheckValid = jasmine.createSpy('CheckValid'); + Formsy.addValidationRule('CheckValid', CheckValid); + OtherCheckValid = jasmine.createSpy('CheckValid'); + Formsy.addValidationRule('OtherCheckValid', OtherCheckValid); + onSubmit = jasmine.createSpy('onSubmit'); + }); + + it('should run when the input changes', function () { + const inputs = [{name: 'one', validations: 'CheckValid', value: 'foo'}]; + const form = TestUtils.renderIntoDocument(); + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); + TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); + expect(CheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true); + expect(OtherCheckValid).not.toHaveBeenCalled(); + }); + + it('should allow the validation to be changed', function () { + const inputs = [{name: 'one', validations: 'CheckValid', value: 'foo'}]; + const form = TestUtils.renderIntoDocument(); + form.setProps({inputs: [{name: 'one', validations: 'OtherCheckValid', value: 'foo'}] }); + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); + TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); + expect(OtherCheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true); + }); + + it('should invalidate a form if dynamically inserted input is invalid', function (done) { + const inputs = [{name: 'one', validations: 'isEmail', value: 'foo@bar.com'}]; + const form = TestUtils.renderIntoDocument(); + expect(isValid).toEqual(true); + form.setProps({inputs: [ + {name: 'one', validations: 'isEmail', value: 'foo@bar.com'}, + {name: 'two', validations: 'isEmail', value: 'foo@bar'} + ]}, () => { + immediate(() => { + expect(isValid).toEqual(false); + done(); + }); + }); + }); + + it('should validate a form when removing an invalid input', function (done) { + const form = TestUtils.renderIntoDocument(); + expect(isValid).toEqual(false); + form.setProps({inputs: [{name: 'one', validations: 'isEmail', value: 'foo@bar.com'}]}, () => { + immediate(() => { + expect(isValid).toEqual(true); + done(); + }); + }); + }); + + it('runs multiple validations', function () { + const inputs = [{name: 'one', validations: 'CheckValid,OtherCheckValid', value: 'foo'}]; + const form = TestUtils.renderIntoDocument(); + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); + TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); + expect(CheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true); + expect(OtherCheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true); + }); + }); + + it('should not trigger onChange when form is mounted', function () { + const hasChanged = jasmine.createSpy('onChange'); + const TestForm = React.createClass({ + render() { + return ; + } + }); + TestUtils.renderIntoDocument(); + expect(hasChanged).not.toHaveBeenCalled(); + }); + + it('should trigger onChange when form element is changed', function () { + const hasChanged = jasmine.createSpy('onChange'); + const TestForm = React.createClass({ + render() { + return ( + + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + TestUtils.Simulate.change(TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'), {target: {value: 'bar'}}); + expect(hasChanged).toHaveBeenCalled(); + }); + + it('should trigger onChange when new input is added to form', function (done) { + const hasChanged = jasmine.createSpy('onChange'); + const inputs = []; + let forceUpdate = null; + const TestForm = React.createClass({ + componentWillMount() { + forceUpdate = this.forceUpdate.bind(this); + }, + render() { + return ( + + {inputs} + ); + } + }); + TestUtils.renderIntoDocument(); + + // Wait before adding the input + inputs.push(); + + forceUpdate(() => { + + // Wait for next event loop, as that does the form + immediate(() => { + expect(hasChanged).toHaveBeenCalled(); + done(); + }); + + }); + + }); + + }); + + describe('Update a form', function () { + + it('should allow elements to check if the form is disabled', function (done) { + + const TestForm = React.createClass({ + getInitialState() { return { disabled: true }; }, + enableForm() { this.setState({ disabled: false }); }, + render() { + return ( + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + expect(input.isFormDisabled()).toBe(true); + + form.enableForm(); + immediate(() => { + expect(input.isFormDisabled()).toBe(false); + done(); + }); + + }); + + it('should be possible to pass error state of elements by changing an errors attribute', function (done) { + + const TestForm = React.createClass({ + getInitialState() { return { validationErrors: { foo: 'bar' } }; }, + onChange(values) { + this.setState(values.foo ? { validationErrors: {} } : { validationErrors: {foo: 'bar'} }); + }, + render() { + return ( + + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + // Wait for update + immediate(() => { + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + expect(input.getErrorMessage()).toBe('bar'); + input.setValue('gotValue'); + + // Wait for update + immediate(() => { + expect(input.getErrorMessage()).toBe(null); + done(); + }); + }); + + }); + + + it('should trigger an onValidSubmit when submitting a valid form', function () { + + let isCalled = false; + const TestForm = React.createClass({ + render() { + return ( + (isCalled = true)}> + + ); + } + }); + const form = TestUtils.renderIntoDocument(); + + const FoundForm = TestUtils.findRenderedComponentWithType(form, TestForm); + TestUtils.Simulate.submit(React.findDOMNode(FoundForm)); + expect(isCalled).toBe(true); + + }); + + it('should trigger an onInvalidSubmit when submitting an invalid form', function () { + + let isCalled = false; + const TestForm = React.createClass({ + render() { + return ( + (isCalled = true)}> + + ); + } + }); + const form = TestUtils.renderIntoDocument( + + ); + + const FoundForm = TestUtils.findRenderedComponentWithType(form, TestForm); + TestUtils.Simulate.submit(React.findDOMNode(FoundForm)); + expect(isCalled).toBe(true); + + }); + + }); + + describe("value === false", function () { + let onSubmit; + const TestForm = React.createClass({ + render() { + return ( + onSubmit(x)}> + + + + ); + } + }); + + beforeEach(() => { + onSubmit = jasmine.createSpy('onSubmit'); + }); + + it("should call onSubmit correctly", function () { + const form = TestUtils.renderIntoDocument(); + TestUtils.Simulate.submit(React.findDOMNode(form)); + expect(onSubmit).toHaveBeenCalledWith({foo: false}); + }); + + it("should allow dynamic changes to false", function () { + const form = TestUtils.renderIntoDocument(); + form.setProps({value: false}); + TestUtils.Simulate.submit(React.findDOMNode(form)); + expect(onSubmit).toHaveBeenCalledWith({foo: false}); + }); + + it("should say the form is submitted", function () { + const form = TestUtils.renderIntoDocument(); + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + expect(input.isFormSubmitted()).toBe(false); + TestUtils.Simulate.submit(React.findDOMNode(form)); + expect(input.isFormSubmitted()).toBe(true); + }); + + it("should be able to reset the form to its pristine state", function () { + const form = TestUtils.renderIntoDocument(); + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + const formsyForm = TestUtils.findRenderedComponentWithType(form, Formsy.Form); + expect(input.getValue()).toBe(true); + form.setProps({value: false}); + expect(input.getValue()).toBe(false); + formsyForm.reset(); + expect(input.getValue()).toBe(true); + }); + + it("should be able to reset the form using custom data", function () { + const form = TestUtils.renderIntoDocument(); + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + const 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 () { + let onChange; + + const TestForm = React.createClass({ + getDefaultProps() { + return { inputs: [] }; + }, + render() { + const builtInputs = this.props.inputs.map((input) => ); + return ( + + { builtInputs } + { this.props.children } + + ); + } + }); + + beforeEach(() => { + onChange = jasmine.createSpy('onChange'); + }); + + it('initially returns false', function () { + const form = TestUtils.renderIntoDocument(); + expect(form.refs.formsy.isChanged()).toEqual(false); + expect(onChange).not.toHaveBeenCalled(); + }); + + it('returns true when changed', function () { + const form = TestUtils.renderIntoDocument(); + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); + TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); + expect(form.refs.formsy.isChanged()).toEqual(true); + expect(onChange).toHaveBeenCalledWith({one: 'bar'}, true); + }); + + it('returns false if changes are undone', function () { + const form = TestUtils.renderIntoDocument(); + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); + TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); + expect(onChange).toHaveBeenCalledWith({one: 'bar'}, true); + TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'foo'}}); + expect(form.refs.formsy.isChanged()).toEqual(false); + expect(onChange).toHaveBeenCalledWith({one: 'foo'}, false); + }); + }); + +}); diff --git a/specs/Formsy-spec.jsx b/specs/Formsy-spec.jsx deleted file mode 100755 index d9d67fa..0000000 --- a/specs/Formsy-spec.jsx +++ /dev/null @@ -1,693 +0,0 @@ -var React = require('react/addons'); -var TestUtils = React.addons.TestUtils; -var Formsy = require('./../src/main.js'); - -describe('Formsy', function () { - - describe('Setting up a form', function () { - - it('should render a form into the document', function () { - var form = TestUtils.renderIntoDocument( ); - expect(React.findDOMNode(form).tagName).toEqual('FORM'); - }); - - it('should set a class name if passed', function () { - var form = TestUtils.renderIntoDocument( ); - expect(React.findDOMNode(form).className).toEqual('foo'); - }); - - it('should allow for null/undefined children', function (done) { - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - changeValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - - var model = null; - var TestForm = React.createClass({ - onSubmit: function (formModel) { - model = formModel; - }, - render: function () { - return ( - -

Test

- { null } - { undefined } - -
- ); - } - }); - - var form = TestUtils.renderIntoDocument(); - setTimeout(function () { - TestUtils.Simulate.submit(React.findDOMNode(form)); - expect(model).toEqual({name: 'foo'}); - done(); - }, 10); - }); - - it('should allow for inputs being added dynamically', function (done) { - - var inputs = []; - var forceUpdate = null; - var model = null; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return
- } - }); - var TestForm = React.createClass({ - componentWillMount: function () { - forceUpdate = this.forceUpdate.bind(this); - }, - onSubmit: function (formModel) { - model = formModel; - }, - render: function () { - return ( - - {inputs} - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - // Wait before adding the input - setTimeout(function () { - - inputs.push(); - - forceUpdate(function () { - // Wait for next event loop, as that does the form - setTimeout(function () { - TestUtils.Simulate.submit(React.findDOMNode(form)); - expect(model.test).toBeDefined(); - done(); - }, 0); - - }); - - }, 10); - - }); - - it('should allow dynamically added inputs to update the form-model', function (done) { - - var inputs = []; - var forceUpdate = null; - var model = null; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - changeValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var TestForm = React.createClass({ - componentWillMount: function () { - forceUpdate = this.forceUpdate.bind(this); - }, - onSubmit: function (formModel) { - model = formModel; - }, - render: function () { - return ( - - {inputs} - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - // Wait before adding the input - setTimeout(function () { - - inputs.push(); - - forceUpdate(function () { - - // Wait for next event loop, as that does the form - setTimeout(function () { - TestUtils.Simulate.change(TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'), {target: {value: 'foo'}}); - TestUtils.Simulate.submit(React.findDOMNode(form)); - expect(model.test).toBe('foo'); - done(); - }, 0); - - }); - - }, 0); - - }); - - it('should allow a dynamically updated input to update the form-model', function (done) { - - var forceUpdate = null; - var model = null; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - changeValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - - var input; - var TestForm = React.createClass({ - componentWillMount: function () { - forceUpdate = this.forceUpdate.bind(this); - }, - onSubmit: function (formModel) { - model = formModel; - }, - render: function () { - input = ; - - return ( - - {input} - ); - } - }); - var form = TestUtils.renderIntoDocument(); - - // Wait before changing the input - setTimeout(function () { - - form = TestUtils.renderIntoDocument(); - - forceUpdate(function () { - // Wait for next event loop, as that does the form - setTimeout(function () { - TestUtils.Simulate.submit(React.findDOMNode(form)); - expect(model.test).toBe('bar'); - done(); - }, 0); - - }); - - }, 10); - - }); - - describe('validations', function() { - var CheckValid, onSubmit, OtherCheckValid; - var isValid; - - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - changeValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - - var TestForm = React.createClass({ - getDefaultProps: function() { - return { - inputs: [], - }; - }, - render: function () { - var builtInputs = []; - var inputs = this.props.inputs; - for (var i=0; i < inputs.length; i++) { - var input = inputs[i]; - builtInputs.push(); - } - var _this = this; - return - { builtInputs } - ; - } - }); - - beforeEach(function() { - isValid = true; - CheckValid = jasmine.createSpy('CheckValid'); - Formsy.addValidationRule('CheckValid', CheckValid); - OtherCheckValid = jasmine.createSpy('CheckValid'); - Formsy.addValidationRule('OtherCheckValid', OtherCheckValid); - onSubmit = jasmine.createSpy('onSubmit'); - }); - - it('should run when the input changes', function() { - var form = TestUtils.renderIntoDocument(); - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); - expect(CheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true); - expect(OtherCheckValid).not.toHaveBeenCalled(); - }); - - it('should allow the validation to be changed', function() { - var form = TestUtils.renderIntoDocument(); - form.setProps({inputs: [{name: 'one', validations: 'OtherCheckValid', value: 'foo'}] }); - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); - expect(OtherCheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true); - }); - - it('should invalidate a form if dynamically inserted input is invalid', function(done) { - var form = TestUtils.renderIntoDocument(); - expect(isValid).toEqual(true); - form.setProps({inputs: [ - {name: 'one', validations: 'isEmail', value: 'foo@bar.com'}, - {name: 'two', validations: 'isEmail', value: 'foo@bar'}, - ]}, function() { - setTimeout(function() { - expect(isValid).toEqual(false); - done(); - }, 0); - }); - }); - - it('should validate a form when removing an invalid input', function(done) { - var form = TestUtils.renderIntoDocument(); - expect(isValid).toEqual(false); - form.setProps({inputs: [{name: 'one', validations: 'isEmail', value: 'foo@bar.com'}]}, function() { - setTimeout(function() { - expect(isValid).toEqual(true); - done(); - }, 0); - }); - }); - - it('runs multiple validations', function() { - var form = TestUtils.renderIntoDocument(); - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); - expect(CheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true); - expect(OtherCheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true); - }); - }); - - it('should not trigger onChange when form is mounted', function () { - var hasChanged = jasmine.createSpy('onChange'); - var TestForm = React.createClass({ - onChange: function () { - hasChanged(); - }, - render: function () { - return ; - } - }); - var form = TestUtils.renderIntoDocument(); - expect(hasChanged).not.toHaveBeenCalled(); - }); - - it('should trigger onChange when form element is changed', function () { - var hasChanged = jasmine.createSpy('onChange'); - var MyInput = React.createClass({ - mixins: [Formsy.Mixin], - onChange: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var TestForm = React.createClass({ - onChange: function () { - hasChanged(); - }, - render: function () { - return ( - - - - ); - } - }); - var form = TestUtils.renderIntoDocument(); - TestUtils.Simulate.change(TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'), {target: {value: 'bar'}}); - expect(hasChanged).toHaveBeenCalled(); - }); - - it('should trigger onChange when new input is added to form', function (done) { - var hasChanged = jasmine.createSpy('onChange'); - var inputs = []; - var forceUpdate = null; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - changeValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var TestForm = React.createClass({ - componentWillMount: function () { - forceUpdate = this.forceUpdate.bind(this); - }, - onChange: function () { - hasChanged(); - }, - render: function () { - return ( - - {inputs} - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - // Wait before adding the input - inputs.push(); - - forceUpdate(function () { - - // Wait for next event loop, as that does the form - setTimeout(function () { - expect(hasChanged).toHaveBeenCalled(); - done(); - }, 0); - - }); - - }); - - }); - - describe('Update a form', function () { - - it('should allow elements to check if the form is disabled', function (done) { - - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return - } - }); - var TestForm = React.createClass({ - getInitialState: function () { - return {disabled: true}; - }, - enableForm: function () { - this.setState({ - disabled: false - }); - }, - render: function () { - return ( - - - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - var input = TestUtils.findRenderedComponentWithType(form, TestInput); - expect(input.isFormDisabled()).toBe(true); - form.enableForm(); - setTimeout(function () { - expect(input.isFormDisabled()).toBe(false); - done(); - }, 0); - - }); - - it('should be possible to pass error state of elements by changing an errors attribute', function (done) { - - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return ; - } - }); - var TestForm = React.createClass({ - getInitialState: function () { - return { - validationErrors: { - foo: 'bar' - } - }; - }, - onChange: function (values) { - if (values.foo) { - this.setState({ - validationErrors: {} - }); - } else { - this.setState({ - validationErrors: {foo: 'bar'} - }); - } - }, - render: function () { - return ( - - - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - // Wait for update - setTimeout(function () { - var input = TestUtils.findRenderedComponentWithType(form, TestInput); - expect(input.getErrorMessage()).toBe('bar'); - input.setValue('gotValue'); - - // Wait for update - setTimeout(function () { - expect(input.getErrorMessage()).toBe(null); - done(); - }, 0); - }, 0); - - }); - - - it('should trigger an onValidSubmit when submitting a valid form', function () { - - var isCalled = false; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return ; - } - }); - var TestForm = React.createClass({ - onValidSubmit: function () { - isCalled = true; - }, - render: function () { - return ( - - - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - var TestForm = TestUtils.findRenderedComponentWithType(form, TestForm); - TestUtils.Simulate.submit(React.findDOMNode(TestForm)); - expect(isCalled).toBe(true); - - }); - - it('should trigger an onInvalidSubmit when submitting an invalid form', function () { - - var isCalled = false; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return ; - } - }); - var TestForm = React.createClass({ - onInvalidSubmit: function () { - isCalled = true; - }, - render: function () { - return ( - - - ); - } - }); - var form = TestUtils.renderIntoDocument( - - ); - - var TestForm = TestUtils.findRenderedComponentWithType(form, TestForm); - TestUtils.Simulate.submit(React.findDOMNode(TestForm)); - expect(isCalled).toBe(true); - - }); - - }); - - describe("value === false", function() { - var onSubmit; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - getDefaultProps: function() { - return { - type: "text", - }; - }, - changeValue: function() { - this.setValue(e.target[this.props.type === "checkbox" ? "checked" : "value"]); - }, - render: function () { - return - } - }); - - var TestForm = React.createClass({ - render: function () { - return ( - - - - - ); - } - }); - - beforeEach(function() { - onSubmit = jasmine.createSpy("onSubmit"); - }); - - it("should call onSubmit correctly", function() { - var form = TestUtils.renderIntoDocument(); - TestUtils.Simulate.submit(React.findDOMNode(form)); - expect(onSubmit).toHaveBeenCalledWith({foo: false}); - }); - - it("should allow dynamic changes to false", function() { - var form = TestUtils.renderIntoDocument(); - form.setProps({value: false}); - TestUtils.Simulate.submit(React.findDOMNode(form)); - expect(onSubmit).toHaveBeenCalledWith({foo: false}); - }); - - it("should say the form is submitted", function() { - var form = TestUtils.renderIntoDocument(); - var input = TestUtils.findRenderedComponentWithType(form, TestInput); - expect(input.isFormSubmitted()).toBe(false); - TestUtils.Simulate.submit(React.findDOMNode(form)); - expect(input.isFormSubmitted()).toBe(true); - }); - - it("should be able to reset the form to its pristine state", function() { - var form = TestUtils.renderIntoDocument(); - 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(); - expect(input.getValue()).toBe(true); - }); - - it("should be able to reset the form using custom data", function() { - var form = TestUtils.renderIntoDocument(); - 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() { - var onChange; - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - changeValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - - var TestForm = React.createClass({ - getDefaultProps: function() { - return { - inputs: [], - }; - }, - render: function () { - var builtInputs = []; - var inputs = this.props.inputs; - for (var i=0; i < inputs.length; i++) { - var input = inputs[i]; - builtInputs.push(); - } - return - { builtInputs } - { this.props.children } - ; - } - }); - - beforeEach(function() { - onChange = jasmine.createSpy("onChange"); - }); - - it('initially returns false', function() { - var form = TestUtils.renderIntoDocument(); - expect(form.refs.formsy.isChanged()).toEqual(false); - expect(onChange).not.toHaveBeenCalled(); - }); - - it('returns true when changed', function() { - var form = TestUtils.renderIntoDocument(); - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); - expect(form.refs.formsy.isChanged()).toEqual(true); - expect(onChange).toHaveBeenCalledWith({one: 'bar'}, true); - }); - - it('returns false if changes are undone', function() { - var form = TestUtils.renderIntoDocument(); - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'bar'}}); - expect(onChange).toHaveBeenCalledWith({one: 'bar'}, true); - TestUtils.Simulate.change(React.findDOMNode(input), {target: {value: 'foo'}}); - expect(form.refs.formsy.isChanged()).toEqual(false); - expect(onChange).toHaveBeenCalledWith({one: 'foo'}, false); - }); - }); - -}); diff --git a/specs/Rules-equals-spec.js b/specs/Rules-equals-spec.js new file mode 100644 index 0000000..1055774 --- /dev/null +++ b/specs/Rules-equals-spec.js @@ -0,0 +1,60 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: equals', function () { + let Input, isValid, form, input; + + function pass(value) { + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(true); + } : () => expect(isValid).toBe(true); + } + + function fail(value) { + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(false); + } : () => expect(isValid).toBe(false); + } + + beforeEach(() => { + Input = customizeInput({ + render() { + isValid = this.isValid(); + return ; + } + }); + + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + + }); + + afterEach(() => { + Input = isValid = form = null; + }); + + it('should pass with a default value', pass()); + + it('should fail when the value is not equal', fail('foo')); + + it('should pass when the value is equal', pass('myValue')); + + it('should pass with an empty string', pass('')); + + it('should pass with an undefined', pass(undefined)); + + it('should pass with a null', pass(null)); + + it('should fail with a number', fail(42)); + +}); diff --git a/specs/Rules-equals-spec.jsx b/specs/Rules-equals-spec.jsx deleted file mode 100644 index a689b16..0000000 --- a/specs/Rules-equals-spec.jsx +++ /dev/null @@ -1,62 +0,0 @@ -var React = require('react/addons'); -var TestUtils = React.addons.TestUtils; -var Formsy = require('./../src/main.js'); - -describe('Rules: equals', function() { - var TestInput, isValid, form, input; - - function pass(value) { - return pass.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); - expect(isValid).toBe(true); - } : function () { expect(isValid).toBe(true); }; - } - - function fail(value) { - return fail.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); - expect(isValid).toBe(false); - } : function () { expect(isValid).toBe(false); }; - } - - beforeEach(function() { - TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - isValid = this.isValid(); - return - } - }); - - form = TestUtils.renderIntoDocument( - - - - ); - - input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - - }); - - afterEach(function() { - TestInput = isValid = form = null; - }); - - it('should pass with a default value', pass()); - - it('should fail when the value is not equal', fail('foo')); - - it('should pass when the value is equal', pass('myValue')); - - it('should pass with an empty string', pass('')); - - it('should pass with an undefined', pass(undefined)); - - it('should pass with a null', pass(null)); - - it('should fail with a number', fail(42)); - -}); diff --git a/specs/Rules-isAlpha-spec.js b/specs/Rules-isAlpha-spec.js new file mode 100644 index 0000000..5d795d7 --- /dev/null +++ b/specs/Rules-isAlpha-spec.js @@ -0,0 +1,60 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: isAlpha', function () { + let Input, isValid, form, input; + + function pass(value) { + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(true); + } : () => expect(isValid).toBe(true); + } + + function fail(value) { + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(false); + } : () => expect(isValid).toBe(false); + } + + beforeEach(() => { + Input = customizeInput({ + render() { + isValid = this.isValid(); + return ; + } + }); + + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + + }); + + afterEach(() => { + Input = isValid = form = null; + }); + + it('should pass with a default value', pass()); + + it('should pass with a string is only latin letters', pass('myValue')); + + it('should fail with a string with numbers', fail('myValue 42')); + + it('should pass with an undefined', pass(undefined)); + + it('should pass with a null', pass(null)); + + it('should pass with an empty string', pass('')); + + it('should fail with a number', fail(42)); + +}); diff --git a/specs/Rules-isAlpha-spec.jsx b/specs/Rules-isAlpha-spec.jsx deleted file mode 100644 index 60b7a5e..0000000 --- a/specs/Rules-isAlpha-spec.jsx +++ /dev/null @@ -1,62 +0,0 @@ -var React = require('react/addons'); -var TestUtils = React.addons.TestUtils; -var Formsy = require('./../src/main.js'); - -describe('Rules: isAlpha', function() { - var TestInput, isValid, form, input; - - function pass(value) { - return pass.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); - expect(isValid).toBe(true); - } : function () { expect(isValid).toBe(true); }; - } - - function fail(value) { - return fail.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); - expect(isValid).toBe(false); - } : function () { expect(isValid).toBe(false); }; - } - - beforeEach(function() { - TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - isValid = this.isValid(); - return - } - }); - - form = TestUtils.renderIntoDocument( - - - - ); - - input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - - }); - - afterEach(function() { - TestInput = isValid = form = null; - }); - - it('should pass with a default value', pass()); - - it('should pass with a string is only latin letters', pass('myValue')); - - it('should fail with a string with numbers', fail('myValue 42')); - - it('should pass with an undefined', pass(undefined)); - - it('should pass with a null', pass(null)); - - it('should pass with an empty string', pass('')); - - it('should fail with a number', fail(42)); - -}); diff --git a/specs/Rules-isEmail-spec.js b/specs/Rules-isEmail-spec.js new file mode 100644 index 0000000..55b7588 --- /dev/null +++ b/specs/Rules-isEmail-spec.js @@ -0,0 +1,60 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: isEmail', function () { + let Input, isValid, form, input; + + function pass(value) { + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(true); + } : () => expect(isValid).toBe(true); + } + + function fail(value) { + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(false); + } : () => expect(isValid).toBe(false); + } + + beforeEach(() => { + Input = customizeInput({ + render() { + isValid = this.isValid(); + return ; + } + }); + + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + + }); + + afterEach(() => { + Input = isValid = form = null; + }); + + it('should pass with a default value', pass()); + + it('should fail with "foo"', fail('foo')); + + it('should pass with "foo@foo.com"', pass('foo@foo.com')); + + it('should pass with an undefined', pass(undefined)); + + it('should pass with a null', pass(null)); + + it('should pass with an empty string', pass('')); + + it('should fail with a number', fail(42)); + +}); diff --git a/specs/Rules-isEmail-spec.jsx b/specs/Rules-isEmail-spec.jsx deleted file mode 100644 index 29e5943..0000000 --- a/specs/Rules-isEmail-spec.jsx +++ /dev/null @@ -1,62 +0,0 @@ -var React = require('react/addons'); -var TestUtils = React.addons.TestUtils; -var Formsy = require('./../src/main.js'); - -describe('Rules: isEmail', function() { - var TestInput, isValid, form, input; - - function pass(value) { - return pass.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); - expect(isValid).toBe(true); - } : function () { expect(isValid).toBe(true); }; - } - - function fail(value) { - return fail.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); - expect(isValid).toBe(false); - } : function () { expect(isValid).toBe(false); }; - } - - beforeEach(function() { - TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - isValid = this.isValid(); - return - } - }); - - form = TestUtils.renderIntoDocument( - - - - ); - - input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - - }); - - afterEach(function() { - TestInput = isValid = form = null; - }); - - it('should pass with a default value', pass()); - - it('should fail with "foo"', fail('foo')); - - it('should pass with "foo@foo.com"', pass('foo@foo.com')); - - it('should pass with an undefined', pass(undefined)); - - it('should pass with a null', pass(null)); - - it('should pass with an empty string', pass('')); - - it('should fail with a number', fail(42)); - -}); diff --git a/specs/Rules-isEmptyString-spec.js b/specs/Rules-isEmptyString-spec.js new file mode 100644 index 0000000..e68265a --- /dev/null +++ b/specs/Rules-isEmptyString-spec.js @@ -0,0 +1,60 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: isEmptyString', function () { + let Input, isValid, form, input; + + function pass(value) { + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(true); + } : () => expect(isValid).toBe(true); + } + + function fail(value) { + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(false); + } : () => expect(isValid).toBe(false); + } + + beforeEach(() => { + Input = customizeInput({ + render() { + isValid = this.isValid(); + return ; + } + }); + + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + + }); + + afterEach(() => { + Input = isValid = form = null; + }); + + it('should fail with a default value', fail()); + + it('should fail with non-empty string', fail('asd')); + + it('should pass with an empty string', pass('')); + + it('should fail with a undefined', fail(undefined)); + + it('should fail with a null', fail(null)); + + it('should fail with a number', fail(123)); + + it('should fail with a zero', fail(0)); + +}); diff --git a/specs/Rules-isEmptyString-spec.jsx b/specs/Rules-isEmptyString-spec.jsx deleted file mode 100644 index 7fdad83..0000000 --- a/specs/Rules-isEmptyString-spec.jsx +++ /dev/null @@ -1,62 +0,0 @@ -var React = require('react/addons'); -var TestUtils = React.addons.TestUtils; -var Formsy = require('./../src/main.js'); - -describe('Rules: isEmptyString', function() { - var TestInput, isValid, form, input; - - function pass(value) { - return pass.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); - expect(isValid).toBe(true); - } : function () { expect(isValid).toBe(true); }; - } - - function fail(value) { - return fail.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); - expect(isValid).toBe(false); - } : function () { expect(isValid).toBe(false); }; - } - - beforeEach(function() { - TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - isValid = this.isValid(); - return - } - }); - - form = TestUtils.renderIntoDocument( - - - - ); - - input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - - }); - - afterEach(function() { - TestInput = isValid = form = null; - }); - - it('should fail with a default value', fail()); - - it('should fail with non-empty string', fail('asd')); - - it('should pass with an empty string', pass('')); - - it('should fail with a undefined', fail(undefined)); - - it('should fail with a null', fail(null)); - - it('should fail with a number', fail(123)); - - it('should fail with a zero', fail(0)); - -}); diff --git a/specs/Rules-isExisty-spec.js b/specs/Rules-isExisty-spec.js new file mode 100644 index 0000000..25821fb --- /dev/null +++ b/specs/Rules-isExisty-spec.js @@ -0,0 +1,60 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: isExisty', function () { + let Input, isValid, form, input; + + function pass(value) { + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(true); + } : () => expect(isValid).toBe(true); + } + + function fail(value) { + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(false); + } : () => expect(isValid).toBe(false); + } + + beforeEach(() => { + Input = customizeInput({ + render() { + isValid = this.isValid(); + return ; + } + }); + + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + + }); + + afterEach(() => { + Input = isValid = form = null; + }); + + it('should fail with a default value', fail()); + + it('should pass with a string', pass('myValue')); + + it('should pass with an empty string', pass('')); + + it('should fail with an undefined', fail(undefined)); + + it('should fail with a null', fail(null)); + + it('should pass with a number', pass(42)); + + it('should pass with a zero', pass(0)); + +}); diff --git a/specs/Rules-isExisty-spec.jsx b/specs/Rules-isExisty-spec.jsx deleted file mode 100644 index e946b81..0000000 --- a/specs/Rules-isExisty-spec.jsx +++ /dev/null @@ -1,62 +0,0 @@ -var React = require('react/addons'); -var TestUtils = React.addons.TestUtils; -var Formsy = require('./../src/main.js'); - -describe('Rules: isExisty', function() { - var TestInput, isValid, form, input; - - function pass(value) { - return pass.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); - expect(isValid).toBe(true); - } : function () { expect(isValid).toBe(true); }; - } - - function fail(value) { - return fail.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); - expect(isValid).toBe(false); - } : function () { expect(isValid).toBe(false); }; - } - - beforeEach(function() { - TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - isValid = this.isValid(); - return - } - }); - - form = TestUtils.renderIntoDocument( - - - - ); - - input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - - }); - - afterEach(function() { - TestInput = isValid = form = null; - }); - - it('should fail with a default value', fail()); - - it('should pass with a string', pass('myValue')); - - it('should pass with an empty string', pass('')); - - it('should fail with an undefined', fail(undefined)); - - it('should fail with a null', fail(null)); - - it('should pass with a number', pass(42)); - - it('should pass with a zero', pass(0)); - -}); diff --git a/specs/Rules-isLength-spec.jsx b/specs/Rules-isLength-spec.js similarity index 57% rename from specs/Rules-isLength-spec.jsx rename to specs/Rules-isLength-spec.js index 1e52cc3..5f7e21c 100644 --- a/specs/Rules-isLength-spec.jsx +++ b/specs/Rules-isLength-spec.js @@ -1,47 +1,45 @@ -var React = require('react/addons'); -var TestUtils = React.addons.TestUtils; -var Formsy = require('./../src/main.js'); +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; -describe('Rules: isLength', function() { - var TestInput, isValid, form, input; +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: isLength', function () { + let Input, isValid, form, input; function pass(value) { - return pass.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); expect(isValid).toBe(true); - } : function () { expect(isValid).toBe(true); }; + } : () => expect(isValid).toBe(true); } function fail(value) { - return fail.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); expect(isValid).toBe(false); - } : function () { expect(isValid).toBe(false); }; + } : () => expect(isValid).toBe(false); } - beforeEach(function() { - TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { + beforeEach(() => { + Input = customizeInput({ + render() { isValid = this.isValid(); - return + return ; } }); }); - afterEach(function() { - TestInput = isValid = form = null; + afterEach(() => { + Input = isValid = form = null; }); - describe('isLength:3', function() { + describe('isLength:3', () => { - beforeEach(function() { + beforeEach(() => { form = TestUtils.renderIntoDocument( - + ); @@ -66,12 +64,12 @@ describe('Rules: isLength', function() { }); - describe('isLength:0', function() { + describe('isLength:0', () => { - beforeEach(function() { + beforeEach(() => { form = TestUtils.renderIntoDocument( - + ); diff --git a/specs/Rules-isNumeric-spec.jsx b/specs/Rules-isNumeric-spec.js similarity index 53% rename from specs/Rules-isNumeric-spec.jsx rename to specs/Rules-isNumeric-spec.js index 94e21fd..f7b1938 100644 --- a/specs/Rules-isNumeric-spec.jsx +++ b/specs/Rules-isNumeric-spec.js @@ -1,39 +1,37 @@ -var React = require('react/addons'); -var TestUtils = React.addons.TestUtils; -var Formsy = require('./../src/main.js'); +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; -describe('Rules: isNumeric', function() { - var TestInput, isValid, form, input; +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: isNumeric', function () { + let Input, isValid, form, input; function pass(value) { - return pass.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); expect(isValid).toBe(true); - } : function () { expect(isValid).toBe(true); }; + } : () => expect(isValid).toBe(true); } function fail(value) { - return fail.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); expect(isValid).toBe(false); - } : function () { expect(isValid).toBe(false); }; + } : () => expect(isValid).toBe(false); } - beforeEach(function() { - TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { + beforeEach(() => { + Input = customizeInput({ + render() { isValid = this.isValid(); - return + return ; } }); form = TestUtils.renderIntoDocument( - + ); @@ -41,8 +39,8 @@ describe('Rules: isNumeric', function() { }); - afterEach(function() { - TestInput = isValid = form = null; + afterEach(() => { + Input = isValid = form = null; }); it('should pass with a default value', pass()); diff --git a/specs/Rules-isUrl-spec.js b/specs/Rules-isUrl-spec.js new file mode 100644 index 0000000..9755512 --- /dev/null +++ b/specs/Rules-isUrl-spec.js @@ -0,0 +1,60 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: isUrl', function () { + let Input, isValid, form, input; + + function pass(value) { + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(true); + } : () => expect(isValid).toBe(true); + } + + function fail(value) { + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(false); + } : () => expect(isValid).toBe(false); + } + + beforeEach(() => { + Input = customizeInput({ + render() { + isValid = this.isValid(); + return ; + } + }); + + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + + }); + + afterEach(() => { + Input = isValid = form = null; + }); + + it('should pass with a default value', pass()); + + it('should fail with "foo"', fail('foo')); + + it('should pass with "https://www.google.com/"', pass('https://www.google.com/')); + + it('should pass with an undefined', pass(undefined)); + + it('should pass with a null', pass(null)); + + it('should fail with a number', fail(42)); + + it('should pass with an empty string', pass('')); + +}); diff --git a/specs/Rules-isUrl-spec.jsx b/specs/Rules-isUrl-spec.jsx deleted file mode 100644 index cabf8ac..0000000 --- a/specs/Rules-isUrl-spec.jsx +++ /dev/null @@ -1,62 +0,0 @@ -var React = require('react/addons'); -var TestUtils = React.addons.TestUtils; -var Formsy = require('./../src/main.js'); - -describe('Rules: isUrl', function() { - var TestInput, isValid, form, input; - - function pass(value) { - return pass.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); - expect(isValid).toBe(true); - } : function () { expect(isValid).toBe(true); }; - } - - function fail(value) { - return fail.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); - expect(isValid).toBe(false); - } : function () { expect(isValid).toBe(false); }; - } - - beforeEach(function() { - TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - isValid = this.isValid(); - return - } - }); - - form = TestUtils.renderIntoDocument( - - - - ); - - input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - - }); - - afterEach(function() { - TestInput = isValid = form = null; - }); - - it('should pass with a default value', pass()); - - it('should fail with "foo"', fail('foo')); - - it('should pass with "https://www.google.com/"', pass('https://www.google.com/')); - - it('should pass with an undefined', pass(undefined)); - - it('should pass with a null', pass(null)); - - it('should fail with a number', fail(42)); - - it('should pass with an empty string', pass('')); - -}); diff --git a/specs/Rules-isWords-spec.js b/specs/Rules-isWords-spec.js new file mode 100644 index 0000000..fffd080 --- /dev/null +++ b/specs/Rules-isWords-spec.js @@ -0,0 +1,60 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: isWords', function () { + let Input, isValid, form, input; + + function pass(value) { + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(true); + } : () => expect(isValid).toBe(true); + } + + function fail(value) { + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(false); + } : () => expect(isValid).toBe(false); + } + + beforeEach(() => { + Input = customizeInput({ + render() { + isValid = this.isValid(); + return ; + } + }); + + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + + }); + + afterEach(() => { + Input = isValid = form = null; + }); + + it('should pass with a default value', pass()); + + it('should pass with a 1 word', pass('sup')); + + it('should pass with 2 words', pass('sup dude')); + + it('should fail with a string with numbers', fail('myValue 42')); + + it('should pass with an undefined', pass(undefined)); + + it('should pass with a null', pass(null)); + + it('should fail with a number', fail(42)); + +}); diff --git a/specs/Rules-isWords-spec.jsx b/specs/Rules-isWords-spec.jsx deleted file mode 100644 index f7752f4..0000000 --- a/specs/Rules-isWords-spec.jsx +++ /dev/null @@ -1,62 +0,0 @@ -var React = require('react/addons'); -var TestUtils = React.addons.TestUtils; -var Formsy = require('./../src/main.js'); - -describe('Rules: isWords', function() { - var TestInput, isValid, form, input; - - function pass(value) { - return pass.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); - expect(isValid).toBe(true); - } : function () { expect(isValid).toBe(true); }; - } - - function fail(value) { - return fail.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); - expect(isValid).toBe(false); - } : function () { expect(isValid).toBe(false); }; - } - - beforeEach(function() { - TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - isValid = this.isValid(); - return - } - }); - - form = TestUtils.renderIntoDocument( - - - - ); - - input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - - }); - - afterEach(function() { - TestInput = isValid = form = null; - }); - - it('should pass with a default value', pass()); - - it('should pass with a 1 word', pass('sup')); - - it('should pass with 2 words', pass('sup dude')); - - it('should fail with a string with numbers', fail('myValue 42')); - - it('should pass with an undefined', pass(undefined)); - - it('should pass with a null', pass(null)); - - it('should fail with a number', fail(42)); - -}); diff --git a/specs/Rules-maxLength-spec.jsx b/specs/Rules-maxLength-spec.js similarity index 50% rename from specs/Rules-maxLength-spec.jsx rename to specs/Rules-maxLength-spec.js index 5c00103..727c820 100644 --- a/specs/Rules-maxLength-spec.jsx +++ b/specs/Rules-maxLength-spec.js @@ -1,39 +1,37 @@ -var React = require('react/addons'); -var TestUtils = React.addons.TestUtils; -var Formsy = require('./../src/main.js'); +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; -describe('Rules: maxLength', function() { - var TestInput, isValid, form, input; +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: maxLength', function () { + let Input, isValid, form, input; function pass(value) { - return pass.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); expect(isValid).toBe(true); - } : function () { expect(isValid).toBe(true); }; + } : () => expect(isValid).toBe(true); } function fail(value) { - return fail.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); expect(isValid).toBe(false); - } : function () { expect(isValid).toBe(false); }; + } : () => expect(isValid).toBe(false); } - beforeEach(function() { - TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { + beforeEach(() => { + Input = customizeInput({ + render() { isValid = this.isValid(); - return + return ; } }); form = TestUtils.renderIntoDocument( - + ); @@ -41,8 +39,8 @@ describe('Rules: maxLength', function() { }); - afterEach(function() { - TestInput = isValid = form = null; + afterEach(() => { + Input = isValid = form = null; }); it('should pass with a default value', pass()); diff --git a/specs/Rules-minLength-spec.jsx b/specs/Rules-minLength-spec.js similarity index 57% rename from specs/Rules-minLength-spec.jsx rename to specs/Rules-minLength-spec.js index 57b7712..be9a491 100644 --- a/specs/Rules-minLength-spec.jsx +++ b/specs/Rules-minLength-spec.js @@ -1,47 +1,45 @@ -var React = require('react/addons'); -var TestUtils = React.addons.TestUtils; -var Formsy = require('./../src/main.js'); +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; -describe('Rules: minLength', function() { - var TestInput, isValid, form, input; +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: minLength', function () { + let Input, isValid, form, input; function pass(value) { - return pass.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); expect(isValid).toBe(true); - } : function () { expect(isValid).toBe(true); }; + } : () => expect(isValid).toBe(true); } function fail(value) { - return fail.length ? function () { - TestUtils.Simulate.change(input, {target: {value: value}}); + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); expect(isValid).toBe(false); - } : function () { expect(isValid).toBe(false); }; + } : () => expect(isValid).toBe(false); } - beforeEach(function() { - TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { + beforeEach(() => { + Input = customizeInput({ + render() { isValid = this.isValid(); - return + return ; } }); }); - afterEach(function() { - TestInput = isValid = form = null; + afterEach(() => { + Input = isValid = form = null; }); - describe('minLength:3', function() { + describe('minLength:3', function () { - beforeEach(function() { + beforeEach(() => { form = TestUtils.renderIntoDocument( - + ); @@ -66,12 +64,12 @@ describe('Rules: minLength', function() { }); - describe('minLength:0', function() { + describe('minLength:0', () => { - beforeEach(function() { + beforeEach(() => { form = TestUtils.renderIntoDocument( - + ); diff --git a/specs/Utils-spec.jsx b/specs/Utils-spec.js similarity index 55% rename from specs/Utils-spec.jsx rename to specs/Utils-spec.js index c32fa8c..a113c1e 100644 --- a/specs/Utils-spec.jsx +++ b/specs/Utils-spec.js @@ -1,15 +1,16 @@ -var utils = require('./../src/utils.js'); +import utils from './../src/utils.js'; -describe('Utils', function() { +describe('Utils', function () { - it('should check equality of objects and arrays', function () { - var objA = { foo: 'bar' }; - var objB = { foo: 'bar' }; - var objC = [{ foo: ['bar'] }]; - var objD = [{ foo: ['bar'] }]; - var objE, objF; - var objG = null; - var objH = null; + it('should check equality of objects and arrays', () => { + const objA = { foo: 'bar' }; + const objB = { foo: 'bar' }; + const objC = [{ foo: ['bar'] }]; + const objD = [{ foo: ['bar'] }]; + const objE = undefined; + const objF = undefined; + const objG = null; + const objH = null; expect(utils.isSame(objA, objB)).toBe(true); expect(utils.isSame(objC, objD)).toBe(true); diff --git a/specs/Validation-spec.js b/specs/Validation-spec.js new file mode 100644 index 0000000..a0d4fcc --- /dev/null +++ b/specs/Validation-spec.js @@ -0,0 +1,202 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import TestInput, { customizeInput } from './utils/TestInput'; +import immediate from './utils/immediate'; + +describe('Validation', function () { + + it('should reset only changed form element when external error is passed', function (done) { + + const form = TestUtils.renderIntoDocument( + invalidate({ foo: 'bar', bar: 'foo' })}> + + + + ); + + const input = TestUtils.scryRenderedDOMComponentsWithTag(form, 'INPUT')[0]; + const inputComponents = TestUtils.scryRenderedComponentsWithType(form, TestInput); + + form.submit(); + expect(inputComponents[0].isValid()).toBe(false); + expect(inputComponents[1].isValid()).toBe(false); + + TestUtils.Simulate.change(input, {target: {value: 'bar'}}); + immediate(() => { + expect(inputComponents[0].isValid()).toBe(true); + expect(inputComponents[1].isValid()).toBe(false); + done(); + }); + + }); + + it('should let normal validation take over when component with external error is changed', function (done) { + + const form = TestUtils.renderIntoDocument( + invalidate({ foo: 'bar' })}> + + + ); + + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); + + form.submit(); + expect(inputComponent.isValid()).toBe(false); + + TestUtils.Simulate.change(input, {target: {value: 'bar'}}); + immediate(() => { + expect(inputComponent.getValue()).toBe('bar'); + expect(inputComponent.isValid()).toBe(false); + done(); + }); + + }); + + it('should trigger an onValid handler, if passed, when form is valid', function () { + + const onValid = jasmine.createSpy('valid'); + const onInvalid = jasmine.createSpy('invalid'); + + TestUtils.renderIntoDocument( + + + + ); + + expect(onValid).toHaveBeenCalled(); + expect(onInvalid).not.toHaveBeenCalled(); + + }); + + it('should trigger an onInvalid handler, if passed, when form is invalid', function () { + + const onValid = jasmine.createSpy('valid'); + const onInvalid = jasmine.createSpy('invalid'); + + TestUtils.renderIntoDocument( + + + + ); + + expect(onValid).not.toHaveBeenCalled(); + expect(onInvalid).toHaveBeenCalled(); + + }); + + it('should use provided validate function', function () { + + const isValid = jasmine.createSpy('valid'); + + const Input = customizeInput({ + render() { + if (this.isValid()) { + isValid(); + } + return ; + }, + validate() { + return this.getValue() === 'checkValidity'; + } + }); + + const form = TestUtils.renderIntoDocument( + + + + ); + + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + TestUtils.Simulate.change(input, {target: {value: 'checkValidity'}}); + expect(isValid).toHaveBeenCalled(); + + }); + + it('should provide invalidate callback on onValiSubmit', function () { + + const TestForm = React.createClass({ + render() { + return ( + invalidate({ foo: 'bar' })}> + + + ); + } + }); + + const form = TestUtils.renderIntoDocument(); + + const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + TestUtils.Simulate.submit(formEl); + expect(input.isValid()).toBe(false); + + }); + + it('should provide invalidate callback on onInvalidSubmit', function () { + + const TestForm = React.createClass({ + render() { + return ( + invalidate({ foo: 'bar' })}> + + + ); + } + }); + + const form = TestUtils.renderIntoDocument(); + const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + TestUtils.Simulate.submit(formEl); + expect(input.getErrorMessage()).toBe('bar'); + + }); + + + it('should not invalidate inputs on external errors with preventExternalInvalidation prop', function () { + + const TestForm = React.createClass({ + render() { + return ( + invalidate({ foo: 'bar' })}> + + + ); + } + }); + + const form = TestUtils.renderIntoDocument(); + const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); + const 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 () { + + const TestForm = React.createClass({ + render() { + return ( + invalidate({ foo: 'bar' })}> + + + ); + } + }); + + const form = TestUtils.renderIntoDocument(); + const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + TestUtils.Simulate.submit(formEl); + expect(input.isValid()).toBe(false); + + }); + +}); diff --git a/specs/Validation-spec.jsx b/specs/Validation-spec.jsx deleted file mode 100644 index fd6fabe..0000000 --- a/specs/Validation-spec.jsx +++ /dev/null @@ -1,281 +0,0 @@ -var React = require('react/addons'); -var TestUtils = React.addons.TestUtils; -var Formsy = require('./../src/main.js'); - -describe('Validation', function() { - - it('should reset only changed form element when external error is passed', function (done) { - - var onSubmit = function (model, reset, invalidate) { - invalidate({ - foo: 'bar', - bar: 'foo' - }); - } - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var form = TestUtils.renderIntoDocument( - - - - - ); - - var input = TestUtils.scryRenderedDOMComponentsWithTag(form, 'INPUT')[0]; - var inputComponents = TestUtils.scryRenderedComponentsWithType(form, TestInput); - - form.submit(); - expect(inputComponents[0].isValid()).toBe(false); - expect(inputComponents[1].isValid()).toBe(false); - TestUtils.Simulate.change(input, {target: {value: 'bar'}}); - setTimeout(function () { - expect(inputComponents[0].isValid()).toBe(true); - expect(inputComponents[1].isValid()).toBe(false); - done(); - }, 0); - }); - - it('should let normal validation take over when component with external error is changed', function (done) { - - var onSubmit = function (model, reset, invalidate) { - invalidate({ - foo: 'bar' - }); - } - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var form = TestUtils.renderIntoDocument( - - - - ); - - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - var inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - - form.submit(); - expect(inputComponent.isValid()).toBe(false); - TestUtils.Simulate.change(input, {target: {value: 'bar'}}); - setTimeout(function () { - expect(inputComponent.getValue()).toBe('bar'); - expect(inputComponent.isValid()).toBe(false); - done(); - }, 0); - }); - - it('should trigger an onValid handler, if passed, when form is valid', function () { - - var onValid = jasmine.createSpy('valid'); - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var form = TestUtils.renderIntoDocument( - - - - ); - - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - TestUtils.Simulate.change(input, {target: {value: 'foo'}}); - expect(onValid).toHaveBeenCalled(); - - }); - - it('should trigger an onInvalid handler, if passed, when form is invalid', function () { - - var onInvalid = jasmine.createSpy('invalid'); - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - return - } - }); - var form = TestUtils.renderIntoDocument( - - - - ); - - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - TestUtils.Simulate.change(input, {target: {value: ''}}); - expect(onInvalid).toHaveBeenCalled(); - - }); - - it('should use provided validate function', function () { - - var isValid = jasmine.createSpy('valid'); - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - updateValue: function (event) { - this.setValue(event.target.value); - }, - render: function () { - if (this.isValid()) { - isValid(); - } - return - }, - validate: function () { - return this.getValue() === "checkValidity"; - } - }); - var form = TestUtils.renderIntoDocument( - - - - ); - - var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - TestUtils.Simulate.change(input, {target: {value: 'checkValidity'}}); - expect(isValid).toHaveBeenCalled(); - - }); - - it('should provide invalidate callback on onValiSubmit', function () { - - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return - } - }); - var TestForm = React.createClass({ - invalidate: function (model, reset, invalidate) { - invalidate({ - foo: 'bar' - }); - }, - render: function () { - return ( - - - - ); - } - }); - var form = TestUtils.renderIntoDocument(); - - var formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); - var input = TestUtils.findRenderedComponentWithType(form, TestInput); - TestUtils.Simulate.submit(formEl); - expect(input.isValid()).toBe(false); - - }); - - it('should provide invalidate callback on onInvalidSubmit', function () { - - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return - } - }); - var TestForm = React.createClass({ - invalidate: function (model, reset, invalidate) { - invalidate({ - foo: 'bar' - }); - }, - render: function () { - return ( - - - - ); - } - }); - var form = TestUtils.renderIntoDocument(); - - var formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); - var input = TestUtils.findRenderedComponentWithType(form, TestInput); - TestUtils.Simulate.submit(formEl); - expect(input.getErrorMessage()).toBe('bar'); - - }); - - - it('should not invalidate inputs on external errors with preventExternalInvalidation prop', function () { - - var TestInput = React.createClass({ - mixins: [Formsy.Mixin], - render: function () { - return - } - }); - var TestForm = React.createClass({ - invalidate: function (model, reset, invalidate) { - invalidate({ - foo: 'bar' - }); - }, - render: function () { - return ( - - - - ); - } - }); - var form = TestUtils.renderIntoDocument(); - 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 - } - }); - var TestForm = React.createClass({ - invalidate: function (model, reset, invalidate) { - invalidate({ - foo: 'bar' - }); - }, - render: function () { - return ( - - - - ); - } - }); - var form = TestUtils.renderIntoDocument(); - var formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); - var input = TestUtils.findRenderedComponentWithType(form, TestInput); - TestUtils.Simulate.submit(formEl); - expect(input.isValid()).toBe(false); - - }); - -}); diff --git a/specs/utils/TestInput.js b/specs/utils/TestInput.js new file mode 100644 index 0000000..8a917ae --- /dev/null +++ b/specs/utils/TestInput.js @@ -0,0 +1,22 @@ +import React from 'react'; +import Formsy from './../..'; +import assign from 'react/lib/Object.assign'; + +const defaultProps = { + mixins: [Formsy.Mixin], + getDefaultProps() { + return { type: 'text' }; + }, + updateValue(event) { + this.setValue(event.target[this.props.type === 'checkbox' ? 'checked' : 'value']); + }, + render() { + return ; + } +}; + +export function customizeInput(props) { + return React.createClass(assign(defaultProps, props)); +} + +export default React.createClass(defaultProps); diff --git a/specs/utils/immediate.js b/specs/utils/immediate.js new file mode 100644 index 0000000..ed311ae --- /dev/null +++ b/specs/utils/immediate.js @@ -0,0 +1,3 @@ +export default function (fn) { + setTimeout(fn, 0); +} diff --git a/testrunner.js b/testrunner.js index 48f4251..9801b91 100644 --- a/testrunner.js +++ b/testrunner.js @@ -10,16 +10,13 @@ global.navigator = global.window.navigator; var jasmineOptions = { specFolders: [path.resolve(__dirname, 'specs')], - //onComplete: onComplete, isVerbose: true, showColors: true, teamcity: false, useRequireJs: false, - regExpSpec: /spec\.jsx$/, + regExpSpec: /spec\.js$/, junitreport: true, - includeStackTrace: true, - //coffee: options.coffee, - //growl: options.growl + includeStackTrace: true }; jasmine.executeSpecsInFolder(jasmineOptions); From 5c33b56e7100e5c195dc1893125a6741527e54cf Mon Sep 17 00:00:00 2001 From: Zach Alexander Date: Wed, 9 Sep 2015 10:40:14 -0400 Subject: [PATCH 19/24] Fix 'localhost' links in 'Examples' readme --- examples/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/README.md b/examples/README.md index 89a49a3..c1bcebc 100644 --- a/examples/README.md +++ b/examples/README.md @@ -23,10 +23,10 @@ If it is not helped try update your node.js and npm. ## Examples -1. [**Login**](http://localhost:8080/login) +1. [**Login**](login) Two required fields with simple validation. -2. [**Custom Validation**](http://localhost:8080/custom-validation) +2. [**Custom Validation**](custom-validation) - One field with added validation rule (`Formsy.addValidationRule`) and one field with dynamically added validation and error messages. \ No newline at end of file + One field with added validation rule (`Formsy.addValidationRule`) and one field with dynamically added validation and error messages. From 6a0d23cc036bfe5ec33fec9116653297c1a592be Mon Sep 17 00:00:00 2001 From: Semigradsky Date: Thu, 10 Sep 2015 15:26:17 +0300 Subject: [PATCH 20/24] Added `reset-values` example. Moved examples to es2015 --- examples/components/Input.js | 43 +++++++++++++++ examples/components/Select.js | 35 ++++++++++++ examples/custom-validation/app.js | 92 ++++++++++++------------------- examples/global.css | 12 +++- examples/index.html | 3 +- examples/login/app.js | 69 ++++++----------------- examples/reset-values/app.css | 4 ++ examples/reset-values/app.js | 44 +++++++++++++++ examples/reset-values/index.html | 14 +++++ examples/webpack.config.js | 2 +- 10 files changed, 206 insertions(+), 112 deletions(-) create mode 100644 examples/components/Input.js create mode 100644 examples/components/Select.js create mode 100644 examples/reset-values/app.css create mode 100644 examples/reset-values/app.js create mode 100644 examples/reset-values/index.html diff --git a/examples/components/Input.js b/examples/components/Input.js new file mode 100644 index 0000000..a73e060 --- /dev/null +++ b/examples/components/Input.js @@ -0,0 +1,43 @@ +import React from 'react'; +import Formsy from 'formsy-react'; + +const MyInput = React.createClass({ + + // Add the Formsy Mixin + mixins: [Formsy.Mixin], + + // setValue() will set the value of the component, which in + // turn will validate it and the rest of the form + changeValue(event) { + this.setValue(event.currentTarget[this.props.type === 'checkbox' ? 'checked' : 'value']); + }, + render() { + + // Set a specific className based on the validation + // state of this component. showRequired() is true + // when the value is empty and the required prop is + // passed to the input. showError() is true when the + // value typed is invalid + const className = this.props.className + ' ' + (this.showRequired() ? 'required' : this.showError() ? 'error' : null); + + // An error message is returned ONLY if the component is invalid + // or the server has returned an error message + const errorMessage = this.getErrorMessage(); + + return ( +
+ + + {errorMessage} +
+ ); + } +}); + +export default MyInput; diff --git a/examples/components/Select.js b/examples/components/Select.js new file mode 100644 index 0000000..f8d9afa --- /dev/null +++ b/examples/components/Select.js @@ -0,0 +1,35 @@ +import React from 'react'; +import Formsy from 'formsy-react'; + +const MySelect = React.createClass({ + mixins: [Formsy.Mixin], + + changeValue(event) { + this.setValue(event.currentTarget.value); + }, + + render() { + const className = this.props.className + ' ' + (this.showRequired() ? 'required' : this.showError() ? 'error' : null); + const errorMessage = this.getErrorMessage(); + + const value = this.getValue(); + const options = this.props.options.map(option => ( + + )); + + return ( +
+ + + {errorMessage} +
+ ); + } + +}); + +export default MySelect; diff --git a/examples/custom-validation/app.js b/examples/custom-validation/app.js index beef629..886e583 100644 --- a/examples/custom-validation/app.js +++ b/examples/custom-validation/app.js @@ -1,10 +1,12 @@ -var React = require('react'); -var ReactDOM = require('react-dom'); -var Formsy = require('formsy-react'); +import React from 'react'; +import ReactDOM from 'react-dom'; +import Formsy from 'formsy-react'; -var currentYear = new Date().getFullYear(); +import MyInput from './../components/Input'; -var validators = { +const currentYear = new Date().getFullYear(); + +const validators = { time: { regexp: /^(([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9])(:([0-5]?[0-9]))?$/, message: 'Not valid time' @@ -19,79 +21,56 @@ var validators = { } }; -Formsy.addValidationRule('isYearOfBirth', function (values, value) { +Formsy.addValidationRule('isYearOfBirth', (values, value) => { value = parseInt(value); - if (typeof value !== 'number' || value !== value) { + if (typeof value !== 'number') { return false; } return value < currentYear && value > currentYear - 130; }); -var App = React.createClass({ - submit: function (data) { +const App = React.createClass({ + submit(data) { alert(JSON.stringify(data, null, 4)); }, - render: function () { + render() { return ( - - + + ); } }); -var MyOwnInput = React.createClass({ +const DynamicInput = React.createClass({ mixins: [Formsy.Mixin], - changeValue: function (event) { + getInitialState() { + return { validationType: 'time' }; + }, + changeValue(event) { this.setValue(event.currentTarget.value); }, - render: function () { - var className = this.props.className + ' ' + (this.showError() ? 'error' : null); - var errorMessage = this.getErrorMessage(); - - return ( -
- - - {errorMessage} -
- ); - } -}); - -var DynamicInput = React.createClass({ - mixins: [Formsy.Mixin], - getInitialState: function() { - return { - validationType: 'time' - }; - }, - changeValue: function (event) { - this.setValue(event.currentTarget.value); - }, - changeValidation: function(validationType) { - this.setState({ - validationType: validationType - }); + changeValidation(validationType) { + this.setState({ validationType: validationType }); this.setValue(this.getValue()); }, - validate: function () { - var value = this.getValue(); - return value === '' ? true : validators[this.state.validationType].regexp.test(value); + validate() { + const value = this.getValue(); + return value !== '' ? validators[this.state.validationType].regexp.test(value) : true; }, - getCustomErrorMessage: function() { + getCustomErrorMessage() { return this.showError() ? validators[this.state.validationType].message : ''; }, - render: function () { - var className = this.props.className + ' ' + (this.showError() ? 'error' : null); - var errorMessage = this.getCustomErrorMessage(); + render() { + const className = this.props.className + ' ' + (this.showError() ? 'error' : null); + const errorMessage = this.getCustomErrorMessage(); return (
- + {errorMessage}
@@ -99,22 +78,23 @@ var DynamicInput = React.createClass({ } }); -var Validations = React.createClass({ - changeValidation: function(e) { +const Validations = React.createClass({ + changeValidation(e) { this.props.changeValidation(e.target.value); }, - render: function() { + render() { + const { validationType } = this.props; return (
Validation Type
- Time + Time
- Decimal + Decimal
- Binary + Binary
); diff --git a/examples/global.css b/examples/global.css index 15a2a75..ebdad7f 100644 --- a/examples/global.css +++ b/examples/global.css @@ -38,7 +38,8 @@ form { .form-group input[type='text'], .form-group input[type='email'], .form-group input[type='number'], -.form-group input[type='password'] { +.form-group input[type='password'], +.form-group select { display: block; width: 100%; height: 34px; @@ -62,4 +63,11 @@ form { button { padding: 10px 15px; border-radius: 4px; -} \ No newline at end of file +} + +.buttons button { + margin-left: 10px; +} +.buttons button:first-child { + margin-left: 0; +} diff --git a/examples/index.html b/examples/index.html index d813a18..175c07b 100644 --- a/examples/index.html +++ b/examples/index.html @@ -9,6 +9,7 @@ - \ No newline at end of file + diff --git a/examples/login/app.js b/examples/login/app.js index d6e0da8..1de0d0a 100644 --- a/examples/login/app.js +++ b/examples/login/app.js @@ -1,64 +1,29 @@ -var React = require('react'); -var ReactDOM = require('react-dom'); -var Formsy = require('formsy-react'); +import React from 'react'; +import ReactDOM from 'react-dom'; +import { Form } from 'formsy-react'; -var App = React.createClass({ - getInitialState: function() { +import MyInput from './../components/Input'; + +const App = React.createClass({ + getInitialState() { return { canSubmit: false }; }, - submit: function (data) { + submit(data) { alert(JSON.stringify(data, null, 4)); }, - enableButton: function () { - this.setState({ - canSubmit: true - }); + enableButton() { + this.setState({ canSubmit: true }); }, - disableButton: function () { - this.setState({ - canSubmit: false - }); + disableButton() { + this.setState({ canSubmit: false }); }, - render: function () { + render() { return ( - - - +
+ + - - ); - } -}); - -var MyOwnInput = React.createClass({ - - // Add the Formsy Mixin - mixins: [Formsy.Mixin], - - // setValue() will set the value of the component, which in - // turn will validate it and the rest of the form - changeValue: function (event) { - this.setValue(event.currentTarget.value); - }, - render: function () { - - // Set a specific className based on the validation - // state of this component. showRequired() is true - // when the value is empty and the required prop is - // passed to the input. showError() is true when the - // value typed is invalid - var className = this.props.className + ' ' + (this.showRequired() ? 'required' : this.showError() ? 'error' : null); - - // An error message is returned ONLY if the component is invalid - // or the server has returned an error message - var errorMessage = this.getErrorMessage(); - - return ( -
- - - {errorMessage} -
+ ); } }); diff --git a/examples/reset-values/app.css b/examples/reset-values/app.css new file mode 100644 index 0000000..e9e02dc --- /dev/null +++ b/examples/reset-values/app.css @@ -0,0 +1,4 @@ +.form { + width: 400px; + margin: 0 auto; +} diff --git a/examples/reset-values/app.js b/examples/reset-values/app.js new file mode 100644 index 0000000..d5deb8f --- /dev/null +++ b/examples/reset-values/app.js @@ -0,0 +1,44 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { Form } from 'formsy-react'; + +import MyInput from './../components/Input'; +import MySelect from './../components/Select'; + +const user = { + name: 'Sam', + free: true, + hair: 'brown' +}; + +const App = React.createClass({ + submit(data) { + alert(JSON.stringify(data, null, 4)); + }, + resetForm() { + this.refs.form.reset(); + }, + render() { + return ( + + + + + +
+ + +
+
+ ); + } +}); + +ReactDOM.render(, document.getElementById('example')); diff --git a/examples/reset-values/index.html b/examples/reset-values/index.html new file mode 100644 index 0000000..036a23a --- /dev/null +++ b/examples/reset-values/index.html @@ -0,0 +1,14 @@ + + + + Reset Values + + + + +

Formsy React Examples / Reset Values

+
+ + + + diff --git a/examples/webpack.config.js b/examples/webpack.config.js index ca9992b..06bbc10 100644 --- a/examples/webpack.config.js +++ b/examples/webpack.config.js @@ -11,7 +11,7 @@ module.exports = { devtool: 'inline-source-map', entry: fs.readdirSync(__dirname).reduce(function (entries, dir) { - var isDraft = dir.charAt(0) === '_'; + var isDraft = dir.charAt(0) === '_' || dir.indexOf('components') >= 0; if (!isDraft && isDirectory(path.join(__dirname, dir))) { entries[dir] = path.join(__dirname, dir, 'app.js'); From 5deb7554c9b66da2ec366f94803afb9f06f09314 Mon Sep 17 00:00:00 2001 From: Semigradsky Date: Thu, 10 Sep 2015 15:30:01 +0300 Subject: [PATCH 21/24] Added description for `reset-values` example --- examples/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/README.md b/examples/README.md index c1bcebc..691cc4f 100644 --- a/examples/README.md +++ b/examples/README.md @@ -30,3 +30,7 @@ If it is not helped try update your node.js and npm. 2. [**Custom Validation**](custom-validation) One field with added validation rule (`Formsy.addValidationRule`) and one field with dynamically added validation and error messages. + +3. [**Reset Values**](reset-values) + + Reset text input, checkbox and select to their pristine values. From 8fe0d4d73fbf2a65ab2d89a4ba0cc1e7b09c98a9 Mon Sep 17 00:00:00 2001 From: Semigradsky Date: Thu, 10 Sep 2015 16:10:17 +0300 Subject: [PATCH 22/24] Fixed React warnings --- examples/components/Select.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/components/Select.js b/examples/components/Select.js index f8d9afa..57a286d 100644 --- a/examples/components/Select.js +++ b/examples/components/Select.js @@ -12,9 +12,8 @@ const MySelect = React.createClass({ const className = this.props.className + ' ' + (this.showRequired() ? 'required' : this.showError() ? 'error' : null); const errorMessage = this.getErrorMessage(); - const value = this.getValue(); - const options = this.props.options.map(option => ( - )); @@ -22,7 +21,7 @@ const MySelect = React.createClass({ return (
- {options} {errorMessage} From a96f5246e77821236fefdcd2fca314ceb174bc0e Mon Sep 17 00:00:00 2001 From: Semigradsky Date: Fri, 11 Sep 2015 11:02:35 +0300 Subject: [PATCH 23/24] Added new validation rules: `isAlphanumeric`, `isInt`, `isFloat` --- API.md | 30 ++++++++++--- specs/Rules-isAlpha-spec.js | 2 +- specs/Rules-isAlphanumeric-spec.js | 62 +++++++++++++++++++++++++++ specs/Rules-isFloat-spec.js | 68 ++++++++++++++++++++++++++++++ specs/Rules-isInt-spec.js | 68 ++++++++++++++++++++++++++++++ specs/Rules-isNumeric-spec.js | 2 + src/validationRules.js | 17 ++++++-- 7 files changed, 238 insertions(+), 11 deletions(-) create mode 100644 specs/Rules-isAlphanumeric-spec.js create mode 100644 specs/Rules-isFloat-spec.js create mode 100644 specs/Rules-isInt-spec.js diff --git a/API.md b/API.md index 1a31266..44e2f2e 100644 --- a/API.md +++ b/API.md @@ -659,18 +659,36 @@ Returns true if the value is the boolean true ``` Returns true if the value is the boolean false -**isNumeric** -```html - -``` -Returns true if string only contains numbers - **isAlpha** ```html ``` Returns true if string is only letters +**isNumeric** +```html + +``` +Returns true if string only contains numbers. Examples: 42; -3.14 + +**isAlphanumeric** +```html + +``` +Returns true if string only contains letters or numbers + +**isInt** +```html + +``` +Returns true if string represents integer value. Examples: 42; -12; 0 + +**isFloat** +```html + +``` +Returns true if string represents float value. Examples: 42; -3.14; 1e3 + **isWords** ```html diff --git a/specs/Rules-isAlpha-spec.js b/specs/Rules-isAlpha-spec.js index 5d795d7..c851430 100644 --- a/specs/Rules-isAlpha-spec.js +++ b/specs/Rules-isAlpha-spec.js @@ -47,7 +47,7 @@ describe('Rules: isAlpha', function () { it('should pass with a string is only latin letters', pass('myValue')); - it('should fail with a string with numbers', fail('myValue 42')); + it('should fail with a string with numbers', fail('myValue42')); it('should pass with an undefined', pass(undefined)); diff --git a/specs/Rules-isAlphanumeric-spec.js b/specs/Rules-isAlphanumeric-spec.js new file mode 100644 index 0000000..b7a6bc9 --- /dev/null +++ b/specs/Rules-isAlphanumeric-spec.js @@ -0,0 +1,62 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: isAlphanumeric', function () { + let Input, isValid, form, input; + + function pass(value) { + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(true); + } : () => expect(isValid).toBe(true); + } + + function fail(value) { + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(false); + } : () => expect(isValid).toBe(false); + } + + beforeEach(() => { + Input = customizeInput({ + render() { + isValid = this.isValid(); + return ; + } + }); + + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + + }); + + afterEach(() => { + Input = isValid = form = null; + }); + + it('should pass with a default value', pass()); + + it('should pass with a string is only latin letters', pass('myValue')); + + it('should pass with a string with numbers', pass('myValue42')); + + it('should pass with an undefined', pass(undefined)); + + it('should pass with a null', pass(null)); + + it('should pass with an empty string', pass('')); + + it('should pass with a number', pass(42)); + + it('should fail with a non alpha and number symbols', fail('!@#$%^&*()')); + +}); diff --git a/specs/Rules-isFloat-spec.js b/specs/Rules-isFloat-spec.js new file mode 100644 index 0000000..138c68c --- /dev/null +++ b/specs/Rules-isFloat-spec.js @@ -0,0 +1,68 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: isFloat', function () { + let Input, isValid, form, input; + + function pass(value) { + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(true); + } : () => expect(isValid).toBe(true); + } + + function fail(value) { + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(false); + } : () => expect(isValid).toBe(false); + } + + beforeEach(() => { + Input = customizeInput({ + render() { + isValid = this.isValid(); + return ; + } + }); + + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + + }); + + afterEach(() => { + Input = isValid = form = null; + }); + + it('should pass with a default value', pass()); + + it('should pass with an empty string', pass('')); + + it('should fail with an unempty string', fail('myValue')); + + it('should pass with a number as string', pass('+42')); + + it('should fail with a number as string with not digits', fail('42 as an answer')); + + it('should pass with an int', pass(42)); + + it('should pass with a float', pass(Math.PI)); + + it('should pass with a float in science notation', pass('-1e3')); + + it('should pass with an undefined', pass(undefined)); + + it('should pass with a null', pass(null)); + + it('should pass with a zero', pass(0)); + +}); diff --git a/specs/Rules-isInt-spec.js b/specs/Rules-isInt-spec.js new file mode 100644 index 0000000..17cf42c --- /dev/null +++ b/specs/Rules-isInt-spec.js @@ -0,0 +1,68 @@ +import React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import Formsy from './..'; +import { customizeInput } from './utils/TestInput'; + +describe('Rules: isInt', function () { + let Input, isValid, form, input; + + function pass(value) { + return pass.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(true); + } : () => expect(isValid).toBe(true); + } + + function fail(value) { + return fail.length ? () => { + TestUtils.Simulate.change(input, {target: {value}}); + expect(isValid).toBe(false); + } : () => expect(isValid).toBe(false); + } + + beforeEach(() => { + Input = customizeInput({ + render() { + isValid = this.isValid(); + return ; + } + }); + + form = TestUtils.renderIntoDocument( + + + + ); + + input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + + }); + + afterEach(() => { + Input = isValid = form = null; + }); + + it('should pass with a default value', pass()); + + it('should pass with an empty string', pass('')); + + it('should fail with an unempty string', fail('myValue')); + + it('should pass with a number as string', pass('+42')); + + it('should fail with a number as string with not digits', fail('42 as an answer')); + + it('should pass with an int', pass(42)); + + it('should fail with a float', fail(Math.PI)); + + it('should fail with a float in science notation', fail('-1e3')); + + it('should pass with an undefined', pass(undefined)); + + it('should pass with a null', pass(null)); + + it('should pass with a zero', pass(0)); + +}); diff --git a/specs/Rules-isNumeric-spec.js b/specs/Rules-isNumeric-spec.js index f7b1938..94bd4f0 100644 --- a/specs/Rules-isNumeric-spec.js +++ b/specs/Rules-isNumeric-spec.js @@ -57,6 +57,8 @@ describe('Rules: isNumeric', function () { it('should pass with a float', pass(Math.PI)); + it('should fail with a float in science notation', fail('-1e3')); + it('should pass with an undefined', pass(undefined)); it('should pass with a null', pass(null)); diff --git a/src/validationRules.js b/src/validationRules.js index 9b5f527..f6c0e95 100644 --- a/src/validationRules.js +++ b/src/validationRules.js @@ -38,16 +38,25 @@ var validations = { if (typeof value === 'number') { return true; } - return validations.matchRegexp(values, value, /^[-+]?(\d*[.])?\d+$/); + return validations.matchRegexp(values, value, /^[-+]?(?:\d*[.])?\d+$/); }, isAlpha: function (values, value) { - return validations.matchRegexp(values, value, /^[a-zA-Z]+$/); + return validations.matchRegexp(values, value, /^[A-Z]+$/i); + }, + isAlphanumeric: function (values, value) { + return validations.matchRegexp(values, value, /^[0-9A-Z]+$/i); + }, + isInt: function (values, value) { + return validations.matchRegexp(values, value, /^(?:[-+]?(?:0|[1-9]\d*))$/); + }, + isFloat: function (values, value) { + return validations.matchRegexp(values, value, /^(?:[-+]?(?:\d+))?(?:\.\d*)?(?:[eE][\+\-]?(?:\d+))?$/); }, isWords: function (values, value) { - return validations.matchRegexp(values, value, /^[a-zA-Z\s]+$/); + return validations.matchRegexp(values, value, /^[A-Z\s]+$/i); }, isSpecialWords: function (values, value) { - return validations.matchRegexp(values, value, /^[a-zA-Z\s\u00C0-\u017F]+$/); + return validations.matchRegexp(values, value, /^[A-Z\s\u00C0-\u017F]+$/i); }, isLength: function (values, value, length) { return !isExisty(value) || isEmpty(value) || value.length === length; From 5083c31c8d8653c24b311e117412dc85a9cf018e Mon Sep 17 00:00:00 2001 From: Dan Pantry Date: Sat, 26 Sep 2015 23:54:39 +0100 Subject: [PATCH 24/24] transpile with Babel prior to publishing to npm This enables Node environments to use require('formsy-react') instead of having to transpile it themselves --- .gitignore | 1 + package.json | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index f03556e..15d5043 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store build node_modules +lib diff --git a/package.json b/package.json index b125879..90705f4 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,13 @@ "type": "git", "url": "https://github.com/christianalfoni/formsy-react.git" }, - "main": "src/main.js", + "main": "lib/main.js", "scripts": { "start": "webpack-dev-server --content-base build", "deploy": "NODE_ENV=production webpack -p --config webpack.production.config.js", "test": "node testrunner", - "examples": "webpack-dev-server --config examples/webpack.config.js --content-base examples" + "examples": "webpack-dev-server --config examples/webpack.config.js --content-base examples", + "prepublish": "babel ./src/ -d ./lib/" }, "author": "Christian Alfoni", "license": "MIT",