import React from 'react';
import ReactTooltip from 'react-tooltip';
const DataInputBox = () => {
return (
<div>
<ReactTooltip id="title required"effect="solid" place="bottom" >
"Title required"
</ReactTooltip>
<input
type="text"
data-tip
data-for="title required"
placeholder="Type title"
name="title"
/>
</div>
);
}
export default DataInputBox;
Not able to get tooltip at bottom start of input box.Can anyone please help me to get tooltip at cursor start.
You need to add ref to input element and pass this ref to ReactTooltip.show() method.
const DataInputBox = () => {
const inputRef = React.useRef(null)
React.useEffect(() => {
ReactTooltip.show(inputRef.current);
}, []);
return (
<div>
<ReactTooltip id="title required" efect="solid" place="bottom">
"Title required"
</ReactTooltip>
<input
type="text"
ref={inputRef}
data-tip
data-for="title required"
placeholder="Type title"
name="title"
/>
</div>
);
}
Related
I am learning react and I have a component which as a 2 input fields and a button, at the moment, clicking on the button will display a message in console log, but when the button is clicked it displays a popup Leave site?, Changes that you made may not be saved.
this is my code in this component
import React, { useRef, useState, Component } from 'react'
import { useAuthState } from 'react-firebase-hooks/auth';
import { useCollectionData } from 'react-firebase-hooks/firestore';
import { signOut } from 'firebase/auth';
class InfoLgnTest extends Component {
render() {
this.state = {
user: null
}
return (
<div>
<div className="App">
<SignInWithEmailPassword />
</div>
</div>
)
}
}
function SignInWithEmailPassword() {
const emailRef = useRef()
const passwordRef = useRef()
const signIn = () => {
console.log("InfoLgnTest singin clicked")
}
return (
<>
<div className="form">
<form>
<div className="input-container">
<label>Username </label>
<input
name="email"
type="text"
ref={emailRef}
required
placeholder ="something#gmail.com"
/>
</div>
<div className="input-container">
<label>Password </label>
<input
type="text"
name="pass"
ref={passwordRef}
required
placeholder ="..."
/>
</div>
<div className="button-container">
<input type="submit" onClick={signIn}/>
</div>
</form>
</div>
</>
)
}
export default InfoLgnTest
This code has a form, by default form send data as a request on the same page, for resolve this:
Add onSubmit to form,
call preventDefault method from event
call the function signIn
Change <input type="submit" ... /> to <button type="submit">Send</button>
function SignInWithEmailPassword() {
const emailRef = useRef()
const passwordRef = useRef()
const signIn = () => {
console.log("InfoLgnTest singin clicked")
}
// new function to handle submit
const submitForm = (event) => {
event.preventDefault();
signIn();
}
return (
<>
<div className="form">
{/* Add onSubmit */}
<form onSubmit={submitForm}>
<div className="input-container">
<label>Username </label>
<input
name="email"
type="text"
ref={emailRef}
required
placeholder ="something#gmail.com"
/>
</div>
<div className="input-container">
<label>Password </label>
<input
type="text"
name="pass"
ref={passwordRef}
required
placeholder ="..."
/>
</div>
<div className="button-container">
{/* Change input to button */}
<button type="submit">Send</button>
</div>
</form>
</div>
</>
)
}
I have the following form, and I need that when submitting the form, its information is displayed in a new component.
Perhaps the issue of redirecting to the other component could be done by creating a route. But I don't know how said component obtains the information of the form
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
import {useState, useRef} from 'React'
export default const FormX = () => {
const [formValues, setFormValues] = useState({
name: "",
priceUnitary: "",
size: "",
description: "",
});
const inputFileRef = useRef();
const handleChange = (event) => {
const { name, value } = event.target;
console.log(name, value);
setFormValues({ ...formValues, [name]: value });
};
const handleSubmit = (e) => {
e.preventDefault();
console.log(formValues);
console.log(inputFileRef.current.files);
};
return (
<>
<form id="formu" onSubmit={handleSubmit} className="row">
<h1>FORM SEND</h1>
<div className="col-md-6">
<label>Name</label>
<input
placeholder="Text input"
name="name"
value={formValues.name}
onChange={handleChange}
/>
</div>
<div className="col-md-6">
<label>Size</label>
<input
type="number"
placeholder="Text input"
name="size"
value={formValues.size}
onChange={handleChange}
/>
</div>
<div className="col-md-6">
<label>Price Unitary</label>
<input
type="number"
placeholder="Text input"
name="priceUnitary"
value={formValues.priceUnitary}
onChange={handleChange}
/>
</div>
<div className="col-md-6">
<label>Description</label>
<input
placeholder="Text input"
name="description"
value={formValues.description}
onChange={handleChange}
/>
</div>
<div className="col-md-6">
<label>File / Image</label>
<input type="file" ref={inputFileRef} />
</div>
<button type="submit" className="color-primary">
Save
</button>
</form>
</>
);
};
Link:
https://codesandbox.io/s/send-form-dcj5v?file=/src/App.js
You can hide your form by change your state on form sumbit and display another component. You have to pass formValue as props in View component. Now think you have better idea what you have to do...
Here i added new component, that display form value on submit
App.js
import { useState, useRef } from "react";
import View from "./View";
const FormX = () => {
const [formValues, setFormValues] = useState({
name: "",
priceUnitary: "",
size: "",
description: ""
});
const [isFormVisible, setIsFormVisible] = useState(true);
const inputFileRef = useRef();
const handleChange = (event) => {
const { name, value } = event.target;
console.log(name, value);
setFormValues({ ...formValues, [name]: value });
};
const handleSubmit = (e) => {
e.preventDefault();
console.log(formValues);
console.log(inputFileRef?.current?.files);
setIsFormVisible(false);
};
return (
<>
{isFormVisible ? (
<form id="formu" onSubmit={handleSubmit} className="row">
<h1>FORM SEND</h1>
<div className="col-md-6">
<label>Name</label>
<input
placeholder="Text input"
name="name"
value={formValues?.name}
onChange={handleChange}
/>
</div>
<div className="col-md-6">
<label>Size</label>
<input
type="number"
placeholder="Text input"
name="size"
value={formValues.size}
onChange={handleChange}
/>
</div>
<div className="col-md-6">
<label>Price Unitary</label>
<input
type="number"
placeholder="Text input"
name="priceUnitary"
value={formValues.priceUnitary}
onChange={handleChange}
/>
</div>
<div className="col-md-6">
<label>Description</label>
<input
placeholder="Text input"
name="description"
value={formValues.description}
onChange={handleChange}
/>
</div>
<div className="col-md-6">
<label>File / Image</label>
<input type="file" ref={inputFileRef} />
</div>
<button type="submit" className="color-primary">
Save
</button>
</form>
) : (
<View data={formValues} />
)}
</>
);
};
export default FormX;
View.js
import React from "react";
const View = ({ data }) => {
return (
<div>
<p>Name: {data?.name}</p>
<p>priceUnitary: {data?.priceUnitary}</p>
<p>description: {data?.description}</p>
</div>
);
};
export default View;
What could be wrong with these codes? The input is not working once I add [event.target.name]. If I remove that line of codes, I can see the contents that I type inside the input box. The issue is that I want it to work with this code [event.target.name]. This will enable me pick each inputbox values as entered by the user. There are three input boxes and I need to capture the three values in my useState. Any help on how to write it better?
import React, { useState } from 'react';
import "./addbirthday.css";
import "./home.css";
export default function Addbirthday({setShowAdd}) {
const [inputDatas, setInputData] = useState([
{fullName: '', fullDate: '', relationship: ''}
]);
const handlePublish = () =>{
console.log("Hi ", inputDatas)
}
const handleChangeInput = (index, event) =>{
const values = [...inputDatas];
values[index][event.target.name] = event.target.value
setInputData(values)
}
return (
<div className="container">
<div className= { closeInput? "addContainer" :"addWrapper homeWrapper "}>
<i className="fas fa-window-close" onClick={closeNow} ></i>
{inputDatas.map((inputData, index)=> (
<div key={index} className="addbirth">
<label>Name</label>
<input type="text" name="Fname" placeholder='Namend' value=
{inputData.fullName} onChange = {event => handleChangeInput(index, event)} />
<label>Date</label>
<input type="date" placeholder='Date' name="fdate" value=
{inputData.fullDate} onChange = {event => handleChangeInput(index, event)} />
<label>Relationship</label>
<input type="text" placeholder='Friend' name="frelationship" value=
{inputData.relationship} onChange = {event => handleChangeInput(index, event)}/>
</div>
))}
<button className="addBtn" onClick={handlePublish} >Add</button>
</div>
</div>
)
}
You are not setting the name correctly
Change your input tags name to same as state object name meaning
<input name='fullname' />
I have modified your code a bit. Make it as your own and get it done
Upvote my answer if it helps
https://codesandbox.io/s/jolly-khayyam-51ybe?file=/src/App.js:0-1711
import React, { useState } from "react";
export default function Addbirthday({ setShowAdd }) {
const [inputDatas, setInputData] = useState([
{ Fname: "", fdate: "", frelationship: "" }
]);
const handlePublish = () => {
console.log("Hi ", inputDatas);
};
const handleChangeInput = (index, event) => {
const values = [...inputDatas];
values[index][event.target.name] = event.target.value;
setInputData(values);
console.log(values[index][event.target.name]);
};
return (
<div className="container">
<div className={"addContainer addWrapper homeWrapper"}>
<i className="fas fa-window-close"></i>
{inputDatas.map((inputData, index) => (
<div key={index} className="addbirth">
<label>Name</label>
<input
type="text"
name="Fname"
placeholder="Namend"
value={inputData.fullName}
onChange={(event) => handleChangeInput(index, event)}
/>
<label>Date</label>
<input
type="date"
placeholder="Date"
name="fdate"
value={inputData.fullDate}
onChange={(event) => handleChangeInput(index, event)}
/>
<label>Relationship</label>
<input
type="text"
placeholder="Friend"
name="frelationship"
value={inputData.relationship}
onChange={(event) => handleChangeInput(index, event)}
/>
</div>
))}
<button className="addBtn" onClick={handlePublish}>
Add
</button>
</div>
</div>
);
}
I am trying to learn to code by following an eCommerce product tutorial guide in React.
I have finished setting up the product page and checkout.
My goal now is to extract the cart: [] along with the checkout total into a form using EmailJS.
import React from 'react';
import emailjs from 'emailjs-com';
import './form.css';
import { ProductConsumer } from '../../context'
import CartList from './CartList'
import CartColumns from "./CartColumns"
import CartTotals from './CartTotals'
import Title from "../Title";
import { ProductProvider } from "../../context"
import CartItem from './CartItem'
export default function CheckOut() {
function sendEmail(e) {
alert("Your order has been placed!")
e.preventDefault();
emailjs.sendForm('gmail', 'template_3DAGPnwJ', e.target, 'user_m49ol85bvoqFluF8IKatG')
.then((result) => {
console.log(result.text);
}, (error) => {
console.log(error.text);
});
}
let Order = "cat"
return (
<div>
<ProductConsumer>
{value => {
return(
<div>
<Title name="Check" title="Out"/>
<CartColumns />
<CartList value={value} />
<CartTotals value={value}/>
</div>
)
}
}
</ProductConsumer>
<form className="contact-form" onSubmit={sendEmail}>
<label>Contact Number eg. 12345678 </label>
<input type="tel" name="contact_number" placeholder="12345678" pattern="[0-9]{8}" required />
<label>Name</label>
<input type="name" name="user_name" required />
<label>Email</label>
<input type="email" name="user_email" required />
<label>Address Line 1</label>
<input type="address-line1" name="user_address1" required />
<label>Address Line 2</label>
<input type="address-line2" name="user_address2" />
<label>Message (eg. Special Requests)</label>
<textarea name="message_html" />
<input type="submit" value="Place Order" />
<textarea name="proudct order" value={Order}/>
</form>
</div>
);
}
So far the textarea is showing "cat" from the let Order = "cat".
I would like to put the array information from CartList and CartTotal into Order. Once the client submits the form, I will have their name email address and the order they collected in the cart. This will be emailed to me via EmailJS.
import React from 'react';
import emailjs from 'emailjs-com';
import './form.css';
import { ProductConsumer } from '../../context';
import CartList from './CartList';
import CartTotals from './CartTotals';
import Title from '../Title';
export default function CheckOut() {
function sendEmail(e) {
alert('Your order has been placed! Our staff will get in touch with you to confirm your order and to process payment.');
e.preventDefault();
emailjs
.sendForm(
'gmail',
'xxxxxxxxx',
e.target,
'xxxxxxxxx'
)
.then(
(result) => {
console.log(result.text);
},
(error) => {
console.log(error.text);
}
);
}
const Form = ({ context }) => {
let Order = context.cart.map((item) => `ID: ${item.id} \n${item.title} \t $ ${item.price} \t Qty:${item.count} \n\n`);
let OrderSubtotal = context.cartSubtotal ;
let OrderServce = context.cartService;
let OrderShipping = context.cartShipping;
let OrderTotal = context.cartTotal;
return (
<form className="contact-form" onSubmit={sendEmail}>
<label>Contact Number eg. 12345678 </label>
<input
type="tel"
name="contact_number"
placeholder="12345678"
pattern="[0-9]{8}"
required
/>
<label>Name</label>
<input type="name" name="user_name" required />
<label>Email</label>
<input type="email" name="user_email" required />
<label>Address Line 1</label>
<input type="address-line1" name="user_address1" required />
<label>Address Line 2</label>
<input type="address-line2" name="user_address2" />
<label>Message (eg. Special Requests)</label>
<textarea name="message_html" />
<input type="submit" value="Place Order" />
<textarea style={{display:"none"}} name="Order" defaultValue={Order} />
<textarea style={{display:"none"}} name="OrderSubtotal" defaultValue={OrderSubtotal} />
<textarea style={{display:"none"}} name="OrderServce" defaultValue={OrderServce} />
<textarea style={{display:"none"}} name="OrderShipping" defaultValue={OrderShipping} />
<textarea style={{display:"none"}} name="OrderTotal" defaultValue={OrderTotal} />
</form>
);
};
return (
<div>
<ProductConsumer>
{(value) => {
return (
<div>
<Title name="Check" title="Out" />
<CartList value={value} />
<CartTotals value={value} />
</div>
);
}}
</ProductConsumer>
<ProductConsumer>
{(context) => <Form context={context} />}
</ProductConsumer>
</div>
);
}
The answer.
import { ProductConsumer } from '../../context';
let Order = context.cart.map((item) => ID: ${item.id} \n${item.title} \t $ ${item.price} \t Qty:${item.count} \n\n);
which is then exported to emailJS in the textarea.
<textarea style={{display:"none"}} name="Order" defaultValue={Order} />
and rendered
<ProductConsumer>
{(context) => <Form context={context} />}
</ProductConsumer>
Answer suggested by Metafield on Scrimba Discord Community. Thanks a ton!
You can and should use state to update any variable in a React component! CheckOut is a functional component. To use state in a functional component you have to use a hook, which is useState.
To get value from CartList and CartTotal and update Order, pass callback functions from CheckOut component.
Please check the following code, hope it helps.
import React, { useState } from "react";
import emailjs from "emailjs-com";
import "./form.css";
import { ProductConsumer } from "../../context";
import CartList from "./CartList";
import CartColumns from "./CartColumns";
import CartTotals from "./CartTotals";
import Title from "../Title";
import { ProductProvider } from "../../context";
import CartItem from "./CartItem";
export default function CheckOut() {
// Order default value is empty array. i.e. no orders
// updateOrder will update Order
const [Order, updateOrder] = useState([]);
// cartTotal to store CartTotals value
// updateCartTotal will update cartTotal
const [cartTotal, updateCartTotal] = useState(0);
function sendEmail(e) {
alert("Your order has been placed!");
e.preventDefault();
// You can access Order and cartTotal here.
console.log(Order, cartTotal);
emailjs
.sendForm(
"gmail",
"template_3DAGPnwJ",
e.target,
"user_m49ol85bvoqFluF8IKatG"
)
.then(
(result) => {
console.log(result.text);
},
(error) => {
console.log(error.text);
}
);
}
return (
<div>
<ProductConsumer>
{(value) => {
return (
<div>
<Title name="Check" title="Out" />
<CartColumns />
{/* updateOrder is a callback passed by prop */}
<CartList value={value} onCartUpdate={updateOrder} />
{/* updateCartTotal is a callback passed by prop */}
<CartTotals value={value} onCartTotalUpdate={updateCartTotal} />
</div>
);
}}
</ProductConsumer>
<form className="contact-form" onSubmit={sendEmail}>
<label>Contact Number eg. 12345678 </label>
<input
type="tel"
name="contact_number"
placeholder="12345678"
pattern="[0-9]{8}"
required
/>
<label>Name</label>
<input type="name" name="user_name" required />
<label>Email</label>
<input type="email" name="user_email" required />
<label>Address Line 1</label>
<input type="address-line1" name="user_address1" required />
<label>Address Line 2</label>
<input type="address-line2" name="user_address2" />
<label>Message (eg. Special Requests)</label>
<textarea name="message_html" />
<input type="submit" value="Place Order" />
<textarea name="proudct order" value={Order} />
</form>
</div>
);
}
I see your input fields are uncontrolled! React suggests to use a controlled component for form input. You can get idea from here - https://reactjs.org/docs/forms.html#controlled-components
Also, since you are learning React I suggest you read about two core parts of React. They are props and state.
For working with forms you can check this popular form handling library for react. https://formik.org/
Im trying to make an input field for name in my code, and I get:
'Input' is not defined react/jsx-no-undef and I cant see whats wrong, can anyone please help me?
I will later pass name into my dispatch
The form part with textarea is working.
import React, { useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import '../styles/NewMessage.css'
import { fetchNewMessage } from 'reducer/messages'
export const NewMessage = () => {
const [message, setMessage] = useState('')
const [name, setName] = useState('')
const dispatch = useDispatch()
const handleMessageSubmit = (event) => {
event.preventDefault()
//console.log('addNewMessage', message)
dispatch(fetchNewMessage(message))
setMessage('')
}
return (
<div className="add-message-container">
{/* ******Form for sending a new message******* */}
<form onSubmit={handleMessageSubmit} className="add-message-form">
<span>
<label>
Name:
This input is giving me the 'Input' is not defined react/jsx-no-undef
<Input
placeholder="Name"
type="text"
onChange={event => setName(event.target.value)}
value={name}
required
/>
</label>
</span>
This textarea is working fine
<span>
<label For="new-message">
<textarea
id="new-message"
className="input-message"
rows='3'
minLength='5'
maxLength='150'
placeholder="Type your message"
onChange={(event) => setMessage(event.target.value)}
value={message}
required />
</label>
</span>
{/* * Form submit button * */}
<div className="add-message-btn-container">
<button
className="add-message-btn"
type="submit"
title="Send">
Send
</button>
</div>
</form>
</div>
)
}
You either need to import Input component from some component library or you need to use input which is the HTML element. JSX tags are case-sensitive, which is why it gives you are warning from eslint
<input
placeholder="Name"
type="text"
onChange={event => setName(event.target.value)}
value={name}
required
/>
it is <input> tag with small i.
Use <input /> instead of <Input />, as JSX attributes are case-sensitive