Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8a4f365

Browse filesBrowse files
committed
ref:Lemoncode#187 14_FormValidation refactor
1 parent cca74be commit 8a4f365
Copy full SHA for 8a4f365

File tree

Expand file treeCollapse file tree

11 files changed

+139
-187
lines changed
Filter options
Expand file treeCollapse file tree

11 files changed

+139
-187
lines changed

‎hooks/14_FormValidation/Readme.md

Copy file name to clipboardExpand all lines: hooks/14_FormValidation/Readme.md
+1-20Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Let's add validation support to this form.
44

5-
For this we will use lc-form-validation library
5+
For this we will use formik, fonk and fonk-formik library
66

77
Summary steps:
88

@@ -101,24 +101,6 @@ const validationSchema: ValidationSchema = {
101101
export const loginFormValidation = createFormikValidation(validationSchema);
102102
```
103103

104-
- Let's create now a class to hold the dataFormErrors.
105-
106-
_./src/pages/loginPage.viewmodel.ts_
107-
108-
```typescript
109-
import { FieldValidationResult } from "lc-form-validation";
110-
111-
export interface LoginFormErrors {
112-
login: FieldValidationResult;
113-
password: FieldValidationResult;
114-
}
115-
116-
export const createDefaultLoginFormErrors = (): LoginFormErrors => ({
117-
login: new FieldValidationResult(),
118-
password: new FieldValidationResult()
119-
});
120-
```
121-
122104
- Now let's go for the component side.
123105

124106
- First let's add the dataFormErrors to the state of the component.
@@ -128,7 +110,6 @@ _./src/pages/loginPage.tsx_
128110
```diff
129111
import { isValidLogin } from "../api/login";
130112
import { NotificationComponent } from "../common";
131-
+ import {LoginFormErrors, createDefaultLoginFormErrors} from './loginPage.viewmodel';
132113
```
133114

134115
_./src/pages/loginPage.tsx_
+8-3Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
import {LoginEntity} from '../model/login';
1+
import { LoginEntity } from "../model/login";
22

33
// Just a fake loginAPI
4-
export const isValidLogin = (loginInfo : LoginEntity) : boolean =>
5-
(loginInfo.login === 'admin' && loginInfo.password === 'test');
4+
export const isValidLogin = (loginInfo: LoginEntity): Promise<boolean> =>
5+
new Promise((resolve) => {
6+
setTimeout(() => {
7+
// mock call
8+
resolve(loginInfo.login === "admin" && loginInfo.password === "test");
9+
}, 500);
10+
});

‎hooks/14_FormValidation/src/app.tsx

Copy file name to clipboardExpand all lines: hooks/14_FormValidation/src/app.tsx
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import * as React from "react";
22
import { HashRouter, Switch, Route } from "react-router-dom";
3-
import { LoginPage } from "./pages/loginPage";
3+
import { LoginContainer } from "./pages/login.container";
44
import { PageB } from "./pages/pageB";
55

66
export const App = () => {
77
return (
88
<>
99
<HashRouter>
1010
<Switch>
11-
<Route exact={true} path="/" component={LoginPage} />
11+
<Route exact={true} path="/" component={LoginContainer} />
1212
<Route path="/pageB" component={PageB} />
1313
</Switch>
1414
</HashRouter>
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
export * from './notification';
2-
export * from './textFieldForm';
2+
export * from './textField.component';
+25Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import * as React from "react";
2+
import { useField } from "formik";
3+
import MuiTextField, { TextFieldProps } from "@material-ui/core/TextField";
4+
5+
export const TextFieldComponent: React.FC<TextFieldProps> = (props) => {
6+
const [field, meta] = useField(props.name);
7+
const textFieldProps = Boolean(field) ? field : props;
8+
const hasError = Boolean(meta && meta.touched && meta.error);
9+
10+
return (
11+
<>
12+
<MuiTextField
13+
{...props}
14+
name={textFieldProps.name}
15+
onChange={textFieldProps.onChange}
16+
onBlur={textFieldProps.onBlur}
17+
value={textFieldProps.value}
18+
error={hasError}
19+
helperText={hasError ? meta.error : ""}
20+
fullWidth={true}
21+
margin="normal"
22+
/>
23+
</>
24+
);
25+
};

‎hooks/14_FormValidation/src/common/textFieldForm.tsx

Copy file name to clipboardExpand all lines: hooks/14_FormValidation/src/common/textFieldForm.tsx
-41Lines changed: 0 additions & 41 deletions
This file was deleted.
+65Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import * as React from "react";
2+
import { LoginEntity, createEmptyLogin } from "../model/login";
3+
import { TextFieldComponent } from "../common";
4+
import { Form } from "formik";
5+
import createStyles from "@material-ui/styles/createStyles";
6+
import makeStyles from "@material-ui/styles/makeStyles";
7+
import Button from "@material-ui/core/Button";
8+
import Card from "@material-ui/core/Card";
9+
import CardHeader from "@material-ui/core/CardHeader";
10+
import CardContent from "@material-ui/core/CardContent";
11+
import { loginFormValidation } from "./login.validation";
12+
import { Formik } from "formik";
13+
14+
interface PropsForm {
15+
onLogin: (login: LoginEntity) => void;
16+
}
17+
18+
// https://material-ui.com/styles/api/#makestyles-styles-options-hook
19+
const useFormStyles = makeStyles((theme) =>
20+
createStyles({
21+
formContainer: {
22+
display: "flex",
23+
flexDirection: "column",
24+
justifyContent: "center",
25+
},
26+
card: {
27+
maxWidth: 400,
28+
margin: "0 auto",
29+
},
30+
})
31+
);
32+
33+
export const LoginComponent: React.FC<PropsForm> = (props) => {
34+
const classes = useFormStyles();
35+
const { onLogin } = props;
36+
37+
return (
38+
<Card className={classes.card}>
39+
<CardHeader title="Login" />
40+
<CardContent>
41+
<Formik
42+
onSubmit={onLogin}
43+
initialValues={createEmptyLogin()}
44+
validate={loginFormValidation.validateForm}
45+
>
46+
{() => (
47+
<Form>
48+
<div className={classes.formContainer}>
49+
<TextFieldComponent label="Name" name="login" />
50+
<TextFieldComponent
51+
label="Password"
52+
type="password"
53+
name="password"
54+
/>
55+
<Button type="submit" variant="contained" color="primary">
56+
Login
57+
</Button>
58+
</div>
59+
</Form>
60+
)}
61+
</Formik>
62+
</CardContent>
63+
</Card>
64+
);
65+
};
+37Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import * as React from "react";
2+
import { useHistory } from "react-router-dom";
3+
import { LoginEntity } from "../model/login";
4+
import { isValidLogin } from "../api/login";
5+
import { LoginComponent } from "./login.component";
6+
import { NotificationComponent } from "../common";
7+
8+
interface Props {}
9+
10+
export const LoginContainer: React.FC<Props> = (props) => {
11+
const history = useHistory();
12+
const [isShowAlert, setShowAlert] = React.useState(false);
13+
14+
const loginSucceeded = (isValid: boolean) => {
15+
if (isValid) {
16+
history.push("/pageB");
17+
} else {
18+
setShowAlert(true);
19+
}
20+
};
21+
22+
const handleLogin = (login: LoginEntity) => {
23+
isValidLogin(login).then(loginSucceeded);
24+
};
25+
26+
return (
27+
<>
28+
<LoginComponent onLogin={handleLogin} />
29+
<NotificationComponent
30+
show={isShowAlert}
31+
message="Invalid Form"
32+
onClose={() => setShowAlert(false)}
33+
/>
34+
;
35+
</>
36+
);
37+
};

‎hooks/14_FormValidation/src/pages/loginFormComponent.tsx

Copy file name to clipboardExpand all lines: hooks/14_FormValidation/src/pages/loginFormComponent.tsx
-52Lines changed: 0 additions & 52 deletions
This file was deleted.

‎hooks/14_FormValidation/src/pages/loginPage.tsx

Copy file name to clipboardExpand all lines: hooks/14_FormValidation/src/pages/loginPage.tsx
-68Lines changed: 0 additions & 68 deletions
This file was deleted.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.