Новый пакет валидаций для React на Mobx @quantumart/mobx-form-validation-kit
- среда, 9 октября 2019 г. в 00:29:51
this.form = new FormGroup<IUserInfo>({
name: new FormControl(
this.userInfo.name,
[],
v => (this.userInfo.name = v)
),
surname: new FormControl(
this.userInfo.surname,
[],
v => (this.userInfo.surname = v)
)
// …
});
this.form = new FormGroup<IUserInfo>({
name: new FormControl(
this.userInfo.name,
[],
v => (this.userInfo.name = v)
),
surname: new FormControl(
this.userInfo.surname,
[],
v => (this.userInfo.surname = v)
)
passport: new FormGroup<IPassport >({
number: new FormControl(
this.userInfo.passport.number,
[],
v => (this.userInfo.passport.number = v)
),
// …
})
// …
});
await this.form.wait();
if (this.form.invalid) {
…
await this.form.wait();
if (this.form.invalid) {
this.form.setTouched(true);
const firstError = this.form.allControls().find(c => c.invalid && !!c.element);
if (!!firstError) {
firstError.element.focus();
}
}
...
new FormControl<number>(
this.userInfo.age,
[required(), minValue(18, "Вам должно быть больше 18 лет.", ValidationEventTypes.Warning)],
v => (this.userInfo.age = v)
)
new FormControl(
this.userInfo.megapole,
[wrapperActivateValidation(() => this.info.A === 10, [
required(),
pattern(/\^d{10}$/)
]),
wrapperActivateValidation(() => this.info.A === 20, [
wrapperSequentialCheck([
notContainSpaces(),
pattern(/\^d{20}$/)
])
])],
v => (this.userInfo.megapole = v)
)
async function checkValueOnServer(control: FormControl): Promise<ValidationEvent[]> {
if (control.value == null) {
return [];
}
const result = await sendToServer(control.value);
if (result.errorMessage) {
return [
{
message: result.errorMessage,
type: ValidationEventTypes.Error,
},
];
}
return [];
}
this.form = new FormGroup<IUserInfo>({
name: new FormControl(
this.userInfo.name,
[],
v => (this.userInfo.name = v)
)
});
this.form = new FormGroup<IUserInfo>({
name: FormControl.for(this.userInfo, 'name', [])
});
{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": true,
"module": "commonjs",
"target": "es6",
"jsx": "react",
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
import * as React from "react";
export class Hello extends React.Component {
render() {
return (
<h1>
Hello from TypeScript and React!
</h1>
);
}
}
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Hello } from "./components/Hello";
ReactDOM.render(
<Hello />,
document.getElementById("example")
);
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
</head>
<body>
<div id="example"></div>
<!-- Dependencies -->
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
<!-- Main -->
<script src="./dist/main.js"></script>
</body>
</html>
src\assets\global.scss
.row {
display: inline;
}
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.tsx',
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
output: {
path: path.join(__dirname, '/dist'),
filename: 'bundle.min.js'
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'awesome-typescript-loader'
},
{
test: /\.(scss|css)?$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
importLoaders: 1,
},
},
{ loader: 'sass-loader', options: { sourceMap: true } },
],
},
]
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html'
})
]
}
"mobx": "4",
"mobx-react": "^6.1.1",
"style-loader": "^0.23.1",
"css-loader": "^3.1.0",
"node-sass": "^4.12.0",
"sass-loader": "^7.1.0"
{
"name": "ttt",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --mode development --open",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "MIT",
"devDependencies": {
"@types/react": "^16.9.5",
"@types/react-dom": "^16.9.1",
"awesome-typescript-loader": "^5.2.1",
"html-webpack-plugin": "^3.2.0",
"source-map-loader": "^0.2.4",
"ts-loader": "^6.2.0",
"typescript": "^3.6.3",
"webpack": "^4.41.0",
"webpack-cli": "^3.3.9"
},
"dependencies": {
"@quantumart/mobx-form-validation-kit": "^1.0.8",
"mobx": "4",
"mobx-react": "^6.1.1",
"react": "^16.10.2",
"react-dom": "^16.10.2",
"webpack-dev-server": "^3.8.2",
"style-loader": "^0.23.1",
"css-loader": "^3.1.0",
"node-sass": "^4.12.0",
"sass-loader": "^7.1.0"
}
}
import { observable } from "mobx";
export class RegistrationStore {
@observable
public userInfo = {
name: "Виталий"
};
}
export const registrationStore = new RegistrationStore();
import * as React from "react";
import { observer } from "mobx-react";
import { registrationStore } from "../RegistrationStore";
@observer
export class Hello extends React.Component {
private changeName = (event: React.ChangeEvent<HTMLInputElement>) => {
registrationStore.userInfo.name = event.target.value;
};
render() {
return (
<React.Fragment>
<h1>Здравствуйте, {registrationStore.userInfo.name}</h1>
<div className="row">
<span>Имя:</span>
<input
type="text"
value={registrationStore.userInfo.name}
onChange={this.changeName}
/>
</div>
</React.Fragment>
);
}
}
import * as React from "react";
import { observer } from "mobx-react";
import { FormControl } from "@quantumart/mobx-form-validation-kit";
interface Props {
formControl: FormControl;
}
@observer
export class ErrorWraper extends React.Component<Props> {
render() {
return (
<div>
{this.props.children}
{this.props.formControl.errors.map(error => (
<span key={error.message} className="error">
{error.message}
</span>
))}
</div>
);
}
}
import * as React from "react";
import { observer } from "mobx-react";
import { registrationStore } from "../RegistrationStore";
import { ErrorWraper } from "../ErrorWraper";
import { InputFormControl } from "@quantumart/mobx-form-validation-kit";
@observer
export class Hello extends React.Component {
constructor(props: any) {
super(props);
registrationStore.initForm();
}
componentWillUnmount() {
registrationStore.form.dispose();
}
render() {
const controls = registrationStore.form.controls;
return (
<React.Fragment>
<h1>Здравствуйте, {registrationStore.userInfo.name}</h1>
<div className="row">
<span>Имя:</span>
<ErrorWraper formControl={controls.name}>
<input
type="text"
{...InputFormControl.bindActions(controls.name)}
/>
</ErrorWraper>
</div>
</React.Fragment>
);
}
}
import { observable } from "mobx";
import {
FormControl,
FormGroup,
AbstractControls
} from "@quantumart/mobx-form-validation-kit";
interface IUserInfo extends AbstractControls {
name: FormControl;
}
export class RegistrationStore {
@observable
public userInfo = {
name: "Виталий"
};
@observable
public form: FormGroup<IUserInfo>;
public initForm(): void {
this.form = new FormGroup<IUserInfo>({
name: new FormControl(
this.userInfo.name,
[],
v => (this.userInfo.name = v)
)
});
}
}
export const registrationStore = new RegistrationStore();