I have a navbar and based on the url parameters I want to show different elements on that navbar such as user items, Edit settings etc. Right now I have a Connect to wallet button and when the url has /wallet in it i want to hide that button.
I tried using useParams() from react-router-dom but as a beginner how I can't figure it out where do I put conditions so that it shows or hides based on that Url parameters.
Here's my code
import React, { useState } from "react";
import { Nav, Navbar, Button, Modal, Form } from "react-bootstrap";
import { Link } from "react-router-dom";
function NavbarTop() {
const [showLogin, setShowLogin] = useState(false);
const [showSignup, setShowSignup] = useState(false);
//handler for login
const handleCloseLogin = () => setShowLogin(false);
const handleShowLogin = () => setShowLogin(true);
//handler for signup
const handleCloseSignup = () => setShowSignup(false);
const handleShowSignup = () => setShowSignup(true);
return (
<Navbar className="navBar" variant="dark" expand="lg" sticky="top">
<Navbar.Brand>
<Link to="/">
<img src="images/logo.png" alt="playtoshi" className="logo" />
</Link>
</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="ml-auto mr-md-3">
<Nav.Link href="#home">MARKETPLACE</Nav.Link>
<Nav.Link href="#link">COMMUNITY</Nav.Link>
<Nav.Link href="#link" className="mr-md-2">
HELP
</Nav.Link>
//I want to hide this button if the url has /wallet in it
<Link to="/wallet">
<Button variant="outline-warning">Connect your wallet</Button>{" "}
</Link>
</Nav>
<Button
variant="outline-primary"
className="mr-sm-2"
onClick={handleShowLogin}
>
Login
</Button>{" "}
<Button variant="outline-success" onClick={handleShowSignup}>
Sign Up
</Button>{" "}
</Navbar.Collapse>
{/* Login Modal */}
<Modal show={showLogin} onHide={handleCloseLogin} animation={false}>
<Modal.Header closeButton>
<Modal.Title>Login</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Group controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control type="email" placeholder="Enter email" required />
<Form.Text className="text-muted">
We'll never share your email with anyone else.
</Form.Text>
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password" placeholder="Password" required />
</Form.Group>
<Form.Group controlId="formBasicCheckbox">
<Form.Check type="checkbox" label="Check me out" />
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleCloseLogin}>
Close
</Button>
</Modal.Footer>
</Modal>
{/* Signup modal */}
<Modal show={showSignup} onHide={handleCloseSignup} animation={false}>
<Modal.Header closeButton>
<Modal.Title>Signup</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Group>
<Form.Label>Enter Your Name</Form.Label>
<Form.Control
type="text"
placeholder="First Name"
required
className="mb-sm-2"
/>
<Form.Control type="text" placeholder="Last Name" required />
</Form.Group>
<Form.Group controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control type="email" placeholder="Enter email" required />
<Form.Text className="text-muted">
We'll never share your email with anyone else.
</Form.Text>
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password" placeholder="Password" required />
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
placeholder="Retype Password"
required
/>
</Form.Group>
<Form.Group controlId="formBasicCheckbox">
<Form.Check
type="checkbox"
label="I Agree the terms and conditions"
/>
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleCloseSignup}>
Close
</Button>
</Modal.Footer>
</Modal>
</Navbar>
);
}
export default NavbarTop;
I hope it works, try this
const currentPath = this.props.location.pathname
const walletPath = '/wallet'
const className = currentPath === walletPath ? 'hideThisButton' : '';
/* if you want to check that current path includes the wallet path try
* "currentPath.includes(walletPath)"
* instead of "currentPath === walletPath"
*/
return (
//...
<Link to="/wallet">
<Button className={className} variant="outline-warning">Connect your wallet</Button>{" "}
</Link>
//..
)
and add this to css
.hideThisButton { display: none; }
In React you can use useLocation() from react-router-dom to get the actual pathname
import { useLocation } from 'react-router-dom';
const walletPath = '/wallet'
const [hide, setHide] = useState(useLocation().pathname === walletPath ? true : false);
return (
//....
{ !hide ? (
<Link to = "/wallet" >
<Button variant = "outline-warning" > Connect your wallet </Button>
</Link>
) : null }
);
Related
I am trying to implement Google authentication in my web application, but I keep getting an error.
I generated my token on the Google Console Website, but when I try to sign in I get the error: "popup_closed_by_user", when in the console I should have seen the credentials of the google account. Below is the code for the authentication:
import React, {useState} from 'react';
import {Avatar, Button, Paper, Grid, Typography, Container, TextField} from '#material-ui/core';
import {GoogleLogin} from 'react-google-login';
import LockOutlinedIcon from '#material-ui/icons/LockOutlined';
import useStyles from './styles';
import Input from './Input';
import Icon from './icon';
const Auth=()=>{
const classes=useStyles();
const [showPassword, setShowPassword] =useState(false);
const [isSignup, setIsSignup] = useState(false);
const handleShowPassword=()=>setShowPassword((prevShowPassword)=> !prevShowPassword);
const handleSubmit=()=>{
};
const handleChange=()=>{
};
const switchMode=()=>{
setIsSignup((prevIsSignUp)=> !prevIsSignUp);
handleShowPassword(false);
};
const googleSuccess=async (res)=>{
console.log(res);
};
const googleFailure=(error)=>{
console.log(error);
console.log("Google Sign In was unsuccessful. Try Again Later.");
};
return (
<Container component="main" maxWidth="xs">
<Paper className={classes.paper} elevation={3}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon/>
</Avatar>
<Typography variant="h5">{isSignup ? 'Sign Up' : 'Sign In'}</Typography>
<form className={classes.form} onSubmit={handleSubmit}>
<Grid container spacing={2}>
{
isSignup && (
<>
<Input name="firstName" label="First Name" handleChange={handleChange} autoFocus half/>
<Input name="lastName" label="Last Name" handleChange={handleChange} half/>
</>
)}
<Input name="email" label="Email Address" handleChange={handleChange} type="email"/>
<Input name="password" label="Password" handleChange={handleChange} type={showPassword ? "text" : "password"} handleShowPassword={handleShowPassword}/>
{
isSignup && <Input name="confirmPassword" label="Repeat Password" handleChange={handleChange} type="password"/>
}
</Grid>
<Button type="submit" fullWidth variant="contained" color="primary" className={classes.submit}>
{isSignup ? 'Sign Up' : 'Sign In'}
</Button>
<GoogleLogin
clientId=""
render={(renderProps)=>(
<Button
className={classes.googleButton}
color="primary"
fullWidth
onClick={renderProps.onClick}
disabled={renderProps.disabled}
startIcon={<Icon/>}
variant="contained"
>
Google Sign In
</Button>
)}
onSuccess={googleSuccess}
onFailure={googleFailure}
cookiePolicy="single_host_origin"
/>
<Grid container justifyContent="flex-end">
<Grid item>
<Button onClick={switchMode}>
{isSignup ? 'Already have an account? Sign In' : "Don't have an account? Sign Up"}
</Button>
</Grid>
</Grid>
</form>
</Paper>
</Container>
);
};
export default Auth
I have generated the token and put it in my code, but I deleted it for this post and I also cleared my cache and unchecked the "Block third-party cookies button" in my browser settings.
Could you help me?
I'm pretty new to React, I have an simple app where the user can login via modal window that is displayed when the button "Login" it's clicked. User data is stored in a MongoDB collection, to validate the email and password entered by the user in the modal window the app send a request to a service that returns the data of the logged user or nothig if any error happens. If the user exists, the id is stored in local storage, then it must be redirected to another page. The problem is that apparently the method 'onSession' does not exist thus generating the warning: "Unknown property of the event handler onSession".
I have created three components: "LoginForm.js", "LoginModal.js" and "Menu.js". The first has the fields for the email and password and the validations for the login, the second has the properties of the modal window and the last one is for a navigation bar where the "Login" button is displayed.
LoginForm.js:
import React from 'react';
import { Col, Row, Form, Stack, Button, Image } from 'react-bootstrap';
import LoginIMG from '../../../assets/login.png'
import './LoginForm.css';
class LoginForm extends React.Component{
constructor(props) {
super(props);
this.state = {
email: '',
password: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
event.preventDefault();
if(this.state.email === '' || this.state.password === '') {
alert('You must fill all inputs');
}else{
fetch('http://localhost:8080/api/user/'+this.state.email+'/'+this.state.password)
.then(res => res.json())
.then(data => {
if(data.id !== null) {
localStorage.setItem('idUser', data.id);
this.props.onHide();
this.props.onSession();
}else{
alert('Wrong password or username');
}
});
}
}
handleChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<div className="form">
<br />
<Row className="justify-content-md-center">
<Form onSubmit={this.handleSubmit}>
<Stack gap={3}>
<Row className="justify-content-md-center">
<Col lg={6} md={4} className='text-center'>
<Image src={LoginIMG} className="avatar" roundedCircle />
</Col>
</Row>
<Row className="justify-content-md-center">
<Col lg={6}>
<Form.Group controlId="formEmail">
<Form.Label>Email</Form.Label>
<Form.Control type="email" name="email" value={this.state.email} onChange={this.handleChange} placeholder="Enter email" />
</Form.Group>
</Col>
</Row>
<Row className="justify-content-md-center">
<Col lg={6}>
<Form.Group controlId="formPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password" name="password" value={this.state.password} onChange={this.handleChange} />
</Form.Group>
</Col>
</Row>
<Row className="justify-content-md-center">
<Col lg={6} className="d-grid gap-2">
<Button type="submit" variant="success" size="lg">Login</Button>
</Col>
</Row>
</Stack>
</Form>
</Row>
</div>
);
}
}
export default LoginForm;
LoginModal.js:
import LoginForm from '../../forms/loginForm/LoginForm'
import { Modal } from 'react-bootstrap';
import './LoginModal.css';
function LoginModal(props){
return (
<Modal {...props} size="lg" aria-labelledby="contained-modal-title-vcenter" centered>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
{props.title}
</Modal.Title>
</Modal.Header>
<Modal.Body>
<LoginForm onHide={props.onHide} />
</Modal.Body>
<Modal.Footer>
{/* <Button onClick={props.onHide}>Close</Button> */}
</Modal.Footer>
</Modal>
);
}
export default LoginModal;
Menu.js:
import React from 'react';
import {Navbar, Nav, Container} from 'react-bootstrap';
import { Link } from "react-router-dom";
import LoginModal from '../../modals/loginModal/LoginModal';
import { useState } from 'react';
function Menu(){
const [modalShow, setModalShow] = useState(false);
const [idUser, setIdUser] = useState(0);
const setSession = () => {
if(localStorage.getItem('idUser') != null){
setIdUser(localStorage.getItem('idUser'));
console.log(idUser);
}
}
return(
<>
<Navbar bg="dark" expand="lg" variant="dark">
<Container>
<Link className='navbar-brand' to="/">Divina Comedia</Link>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Link className='nav-link' to="/">Home</Link>
{idUser === 0 ? <Nav.Link id="login" onClick={() => setModalShow(true)}>Login</Nav.Link> : null }
{idUser !== 0 ? <Link className='nav-link' to="/orders">Orders</Link> : null }
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
<LoginModal show={modalShow} onHide={() => setModalShow(false)} onSession={() => setSession()} />
</>
);
}
export default Menu;
I'm really don't know what is wrong, any help is appreciated.
onSession={() => setSession()}
This gets passed into LoginModal, which then passes it into Modal here in LoginModal.js:
<Modal {...props}
And Modal ultimately ends up putting it on a <div>. There is no dom event with that name, and thus you are getting the error.
If that prop is intended for LoginModal, then make sure you deal with it there, and don't pass it on to Modal using the spread syntax. For example:
function LoginModal({ onSession, ...rest }){
// Do something with the onSession prop
return (
<Modal {...rest} size="lg" aria-labelledby="contained-modal-title-vcenter" centered>
// Or maybe do something with it here?
)
}
There is this dynamic form component.
Main.js
import RegistrationItemfrom "./RegistrationItem"
.......
<Form onSubmit={(e) => {e.preventDefault();}}>
<RegistrationItem
inputtype="email"
inputplaceholder="Email Address*"
icon={faEnvelope}
/>
<RegistrationItem
inputtype="password"
inputplaceholder="Password*"
icon={faLock}
/>
<button onClick={handleLogin()} > Login </Login>
</Form>
File for input fields with styling and icons add to it.
RegistrationItem.js.
const RegistrationItem = () ={
return(
<InputGroup className=" mb-4">
<Input
type={inputtype}
name={inputname}
id={inputid}
placeholder={inputplaceholder}
className="border-right-0"
/>
<InputGroupAddon addonType="append">
<InputGroupText className="bg-transparent text-primary border-left-0">
<FontAwesomeIcon className="text-primary" icon={icon} />
</InputGroupText>
</InputGroupAddon>
</InputGroup>
)
}
How to implement submit of the form from the Login button <button onClick={handleLogin()} > Login </Login>
Based on the code given we need two values. One is the email and the other is the password.
So two states needed to be added to the Form element email and password. These values need to be changed based on the change in the input.
So when the form is submitted these values can be used to perform whatever action is needed
The code could be like this if we are using only react and not other form libraries like react hook form
Main.js
import RegistrationItemfrom "./RegistrationItem"
.......
const [email,setEmail] = useState('');
const [password,setPasword] = useState('')
<Form onSubmit={(e) => {e.preventDefault();handleSubmit(email,password,...otherArgs);}}>
<RegistrationItem
inputtype="email"
inputplaceholder="Email Address*"
icon={faEnvelope}
value={email}
setValue={setEmail}
/>
<RegistrationItem
inputtype="password"
inputplaceholder="Password*"
icon={faLock}
value={password}
setValue={setPassword}
/>
<button type="submit" > Login </button>
</Form>
RegistrationItem.js
const RegistrationItem = ({inputtype,inputname,inputid,inputplaceholder,value,setValue,icon}) ={
return(
<InputGroup className=" mb-4">
<Input
type={inputtype}
name={inputname}
id={inputid}
placeholder={inputplaceholder}
value={value}
onChange={e=>setValue(e.target.value)}
className="border-right-0"
/>
<InputGroupAddon addonType="append">
<InputGroupText className="bg-transparent text-primary border-left-0">
<FontAwesomeIcon className="text-primary" icon={icon} />
</InputGroupText>
</InputGroupAddon>
</InputGroup>
)
}
you need to declare state and pass that to your child component and can update the state from child element and when you click on login you can use the state.
below i have shown you how you can declare the state and how you can pass it to your child element and in child element you can use it.
note : i have just passed it in your child component and over ther in argument you can see it so wherever you want to use them you can use it.
const [registrationTypeValue,setRegistrationTypeValue]=useState("")
<Form onSubmit={(e) => {e.preventDefault();}}>
<RegistrationItem
inputtype="email"
inputplaceholder="Email Address*"
icon={faEnvelope}
registrationTypeValue={registrationTypeValue}
setRegistrationTypeValue={setRegistrationTypeValue}/>
<RegistrationItem
inputtype="password"
inputplaceholder="Password*"
icon={faLock}
/>
<button onClick={handleLogin()} > Login </Login></Form>
const RegistrationItem = ({registrationTypeValue,setRegistrationTypeValue}) ={
return(
<InputGroup className=" mb-4">
<Input
type={inputtype}
name={inputname}
id={inputid}
placeholder={inputplaceholder}
className="border-right-0"
/>
<InputGroupAddon addonType="append">
<InputGroupText className="bg-transparent text-primary border-left-0">
<FontAwesomeIcon className="text-primary" icon={icon} />
</InputGroupText>
</InputGroupAddon>
</InputGroup>
)
}
I am using React Bootstrap and Modal.
I want the Modal to open, and behind it is the window that I was in (i.e. to have the background behind the Modal to be transparent).
When I am currently getting is, when I click on the link the Modal opens in a new page with empty background.
ie.
<<<<<<<<< Current screenshot >>>>>>>>>>>>>>
What I want to achieve is something similar to the following, were the background behind the Modal is transparent:
ie.
<<<<<<<<< Desired screenshot >>>>>>>>>>>>>>
Here is my code:
<Modal.Dialog>
<Modal.Header>
<Modal.Title>New Component</Modal.Title>
<Button variant="light">X</Button>
</Modal.Header>
<Modal.Body>
<h5 className="mb-4">Component information</h5>
<Form >
<FormGroup>
<Row>
<Col md={6} className="mb-3">
<Form.Label>Name</Form.Label>
<Form.Control required type="text" placeholder="Component Name" />
</Col>
<Col md={6} className="mb-3">
<Form.Label>Quantity</Form.Label>
<Form.Control required type="number" placeholder="Quantity" />
</Col>
</Row>
</FormGroup>
</Form>
</Modal.Body>
</Modal.Dialog>
Here is the routing part, where I am linking the page to a route:
Routing:
<Switch>
<Router>
<Route exact path="/app/new" component={NewComponentForm}/>
</Router>
</Switch>
import React, { useState } from "react";
import {
Button,
Col,
Container,
Form,
FormGroup,
Modal,
Row,
} from "react-bootstrap";
import "./styles.css";
function App() {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<Container>
<Row className="justify-content-md-center align-items-center">
<Button
className="d-flex justify-content-center"
variant="primary"
onClick={handleShow}
>
Launch demo modal
</Button>
<Modal show={show} onHide={handleClose}>
<Modal.Header>
<Modal.Title>New Component</Modal.Title>
<Button variant="light" onClick={handleClose}>
X
</Button>
</Modal.Header>
<Modal.Body>
<h5 className="mb-4">Component information</h5>
<Form>
<FormGroup>
<Row>
<Col md={6} className="mb-3">
<Form.Label>Name</Form.Label>
<Form.Control
required
type="text"
placeholder="Component Name"
/>
</Col>
<Col md={6} className="mb-3">
<Form.Label>Quantity</Form.Label>
<Form.Control
required
type="number"
placeholder="Quantity"
/>
</Col>
</Row>
</FormGroup>
</Form>
</Modal.Body>
</Modal>
</Row>
</Container>
);
}
export default App;
There is a codesandbox
I am trying to populate a form with initial data however I am unsure of the syntax for this functionality and how it's suppose to be applied. initially the form I am using is a component that I also use to create a client. I am trying to reuse this form as the form for editing a client. It has two functions.
As per suggestions in Redux I have a this as a component and I also have a container.
Now, using the redux tool in Chrome I can look at the state and its clear the action has added an "editClient" entry with data so I do have the data. Its called "editClient" in the state.
My problem is that I do not know how to use this to set these state values as initial values. I have looked carefully at the docs but I am confused as to the way it should be stuctured.
Here is my client form in its entirety:
import React, { PropTypes } from 'react'
import { Field, reduxForm, FormSection } from 'redux-form'
import { connect } from 'react-redux'
import { Col, Row } from 'react-bootstrap'
import { Button, Glyphicon, Panel } from 'react-bootstrap'
import Moment from 'moment'
import Address from '../../address/addressContainer'
import FormField from '../../formComponents/formField'
import CheckboxField from '../../formComponents/checkboxField'
import TextField from '../../formComponents/textField'
import StaticText from '../../formComponents/staticText'
import TextAreaField from '../../formComponents/textAreaField'
import DateField from '../../formComponents/datefield'
import reducer from '../edit/reducer'
export const CLIENT_FORM_NAME = 'Client'
const required = value => (value ? undefined : 'Required')
const maxLength = max => value =>
value && value.length > max ? `Must be ${max} characters or less` : undefined
const number = value =>
value && isNaN(Number(value)) ? 'Must be a number' : undefined
const minValue = min => value =>
value && value < min ? `Must be at least ${min}` : undefined
const email = value =>
value && !/^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)
? 'Invalid email address'
: undefined
const tooOld = value =>
value && value > 65 ? 'You might be too old for this' : undefined
const aol = value =>
value && /.+#aol\.com/.test(value)
? 'Really? You still use AOL for your email?'
: undefined
const normalizeMobilePhone = value => {
if (!value) {
return value
}
const onlyNums = value.replace(/[^\d]/g, '')
if (onlyNums.length <= 4) {
return onlyNums
}
if (onlyNums.length <= 8) {
return `${onlyNums.slice(0, 4)} ${onlyNums.slice(4)}`
}
return `${onlyNums.slice(0, 4)} ${onlyNums.slice(4, 7)} ${onlyNums.slice(7, 10)}`
}
export const Client = (props) => {
const {
handleSubmit,
companyValue,
isWarrantyCompanyValue,
isEditMode } = props
const { reset } = props
return (
<Row>
<Col md={12}>
<h2><Glyphicon glyph="edit" /> {isEditMode ? 'Edit' : 'New'} Client</h2>
<hr />
<form onSubmit={handleSubmit} className="form-horizontal">
{isEditMode && (
<Panel header={<h3>Client - Basic Details</h3>}>
<Row>
<Field component={StaticText}
name="clientNo"
id="clientNo"
label="Client No."
fieldCols={4}
labelCols={4}
controlCols={8}
/>
<Field component={StaticText}
name="dateCreated"
id="dateCreated"
label="Date Created."
fieldCols={4}
labelCols={4}
controlCols={8}
/>
<Field component={StaticText}
name="userName"
id="userName"
label="Created By."
fieldCols={4}
labelCols={4}
controlCols={8}
/>
</Row>
<Row>
<Field
component={props => {
return (
<StaticText {...props}>
<p
className="form-control-static"
>
<Glyphicon glyph={props.input.value ? 'ok' : 'remove'} />
{' '}{props.input.value ? 'Has jobs attached' : 'No jobs attached'}
</p>
</StaticText>
)
}}
name="activity"
id="activity"
label="Activity"
fieldCols={4}
labelCols={4}
controlCols={8}
/>
<Field component={CheckboxField}
name="active"
id="active"
label="De-Activate"
checkboxLabel="De activate this client"
fieldCols={4}
labelCols={4}
controlCols={8}
/>
</Row>
</Panel>
)}
<Panel header={<h3>Client - CompanyDetails</h3>}>
<Row>
<Field component={CheckboxField}
id="company"
name="company"
label="Company?"
checkboxLabel="Client represents a company"
fieldCols={6}
labelCols={3}
controlCols={9}
/>
</Row>
{companyValue && (
<div>
<Row>
<Field component={TextField}
name="companyName"
id="companyName"
type="text"
label="Company Name"
placeholder="Enter company name..."
fieldCols={6}
labelCols={3}
controlCols={9}
/>
<Field component={TextField}
name="abn"
id="abn"
type="text"
label="ABN."
fieldCols={6}
labelCols={3}
controlCols={5}
/>
</Row>
<Row>
<Field component={CheckboxField}
id="isWarrantyCompany"
name="isWarrantyCompany"
label="Warranty Company?"
checkboxLabel="Client represents a warranty company"
fieldCols={6}
labelCols={3}
controlCols={9}
/>
{isWarrantyCompanyValue && (
<Field component={CheckboxField}
id="requiresPartsPayment"
name="requiresPartsPayment"
label="Requires Parts Payment?"
checkboxLabel="We pay for parts"
fieldCols={6}
labelCols={3}
controlCols={9}
/>
)}
</Row>
<Row>
<Field component={TextField}
name="companyEmail"
id="companyEmail"
type="email"
label="Spare Parts Email."
placeholder="Enter spare parts email..."
fieldCols={6}
labelCols={3}
controlCols={9}
/>
</Row>
</div>
)}
</Panel>
<Panel header={<h3>Client - {companyValue ? 'Company Contact' : 'Personal'} Details</h3>}>
<Row>
<Field component={TextField}
name="clientFirstName"
id="clientFirstName"
type="text"
label="First Name."
placeholder="Enter first name..."
fieldCols={6}
labelCols={3}
controlCols={9}
validate={[required]}
/>
<Field component={TextField}
name="clientLastName"
id="clientLastName"
type="text"
label="Last Name."
placeholder="Enter last name..."
fieldCols={6}
labelCols={3}
controlCols={9}
/>
</Row>
<Row>
<Field component={TextField}
name="mobilePhone"
id="mobilePhone"
type="text"
label="Mobile No."
placeholder="Enter mobile No..."
fieldCols={6}
labelCols={3}
controlCols={5}
normalize={normalizeMobilePhone}
/>
<Field component={TextField}
name="phone"
id="phone"
type="text"
label="Phone No."
placeholder="Enter phone No..."
fieldCols={6}
labelCols={3}
controlCols={5}
/>
</Row>
<Row>
<Field component={TextField}
name="email"
id="email"
type="email"
label="Email."
placeholder="Enter email address..."
fieldCols={6}
labelCols={3}
controlCols={9}
/>
</Row>
</Panel>
<FormSection name="Address">
<Address />
</FormSection>
<Panel header={<h3>Notes</h3>}>
<Row>
<Field component={TextAreaField}
id="notes"
name="notes"
label="Notes."
placeholder="Enter notes here..."
fieldCols={12}
labelCols={1}
controlCols={11}
/>
</Row>
</Panel>
<Panel header={<h3>Client - Bank Details</h3>}>
<Row>
<Field component={TextField}
name="bankName"
id="bankName"
type="text"
label="Bank Name."
placeholder="Enter bank name..."
fieldCols={4}
labelCols={4}
controlCols={8}
/>
<Field component={TextField}
name="bsb"
id="bsb"
type="text"
label="BSB No."
placeholder="Enter BSB No..."
fieldCols={4}
labelCols={4}
controlCols={8}
/>
<Field component={TextField}
name="account"
id="account"
type="text"
label="Account No."
placeholder="Enter Account No..."
fieldCols={4}
labelCols={4}
controlCols={8}
/>
</Row>
</Panel>
<div className="panel-body">
<Row>
<Col xs={4}>
<Row>
<Col xs={8} xsOffset={4}>
<Button bsStyle="primary" type="submit" bsSize="small">
<Glyphicon glyph="ok" /> Submit
</Button>
{' '}
<Button type="reset" bsSize="small" onClick={reset}>
<Glyphicon glyph="ban-circle" /> Clear
</Button>
</Col>
</Row>
</Col>
</Row>
</div>
</form>
</Col>
</Row >
)
}
let ClientForm = reduxForm({
form: CLIENT_FORM_NAME,
})(Client)
ClientForm = connect(
state => ({
initialValues: state.editClient // pull initial values from client reducer
}),
{ reducer } // bind client loading action creator
)(Client)
export default ClientForm
I have added the following at the bottom as per the redux form example:
ClientForm = connect(
state => ({
initialValues: state.editClient // pull initial values from client reducer
}),
{ reducer } // bind client loading action creator
)(Client)
...wnd when I save it I get the following error.
Exception: Call to Node module failed with error: Error: Field must be inside a component decorated with reduxForm()
I believe I have not understood how to set the initial values.
Where have I gone wrong and what I need to do to make this take the state values and load them?
The parameter for the function that connect returns should be ClientForm instead of Client. Try this:
ClientForm = connect(
state => ({
initialValues: state.editClient // pull initial values from client reducer
}),
{ reducer } // bind client loading action creator
)(ClientForm)