I have created a form with two field username and password and both are number username has length of 3 and password has a length of 6 .Could someone help me with validation.Such that if user enter a username of length less than 3 it should show a message and if somone shows password less than or greater than 6 it should show a message
import withRoot from './modules/withRoot';
// --- Post bootstrap -----
import React, { useState } from 'react';
import history from './history';
import { makeStyles } from '#material-ui/core/styles';
import Grid from '#material-ui/core/Grid';
import Link from '#material-ui/core/Link';
import { FormGroup, FormControl, ControlLabel } from "react-bootstrap";
import { Field } from 'react-final-form';
import Typography from './modules/components/Typography';
import AppFooter from './modules/views/AppFooter';
import AppAppBar from './modules/views/AppAppBar';
import Axios from 'axios';
import AppForm from './modules/views/AppForm';
import Button from '#material-ui/core/Button';
import { Alert } from 'react-bootstrap';
import { email, required } from './modules/form/validation';
import RFTextField from './modules/form/RFTextField';
import FormButton from './modules/form/FormButton';
import FormFeedback from './modules/form/FormFeedback';
import TextField from '#material-ui/core/TextField';
import Home from './Home';
import Dashb from './Dashb';
const useStyles = makeStyles((theme) => ({
form: {
marginTop: theme.spacing(6),
},
button: {
marginTop: theme.spacing(3),
marginBottom: theme.spacing(2),
},
feedback: {
marginTop: theme.spacing(2),
},
}));
export default function SignIn() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [status, setStatus] = useState(true);
const classes = useStyles();
let demo;
function validateForm() {
return username.length > 0 && password.length > 0;
}
function setIncorrect() {
setStatus(false);
}
function setCorrect() {
setStatus(true);
}
async function handleSubmit(event) {
event.preventDefault()
let user = await Axios.get(
'http://localhost:9000/admin-service/admin/check/' +
username +
'/' +
password
)
.then(response => {
demo = response.data
if (demo == true) {
history.push('/admin');
console.log('####')
} else{
console.log('not true')
Functions();
}
})
.catch(error => {
console.log(error.response.data)
setIncorrect()
})
}
function Functions() {
alert("PLEASE ENTER CORRECT CREDENTIALS!!!!!!!!!!")
}
return (
<React.Fragment>
<AppAppBar />
<AppForm>
<React.Fragment>
<Typography variant="h3" gutterBottom marked="center" align="center">
Admin Sign In
</Typography>
</React.Fragment>
<form onSubmit={handleSubmit} className={classes.form} noValidate>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="username"
label="Username"
name="username"
autoFocus
onChange={e => { setUsername(e.target.value); setCorrect() }}
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
onChange={e => { setPassword(e.target.value); setCorrect() }}
/>
{(!status) && <Alert severity="error">Incorrect credentials. Please try again</Alert>}
<FormButton
type="submit"
className={classes.button}
disabled={!validateForm()}
size="large"
color="secondary"
fullWidth
>
Sign In
</FormButton>
</form>
<Typography align="center">
<Link underline="always" href="/premium-themes/onepirate/forgot-password/">
Forgot password?
</Link>
</Typography>
</AppForm>
</React.Fragment>
);
}
Create two new states: usernameIsValid & passwordIsValid with initial state set to 'true'
On calling handleSubmit(), before calling the api create a condition as follows:
if (username.length !== 3) setUsernameIsValid(false)
if (password.length !== 3) setPasswordIsValid(false)
If the condition fails, do not make the api call.
Under the TextFields create a div to contain the error like so:
{!userNameIsValid && <div>Please enter a valid username</div>}
Related
I am trying to use a container to simplify some styling while learning React and I am having some issues.
Currently this is my Component
import React from 'react'
import { Container, Row, Col } from 'react-bootstrap'
const FormContainer = ({ childern }) => {
return (
<Container>
<Row className="justify-content-md-center">
<Col xs={12} md={6}>
{childern}
</Col>
</Row>
</Container>
)
}
export default FormContainer
And this is where I am loading it into
import React, { useState, useEffect } from 'react'
import { Link } from 'react-router-dom'
import { Form, Button, Row, Col } from 'react-bootstrap'
import { useDispatch, useSelector } from 'react-redux'
import Message from '../components/Message'
import Loader from '../components/Loader'
import FormContainer from '../components/FormContainer'
import { login } from '../actions/userActions'
const LoginScreen = ({location, history}) => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const dispatch = useDispatch()
const userLogin = useSelector(state => state.userLogin)
const {loading, error, userInfo} = userLogin
const redirect = location.search ? location.search.split('=')[1] : '/' // Takes location of Url, splits after the equals sign, and everything right of it or takes us back to '/'
useEffect(()=> {
if(userInfo) {
history.push(redirect)
}
}, [history, userInfo, redirect])
const submitHandler = (e) => {
e.preventDefault()
dispatch(login(email, password))
}
return (
<FormContainer>
<h1>Sign In</h1>
{error && <Message variant='danger'>{error}</Message>}
{loading && <Loader/>}
<Form onSubmit={submitHandler}>
<Form.Group controlId='email'>
<Form.Label>Email Address</Form.Label>
<Form.Control type='email' placeholder="Enter email" value={email} onChange={(e) => setEmail(e.target.value)}>
</Form.Control>
</Form.Group>
<Form.Group controlId='password'>
<Form.Label>Password</Form.Label>
<Form.Control type='password' placeholder="Enter password" value={password} onChange={(e) => setPassword(e.target.value)}>
</Form.Control>
</Form.Group>
<Button type='submit' variant='primary'>
Sign In
</Button>
</Form>
<Row className='py-3'>
<Col>
New Customer <Link to={redirect ? `/register?redirect=${redirect}` : '/register'}>
Register
</Link>
</Col>
</Row>
</FormContainer>
)
}
export default LoginScreen
When I remove FormContainer and replace it with a div the LoginScreen info shows up but without the styling. Otherwise it is blank with no issues in the Console. My other components seem to to show some stuff, but not the text.
Any help would be amazing.
Thanks!
I have an api running at the url used in my axios instance. A route is defined for login that returns JWT access and refresh tokens if valid credentials are provided. I can test it using postman and everything works great, but in my app using axios no tokens or error gets returned even with valid credentials. The API is setup for cors also and is running live.
here is the axios instance:
import axios from 'axios';
const url = NOT SHOWN;
const axiosInstance = axios.create({
baseURL: url,
headers: {
'Content-Type': 'application/json',
},
});
export default axiosInstance;
here is the basic login component:
import React, { Component } from 'react';
import { Link as RouteLink, Redirect } from 'react-router-dom';
import axiosInstance from '../../axiosInstance';
//material ui
import Button from '#material-ui/core/Button';
import CssBaseline from '#material-ui/core/CssBaseline';
import TextField from '#material-ui/core/TextField';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Checkbox from '#material-ui/core/Checkbox';
import Link from '#material-ui/core/Link';
import Grid from '#material-ui/core/Grid';
import Typography from '#material-ui/core/Typography';
import { makeStyles } from '#material-ui/core/styles';
import Container from '#material-ui/core/Container';
class Login extends Component {
state = {
email: '',
password: '',
isAuthenticated: false,
};
login(email, password) {
const data = {
email: email,
password: password,
};
axiosInstance
.post('/login', data)
.then((res) => {
console.log(res.data);
})
.catch((err) => {
console.log(err);
});
}
onSubmit = (e) => {
const { email, password } = this.state;
this.login(email, password);
};
onChange = (e) => this.setState({ [e.target.name]: e.target.value.trim() });
render() {
if (this.state.isAuthenticated) {
return <Redirect to='/' />;
}
return (
<Container component='main' maxWidth='xs' style={{ marginTop: '75px' }}>
<CssBaseline />
<div>
<Typography component='h1' variant='h3' align='center'>
Login
</Typography>
<form noValidate>
<TextField
variant='outlined'
margin='normal'
required
fullWidth
id='email'
label='Email Address'
name='email'
autoComplete='email'
autoFocus
onChange={this.onChange}
/>
<TextField
variant='outlined'
margin='normal'
required
fullWidth
name='password'
label='Password'
type='password'
id='password'
autoComplete='current-password'
onChange={this.onChange}
/>
<FormControlLabel
control={<Checkbox value='remember' color='primary' />}
label='Remember me'
/>
<Button
type='submit'
fullWidth
variant='contained'
color='primary'
//className={classes.submit}
onClick={this.onSubmit}
>
LOGIN
</Button>
<Grid container>
<Grid item xs>
<Link variant='body2'>Forgot password?</Link>
</Grid>
<Grid item>
<Link component={RouteLink} to={'/signup'} variant='body2'>
{"Don't have an account? Sign Up"}
</Link>
</Grid>
</Grid>
</form>
</div>
</Container>
);
}
}
export default Login;
'''
I believe the login function is not defined properly so it is not being called. Please try using a function expression:
login = (email, password) => {
const data = {
email: email,
password: password,
};
axiosInstance
.post('/login', data)
.then((res) => {
console.log(res.data);
})
.catch((err) => {
console.log(err);
});
}
onSubmit = (e) => {
const { email, password } = this.state;
login(email, password);
};
Actually i'm building a Facebook Mesenger Clone in React.js and I used material UI. When we run the code it asks for username. after providing that we can send message in the app. But as soon as we send the message we only get username printed on the screen .
The message is not being displayed on the webpage. This is App.js code:
import React, {useEffect, useState} from 'react';
import {Button, FormControl, Input, InputLabel} from "#material-ui/core";
import Message from "./Message";
import './App.css';
function App() {
const [input, setInput] = useState('');
const [messages, setMessages] = useState([]);
const [username, setUsername] = useState('');
useEffect(() => {
setUsername(prompt('Please enter your name'));
}, [])
const sendMessage = (event) => {
event.preventDefault();
setMessages([...messages, {username: username, text: input}]);
setInput('');
}
return <div className="App">
<h1>Hey Mate! 😃</h1>
<h2>Welcome {username}</h2>
<form>
<FormControl>
<InputLabel>Enter a message...</InputLabel>
<Input value={input} onChange={event => setInput(event.target.value)}/>
<Button disabled={!input} variant="contained" color="primary" type='submit' onClick={sendMessage}>Send
Message</Button>
</FormControl>
</form>
{
messages.map(message => <Message username={username} message={message}/>)
}
</div>
}
export default App;
and this is message component's code:
import React from "react";
import {Card, CardContent, Typography} from "#material-ui/core";
import './Mesage.css';
function Message(message, username) {
const isUser = username === message.username;
return (
<div className={`message ${isUser && 'message_user'}`}>
<Card className={isUser ? "message_userCard" : "message_guestCard"}>
<CardContent>
<Typography color="white" variant="h5" component="h2">
{message.username}: {message.text}
</Typography>
</CardContent>
</Card>
</div>
)
}
export default Message;
Kindly help me
You are getting props in the Message component wrong. Just change it to
function Message({ message, username }) {
...
}
I have a react native app with expo-client and gives a too-many re-renders error I will post the files, notice that I use react-native-paper.
This is App.js which is a wrapper for app
import React from "react";
import { Provider as PaperProvider, DefaultTheme } from "react-native-paper";
import { StatusBar } from "expo-status-bar";
import Homescreen from "./views/screens/homescreen";
//import { SafeAreaView, Text } from "react-native";
export default function App() {
return (
<PaperProvider theme={theme}>
<Homescreen />
<StatusBar />
</PaperProvider>
);
}
const theme = {
...DefaultTheme,
};
This is the homescreen which is a wrapper for login and sign up components
import React from "react";
import { View } from "react-native";
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
import SignUp from "../components/signup";
import Login from "../components/login";
import { Button } from "react-native-paper";
export default function Homescreen({ navigation }) {
const Stack = createStackNavigator();
return (
<View>
<Button onPress={() => navigation.navigate("SignUp")}>SignUp</Button>
<Button onPress={() => navigation.navigate("LogIn")}>Login</Button>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="SignUp" component={SignUp} />
<Stack.Screen name="LogIn" component={Login} />
</Stack.Navigator>
</NavigationContainer>
</View>
);
}
There are sign up and login components which are very identical
import React, { useState } from "react";
import { View } from "react-native";
import { TextInput, Button } from "react-native-paper";
export default function SignUp() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const signUp = (t1, t2) => {
setEmail("");
setPassword("");
};
const changeEmailHandler = (e) => {
setEmail(e.target.value);
};
const changePasswordHandler = (e) => {
setPassword(e.target.value);
};
return (
<View>
<TextInput
mode="outlined"
left
label="email"
placeholder="Enter your email: "
onChangeText={changeEmailHandler}
value={email}
/>
<TextInput
mode="outlined"
left
label="password"
placeholder="Enter your password: "
onChangeText={changePasswordHandler}
value={password}
type="password"
/>
<Button
icon="arrow-right-alt"
mode="contained"
onClick={signUp(email, password)}
>
Join us now
</Button>
</View>
);
}
import React, { useState } from "react";
import { View } from "react-native";
import { TextInput, Button } from "react-native-paper";
export default function Login() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const logIn = (t1, t2) => {
setEmail("");
setPassword("");
};
const changeEmailHandler = (e) => {
setEmail(e.target.value);
};
const changePasswordHandler = (e) => {
setPassword(e.target.value);
};
return (
<View>
<TextInput
mode={outlined}
left
label="email"
placeholder="Enter your email: "
onChangeText={changeEmailHandler}
value={email}
/>
<TextInput
mode={outlined}
left
label="password"
placeholder="Enter your password: "
onChangeText={changePasswordHandler}
value={password}
type="password"
/>
<Button
icon="arrow-right-alt"
mode="contained"
onClick={logIn(email, password)}
></Button>
</View>
);
}
This is the appbar component
import React from "react";
import { View } from "react-native";
import { Appbar } from "react-native-paper";
export default function CustomAppBar() {
return (
<View>
<Appbar>
<Appbar.Header>
<Appbar.Content title="Date Planner" />
</Appbar.Header>
</Appbar>
</View>
);
}
The onClick event in the <Button> is the problem. It calls signUp(email, password) on every render which causes an infinite loop because inside there is a call for setPassword. Instead in onClick you can pass a callback, see my suggestion below.
You need to modify your button as:
<Button
icon="arrow-right-alt"
mode="contained"
onClick={() => signUp(email, password)}
>
Join us now
</Button>
In this way the signUp function will be called only on click event.
Based on the comment also needs to change onClick={logIn(email, password)} as well similarly as suggested above.
I have tried making the username and possword field validated but it by default setting "username is incorrect" when the page loads but it should happen only after user types and then the error should be shown respectively. So once user enters the username and if length is less than "3" a message should be display below the respective fild "Username should be 3 digit!!!"
import withRoot from './modules/withRoot';
// --- Post bootstrap -----
import React, { useState } from 'react';
import history from './history';
import { makeStyles } from '#material-ui/core/styles';
import Grid from '#material-ui/core/Grid';
import Link from '#material-ui/core/Link';
import {BrowserRouter as Router, Route} from 'react-router-dom'
import { FormGroup, FormControl, ControlLabel } from "react-bootstrap";
import { Field } from 'react-final-form';
import Typography from './modules/components/Typography';
import AppFooter from './modules/views/AppFooter';
import AppAppBar from './modules/views/AppAppBar';
import Axios from 'axios';
import AppForm from './modules/views/AppForm';
import Button from '#material-ui/core/Button';
import { Alert } from 'react-bootstrap';
import { email, required } from './modules/form/validation';
import RFTextField from './modules/form/RFTextField';
import FormButton from './modules/form/FormButton';
import FormFeedback from './modules/form/FormFeedback';
import TextField from '#material-ui/core/TextField';
import Home from './Home';
import Dashb from './Dashb';
import Admin from './Admin';
const useStyles = makeStyles((theme) => ({
form: {
marginTop: theme.spacing(6),
},
button: {
marginTop: theme.spacing(3),
marginBottom: theme.spacing(2),
},
feedback: {
marginTop: theme.spacing(2),
},
}));
const SignIn = (props) => {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [usernameerror, setUsernameerror] = useState("");
const [passworderror, setPassworderror] = useState("");
const [status, setStatus] = useState(true);
const classes = useStyles();
let demo;
function validateForm() {
if(username.length!=3)
{
return("Wrong username");
}
if(password.length!=6 )
{
return("Wrong password")
}
return 1;
}
function setIncorrect() {
setStatus(false);
}
function setCorrect() {
setStatus(true);
}
function validate(){
let usernameerror ="";
let passworderror = "";
if(username.length==3){
usernameerror = 'invalid username';
}
if (usernameerror){
setUsernameerror({usernameerror});
return false;
}
}
const handleSubmit = (event) => {
event.preventDefault()
let user = Axios.get(
'http://localhost:9000/admin-service/admin/check/' +
username +
'/' +
password
)
.then(response => {
demo = response.data
if (demo == true) {
props.history.push({
pathname: '/admin',
username
});
console.log('####')
} else{
console.log('not true')
Functions();
}
})
.catch(error => {
console.log(error.response.data)
setIncorrect()
})
};
function Functions() {
alert("PLEASE ENTER CORRECT CREDENTIALS!!!!!!!!!!")
}
return (
<React.Fragment>
<AppAppBar />
<AppForm>
<React.Fragment>
<Typography variant="h3" gutterBottom marked="center" align="center">
Admin Sign In
</Typography>
</React.Fragment>
<form onSubmit={handleSubmit} className={classes.form} noValidate>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="username"
label="Admin-Id"
name="username"
autoFocus
onChange={e => { setUsername(e.target.value); setCorrect() }}
/>
<div style={{ fontSize: 11, color: "red"}}>
{validateForm()}
</div>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
onChange={e => { setPassword(e.target.value); setCorrect() }}
/>
<div style={{ fontSize: 11, color: "red"}}>
{validateForm()}
</div>
{(!status) && <Alert severity="error">Incorrect credentials. Please try again</Alert>}
<FormButton
type="submit"
className={classes.button}
//disabled={!validateForm()}
size="large"
color="secondary"
fullWidth
>
Sign In
</FormButton>
</form>
<Typography align="center">
<Link underline="always" href="/premium-themes/onepirate/forgot-password/">
Forgot password?
</Link>
<p>NOTE-PASSWORD IS YOUR USER PIN</p>
</Typography>
</AppForm>
</React.Fragment>
);
}
export default SignIn;
Try this in your validate form function.The conditions were not working in this respective form
function validateForm() {
if(username.length===0)
{
return null
}
else if(password.length===0 )
{
return null
}
else if(username.length<3)
{
return("Username must be 3 chars long");
}
else if(password.length<6 )
{
return("Password must be 6 chars long")
}
}