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>
)
}
Related
I am using a react-bootstrap component Checkbox to create a general form . The component name is AdminPage, I wanted tp pass all the selected values of the checkboxes into an state (which is initialised as a state ). I am unable to do so.
Here below is the code
import React, { useState } from "react";
import { Button, Row, Col, Dropdown, Form } from "react-bootstrap";
export const AdminPage = () => {
const [name, setName] = useState('');
const [operations, setOperation] = useState([]);
const handleSubmit = () => {
alert("Selected Checkboxes -" + operations);
}
return (
<>
<div className="p-3 border border-dark bg-light ">
<h3 className="text-center">Add Roles Here</h3>
<Form className="p-3">
<Form.Group as={Row} className="mb-3" controlId="formBasicText">
<Form.Label column sm="3">
Name
</Form.Label>
<Col sm="9">
<Form.Control type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder="Enter Name here..." />
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3" controlId="formBasicText">
<Form.Label column sm="3">
Opeations
</Form.Label>
{/* <Col sm="9">
<Form.Control type="text" value={rolecredentials.operations} onChange={(e) => onChange(e, "operations")} placeholder='Eg: GETitems, GETstocks, GETpinfences, GETinventory, ADDinventory' />
<Form.Text className="text-muted mx-2">
Mention multiple values using comma seperator like given in placeholder
</Form.Text>
</Col> */}
<Col sm="8">
<Form value={operations} >
<div key={`inline-checkbox`} className="mb-3">
<Form.Check
inline
label="GETitem"
name="group1"
type="checkbox"
value="GETitem"
id={`inline-checkbox-1`}
/>
<Form.Check
inline
label="GETstocks"
name="group1"
type="checkbox"
value="GETstocks"
id={`inline-checkbox-2`}
/>
<Form.Check
inline
label="GETpinfences"
name="group1"
type="checkbox"
value="GETpinfences"
id={`inline-checkbox-3`}
/>
<Form.Check
inline
label="GETinventory"
name="group1"
type="checkbox"
value="GETinventory"
id={`inline-checkbox-4`}
/>
<Form.Check
inline
label="ADDinventory"
name="group1"
type="checkbox"
value="ADDinventory"
id={`inline-checkbox-5`}
/>
</div>
</Form>
</Col>
</Form.Group>
<div className="w-25 m-auto mt-5 mb-3">
<Button variant="primary" type="submit" onClick={handleSubmit}>
Add Role
</Button>
</div>
</Form>
</div>
</>
)
}
I had tried onSelect but still not able to do so.
Have you given the :checked pseudo selector a try?
const checkedElements = document.querySelectorAll(":checked");
Edit
Oh, and the event you're looking for is onChange.
Edit*
const handleSubmit = () => {
alert("Selected Checkboxes -" + operations);
const checkedElements = documents.querySelectorAll(":checked");
checkedElements.forEach((entry) => {
/*Here we have access to each checked element.
*So maybe define an array, push each value you want to that array
*and finally update the state after the forEach.
*/
});
}
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 }
);
Considering the following example, this is stopping us to create custom components inside forms using antd4 version.
const handleFormSubmit = () => {
form
.validateFields()
.then((values: any) => {
console.log('success values => ', JSON.stringify(values));
successCallback(values);
})
.catch((errorInfo: any) => {
console.log('failureCallback values => ', JSON.stringify(errorInfo));
failureCallback(errorInfo);
});
};
<Form
form={form}
layout="vertical"
name="normal_login"
className="login-form"
initialValues={store.formData.initialValues}
>
<Form.Item>
<Input placeholder="Name" />
</Form.Item>
<Button type="primary" htmlType="submit" onClick={handleFormSubmit}>
Create
</Button>
</Form>
This works absolutely fine, whereas if the component is custom, then it doesn't work. Example:
function CustomInput(props){
return (
<Form.Item>
<Input placeholder={props.name} />
</Form.Item>
)
}
<Form
form={form}
layout="vertical"
name="normal_login"
className="login-form"
initialValues={store.formData.initialValues}
>
<CustomInput name="Name" />
Will display the field and also validates on change event. HandleFormSubmit is called, but it's not triggering success or failure block.
<Button type="primary" htmlType="submit" onClick={handleFormSubmit}>
Create
</Button>
</Form>
What's wrong here?
Try this instead of your Custom JSX
function CustomInput(props){
return (
<Form.Item name={props.name}> # Update this line only and remove this comment #
<Input placeholder={props.name} />
</Form.Item>
)
}
<Form
form={form}
layout="vertical"
name="normal_login"
className="login-form"
initialValues={store.formData.initialValues}
>
<CustomInput name="Name" />
<Button type="primary" htmlType="submit" onClick={handleFormSubmit}>
Create
</Button>
</Form>
NOTE: In Antd if your using Form.Item then you have to set name there
not on input fields. Form.Item assign its value to its Input.
I hope your doubt is solved comment for more views. I also tired of antd and wasted many days to understand this.
I'm very new to React. I'm building a flight booking website. I want to hide the return date form field when the user selects one way trip. I wanted to know what is the best way to go about it.
const TripTypeButton = (props) => {
const [rSelected, setRSelected] = useState(null);
return (
<div>
<ButtonGroup>
<Button color="primary" onClick={() => setRSelected(1)} active={rSelected === 1}>Round Trip</Button>
<Button color="secondary" onClick={() => setRSelected(2)} active={rSelected === 2}>One Way</Button>
</ButtonGroup>
</div>
);
}
const HomePage = (props) =>{
return(
<div>
<div>
<h2> Search for flights</h2>
</div>
<div>
<Form>
<Row form>
<FormGroup>
<TripTypeButton />
</FormGroup>
</Row>
<Row form>
<Col md={3}>
<FormGroup>
<Label>Departure</Label>
<Input type="date" id="departure" name="departure"/>
</FormGroup>
</Col>
<Col md={3}>
<FormGroup>
<Label for="exampleState">Return</Label>
<Input type="date" name="return" id="return"/>
</FormGroup>
</Col>
<Row/>
</Form>
</div>
</div>
);
}
for this situation, you need to keep the state of selected trip type in HomePage component and then based on that state render the Return flight or not!
like below:
const HomePage = (props) => {
const [rSelected, setRSelected] = useState(null);
return (
// some code
// trip type button handler
<TripTypeButton handleSelectedTripType={setRSelected} rSelected={rSelected} />
// the button section of code
{ rSelected !== 1
&& <Col md={3}>
<FormGroup>
<Label for="exampleState">Return</Label>
<Input type="date" name="return" id="return"/>
</FormGroup>
</Col>
}
// rest of jsx code
)
}
and your TripTypeButton would be like below:
const TripTypeButton = ({ handleSelectedTripType, rSelected }) => {
return (
<div>
<ButtonGroup>
<Button color="primary" onClick={() => handleSelectedTripType(1)} active={rSelected === 1}>Round Trip</Button>
<Button color="secondary" onClick={() => handleSelectedTripType(2)} active={rSelected === 2}>One Way</Button>
</ButtonGroup>
</div>
);
}
this is called lifting state up in React! and by that you keep your state in top level components and manage data manipulation by passing required handlers down to the child components by directly props or context!
I'm working on a form to create a new product and I need a row with 3 equals fields but I'm not getting there using React Semantic Ui.
How can I code 3 equal input fields using react semantic ui?
That's what I've tried:
import { Form, Input, Button, TextArea, Header, Icon } from "semantic-ui-react";
function CreateProduct() {
return (
<>
<Header as="h2" block>
<Icon name="add square" color="violet" />
Cadastrar Produto
</Header>
<Form>
<Form.Group widths="equal">
<Form.Field
control={Input}
name="name"
label="Nome"
placeholder="Nome do Produto"
/>
<Form.Field
control={Input}
name="price"
label="Preço"
placeholder="Preço"
min="0.00"
step="0.10"
type="number"
/>
<Form.Field
control={Input}
name="media"
type="file"
label="Imagem"
accept="image/*"
content="Escolha Imagem"
/>
</Form.Group>
<Form.Field
control={TextArea}
name="description"
label="Descrição"
placeholder="Descrição do Produto"
/>
<Form.Field
control={Button}
inverted
color="violet"
icon="pencil alternate"
content="Cadastrar"
type="submit"
/>
</Form>
</>
);
}
export default CreateProduct;
The output that I am getting is:
See the 3rd input "Imagem"?
It seems that the field is not following the Form.Group props widths='equal' from semanctic-react-ui document
This layout is exceed because of the file type content.
May be you can try this way to get that layout
import React, { Component } from "react";
import { Form, Input, Button, TextArea } from "semantic-ui-react";
class FormExample extends Component {
fileInputRef = React.createRef();
render() {
return (
<Form>
<Form.Group widths="equal">
<Form.Field
control={Input}
name="name"
label="Nome"
placeholder="Nome do Produto"
/>
<Form.Field
control={Input}
name="price"
label="Preço"
placeholder="Preço"
min="0.00"
step="0.10"
type="number"
/>
<Form.Field>
<label>Imagem</label>
<Button
style={{ width: "100%" }}
content="Choose File"
labelPosition="left"
icon="file"
onClick={() => this.fileInputRef.current.click()}
/>
<input
ref={this.fileInputRef}
type="file"
hidden
onChange={this.fileChange}
/>
</Form.Field>
</Form.Group>
<Form.Field
control={TextArea}
name="description"
label="Descrição"
placeholder="Descrição do Produto"
/>
<Form.Field
control={Button}
inverted
color="violet"
icon="pencil alternate"
content="Cadastrar"
type="submit"
/>
</Form>
);
}
}
export default FormExample;
demo : https://codesandbox.io/s/zen-frost-9ihqw (adjust the screen size for full view)
I found a good solution just adding the "Fluid" props on the second .
<Form.Field
fluid
control={Input}
name="price"
label="Preço"
placeholder="Preço"
min="0.00"
step="0.10"
type="number"
/>