Skip to content

Commit 566b0c9

Browse files
author
Sahil Bhatia
committed
now showing error msg only when input has changed
1 parent 5415c1e commit 566b0c9

File tree

3 files changed

+132
-69
lines changed

3 files changed

+132
-69
lines changed

src/actions/index.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,14 @@ export const resetLoginForm = () => {
2424
}
2525
}
2626

27-
export const updateText = (email, password) => {
28-
return {
29-
type: 'TEXT_CHANGED',
30-
email,
31-
password
27+
export const updateText = ({ email = null, password = null }) => {
28+
let payload = { type: 'TEXT_CHANGED' };
29+
30+
if (email === null) {
31+
return { ...payload, password };
32+
} else if (password === null) {
33+
return { ...payload, email };
34+
} else {
35+
return { ...payload, email, password };
3236
}
3337
}

src/components/LoginForm.js

Lines changed: 92 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import React, { PureComponent } from 'react';
22
import { connect } from 'react-redux';
33
import {
4-
Grid, Row, Col, Form, FormGroup, FormControl, ControlLabel, Button
4+
Grid, Row, Col, Form, FormGroup, FormControl, ControlLabel, Button, HelpBlock
55
} from 'react-bootstrap';
66

77
import * as actionCreators from '../actions/index.js';
8-
import Logo from './Logo.js';
9-
import logoSvg from '../images/logo.svg';
108

119
/**
1210
This component is responsible for showing the login form.
@@ -22,79 +20,118 @@ class LoginForm extends PureComponent {
2220
this.handleSubmission = this.handleSubmission.bind(this);
2321
}
2422

23+
state = {
24+
errors: {
25+
email: null,
26+
password: null
27+
}
28+
}
29+
2530
render() {
2631
return (
2732
<Grid fluid>
28-
<Row>
29-
<Logo logo={logoSvg} />
30-
</Row>
31-
3233
<Form horizontal onReset={this.handleReset} onSubmit={this.handleSubmission}>
33-
<FormGroup
34-
controlId="formHorizontalEmail"
35-
validationState={this.props.emailValidationState}
36-
>
37-
<Col lgOffset={4} componentClass={ControlLabel} lg={1}>
38-
Email
39-
</Col>
40-
<Col lg={3}>
41-
<FormControl
42-
type="email"
43-
placeholder="e.g. someone@example.com"
44-
autoFocus
45-
name="email"
46-
value={this.props.email}
47-
onChange={this.updateEmail}
48-
/>
49-
</Col>
50-
</FormGroup>
51-
52-
<FormGroup
53-
controlId="formHorizontalPassword"
54-
validationState={this.props.passwordValidationState}
55-
>
56-
<Col lgOffset={4} componentClass={ControlLabel} lg={1}>
57-
Password
34+
<Row>
35+
<Col lgOffset={4} lg={3}>
36+
<FormGroup
37+
controlId="formHorizontalEmail"
38+
validationState={this.props.emailValidationState}
39+
>
40+
<ControlLabel>Email</ControlLabel>
41+
<FormControl
42+
type="email"
43+
placeholder="e.g. someone@example.com"
44+
autoFocus
45+
name="email"
46+
value={this.props.email}
47+
onChange={this.updateEmail}
48+
/>
49+
<HelpBlock>{ this.state.errors.email }</HelpBlock>
50+
</FormGroup>
5851
</Col>
59-
<Col lg={3}>
60-
<FormControl
61-
type="password"
62-
placeholder="e.g. password"
63-
name="password"
64-
value={this.props.password}
65-
onChange={this.updatePassword}
66-
/>
52+
</Row>
53+
54+
<Row>
55+
<Col lgOffset={4} lg={3}>
56+
<FormGroup
57+
controlId="formHorizontalPassword"
58+
validationState={this.props.passwordValidationState}
59+
>
60+
<ControlLabel>Password</ControlLabel>
61+
<FormControl
62+
type="password"
63+
placeholder="e.g. password"
64+
name="password"
65+
value={this.props.password}
66+
onChange={this.updatePassword}
67+
/>
68+
<HelpBlock>{ this.state.errors.password }</HelpBlock>
69+
</FormGroup>
6770
</Col>
68-
</FormGroup>
69-
70-
<FormGroup>
71-
<Col lgOffset={5} lg={2}>
72-
<Button type="reset"> Cancel </Button>
73-
&nbsp;
74-
<Button
75-
type="submit"
76-
bsStyle="primary"
77-
disabled={!this.props.allowSubmission}
78-
> Sign in </Button>
71+
</Row>
72+
73+
<Row>
74+
<Col lgOffset={4} lg={3}>
75+
<FormGroup>
76+
<Button
77+
type="submit"
78+
bsStyle="primary"
79+
block
80+
disabled={!this.props.allowSubmission}
81+
> Sign in </Button>
82+
</FormGroup>
7983
</Col>
80-
</FormGroup>
84+
</Row>
8185
</Form>
8286
</Grid>
8387
);
8488
}
8589

8690
updateEmail(event) {
87-
this.props.handleChange(event.target.value, this.props.password);
91+
let trimmedEmail = event.target.value.trim();
92+
let emailRegex = /\w+@\w+\.\w+/m;
93+
let errorMsg = null;
94+
let updatedErrors = null;
95+
96+
if (trimmedEmail === '') {
97+
errorMsg = "Email can't be left blank";
98+
} else if ( !emailRegex.test(trimmedEmail) ) {
99+
errorMsg = "Email format is invalid!";
100+
} else {
101+
errorMsg = null;
102+
}
103+
104+
updatedErrors = this.state.errors;
105+
updatedErrors.email = errorMsg;
106+
107+
this.setState(updatedErrors);
108+
this.props.handleChange({ email: event.target.value });
88109
}
89110

90111
updatePassword(event) {
91-
this.props.handleChange(this.props.email, event.target.value);
112+
let password = event.target.value;
113+
let errorMsg = null;
114+
let updatedErrors = null;
115+
116+
if (password === '') {
117+
errorMsg = "Password can't be left blank";
118+
} else if (password.length < 8) {
119+
errorMsg = "Password must be at least 8 characters long!";
120+
} else {
121+
errorMsg = null;
122+
}
123+
124+
updatedErrors = this.state.errors;
125+
updatedErrors.password = errorMsg;
126+
127+
this.setState(updatedErrors);
128+
this.props.handleChange({ password: event.target.value });
92129
}
93130

94131
handleSubmission(event) {
95132
event.preventDefault();
96133

97-
this.props.handleLogin(this.props.email, this.props.password);
134+
this.props.handleLogin(this.props.password);
98135
}
99136

100137
componentWillReceiveProps(nextProps) {

src/reducers/SessionReducer.js

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,14 @@ const validPassword = (password) => {
1919
return ( trimmedPassword !== '' && trimmedPassword.length >= 8 )
2020
}
2121

22-
const validInput = (action) => {
23-
return (validEmail(action.email) && validPassword(action.password))
22+
const validInput = (action, state) => {
23+
if (action.email == null) {
24+
return ( validEmail(state.email) && validPassword(action.password) );
25+
} else if (action.password == null) {
26+
return ( validEmail(action.email) && validPassword(state.password) );
27+
} else {
28+
return ( validEmail(action.email) && validPassword(action.password) );
29+
}
2430
}
2531

2632
const sessionReducer = (state = initialState, action) => {
@@ -33,13 +39,29 @@ const sessionReducer = (state = initialState, action) => {
3339
loggedIn: true
3440
}
3541
case 'TEXT_CHANGED':
36-
return {
37-
...state,
38-
email: action.email,
39-
password: action.password,
40-
allowSubmission: validInput(action),
41-
emailValidationState: validEmail(action.email) ? 'success' : 'error',
42-
passwordValidationState: validPassword(action.password) ? 'success' : 'error'
42+
if (action.email != null) {
43+
return {
44+
...state,
45+
email: action.email,
46+
emailValidationState: validEmail(action.email) ? 'success' : 'error',
47+
allowSubmission: validInput(action, state)
48+
}
49+
} else if (action.password != null) {
50+
return {
51+
...state,
52+
password: action.password,
53+
passwordValidationState: validPassword(action.password) ? 'success' : 'error',
54+
allowSubmission: validInput(action, state)
55+
}
56+
} else {
57+
return {
58+
...state,
59+
email: action.email,
60+
password: action.password,
61+
allowSubmission: validInput(action), state,
62+
emailValidationState: validEmail(action.email) ? 'success' : 'error',
63+
passwordValidationState: validPassword(action.password) ? 'success' : 'error'
64+
}
4365
}
4466
default:
4567
return state

0 commit comments

Comments
 (0)