I am using react hook forms to create forms in my application:
import "./styles.css";
import { useForm } from "react-hook-form";
export default function App() {
const { register, setFocus, handleSubmit } = useForm({
defaultValues: { inputText: "", inputCheckbox: false }
});
const onSubmit = (data) => {
console.log(data);
};
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)} className="form">
<br />
<label>inputCheckbox</label>
<input type="checkbox" {...register("inputCheckbox")} />
<br />
<br />
<label>inputCheckbox2</label>
<input type="checkbox" {...register("inputCheckbox")} />
<button
onClick={() => {
setFocus("inputCheckbox");
}}
>
setFocus inputCheckbox
</button>
<br />
<br />
<button type="submit">Submit</button>
</form>
</div>
);
}
I try to set focus when i click on the button, but it does not work, why and how to fix using the library API?
demo: https://codesandbox.io/s/icy-feather-eh1crv?file=/src/App.js:0-899
Related
Hello guys so i tried to make global state so the other page can use the state. The problem is i got an error that says:
Login.js:18 Uncaught TypeError: Cannot destructure property 'emailLog' of '(0 , react__WEBPACK_IMPORTED_MODULE_0__.useContext)(...)' as it is undefined.
Im doing this because i want the email from user after logged in and pass them to another page so that i can display the logged in user.
App.js:
export const EmailUser = React.createContext();
function App() {
Axios.defaults.withCredentials = true;
const [invoice, setInvoice] = useState("");
const [currency, setCurrency] = useState("IDR");
const [myFile, setMyFile] = useState("");
const [emailLog, setEmailLog] = useState("");
return (
<EmailUser.Provider value={{ emailLog, setEmailLog }}>
<div className="App">
<BasicExample />
<div className="formInput">
<form method="POST" encType="multipart/form-data" action="http://localhost:3001/upload">
<div className="textUser"></div>
<input
className="inputForm"
defaultValue={emailLog}
type="email"
disabled
name="email"
/>
<input className="inputForm" type="number" placeholder="Invoice No" name="InvoiceNo" />
<input className="inputForm" type="date" name="Invoice_Date" />
<input className="inputForm" type="text" placeholder="Description" name="Description" />
<select
className="selectBox"
name="Currency"
onChange={(e) => {
setCurrency(e.target.value);
}}
>
<option value="IDR">IDR</option>
<option value="USD">USD</option>
<option value="YEN">YEN</option>
</select>
<input className="inputForm" type="number" placeholder="Amount" name="Amount" />
<input
className="custom-file-upload"
multiple
type="file"
name="DocumentFile"
onChange={(e) => {
setMyFile(e.target.value);
}}
/>
<button className="btnSubmit">Submit</button>
</form>
</div>
</div>
</EmailUser.Provider>
);
}
export default App;
Login.js
const Login = () => {
let navigate = useNavigate();
const { emailLog, setEmailLog } = useContext(EmailUser);
const [passwordLog, setPasswordLog] = useState("");
const [loginStatus, setLoginStatus] = useState("");
Axios.defaults.withCredentials = true;
const login = (e) => {
e.preventDefault();
Axios.post("http://localhost:3001/login", {
email: emailLog,
password: passwordLog,
}).then((response) => {
console.log(response);
if (response.data.message) {
alert(response.data.message);
} else {
setLoginStatus(response.data[0].email);
alert("Redirecting");
navigate("/home");
}
});
};
console.log(emailLog);
useEffect(() => {
Axios.get("http://localhost:3001/login").then((response) => {
if (response.data.loggedIn == true) {
setLoginStatus(response.data.email[0].email);
}
});
});
return (
<div>
<img className="wave" src={Wave} />
<img className="wave2" src={WaveV2} />
<div className="wrapper">
<div className="img">{/* <img src={Background}/> */}</div>
<div className="register-content">
<div className="registerForm">
<img src={Avatar} />
<h2 className="title">Welcome</h2>
<div className="input-div one">
<div className="i">
<i className="fas fa-user">
<GrMail />
</i>
</div>
<div className="div">
<input
type="email"
className="input"
placeholder="Email"
required
onChange={(e) => {
setEmailLog(e.target.value);
}}
/>
</div>
</div>
<div className="input-div pass">
<div className="i">
<i className="fas fa-lock">
<AiFillLock />
</i>
</div>
<div className="div">
<input
type="password"
className="input"
placeholder="Password"
required
onChange={(e) => {
setPasswordLog(e.target.value);
}}
/>
</div>
</div>
Don't have an account ?
<button type="submit" className="btn" onClick={login}>
Login
</button>
</div>
</div>
</div>
</div>
);
};
export default Login;
EmailUser context works only with the components that are children of EmailUser.Provider, and it doesn't seem to be the case for Login component. An easy way is to create a separate component, in some EmailUserProvider.js, like so:
import {createContext, useState} from "react"
export const EmailUser = createContext();
export default function EmailUserProvider({children}) {
const [emailLog, setEmailLog] = useState("");
return (
<EmailUser.Provider value={{ emailLog, setEmailLog }}>
{children}
</EmailUser.Provider>
);
}
And make it wrap all the components that would consume it. If I assume all my components and routes are rendered in App and want the context to be global, I would do so:
<EmailUserProvider>
<App/>
</EmailUserProvider>
It randomly started doing this and I am not sure why tho. I have two modals (these are named differently) that are exactly the same but only one is working. The modal I am using is the React-Modal library. The first one works just fine on the home page but the second doesn't at all on an edit details page.
What I did notice is that there is a div placed with an Id of __Next on the home page that is working that places the content of the modal inside but that same exact div does not show up on the other page for the same modal to work.
Below are the two components I am working with and its parent component that houses both
Parent:
import styles from './homeheader.module.css';
import { useRouter } from 'next/router';
import { useState } from 'react';
import NewInvoice from '../invoice/modal/NewInvoice';
import Link from 'next/link';
import { getDatabase, ref, remove } from "firebase/database";
import { database } from '../firebase/firebase';
import EditInvoice from '../invoice/modal/EditInvoice';
export default function HomeHeader(props) {
const [newInvoiceModalIsOpen, setNewInvoiceOpen] = useState(false);
const [editInvoiceModalIsOpen, setEditInvoiceOpen] = useState(false);
const router = useRouter();
const pathName = router.pathname;
const { data, count, id, detail } = props;
function openNewInvoiceModalHandler() {
setNewInvoiceOpen(true)
}
function closeNewInvoiceModalHandler() {
setNewInvoiceOpen(false)
}
function openEditInvoiceModalHandler() {
setEditInvoiceOpen(true)
}
function closeEditInvoiceModalHandler() {
console.log(data)
setEditInvoiceOpen(false)
}
function deleteInvoiceHandler() {
console.log('delete')
console.log(id)
const db = database;
remove(ref(db, 'invoices/' + id))
}
function markAsPaidInvoiceHandler() {
console.log('paid')
}
if (pathName === '/detail/[id]') {
return (
<>
<div className={styles.headerwrapper}>
<Link href="/">
<a>Go back</a>
</Link>
{/* <p>{detail.data.status}</p> */}
<div>
<button onClick={openEditInvoiceModalHandler}>Edit</button>
<button onClick={deleteInvoiceHandler}>Delete</button>
<button onClick={markAsPaidInvoiceHandler}>Mark as Paid</button>
</div>
</div>
<EditInvoice isOpen={editInvoiceModalIsOpen} closeModal={closeEditInvoiceModalHandler} details={detail}/>
</>
)
}
return (
<div className={styles.headerwrapper}>
<div className={styles.leftside}>
<h1 className={styles.header}>Invoices</h1>
<p className={styles.text}>There are {count} total invoices</p>
</div>
<div className="right-side">
<select className={styles.filter} id="filter" placeholder="Filter by status">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<button className={styles.button} onClick={openNewInvoiceModalHandler}>New Invoice</button>
</div>
<NewInvoice isOpen={newInvoiceModalIsOpen} closeModal={closeNewInvoiceModalHandler} count={count}/>
</div>
)
}
Child modal component that IS WORKING:
import { useForm } from 'react-hook-form';
import ReactModal from 'react-modal';
import { database } from '../../firebase/firebase';
import { ref, set } from "firebase/database";
import styles from './newinvoice.module.css'
// ReactModal.setAppElement("#__next")
export default function NewInvoice (props) {
const { register, handleSubmit, watch, formState: { errors } } = useForm();
function onSubmit(data) {
const randGen = Math.floor(Math.random() * 9999999);
data.id = randGen;
const db = database;
set(ref(db, '/invoices/' + randGen), {
data: data
})
setTimeout(() => {
window.location.reload(true)
}, 500)
props.closeModal();
}
return (
<>
<ReactModal isOpen={props.isOpen}>
<h1>New Invoice</h1>
<form className={styles.form} onSubmit={handleSubmit(onSubmit)}>
<label>Street Address</label>
<input {...register("senderAddress.street")} />
<label>City</label>
<input {...register("senderAddress.city")} />
<label>Postal Code</label>
<input {...register("senderAddress.postCode")} />
<label>Country</label>
<input {...register("senderAddress.country")} />
<label>Client"s Name</label>
<input {...register("clientName")} />
<label>Client"s Email</label>
<input {...register("clientEmail")} />
<label>Street Address</label>
<input {...register("clientAddress.street")} />
<label>City</label>
<input {...register("clientAddress.city")} />
<label>Postal Code</label>
<input {...register("clientAddress.postCode")} />
<label>Country</label>
<input {...register("clientAddress.country")} />
<label>Invoice Date</label>
<input {...register("createdAt")} />
<label>Payment Terms</label>
<input {...register("paymentTerms")} />
<label>Project Description</label>
<input {...register("description")} />
{/* //Item list goes here */}
<input {...register("items")} />
<input type="submit" placeholder="Submit"/>
</form>
<button onClick={props.closeModal}>Close</button>
</ReactModal>
</>
)
}
Child component that is NOT WORKING:
import { useForm } from 'react-hook-form';
import ReactModal from 'react-modal';
import { database } from '../../firebase/firebase';
import { ref, set } from "firebase/database";
import { useRouter } from 'next/router';
import styles from './newinvoice.module.css'
import { useEffect, useState } from 'react';
ReactModal.setAppElement("#react-modals")
export default function EditInvoice(props) {
const { register, handleSubmit, watch, formState: { errors } } = useForm();
const [formData, setFormData] = useState();
const { isOpen, closeModal, detail } = props;
const router = useRouter();
const id = router.query.id;
const dbLink = `https://invoice-app-3fa85-default-rtdb.firebaseio.com/invoices/${id}.json`;
function onSubmit(data) {
const db = database;
set(ref(db, '/invoices/' + id), {
data: data
})
setTimeout(() => {
window.location.reload(true)
}, 500)
props.closeModal();
}
// function onSubmit(data) {
// console.log(data)
// }
useEffect(() => {
// fectchData();
console.log(formData)
})
const fectchData = async () => {
try {
const res = await fetch(dbLink);
const json = await res.json();
setFormData(json)
} catch (error) {
console.log(error)
}
}
if (!formData) {
console.log('not working')
return <p>Loading....</p>
}
return (
<>
<ReactModal isOpen={true} portalClassName="editInvoiceModal" parentSelector={() => document.querySelector('#react-modals')}>
<h1>Edit Invoice </h1>
<form className={styles.form} onSubmit={handleSubmit(onSubmit)}>
<label>Street Address</label>
<input {...register("senderAddress.street")} defaultValue={detail.senderAddress.street}/>
{/* <label>City</label>
<input {...register("senderAddress.city")} defaultValue={formData.senderAddress.city}/>
<label>Postal Code</label>
<input {...register("senderAddress.postCode")} defaultValue={formData.senderAddress.postCode}/>
<label>Country</label>
<input {...register("senderAddress.country")} defaultValue={formData.senderAddress.country}/>
<label>Client"s Name</label>
<input {...register("clientName")} defaultValue={formData.clientName}/>
<label>Client"s Email</label>
<input {...register("clientEmail")} defaultValue={formData.clientEmail}/>
<label>Street Address</label>
<input {...register("clientAddress.street")} defaultValue={formData.clientAddress.street}/>
<label>City</label>
<input {...register("clientAddress.city")} defaultValue={formData.clientAddress.city}/>
<label>Postal Code</label>
<input {...register("clientAddress.postCode")} defaultValue={formData.clientAddress.postCode}/>
<label>Country</label>
<input {...register("clientAddress.country")} defaultValue={formData.clientAddress.country}/>
<label>Invoice Date</label>
<input {...register("createdAt")} defaultValue={formData.createdAt}/>
<label>Payment Terms</label>
<input {...register("paymentTerms")} defaultValue={formData.paymentTerms}/>
<label>Project Description</label>
<input {...register("description")} defaultValue={formData.description}/>
{/* //Item list goes here */}
<input type="submit" placeholder="Submit"/>
</form>
<button onClick={closeModal}>Close</button>
</ReactModal>
</>
)
}
It may be sloppy code as of now and was working to clean it up a lot more until I noticed this issue.
In your parent, try adding a placeholder.
<div id="react-modals" />
Your react modal seems to be looking for a div with the #react-modals id.
I'm trying to run this in react but it showing me error:
path.split is not a function
import React from 'react'
import './SendMail.css'
import CloseIcon from '#material-ui/icons/Close'
import { Button } from '#material-ui/core'
import { useForm } from 'react-hook-form'
function SendMail() {
const { register, handleSubmit, watch, errors } = useForm();
const onSubmit = (data) => {
console.log(data)
}
return (
<div className="sendMail">
<div className="sendMail_header">
<h3>New Message</h3>
<CloseIcon className="sendMail_close"/>
</div>
<form onSubmit={handleSubmit(onSubmit)}>
<input
name='to'
placeholder="To"
type="text"
ref = {register({required:true})}
/>
<input
name='subject'
placeholder="Subject"
type="text"
/>
<input
name='message'
placeholder="Message.."
type="text"
className="sendMail_message"
/>
<div className="sendMail_options">
<Button className="sendMail_send"
variant="contained"
color="primary"
type="submit"
>
Send
</Button>
</div>
</form>
</div>
)
}
Export default SendMail
return (
{jobstate.jobs.map((data,i) =>{
<form>
<input type="text" placeholder="Post a comment" onChange={(e) => jobcmthandler(e,data._id,i) } />
<button type="button" onClick={postcmt} >Send</button>
</form>
})}
)
I generate dynamic HTML using the map function and I want to disabled button if text null for induvial form and also how to get text value on button click in react js
I can't really see why you'd want to do this but here you go (example):
import React, { useState } from "react";
export default function App() {
return ["Name", "Age"].map((label) => <Form label={label} />);
}
function Form({ label }) {
const [readValue, writeValue] = useState("");
return (
<form>
<label>{label}</label>
<input
type="text"
placeholder="Post a comment"
onChange={(e) => writeValue(e.target.value)}
value={readValue}
/>
<button
type="button"
onClick={() => console.log("Submit")}
disabled={readValue === ""}
>
Send
</button>
</form>
);
}
material-ui Items are not showing. I want to show categories of products in SelectField but its not working.
whwn I click on selectfield it does not show any item
All code of my component is given below
import React, { Component } from 'react'
import RaisedButton from 'material-ui/RaisedButton';
import TextField from 'material-ui/TextField';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
const style = {
padding: '10px',
textAlign: 'center'
};
const categories = ["mobile","laptop","camera"];
class AddProduct extends Component {
constructor(props) {
super();
this.state = {
productName: '',
productCategory: '',
}
this.submit = this.submit.bind(this);
this.inputHandler = this.inputHandler.bind(this);
}
inputHandler(e) {
this.setState({
[e.target.name]: e.target.value
})
}
handleChangeCategory = (event, index, value) => {this.setState({productCategory:value}); console.log("value", value)}
render() {
return (
<div ><center>
<h1>Add Product for Auction</h1>
<form onSubmit={this.submit} >
<br />
<br />
<SelectField
floatingLabelText="Catogory"
value={this.state.productCategory}
onChange={this.handleChangeCategory}
>
<MenuItem value={"mobile"} primaryText="Mobile" />
<MenuItem value={"laptop"} primaryText="Laptop" />
<MenuItem value={"camera"} primaryText="Camera" />
</SelectField><br />
<br />
<TextField
type="text"
hintText="Product Title"
name="productName"
value={this.state.productName}
floatingLabelText="Product Title"
onChange={this.inputHandler}
/>
<RaisedButton type="submit" label="Add Product" primary={false} secondary={true} /> <br /><br />
</form>
</center>
</div>
);
}
}
export default AddProduct;
You haven't defined the function submit and according to your code you are trying to bind it.
this.submit = this.submit.bind(this);
define the function submit
submit(){
// do something
}
And try to use ES6 fat arrow functions so you dont have to bind each and every function, like you have done in the above code.
Try something like this (using ES6 fat arrows)
import React, { Component } from 'react'
import RaisedButton from 'material-ui/RaisedButton';
import TextField from 'material-ui/TextField';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
const style = {
padding: '10px',
textAlign: 'center'
};
const categories = ["mobile","laptop","camera"];
class AddProduct extends Component {
constructor(props) {
super();
this.state = {
productName: '',
productCategory: '',
}
}
submit =()=>{
}
inputHandler =(e)=> {
this.setState({
[e.target.name]: e.target.value
})
}
handleChangeCategory = (event, index, value) => {this.setState({productCategory:value}); console.log("value", value)}
render() {
return (
<div ><center>
<h1>Add Product for Auction</h1>
<form onSubmit={this.submit} >
<br />
<br />
<SelectField
floatingLabelText="Catogory"
value={this.state.productCategory}
onChange={this.handleChangeCategory}
>
<MenuItem value={"mobile"} primaryText="Mobile" />
<MenuItem value={"laptop"} primaryText="Laptop" />
<MenuItem value={"camera"} primaryText="Camera" />
</SelectField><br />
<br />
<TextField
type="text"
hintText="Product Title"
name="productName"
value={this.state.productName}
floatingLabelText="Product Title"
onChange={this.inputHandler}
/>
<RaisedButton type="submit" label="Add Product" primary={false} secondary={true} /> <br /><br />
</form>
</center>
</div>
);
}
}
export default AddProduct;