Skip to content

Commit 3d4f35e

Browse files
m.volkovm.volkov
authored andcommitted
Initial
1 parent 8baf22f commit 3d4f35e

15 files changed

+738
-36
lines changed

.eslintignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/**
2+
**/__test__/**
3+
build/**

.eslintrc

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{
2+
"parser" : "babel-eslint",
3+
"plugins": [
4+
"import"
5+
],
6+
"extends" : ["airbnb"],
7+
"rules": {
8+
// Soft some rules.
9+
"camelcase": "off",
10+
"class-methods-use-this": "off",
11+
"default-case": 0, // Required default case is nonsense.
12+
"indent": [2, 4, { 'SwitchCase': 1, 'VariableDeclarator': 1 }],
13+
"linebreak-style": "off",
14+
"max-len": "off",
15+
"new-cap": [2, {"capIsNew": false, "newIsCap": true}], // For Record() etc.
16+
"newline-per-chained-call": 0,
17+
"no-cond-assign": "off",
18+
"no-floating-decimal": 0, // .5 is just fine.
19+
"no-nested-ternary": 0, // It's nice for JSX.
20+
"no-param-reassign": 0, // We love param reassignment. Naming is hard.
21+
"no-plusplus": 0,
22+
"no-prototype-builtins": 0,
23+
"no-shadow": 0, // Shadowing is a nice language feature. Naming is hard.
24+
"react/no-string-refs": 0,
25+
"no-underscore-dangle": "off",
26+
// eslint-plugin-import
27+
"import/no-unresolved": [2, {"commonjs": true}],
28+
"import/no-extraneous-dependencies": 0,
29+
"import/named": 2,
30+
"import/default": 2,
31+
"import/namespace": 2,
32+
"import/export": 2,
33+
"func-names": ["error", "as-needed"],
34+
// Overide Stateless
35+
"react/prefer-stateless-function": 0,
36+
"react/jsx-indent": [2, 4],
37+
"react/jsx-indent-props": [2, 4],
38+
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
39+
"react/no-unused-prop-types": 0,
40+
"react/no-array-index-key": 0,
41+
"react/forbid-prop-types": 0,
42+
"react/require-default-props": 0,
43+
"jsx-a11y/anchor-has-content": 0,
44+
},
45+
"globals": {
46+
"after": false,
47+
"afterEach": false,
48+
"before": false,
49+
"beforeEach": false,
50+
"describe": false,
51+
"it": false,
52+
"require": false,
53+
"window": true,
54+
"localStorage": true,
55+
"document": true,
56+
"navigator": true,
57+
"location": true,
58+
"XMLHttpRequest": true,
59+
"XDomainRequest": true,
60+
"Blob": true,
61+
},
62+
"settings": {
63+
"import/ignore": [
64+
"node_modules",
65+
"\\.json$"
66+
],
67+
"import/parser": "babel-eslint",
68+
"import/resolve": {
69+
"extensions": [
70+
".js",
71+
".jsx",
72+
".json"
73+
]
74+
}
75+
}
76+
}

.gitignore

100644100755
Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,7 @@
1-
# Logs
2-
logs
3-
*.log
4-
npm-debug.log*
5-
6-
# Runtime data
7-
pids
8-
*.pid
9-
*.seed
10-
11-
# Directory for instrumented libs generated by jscoverage/JSCover
12-
lib-cov
13-
14-
# Coverage directory used by tools like istanbul
15-
coverage
16-
17-
# nyc test coverage
18-
.nyc_output
19-
20-
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21-
.grunt
22-
23-
# node-waf configuration
24-
.lock-wscript
25-
26-
# Compiled binary addons (http://nodejs.org/api/addons.html)
27-
build/Release
28-
29-
# Dependency directories
301
node_modules
31-
jspm_packages
32-
33-
# Optional npm cache directory
34-
.npm
35-
36-
# Optional REPL history
37-
.node_repl_history
2+
.DS_Store
3+
build/*
4+
npm-debug.log
5+
config.jsx
6+
!config.jsx.dist
7+
.idea

Readme.md

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
## Validation component for material-ui forms
2+
3+
Simple form validation component for material-ui library inspired by [formsy-react](https://github.com/christianalfoni/formsy-react)
4+
5+
Supported types:
6+
+ Text
7+
+ Select
8+
+ AutoComplete
9+
+ Date
10+
+ Time
11+
12+
Default validation rules:
13+
+ matchRegexp
14+
+ isEmail
15+
+ isEmpty
16+
+ required
17+
+ trim
18+
+ isNumber
19+
+ isFloat
20+
+ isPositive
21+
22+
23+
### Example
24+
25+
[example.gif](../examples/example.gif)
26+
27+
### Usage
28+
29+
You can pass any props of field components except ``errorText``, use ``errorMessages`` instead.
30+
Your component must [provide a theme](http://www.material-ui.com/#/get-started/usage).
31+
32+
````javascript
33+
34+
import React from 'react';
35+
import RaisedButton from 'material-ui/RaisedButton';
36+
import { ValidatorForm, TextValidator} from 'react-material-ui-form-validator';
37+
38+
class MyForm extends React.Component {
39+
40+
constructor(props) {
41+
super(props);
42+
43+
this.handleChange = this.handleChange.bind(this);
44+
}
45+
46+
handleChange(event) {
47+
const email = event.target.value;
48+
this.setState({ email });
49+
}
50+
51+
handleSubmit() {
52+
// your submit logic
53+
}
54+
55+
render() {
56+
const { email } = this.state;
57+
return (
58+
<ValidatorForm
59+
ref="form"
60+
onSubmit={this.handleSubmit}
61+
>
62+
<TextValidator
63+
floatingLabelText="Email"
64+
onChange={this.handleChange}
65+
name="email"
66+
value={email}
67+
validators={['required', 'isEmail']}
68+
errorMessages={['this field is required', 'email is not valid']}
69+
/>
70+
<RaisedButton type="submit" />
71+
</ValidatorForm>
72+
);
73+
}
74+
}
75+
76+
````
77+
78+
You can add your custom rules:
79+
````javascript
80+
81+
import React from 'react';
82+
import RaisedButton from 'material-ui/RaisedButton';
83+
import { ValidatorForm, TextValidator} from 'react-material-ui-form-validator';
84+
85+
class ResetPasswordForm extends React.Component {
86+
87+
constructor(props) {
88+
super(props);
89+
this.state = {
90+
user: {},
91+
};
92+
this.handleChange = this.handleChange.bind(this);
93+
}
94+
95+
componentWillMount() {
96+
// custom rule will have name 'isPasswordMatch'
97+
ValidatorForm.addValidationRule('isPasswordMatch', (value) => {
98+
if (value !== this.state.user.password) {
99+
return false;
100+
}
101+
return true;
102+
});
103+
}
104+
105+
handleChange(event) {
106+
const { user } = this.state;
107+
user[event.target.name] = event.target.value;
108+
this.setState({ user });
109+
}
110+
111+
handleSubmit() {
112+
// your submit logic
113+
}
114+
115+
render() {
116+
const { user } = this.state;
117+
118+
return (
119+
<ValidatorForm
120+
onSubmit={this.handleSubmit}
121+
>
122+
<TextValidator
123+
floatingLabelText="Password"
124+
onChange={this.handleChange}
125+
name="password"
126+
type="password"
127+
validators={['required']}
128+
errorMessages={['this field is required']}
129+
value={user.password}
130+
/>
131+
<TextValidator
132+
floatingLabelText="Repeat password"
133+
onChange={this.handleChange}
134+
name="repeatPassword"
135+
type="password"
136+
validators={['isPasswordMatch', 'required']}
137+
errorMessages={['password mismatch', 'this field is required']}
138+
value={user.repeatPassword}
139+
/>
140+
<RaisedButton type="submit" />
141+
</ValidatorForm>
142+
);
143+
}
144+
145+
````
146+
147+
Currently material-ui [doesn't support](https://github.com/callemall/material-ui/issues/3771) error messages for switches, but you can easily add your own:
148+
````javascript
149+
import React from 'react';
150+
import Checkbox from 'material-ui/Checkbox';
151+
import { ValidatorComponent } from 'react-material-ui-form-validator';
152+
153+
export default class CustomCheckboxValidator extends ValidatorComponent {
154+
155+
render() {
156+
const { errorMessage, validators, requiredError, ...rest } = this.props;
157+
const { isValid } = this.state;
158+
const errorMessage = !isValid && this.getErrorMessage();
159+
return (
160+
<div>
161+
<Checkbox {...rest} />
162+
{errorMessage}
163+
</div>
164+
);
165+
}
166+
}
167+
168+
````
169+
170+
### API
171+
172+
#### ValidatorForm
173+
174+
| Prop | Required | Type | Default value | Description |
175+
|-----------------|----------|----------|---------------|------------------------------------------------------------------------------------------------------------------------------|
176+
| onSubmit | true | function | | Callback for form that fires when all validations are passed |
177+
| instantValidate | false | bool | false | If true, form will be validated after each field change. If false, form will be validated only after clicking submit button. |
178+
179+
#### All validated fields (ValidatorComponent)
180+
181+
| Prop | Required | Type | Default value | Description |
182+
|-----------------|----------|----------|---------------|----------------------------------------------------------------------------------------|
183+
| validators | false | array | | Array of validators. See list of default validators above. |
184+
| errorMessages | false | array | | Array of error messages. Order of messages should be the same as `validators` prop. |
185+
| name | true | string | | Name of input |
186+
187+
### Contributing
188+
189+
This component covers all my needs, but feel free to contribute.

examples/example.gif

182 KB
Loading

package.json

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"name": "react-material-ui-form-validator",
3+
"version": "0.0.1",
4+
"description": "Simple validator for forms designed with material-ui components.",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "test"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/NewOldMax/react-material-ui-form-validator.git"
12+
},
13+
"keywords": [
14+
"materia-ui",
15+
"form",
16+
"validation"
17+
],
18+
"author": "NewOldMax",
19+
"license": "MIT",
20+
"bugs": {
21+
"url": "https://github.com/NewOldMax/react-material-ui-form-validator/issues"
22+
},
23+
"homepage": "https://github.com/NewOldMax/react-material-ui-form-validator#readme",
24+
"peerDependencies": {
25+
"material-ui": "^0.16.0",
26+
"react": "^15.0.0",
27+
"react-dom": "^15.0.0"
28+
},
29+
"devDependencies": {
30+
"babelify": "7.3.0",
31+
"browser-sync": "2.17.5",
32+
"browserify": "13.1.0",
33+
"nodemon": "1.11.0",
34+
"rework": "1.0.1",
35+
"rework-npm": "1.0.0",
36+
"rework-npm-cli": "0.1.1",
37+
"serve": "1.4.0",
38+
"uglify-js": "2.7.3",
39+
"watchify": "3.7.0",
40+
"bufferutil": "1.2.1",
41+
"utf-8-validate": "1.2.1",
42+
"babel-preset-react": "6.16.0",
43+
"babel-preset-es2015": "6.16.0",
44+
"babel-preset-stage-2": "6.16.0",
45+
"envify": "3.4.1",
46+
"babel-eslint": "^7.1.1",
47+
"eslint": "^3.11.1",
48+
"eslint-config-airbnb": "^13.0.0",
49+
"eslint-plugin-import": "^2.2.0",
50+
"eslint-plugin-jsx-a11y": "2.2.3",
51+
"eslint-plugin-react": "^6.8.0"
52+
}
53+
}

src/AutoCompleteValidator.jsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import React from 'react';
2+
import AutoComplete from 'material-ui/AutoComplete';
3+
import ValidatorComponent from './ValidatorComponent';
4+
5+
export default class AutoCompleteValidator extends ValidatorComponent {
6+
7+
render() {
8+
// eslint-disable-next-line
9+
const { errorMessage, validators, requiredError, ...rest } = this.props;
10+
const { isValid } = this.state;
11+
return (
12+
<AutoComplete
13+
{...rest}
14+
errorText={!isValid && this.getErrorMessage()}
15+
/>
16+
);
17+
}
18+
}

0 commit comments

Comments
 (0)