How can I submit the form? - javascript

I am currently making a blog website with "reactjs".In this component, I am creating new blogs by putting values of author, title, and body. I cant submit the form by hitting 'Enter' on the keyboard on any fields.
This problem gets fixed when I remove my input field of author. Please guide me as I am new to Reactjs
import React, { useState } from "react";
function Create() {
const [title, setTitle] = useState();
const [author, setAuthor] = useState();
const [body, setBody] = useState();
const submitFunc = (e) => {
e.preventDefault();
const blog = { title, body, author };
};
return (
<div className="create container ">
<form onSubmit={submitFunc}>
<label className="text-danger" htmlFor="title">
Title:
</label>
<input
name="title"
type="text"
onChange={(e) => setTitle(e.target.value)}
required
/>
<label className="text-danger" htmlFor="body">
Content:
</label>
<textarea
onChange={(e) => setBody(e.target.value)}
required
name="body"
></textarea>
<label className="text-danger" htmlFor="author">
Author:
</label>
<input
name="author"
id="author"
type="text"
onChange={(e) => setAuthor(e.target.value)}
required
/>
</form>
<p>{title}</p>
<p>{author}</p>
<p>{body}</p>
</div>
);
}
export default Create;

From the snippet you reported it is not clear how it should handle the Enter pressing.
If you want to do anything when the user presses Enter on any text area you can use the onKeyPress event handler.
const handleKeyPress = (e) => {
if(e.keyCode === 13){
e.preventDefault();
// ...check title, boby and author exists
const blog = { title, body, author };
// ...submit the form
};
<textarea
name="body"
required
onChange={(e) => setBody(e.target.value)}
onKeyPress={handleKeyPress}
></textarea>

Related

How to make a form with just one input tag but multiple input fields with the use of map, keys and id

I created a form using this code using useState. But the issue is i want to make a code with lesser line and i want to create it with the use of keys and ids that uses only one single input tag in the code instead of multiple input tags. the code is mentioned below:
import './App.css';
import { useState } from "react";
function App() {
const [inputFields, setInputFields] = useState([
{
name:'',
email:'',
username:'',
password:'',
confirm:'',
mobile:''
}
])
const handelFormChange = (index, event) => {
let data = [...inputFields]
data[index][event.target.name] = event.target.value;
setInputFields(data);
}
const submit = (e) => {
e.preventDefault();
console.log(inputFields)
}
return (
<div className="App">
<form className="bg-light" onSubmit={submit}>
{/* <div className="form-group"> */}
{inputFields.map((input, index) => {
return(
<div key={index} className="form-group">
<label className="font-weight-regular"> Name </label>
<input type="name" name='name' required value={input.name} onChange={event => handelFormChange(index,event)}></input>
<label className="font-weight-regular"> Email </label>
<input type="text" name='email' required value={input.email} onChange={event => handelFormChange(index,event)}></input>
<label className="font-weight-regular"> Username </label>
<input type="text" name='username' required value={input.username} onChange={event => handelFormChange(index,event)}></input>
<label className="font-weight-regular"> Password </label>
<input type="password" name='password' required value={input.password} onChange={event => handelFormChange(index,event)}></input>
<label className="font-weight-regular"> Confirm Password </label>
<input type="password" name='confirm' required value={input.confirm} onChange={event => handelFormChange(index,event)}></input>
<label className="font-weight-regular"> Mobile Number </label>
<input type="text" name='mobile' required value={input.mobile} onChange={event => handelFormChange(index,event)}></input>
</div>
)
})}
<button onClick={submit}>Submit</button>
</form>
</div>
)
}
export default App;
So i tried to mention the make a form and i am a fresher in this field so i dont know how to make a form with single input field but i have the requirement of this code
It's possible to use a single input field to create a form with multiple inputs by using the 'name' attribute on the input field. The name attribute allows you to identify which input field the data is coming from when the form is submitted.

Clicking on switch does not change state the first time only if it's checked already

I'm a newbie in React and just started to develop an admin panel on local to practice what I have learned and I have come across this problem and after searching for a long while and being unable to solve it I'm this close to step on kittens and innocent children ...
so here's the situation:
I have a panel for registering some products, say, Shoes and on my Dashboard page of admin panel I have my products listed and I can click on edit on any of them to redirect to edit page and change the info like name, price, image etc.
Up to this point everything works as intended, the problem is I have a Switch Input which indicates if it's a featured product or not and when I land on the edit page it displays correctly if it's On or Off, now when I click on it to change its state, the first time I click nothing happens and it starts working after 2nd click onwards.
I've done my research and came to know it has to do with using useEffect() and such and I've changed my code accordingly and now the real problem is when the switch is off when I land on edit page, on first click it works just fine and it changes to On and I can save it and it'll do as intended but if it's On by default when I land on the edit page, the first click won't work and it takes 2 click and more to change the state and it escapes me how it works fine when it's off and not both ways.
p.s it's my first time asking question here so I might have failed to express my problem clearly or properly enough so my apologies in advance.
Here's the code:
import {useEffect, useState} from "react";
import {useNavigate, useParams} from "react-router-dom";
import getOneProduct from "../../../Services/getOneProduct";
import {useProductsDispatch} from "../../../Context/productsContext";
import {toast} from "react-toastify";
function EditProductForm() {
const dispatch = useProductsDispatch()
const redirect = useNavigate()
const [product, setProduct] = useState({
name: '',
desc: '',
price: '',
offPrice: '',
image: '',
feat: null,
uid: '',
date: '',
})
const [switchVal, setSwitchVal] = useState(); // this is the state I use for the switch but would rather have it in the 'product' state above so they are all together
const switchHandler = (e) => { // the onChange function for the switch
const curVal = e.target.checked
setSwitchVal(curVal)
}
useEffect(() => { // the useEffect to reflect switch changes
setProduct({
...product,
feat: switchVal
})
console.log(switchVal)
}, [switchVal, setSwitchVal]);
const changeHandler = (e) => { // the input handler for all other inputs
setProduct({
...product,
[e.target.name]: e.target.value,
})
}
const editProductSubmit = (e) => { // form onSubmit
e.preventDefault()
dispatch({
type: 'EDIT_PRODUCT',
payload: {
productId,
product
}
})
redirect("/admin/dashboard")
}
const fetchedId = useParams()
const productId = fetchedId.id
useEffect(() => {
const fetchedProduct = async () => {
try {
const {data} = await getOneProduct(productId) // axios.get()
setProduct({
name: data.name,
desc: data.desc,
price: data.price,
offPrice: data.offPrice,
image: data.image,
feat: data.feat,
uid: data.uid,
date: data.date,
})
} catch (error) {
console.log(error)
}
}
fetchedProduct()
}, [productId])
return (
<div>
<form className="add-product-form" onSubmit={editProductSubmit}>
<div className="form-floating mb-3">
<input
defaultValue={product.name}
onChange={changeHandler}
type="text"
className="form-control"
id="productName"
name="name"
placeholder="نام محصول"
/>
<label className="form-label" htmlFor="productName">نام محصول</label>
</div>
<div className="form-floating mb-3">
<textarea
defaultValue={product.desc}
onChange={changeHandler}
className="form-control"
id="productDesc"
name="desc"
placeholder="Leave a comment here"
style={{height: 200}}
/>
<label htmlFor="productDesc">توضیحات محصول</label>
</div>
<div className="form-floating mb-3">
<input
defaultValue={product.price}
onChange={changeHandler}
type="number"
className="form-control"
id="productPrice"
name="price"
placeholder="قیمت اصلی محصول"
/>
<label className="form-label" htmlFor="productPrice">قیمت اصلی محصول</label>
</div>
<div className="form-floating mb-3">
<input
defaultValue={product.offPrice}
onChange={changeHandler}
type="number"
className="form-control"
id="productOffPrice"
name="offPrice"
placeholder="قیمت با تخفیف محصول"
/>
<label className="form-label" htmlFor="productOffPrice">قیمت با تخفیف محصول</label>
</div>
<div className="form-floating mb-3">
<input
defaultValue={product.image}
onChange={changeHandler}
type="text"
className="form-control"
id="productImage"
name="image"
placeholder="لینک تصویر محصول"
/>
<label className="form-label" htmlFor="productImage">لینک تصویر محصول</label>
</div>
<div className="form-check form-switch form-check-reverse mb-3">
<input
onChange={switchHandler}
defaultChecked={product.feat}
value={switchVal}
type="checkbox"
className="form-check-input"
id="productFeat"
role="switch"
/> {/* This is the switch in question */}
<label className="form-check-label" htmlFor="productFeat">محصول ویژه است</label>
</div>
<div className="mb-3">
<button type="submit" className="btn btn-success">ویرایش محصول</button>
</div>
</form>
</div>
);
}
export default EditProductForm;
If you set const [switchVal, setSwitchVal] = useState(); to const [switchVal, setSwitchVal] = useState(false); it will have a starting value of false instead of undefined. Assuming the box has to be unchecked on rendering. Just change it to true if you need it to be true on render.

React form input values in JS

I am using NextJS with bulma CSS to create a simple application. I have this following form:
const MyPage = () => {
const [firstName, setFirstName] = useState('')
const [secondName, setSecondName] = useState('')
const updateFirstName = event => {
setFirstName(event.target.value)
}
const updateSecondName = event => {
setSecondName(event.target.value)
}
const createUser = async() => {
// Todo: perform some action with firstName and secondName
}
return (
<section className='mt-5'>
<div className='container'>
<div className='field'>
<label className='label'>My Form</label>
<div className='control'>
<input onChange={updateFirstName} className='input' type='type' placeholder='Enter First Name'></input>
</div>
</div>
<div className='field'>
<div className='control'>
<input onChange={updateSecondName} className='input' type='type' placeholder='Enter Second Name'></input>
</div>
</div>
<button onClick={createUser} className='button is-primary'>Create</button>
</div>
</section>
)
}
export default MyPage
I have to call updateFirstName and updateSecondName on every input change.
I want to get these input field's value on createUser() function call only. Please suggest how to do it or any other better approach. I want to eliminate firstName and secondName variables, and directly access entered input in the createUser() function.
If you don't want a controlled input. You can quit managing the state and access the value old way using plain vanilla JS.
Make sure to add name attribute with all the input fields.
function createUser() {
const inputs = document.querySelectorAll(".field input")
let data = {}
inputs.forEach(input => {
data[input.name] = input.value
})
/**
This would yield you
{
'firstname': 'value',
'secondName': 'value'
}
**/
}
Please change your input fields as shown below:
<input onChange={(e)=>createUser(e,'firstName')} className='input' type='type' placeholder='Enter First Name'></input>
<input onChange={(e)=>createUser(e,'lastName')} className='input' type='type' placeholder='Enter First Name'></input>
Then in your update your createUser function as shown below:
const createUser = (event, element) => {
if(element==='firstName') {
setFirstName(event.target.value)
}
if(element==='lastName') {
setLastName(event.target.value)
}
}
You can try alternatively with this useRef() hook,
const MyPage = () => {
const firstName = useRef();
const secondaName = useRef();
const createUser = async() => {
// Todo: perform some action with firstName and secondName
console.log(firstName.current.value, secondName.current.value) // It will prints the value that is typed by the user in both the textfields
}
return (
<section className='mt-5'>
<div className='container'>
<div className='field'>
<label className='label'>My Form</label>
<div className='control'>
<input ref={firstName} className='input' type='type' placeholder='Enter First Name'></input>
</div>
</div>
<div className='field'>
<div className='control'>
<input ref={secondName} className='input' type='type' placeholder='Enter Second Name'></input>
</div>
</div>
<button onClick={createUser} className='button is-primary'>Create</button>
</div>
</section>
)
}
export default MyPage
You can write a handler function
Firstly, you should add all variables to same state.
const [userInfo, setUserInfo] = useState({
firstName: "",
secondName: ""
});
and you should give a name to inputs like this.
<input
className="input"
onChange={onChangeHandler}
name="firstName" //name attribute must same your state variable
placeholder="Enter First Name"
/>
<input
className="input"
onChange={onChangeHandler}
name="secondName" //name attribute must same your state variable
placeholder="Enter Second Name"
/>
and your handler function should like this
const onChangeHandler = (e) =>
setUserInfo({ ...userInfo, [e.target.name]: e.target.value });
and this function take your input value and set your state who same name.
Full code
export default function App() {
const [userInfo, setUserInfo] = useState({
firstName: "",
secondName: ""
});
const onChangeHandler = (e) =>
setUserInfo({ ...userInfo, [e.target.name]: e.target.value });
const sendData = () => {
console.log(userInfo);
};
return (
<div className="App">
<section className="mt-5">
<div className="container">
<div className="field">
<label className="label">My Form</label>
<div className="control">
<input
className="input"
onChange={onChangeHandler}
name="firstName"
placeholder="Enter First Name"
/>
</div>
</div>
<div className="field">
<div className="control">
<input
className="input"
onChange={onChangeHandler}
name="secondName"
placeholder="Enter Second Name"
/>
</div>
</div>
<button onClick={sendData} className="button is-primary">
Create
</button>
</div>
</section>
</div>
);
}
https://codesandbox.io/s/gallant-pasteur-uglbri?file=/src/App.js:58-1264

Not able to submit the data to firebase from contact form

import React, { useState } from 'react'
import styled from 'styled-components'
import Title from '../Components/Title'
import { InnerLayout, MainLayout } from '../Styles/Layout'
import Button from '../Components/Button'
import { db } from '../firebase';
function Contact() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [message, setMessage] = useState("");
const [subject, setSubject] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
db.collection('mail').add({
name: name,
email: email,
subject: subject,
message: message,
})
.then(() => {
alert("Thank you for contacting. Your message has been sent successfully.");
})
.catch((err) => {
alert(err.message);
});
setName('')
setEmail('')
setSubject('')
setMessage('')
};
return (
<MainLayout>
<Title title={'Contact'} span={'Contact'} />
<ContactMain>
<InnerLayout className='contact-section'>
<div className="left-content">
<div className="contact-title">
<h4>Get In Touch</h4>
</div>
<form className="form" onSubmit={handleSubmit}>
<div className="form-field">
<label htmlFor="name">Enter Your Name</label>
<input type="text" id="name" value={name} onChange={(e) => setName(e.target.value)} />
</div>
<div className="form-field">
<label htmlFor="email">Enter Your Email</label>
<input type="email" id="email" value={email} onChange={(e) => setEmail(e.target.value)} />
</div>
<div className="form-field">
<label htmlFor="subject">Enter Your Subject</label>
<input type="text" id="subject" value={subject} onChange={(e) => setSubject(e.target.value)} />
</div>
<div className="form-field">
<label htmlFor="text-area">Enter Your Message</label>
<textarea name="textarea" id="textarea" cols="30" rows="10" value={message} onChange={(e) => setMessage(e.target.value)}></textarea>
</div>
<div className="form-field f-button">
<Button title="Send Email" />
</div>
</form>
</div>
</InnerLayout>
</ContactMain>
</MainLayout>
)
}
I don't know why but I am not able to send the details to my firebase database. I am not able to find the issue in this code. I have copied the firebase database key and all in the firebase.js and then imported it in this contact.js and I then made the necessary changes in this. Still, I am not able to figure out the issue.
I would reset the form once the promise returned by add() is resolved.
const handleSubmit = (e) => {
e.preventDefault();
db.collection('mail').add({
name: name,
email: email,
subject: subject,
message: message,
}).then(() => {
// Reset those states here
setName('')
setEmail('')
setSubject('')
setMessage('')
alert("Thank you for contacting. Your message has been sent successfully.");
}).catch((err) => {
alert(err.message);
});
};
I guess your states are being reset to "" before the document is added as those setState methods would have ran before the doc was added.
Potentially because your button html within its the button component type is not set to 'submit' - I had the same issue I think which ended up being super simple.

reactjs clear file input field after submit

I'm trying to delete my file input field data from e.target but i need the rest of the e.target data to send to emailjs.
The problem is when user uploads a file in my form, the file is most of the time bigger than 50kb and this is the limit for my account on emailjs.
I don't need to send my file to emailjs but i need it to just be stored in my database.
I have tried to clear the form field before sending it to emailjs
with fileUpload.current.value = ""; but the data is still actief in
e.target.
This is e.target Data. i need the data to stay in this way in e.target to send to emailjs
<form class="Grade_inputForm__1lbhQ" autocomplete="off">
<div class="Grade_input_container__3ztZk css-vurnku">
<input type="text" name="name" required="" class="Grade_input__22PTE" placeholder="Name*" maxlength="10">
</div>
<div class="Grade_input_container__3ztZk css-vurnku">
<input type="email" required="" name="email" class="Grade_input__22PTE" placeholder="Email*">
</div>
<div class="Grade_input_container__3ztZk css-vurnku">
<input type="text" name="Address" required="" class="Grade_input__22PTE" placeholder="Address*">
</div>
<div class="Grade_input_container__3ztZk css-vurnku">
<input type="tel" name="phone" class="Grade_input__22PTE" placeholder="Phone">
</div>
<div class="Grade_input_container__3ztZk css-vurnku">
<input type="file" class="Grade_input__22PTE" name="5349366.jpg">
</div>
<div class="Grade_textarea__YR0na css-vurnku">
<textarea name="cards" required="" class="Grade_input__22PTE">
</textarea>
</div>
<div class="Grade_textarea__YR0na css-vurnku">
<textarea name="message" class="Grade_input__22PTE" placeholder="Message">
</textarea>
</div>
<br>
<input type="submit" value="Send" class="Grade_btn__1QKUn">
</form>
how can i delete my file from e.target ?
import React, { useRef, useState } from "react";
import { jsx, Box } from "theme-ui";
import style from "../../style/Grade.module.css";
import { db, storage } from "../components/config/config";
import emailjs from "emailjs-com";
export default function GradeCards() {
const [file, setFile] = useState();
const name = useRef("");
const email = useRef("");
const Addres = useRef("");
const phone = useRef("");
const cards = useRef("");
const message = useRef("");
const fileUpload = useRef("");
const sendEmail = (e) => {
e.preventDefault();
//sending data to emailjs with e.target
emailjs
.sendForm(
"service account",
"template name",
e.target,
"user_id"
)
.then(
(result) => {
console.log(result.text);
},
(error) => {
console.log(error.text);
}
);
};
const sendDataToDb = (e) => {
// sendEmail(e);
e.preventDefault();
e.persist(); // this is test when i use sendEmail() in .then()
const formData = new FormData(e.target);
const obj = {};
for (let [key, value] of formData.entries()) {
obj[key] = value;
}
if (file !== null) {
storage
.ref(`/files/${Date.now() + "-" + file.name}`)
.put(file)
.then(() => console.log("Succes"));
}
//this don't help in deleting data from e.target
delete obj[file.name];
db.collection("collectionName")
.add(obj)
.then(() => {
fileUpload.current.value = "";
})
.then(() => {
//test if the data is deleted her.But its still actief in e.target
console.log(e.target);
sendEmail(e);
})
.then(() => {
name.current.value = "";
email.current.value = "";
Addres.current.value = "";
phone.current.value = "";
cards.current.value = "";
message.current.value = "";
console.log("done sending");
});
};
return (
<section>
<Box className={style.container}>
<Box className={style.form}>
<Box className={style.contact_form}>
<form
onSubmit={(e) => sendDataToDb(e)}
className={style.inputForm}
autoComplete="off"
>
<Box className={style.input_container}>
<input
ref={name}
type="text"
name="name"
required
className={style.input}
placeholder="Name*"
maxLength="10"
/>
</Box>
<Box className={style.input_container}>
<input
ref={email}
type="email"
required
name="email"
className={style.input}
placeholder="Email*"
/>
</Box>
<Box className={style.input_container}>
<input
ref={Addres}
type="text"
name="Address"
required
className={style.input}
placeholder="Address*"
/>
</Box>
<Box className={style.input_container}>
<input
ref={phone}
type="tel"
name="phone"
className={style.input}
placeholder="Phone"
/>
</Box>
<Box className={style.input_container}>
<input
ref={fileUpload}
type="file"
name={file?.name}
onChange={(e) => {
setFile(e.target.files[0]);
}}
className={style.input}
/>
</Box>
<Box className={(style.input_container, style.textarea)}>
<textarea
ref={cards}
name="cards"
required
className={style.input}
></textarea>
</Box>
<Box className={(style.input_container, style.textarea)}>
<textarea
ref={message}
name="message"
className={style.input}
placeholder="Message"
></textarea>
</Box>
<br />
<input type="submit" value="Send" className={style.btn} />
</form>
</Box>
</Box>
</Box>
</section>
);
}
I don't know how you can set it here, but in general, if you have an input of type file and with name let's say image2, then you can do the following:
e.target["image2"].value = [];
this will empty the input.
See this sandbox
If you comment out the previous line of code, it will display the full details of the chosen file.
If you have this line there, it will display the object as it was never assigned a file from your disk.

Categories

Resources