'Form' is not defined react/jsx-no-undef - javascript

Hi with the app react below I have to manage a form to verify the login to a page, the parameters are email and password but when I execute the code the following error is printed,error: Line 33: 'Form' is not defined react/jsx-no-undef
Javascript code:
import React, { Component } from 'react';
import { Button, FormGroup, FormControl, ControlLabel } from "react-bootstrap";
import logo from './logo.svg';
import './Home.css';
class Home extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: ""
};
}
validateForm() {
return this.state.email.length > 0 && this.state.password.length > 0;
}
handleChange = event => {
this.setState({
[event.target.id]: event.target.value
});
}
handleSubmit = event => {
event.preventDefault();
}
render() {
return (
<div className="Login">
<Form onSubmit={this.handleSubmit}>
<Form.Group controlId="email" bsSize="large">
<Form.Control
autoFocus
type="email"
value={this.state.email}
onChange={this.handleChange}
/>
</Form.Group>
<Form.Group controlId="password" bsSize="large">
<Form.Control
value={this.state.password}
onChange={this.handleChange}
type="password"
/>
</Form.Group>
<Button
block
bsSize="large"
disabled={!this.validateForm()}
type="submit"
>
Login
</Button>
</Form>
</div>
);
}
}
export default Home;

Seems like you forgot to import Form, just add it:
import { Form, Button, FormGroup, FormControl, ControlLabel } from "react-bootstrap";

Related

How to generate dynamic dropdown with json data in react?

I have components for dropdown. I try to generate a dynamic dropdown using json data. But I can't do it. I share my following code of the components. I am new in react.
1st component:
import React, {Component} from 'react';
import PropTypes from "prop-types";
const DropDownInput = props =>(
<option
value={props.value}
label={props.name}
/>
)
DropDownInput.PropTypes ={
label: PropTypes.array.isRequired,
value: PropTypes.array.isRequired,
}
DropDownInput.defaultProps={
option:'Select',
}
export default DropDownInput;
2nd component:
import React, {Component} from 'react';
import PropTypes from "prop-types";
import DropDownInput from "./DropDownInput";
const SelectDropDown = props => {
return(
<select className="form-select" aria-label="Default select example">
<DropDownInput
value={props.value}
name={props.name}
/>
</select>
)
};
SelectDropDown.propTypes = {
value: PropTypes.array.isRequired,
name: PropTypes.array.isRequired,
}
export default SelectDropDown;
3rd component:
import React, {Component} from 'react';
import {Button} from "react-bootstrap";
import PropTypes from "prop-types";
import TextInput from "./text-input";
import CheckedInput from "./checked-input";
import SelectDropDown from "./SelectDropDown";
const SubCategorySubmitForm = props => {
return(
<form onSubmit={props.submitHandler}>
<SelectDropDown value={props.OptionValue} name={props.label}/>
<TextInput
name="subCategory"
label="Enter Sub Category"
placeholder="Enter Sub Category"
value={props.values.subCategory}
onChange={props.changeHandler}
/>
<TextInput
name="userid"
label="Enter User Id"
placeholder="User Id Enter"
value={props.values.userid}
// error={props.errors.userid}
onChange={props.changeHandler}
/>
<CheckedInput
styleName="mt-2"
checkBoxClassName="mx-2"
label="All Information is Correct"
name="isAgreement"
value={props.values.isAgreement}
checked= {props.isAgreement}
onChange={props.handlerAgreement}
/>
<Button
variant="primary"
type="submit"
disabled={!props.isAgreement}
>
Submit
</Button>
</form>
)
};
SubCategorySubmitForm.propTypes = {
values: PropTypes.object.isRequired,
label: PropTypes.array.isRequired,
changeHandler: PropTypes.func.isRequired,
submitHandler: PropTypes.func.isRequired,
handlerAgreement: PropTypes.func.isRequired,
isAgreement: PropTypes.bool.isRequired,
OptionValue: PropTypes.array.isRequired,
//errors: PropTypes.object.isRequired,
}
export default SubCategorySubmitForm;
I have json data to generate the dropdown.
Last component:
import React, {Component, Fragment} from 'react';
import {Card, Col, Container, Dropdown, Row} from "react-bootstrap";
import FormUp from "./fillup-form";
import Axios from "axios";
import DemoModal from "./DemoModal";
import {MdOutlineEditCalendar} from "react-icons/md";
import DropDownInput from "./DropDownInput";
import SubCategoryFormFillUp from "./SubCategoryFormFillUp";
import SubCategorySubmitForm from "./SubCategoryFormFillUp";
const FormValues={
subCategory: '',
userid: '',
}
class SubCategoryForm extends Component {
state ={
values: FormValues,
DataList:[],
isLoading:true,
isError:false,
isAgreement: true,
}
componentDidMount() {
Axios.get("/getMainCategoryByName").then((response)=>{
if(response.status==200){
this.setState({
DataList:response.data,
isLoading: false,
});
console.log(response.data)
}
else {
this.setState({isLoading: false, isError:true})
}
}).catch((error)=>{
this.setState({isLoading: false, isError:true})
})
}
changeHandler = event =>{
this.setState(
{values :{
... this.state.values,
[event.target.name]: event.target.value
}}
)};
handlerAgreement = event =>{
this.setState({
isAgreement: event.target.checked,
}
)
console.log('ss');
};
submitHandler=(e)=>{
e.preventDefault();
}
render() {
const myList= this.state.DataList;
const myView=myList.map(myList=>{
return(<DropDownInput
value={myList.id}
name={myList.main_category_name}
/>);
})
return (
<Fragment>
<Container fluid className="mt-5">
<Row>
<Col sm={2}>
</Col>
<Col sm={4}>
{Array.from({ length: 1 }).map((_, idx) => (
<Col>
<Card>
<Card.Body>
<Card.Title><u>Main Category Setup</u></Card.Title>
<select className="form-select" aria-label="Default select example">
{myView}
</select>
<SubCategorySubmitForm
values = {this.state.values}
changeHandler={this.changeHandler}
submitHandler={this.submitHandler}
handlerAgreement={this.handlerAgreement}
isAgreement={this.state.isAgreement}
// OptionValue={myList.map(myList=>{myList.id})}
OptionValue={myList.map(myList=>{myList.id})}
label={myList.map(myList=>{myList.main_category_name})}
/>
</Card.Body>
</Card>
</Col>
))}
</Col>
<Col sm={6}>
</Col>
</Row>
</Container>
</Fragment>
);
}
}
export default SubCategoryForm;
How to write the code to generate the dropdown with json data in my last component.

ReferenceError: fullName is not defined

I have to create is a registration form that consists of full name, email, password, mobile number, DOB and once the email validation is done and once the submit button is clicked, it should direct me to the login page. The login page has an email and password (the details from registration need not match the login) and once the button is clicked(after the validation) it should display "Welcome". I'm sharing the files here. Used, react-router, Material UI.
Login.js
/* eslint-disable no-undef */
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { Grid, Paper, TextField } from "#material-ui/core";
import { Button } from "#material-ui/core";
import Welcome from './Welcome';
class Login extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
errors: {},
};
this.validate = this.validate.bind(this);
}
validateEmail(email) {
const re = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
validate() {
const { email, password, errors } = this.state;
if (!this.validateEmail(email)) {
errors.email = "Provide valid email";
}
if (password.length > 5) {
errors.password = "Provide min 5-digit password";
}
if (errors) {
this.setState({ errors });
} else {
this.props.location.push('/Welcome');
}
}
render() {
const paperStyle = {
padding: 20,
height: "70vh",
width: 280,
margin: "20px auto",
};
return (
<Grid>
<Paper elevation={10} style={paperStyle}>
<Grid align="center">
<h2>Login</h2>
</Grid>
<TextField
error={errors.email}
label="Email"
placeholder="Enter mail"
fullwidth
value={email}
onChange={(e) => this.setState({ email: e.target.value })}
required
helperText={errors.password}
/>
<TextField
error={errors.password}
label="Password"
placeholder="Enter password"
type="password"
fullwidth
required
value={password}
onChange={(e) => this.setState({ password: e.target.value })}
helperText={errors.password}
/>
{/*<Link to="/Welcome">*/}
<Button variant="contained" color="primary" onClick={this.validate}>
Login
</Button>
{/*</Link> */}
</Paper>
</Grid>
);
}
}
export default Login;
Registration.js
/* eslint-disable no-undef */
import React, { Component} from 'react';
import { Link } from "react-router-dom";
import { Grid, Paper, TextField } from "#material-ui/core";
import { Button } from "#material-ui/core";
import Login from './Login';
class Registration extends Component {
constructor(props) {
super(props);
this.state = {
fullName: "",
mobileNumber: "",
email: "",
password: "",
errors: {},
};
this.validate = this.validate.bind(this);
}
validateEmail(email) {
const re = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
validate() {
const { fullName, email, password, errors } = this.state;
if (!this.validateEmail(email)){
errors.email = "Provide valid email";
}
if (password.length > 5){
errors.password = "Provide min 5-digit password";
}
if (errors) {
this.setState({ errors });
} else {
this.props.location.push('/Login');
}
}
render() {
const paperStyle = {
padding: 20,
height: "70vh",
width: 280,
margin: "20px auto",
};
return (
<Grid>
<Paper elevation={10} style={paperStyle}>
<Grid align="center">
<h2>Login</h2>
</Grid>
<TextField
label="Full name"
placeholder="Enter name"
fullwidth
value={fullName}
onChange={(e) => this.setState({ fullName: e.target.value })}
required
helperText={errors.fullName}
/>
<TextField
type = 'number'
label="Mobile number"
placeholder="Enter mobile number"
fullwidth
// eslint-disable-next-line no-undef
value={mobileNumber}
onChange={(e) => this.setState({ mobileNumber: e.target.value })}
required
helperText={errors.mobileNumber}
/>
<TextField
error={errors.email}
label="Email"
placeholder="Enter mail"
fullwidth
value={email}
onChange={(e) => this.setState({ email: e.target.value })}
required
helperText={errors.email}
/>
<TextField
error={errors.password}
label="Password"
placeholder="Enter password"
type="password"
fullwidth
required
value={password}
onChange={(e) => this.setState({ password: e.target.value })}
helperText={errors.password}
/>
{/*<Link to="/Login">*/}
<Button variant="contained" color="primary" onClick={this.validate}>
Register here
</Button>
{/*</Link>*/}
</Paper>
</Grid>
);
}
}
export default Registration;
App.js
import React, { Component } from "react";
import "./App.css";
import Login from "./Login";
import Registration from "./Registration";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Welcome from "./Welcome";
import { Typography } from "#material-ui/core";
class App extends Component {
render() {
return (
<Router>
<Typography>
<div className="App">
<Switch>
<Route path="/" exact component={Registration} />
<Route path="/Login" component={Login} />
<Route path="/Welcome" component={Welcome} />
</Switch>
</div>
</Typography>
</Router>
);
}
}
export default App;
Welcome js
import React from "react";
function Welcome() {
return <h1>Welcome</h1>;
}
export default Welcome;
You need add const { fullName, email, password, errors } = this.state; in the render and before return

Redux Form won't allow Initialize Form state values to be edited

I have a redux-form component that I correctly passing in the initial form state values but when I click inside the form I cannot edit the values. I am have followed all the documentation like the following link:
Initialize From State
And I also followed the documentation to implement a custom input:
Will redux-form work with a my custom input component?
So I am trying to figure out what am I missing? Here is my form component:
EditJournalForm.jsx
import "./styles/list-item.scss";
import {Button, ButtonToolbar} from "react-bootstrap";
import {connect} from "react-redux";
import {Field, reduxForm} from "redux-form";
import InputField from "../form-fields/InputField";
import PropTypes from "prop-types";
import React from "react";
class EditJournalForm extends React.Component {
render() {
//console.log('EditJournalForm this.props', this.props);
const {closeOverlay, handleSubmit, initialValues, pristine, submitting,} = this.props;
return (
<form onSubmit={handleSubmit}>
<div>
<div className="form-field">
<Field
component={props =>
<InputField
content={{val: initialValues.title}}
updateFn={param => props.onChange(param.val)}
{...props}
/>
}
label="Journal title"
name="title"
type="text"
/>
</div>
<div className="form-field">
<Field
component={props =>
<InputField
content={{val: initialValues.description}}
updateFn={param => props.onChange(param.val)}
{...props}
/>
}
componentClass="textarea"
label="Description"
name="description"
rows="5"
type="text"
/>
</div>
<div className="form-button-group">
<ButtonToolbar>
<Button
bsSize="small"
style={{"width": "48%"}}
onClick={() => {
if (closeOverlay) {
closeOverlay();
}
}}
>
Cancel
</Button>
<Button
bsSize="small"
disabled={pristine || submitting}
style={
{
"backgroundColor": "#999",
"width": "48%"
}}
type="submit"
>
Add
</Button>
</ButtonToolbar>
</div>
</div>
</form>
);
}
}
EditJournalForm.propTypes = {
"closeOverlay": PropTypes.func,
"handleSubmit": PropTypes.func.isRequired,
"pristine": PropTypes.bool.isRequired,
"submitting": PropTypes.bool.isRequired,
"initialValues": PropTypes.object
};
EditJournalForm.defaultProps = {
"closeOverlay": undefined
};
export default reduxForm({
form: "editJournal",
enableReinitialize: true
})(connect((state, ownProps) => {
return {
initialValues: {
"title": state.bees.entities.journals[ownProps.journal.id].attributes.title,
"description": state.bees.entities.journals[ownProps.journal.id].attributes.description,
}
};
}, undefined)(EditJournalForm));
and here is my custom input:
InputField.jsx
import {ControlLabel, FormControl, FormGroup} from "react-bootstrap";
import PropTypes from "prop-types";
import React from "react";
const InputField = ({input, label, content, updateFn, type, ...props}) => (
<FormGroup >
<ControlLabel>
{label}
</ControlLabel>
<FormControl
{...props}
{...input}
value={content}
onChange={updateFn}
type={type}
/>
</FormGroup>
);
export default InputField;
InputField.propTypes = {
"input": PropTypes.object.isRequired,
"label": PropTypes.string.isRequired,
"type": PropTypes.string.isRequired,
"content": PropTypes.object,
"updateFn": PropTypes.func
};
Try to call onChange function of input field:
const InputField = ({input, label, content, updateFn, type, ...props}) => (
<FormGroup>
<ControlLabel>
{label}
</ControlLabel>
<FormControl
{...props}
{...input}
value={content}
onChange={(e) => {
input.onChange(e);
updateFn(e);
}}
type={type}
/>
</FormGroup>
);
I see at least one problem - you are assigning the content prop as an object with a val property, but in your custom InputField, you are setting value={content}, so that is actually the object with { val: 'the value' } as opposed to the actual value ('the value' in this example).
With redux-form, it isn't necessary to manually assign from initialValues. By having a name property on the Field, it will be correctly assigned for you.

Navigating using react router

I want to redirect to my home route upon submitting my axios request to the api and gathering a valid response. As can be seen, Im trying to use context but in this case i get an error "context is undefined". How can i navigate to my home route in this case? I tried using history.push but that does not seem to work either. Any ideas would be much appreciated?
import React, {Component} from 'react'
import axios from 'axios'
import Home from './Home'
import {
BrowserRouter,
Link,
Route
} from 'react-router-dom'
class SignUp extends Component {
constructor(props){
super(props);
this.state = {
email: '',
password: ''
};
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
handleClick = () => {
axios
.post('http://localhost:9000/signup',{
email: this.state.email,
password: this.state.password
}).then(function(response){
console.log(response.data.success)
this.context.router.push('/home');
})
}
render(){
return(
<BrowserRouter>
<Route path="/" render={() => (
<div>
<h1> Sign Up</h1>
<input name="email" placeholder="enter your email" onChange={e => this.handleChange(e)}/>
<br/>
<input name="password" placeholder="enter your password" onChange={e => this.handleChange(e)}/>
<br/>
<button onClick={() => this.handleClick()}>submit</button>
<Route exact path="/home" component={Home}/>
</div>
)}/>
</BrowserRouter>
)
}
}
SignUp.contextTypes = {
router: React.PropTypes.func.isRequired
};
export default SignUp
Routes should be always level above of all your components (or containers). Then, when a component is "inside" router (in your case BrowserRouter) it will gain access to its context.
Also you have inside render function of another wich does not make sense at all.
So something like this should work:
import React, {Component} from 'react'
import axios from 'axios'
import Home from './Home'
import {
BrowserRouter,
Link,
Route
} from 'react-router-dom'
class SignUp extends Component {
constructor(props){
super(props);
this.state = {
email: '',
password: ''
};
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
handleClick = () => {
axios
.post('http://localhost:9000/signup',{
email: this.state.email,
password: this.state.password
}).then(function(response){
console.log(response.data.success)
this.context.router.push('/home');
})
}
render(){
return(
<div>
<h1> Sign Up</h1>
<input name="email" placeholder="enter your email" onChange={e => this.handleChange(e)}/>
<br/>
<input name="password" placeholder="enter your password" onChange={e => this.handleChange(e)}/>
<br/>
<button onClick={() => this.handleClick()}>submit</button>
</div>
)
}
}
SignUp.contextTypes = {
router: React.PropTypes.func.isRequired
};
class App extends Component {
render() {
return(
<BrowserRouter>
<Route path="/" component={SignUp} />
<Route exact path="/home" component={Home}/>
</BrowserRouter>)
}
}
export default App;
And of course move SignUp component to standalone file to keep the project clean and well structured.

redux-form onSubmit refreshes page

I am new to redux-form and I'm having a strange issue with handling onSubmit.
When I set up my project exactly as in the redux-form example here http://redux-form.com/6.7.0/examples/syncValidation/ it works as expected. I have attempted to extend this example for my needs and have confirmed that it works as expected when it loads the form like so: route component > form.
The issue arises when I attempt to load the form within a react component which is loaded via a route (route component > container component > form). When I click submit the field values are added to the address bar and form validation doesn't run. I have tried absolutely everything I can think of to fix this. The code provided below will work correctly if you replace <Main /> with <RegisterForm handleSubmit={showResults} /> in index.js. Any ideas where I'm going wrong here?
RegisterForm.js:
import React from 'react';
import { Field, reduxForm } from 'redux-form';
const validate = values => {
const errors = {};
if (!values.name) {
errors.name = 'Required';
} else if (values.name.length <= 2) {
errors.username = 'Must be 2 characters or more';
} else if (values.name.length > 50) {
errors.username = 'Must be 50 characters or less';
}
if (!values.email) {
errors.email = 'Required';
} else if (!/^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z] {2,4}$/i.test(values.email)) {
errors.email = 'Invalid email address';
}
if (!values.password) {
errors.password = 'Required';
} else if (!values.confirm) {
errors.confirm = 'Required';
} else if (values.password !== values.confirm) {
errors.confirm = 'Passwords do not match';
}
return errors;
};
const renderField = ({ input, label, type, id, meta: { touched, error, warning } }) => (
<div>
<label htmlFor={id}>{label}</label>
<div>
<input {...input} id={id} placeholder={label} type={type} />
{touched && ((error && <span>{error}</span>) || (warning && <span>{warning}</span>))}
</div>
</div>
);
const RegisterForm = (props) => {
const { handleSubmit, pristine, reset, submitting } = props
return (
<form onSubmit={handleSubmit}>
<div className="row">
<div className="medium-6 columns medium-centered">
<Field type="text" id="name" name="name" component={renderField} placeholder="name" label="Name" />
</div>
<div className="medium-6 columns medium-centered">
<Field type="text" id="email" name="email" component={renderField} placeholder="email" label="Email" />
</div>
<div className="medium-6 columns medium-centered">
<Field type="password" id="password" name="password" component={renderField} placeholder="password" label="Password" />
</div>
<div className="medium-6 columns medium-centered">
<Field type="password" id="confirm" name="confirm" component={renderField} placeholder="confirm" label="Confirm password" />
</div>
<div className="medium-6 columns medium-centered">
<button type="submit" disabled={submitting}>Submit</button>
</div>
</div>
</form>
);
};
export default reduxForm({
form: 'register', // a unique identifier for this form
validate,
})(RegisterForm);
Index.js(works):
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { HashRouter as Router, hashHistory } from 'react-router-dom';
const store = require('./store').configure();
import RegisterForm from './RegisterForm.jsx';
import Main from './Main.jsx';
const rootEl = document.getElementById('app');
const showResults = (values) => {
window.alert(`You submitted:\n\n${JSON.stringify(values, null, 2)}`);
}
ReactDOM.render(
<Provider store={store}>
<Router history={hashHistory}>
<div style={{ padding: 15 }}>
<h2>Synchronous Validation</h2>
<RegisterForm handleSubmit={showResults} />
</div>
</Router>
</Provider>,
rootEl,
);
Index.js(doesn't work):
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { HashRouter as Router, hashHistory } from 'react-router-dom';
const store = require('./store').configure();
import RegisterForm from './RegisterForm.jsx';
import Main from './Main.jsx';
const rootEl = document.getElementById('app');
const showResults = (values) => {
window.alert(`You submitted:\n\n${JSON.stringify(values, null, 2)}`);
}
ReactDOM.render(
<Provider store={store}>
<Router history={hashHistory}>
<div style={{ padding: 15 }}>
<h2>Synchronous Validation</h2>
<Main />
</div>
</Router>
</Provider>,
rootEl,
);
Main.js:
import React, { Component } from 'react';
import RegisterForm from './RegisterForm.jsx';
const showResults = (values) => {
window.alert(`You submitted:\n\n${JSON.stringify(values, null, 2)}`);
};
class Register extends Component {
render() {
return (
<RegisterForm handleSubmit={showResults} />
);
}
}
export default Register;
You should pass in your submit handler to the onSubmit prop, not handleSubmit. It comes in to your form component as handleSubmit, so that code should be fine.
class Register extends Component {
render() {
return (
//change this
<RegisterForm onSubmit={showResults} />
);
}
}

Categories