How can I send data after Preview in React JS with axios? - reactjs

I trying to create multiple send data button. Button work fine in last step display Preview and user send data. In last step data isn't in form body. How can I send this data after submit user?
function ShowOrNot(props) {
const [showForm, setShowForm] = useState(false);
const [showPreview, setShowPreview] = useState(false);
const [formHidden, setFormHidden] = useState(false);
const [inputs , setInputs] = useState({
videoTitle: "",
videoCategory: "",
videoSummary: "",
videoText: "",
coverVideo: null,
videoPoster: null,
file: null,
})
const sendForm = (e) => {
e.preventDefault();
const formData = new FormData(e.target);
formData.append("filename",videoData);
formData.append("videoPoster", posterData);
formData.append("coverVideo", imgData);
formData.append("videoSummary", inputs?.videoSummary);
formData.append("videoText", inputs?.videoText);
formData.append("videoTitle", inputs?.videoTitle);
formData.append("videoCategory", inputs?.videoCategory);
const config = {
headers: {
"content-type": "multipart/form-data",
email: props.user.email,
},
};
axios
.post(
"http://localhost:5000/api/momayezi/uploadFiles/upload",
formData,
config
)
.then((response) => {
alert("The file is successfully uploaded");
})
.catch((error) => {
console.log(error);
});
}
const onChange = ({ target }) => {
const value = target?.value;
const name = target?.name;
setInputs({
...inputs,
[name] : value
});
};
const [picture, setPicture] = useState(null);
const [imgData, setImgData] = useState(null);
const onChangePicture = e => {
if (e.target.files[0]) {
setPicture(e.target.files[0]);
const reader = new FileReader();
reader.addEventListener("load", () => {
setImgData(reader.result);
});
reader.readAsDataURL(e.target.files[0]);
}
};
const [poster, setPoster] = useState(null);
const [posterData, setPosterData] = useState(null);
const onChangePoster = e => {
if (e.target.files[0]) {
setPoster(e.target.files[0]);
const reader = new FileReader();
reader.addEventListener("load", () => {
setPosterData(reader.result);
});
reader.readAsDataURL(e.target.files[0]);
}
};
const [video, setVideo] = useState(null);
const [videoData, setVideoData] = useState(null);
const onChangeVideo = e => {
if (e.target.files[0]) {
setVideo(e.target.files[0]);
const reader = new FileReader();
reader.addEventListener("load", () => {
setVideoData(reader.result);
});
reader.readAsDataURL(e.target.files[0]);
}
};
return (
<div className="col-12">
{!showForm ? (
<ShowFormButton onClick={() => setShowForm(true)}/>
) : undefined}
{showForm ? (
<div className={''} id="scrollbar-style">
<div>
<HideFormButton
onClick={() => {
setShowForm(false);
}}
/>
</div>
{!formHidden ?
<form
onSubmit={ (e) => e.preventDefault()}
className={'mt-3 content-send-form-data register-teacher-inputs-box '}>
<Row>
<div className={'col-lg-6 col-12 mt-4'}>
<label htmlFor={'videoTitle'} className={' text-right'}>
<span>*</span>
</label>
<input
type="text"
className="form-control"
placeholder={'videoTitle'}
name={'videoTitle'}
required="true"
onChange={onChange}
onBlur={(e) => (e.target.placeholder = 'videoTitle')}
onFocus={(e) => (e.target.placeholder = '')}
/>
</div>
<div className={'col-lg-6 col-12 mt-4'}>
<label htmlFor={'videoCategory'} className={' text-right'}>
<span>*</span>
</label>
<input
type="text"
className="form-control"
placeholder={'دvideoCategory'}
name={'videoCategory'}
onChange={onChange}
required="true"
onBlur={(e) => (e.target.placeholder = 'videoCategory')}
onFocus={(e) => (e.target.placeholder = '')}
/>
</div>
</Row>
<Row>
<div className="col-12 mt-3">
<label htmlFor={'name'} className={'label-full-size text-right'}>
<span>*</span>
</label>
<input
type="text"
className="form-control"
placeholder={'خلاصه videoSummary'}
name={'videoSummary'}
required="true"
onChange={onChange}
onBlur={(e) => (e.target.placeholder = 'خلاصه videoSummary')}
onFocus={(e) => (e.target.placeholder = '')}
/>
</div>
</Row>
<Row>
<div className="col-12 mt-3">
<label
htmlFor={'name'}
className={'label-full-size text-right textarea-label'}
>
<span>*</span>
</label>
<textarea
className="video-text-form form-control"
placeholder={'متن videoText'}
name={'videoText'}
required="true"
onChange={onChange}
onBlur={(e) => (e.target.placeholder = 'متن videoText')}
onFocus={(e) => (e.target.placeholder = '')}
/>
</div>
</Row>
<Row>
<div className="col-12 mt-3 video-upload-input-btn">
<div className="register_wrapper">
<div className="register_player_column_layout_one">
<div className="register_player_Twocolumn_layout_two">
<form className="myForm">
<div className="formInstructionsDiv formElement">
<p className="instructionsText" />
<div className="register_profile_image">
<input
accept={"video/*"}
id="videoTeacher"
type="file"
onChange={onChangeVideo}
name={"filename"}
/>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</Row>
<Row>
<div className="col-lg-6 col-12 mt-3">
<div className="register_wrapper">
<div className="register_player_column_layout_one">
<div className="register_player_Twocolumn_layout_two">
<form className="myForm">
<div className="formInstructionsDiv formElement">
<p className="instructionsText" />
<div className="register_profile_image">
<input name={"videoPoster"} accept={"image/*"} id="posterPicture" type="file" onChange={onChangePoster} />
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div className="col-lg-6 col-12 mt-3">
<div className="register_wrapper">
<div className="register_player_column_layout_one">
<div className="register_player_Twocolumn_layout_two">
<form className="myForm">
<div className="formInstructionsDiv formElement">
<p className="instructionsText" />
<div className="register_profile_image">
<input
name={"coverVideo"}
accept={"image/*"}
id="profilePic"
type="file"
onChange={onChangePicture}
/>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</Row>
</form>
</div>
: undefined}
{!showPreview ? (
<ShowPreviewButton
onClick={() => {
setShowPreview(true);
setFormHidden(true);
}}
/>
) : undefined}
{showPreview ? (
<div className={"preview-send-wrapper"}>
<form onSubmit={(e) => sendForm(e)}
<div className={"mt-5 preview-send-cover"}>
<img className="playerProfilePic_home_tile" src={imgData} />
</div>
<div className={"preview-send-video-poster"}>
<video poster={posterData} controls>
<source src={videoData}/>
</video>
<h1 className={"mt-4"}>
{inputs?.videoTitle}
<span className={"mr-4"}><p>{inputs?.videoCategory}</p></span>
</h1>
<h4 className={"mt-3"}>
{inputs?.videoSummary}
</h4>
</div>
<div className={"preview-send-summary-video"}>
<p>
{inputs?.videoText}
</p>
</div>
<Row>
<div className={"col-lg-8 col-12"}>
<button onSubmit={sendForm} type={"submit"} className={"send-video-btn-final"}>
Send
</button>
</div>
<div className={"col-lg-4 col-12"}>
<SendButton
onClick={() => {
setFormHidden(false);
setShowPreview(false);
setShowForm(true);
}}
/>
</div>
</Row>
</form>
</div>
) : undefined}
</div>
) : undefined}
</div>
);
}
function SendButton({onClick}) {
return (
<div>
<button className="edit-send-video-btn" onClick={onClick}>
Edit
</button>
</div>
);
}
function ShowFormButton({onClick}) {
return (
<div>
<button className="upload-content-btn w-100" onClick={onClick}>
<span className="ml-2">
</span>Upload{' '}
</button>
</div>
);
}
function ShowPreviewButton({onClick}) {
return (
<div className={"row show-preview-button"}>
<div className="col-lg-8 col mt-3">
<button className="preview-send-data-btn" onClick={onClick}>
Preview
</button>
</div>
<div className="col-lg-4 col mt-3">
<button className="draft-send-data-btn">Draft</button>
</div>
</div>
);
}
function HideFormButton({onClick}) {
return (
<div className={'content-send-form-close-btn'}>
<button onClick={onClick} className={'close-modal-btn'}>
<span>Close</span>
</button>
</div>
);
}
ReactDOM.render(<ShowOrNot/>, document.getElementById('root'));
class UploadContentButton extends Component {
componentDidMount() {
store.dispatch(loadUser())
}
static propTypes = {
isAuthenticated : PropTypes.bool,
auth: PropTypes.object.isRequired,
logout: PropTypes.func.isRequired,
};
render() {
return (
<div className="mt-5">
<div className={"row"} id="show-button">
<ShowOrNot/>
</div>
</div>
);
}
}
const mapStateToProps = (state) => ({
setPass: state.auth.setPass,
isAuthenticated: state.auth.isAuthenticated,
error: state.error,
auth: state.auth,
user: state.auth.user,
});
export default connect(mapStateToProps, {loadUser}) (UploadContentButton)
<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>
After create Preview section I test endpoint and it's work fine, Now when submit Send button no response back to me.
How to when submit Send button data Posted to server?

Either put your data in local storage or use state management.
for state management react-redux is a package which you can install by below command.
npm i react-redux

Related

How to Store Choose File Image to Local Storage with React Hooks

I am building a profile page but i have some problems with storing the profile image to browser local storage. I choose the file from my device and upload it. but when i refresh the page, it s gone.
below is my code below and also a visual of the page. the local storage function works for everything in the page except for the image. what is the problem here ?
If you can help i will be so glad.
useLocalStorage.js
import React from "react"
import { useState, useEffect } from "react";
function getStorageValue(key, defaultValue) {
// getting stored value
const saved = localStorage.getItem(key);
const initial = JSON.parse(saved);
return initial || defaultValue;
}
export const useLocalStorage = (key, defaultValue) => {
const [value, setValue] = useState(() => {
return getStorageValue(key, defaultValue);
});
useEffect(() => {
// storing input name
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
};
formikData.js
import * as Yup from "yup";
const initialValues = {
fullname: "",
email: "",
phone: "",
bio: "",
city: "",
state: "",
street: "",
zip: "",
};
const yupValidation = {
phone: Yup.number().required("Phone is Required"),
bio: Yup.string().required("Bio is Required"),
city: Yup.string().required("City is Required"),
state: Yup.string().required("State is Required"),
street: Yup.string().required("Street is Required"),
};
export { initialValues, yupValidation };
PersonalDetails.js
import React, { useState, useEffect } from "react";
import { Col, Row, Container, Alert } from "react-bootstrap";
import poodle from "../../images/poodle.jpg";
import { Formik, Field, Form, ErrorMessage } from "formik";
import { initialValues, yupValidation } from "./formikData";
import * as Yup from "yup";
import cities from "../../data/cities";
import "./PersonalDetails.css";
import { useSelector } from "react-redux";
import { db } from "../../firebase";
import { useLocalStorage } from "./useLocalStorage";
import { useTranslation } from "react-i18next";
const PersonalDetails = () => {
const user = useSelector((state) => state.user);
const [fullname, setFullname] = useLocalStorage("fullname", "");
const [email, setEmail] = useLocalStorage("email", "");
const [bio, setBio] = useLocalStorage("bio", "")
const [phone, setPhone] = useLocalStorage("phone", "");
const [city, setCity] = useLocalStorage("city", "");
const [state, setState] = useLocalStorage("state", "");
const [street, setStreet] = useLocalStorage("street", "");
const [zip, setZip] = useLocalStorage("zip", "");
const [alertShown, isAlertShown] = useState(false);
const [picture, setPicture] = useLocalStorage("picture", poodle);
const onChangePicture = e => {
setPicture(URL.createObjectURL(e.target.files[0]));
};
const clearInfo = () => {
setBio("")
setPhone("")
setCity("")
setState("")
setStreet("")
setZip("")
setPicture("");
}
const fetchUserName = async () => {
try {
const query = await db
.collection("profile")
.where("uid", "==", user.uid)
.get();
const data = await query.docs[0].data();
setFullname(data.name);
setEmail(data.email);
} catch (err) {
console.error(err);
alert("An error occured while loading user data");
}
};
useEffect(() => {
if(user) fetchUserName();
}, [user]);
const { t } = useTranslation();
return (
<Container fluid className="mainContainer profile">
<Container className="pt-3 pb-4">
<Row>
<Col lg="4" md="12">
<div class="bgWhite fullHeight">
<img
src={picture}
alt=""
width="120"
height="120"
className="align-items-center mb-4 avatar"
/>
<input className="mb-5" id="profilePic" type="file" onChange={onChangePicture} />
<h5 className="mb-2 text-uppercase newColor">
{fullname}
</h5>
<p className="newColor">
{email}
</p>
<p className="profileInfo">
Tel: {''}
<span>{phone}</span>
</p>
<p className="profileInfo">
{t("personalPage.sideText0")} : {''}
<span>{city}</span>
</p>
<p className="profileInfo">
{t("personalPage.sideText1")} : {''}
<span>{state}</span>
</p>
<p className="profileInfo">
{t("personalPage.sideText2")} : {''}
<span>{street}</span>
</p>
<p className="profileInfo">
{t("personalPage.sideText3")} : {''}
<span>{zip}</span>
</p>
{bio && (
<h4 className="mb-2 mt-4 newColor">About</h4>
)}
<p className="profileInfo">
Bio: {''}
<span>{bio}</span>
</p>
</div>
</Col>
<Col lg="8" md="12" className="mt-lg-0 mt-5 formSection">
<div className="bgWhite personelInfo" align="left">
{alertShown && (
<Alert variant="success">{t("personalPage.alert0")}</Alert>
)}
<Formik
initialValues={initialValues}
validationSchema={Yup.object(yupValidation)}
onSubmit={(values, { setSubmitting }) => {
isAlertShown(true);
setFullname(values.fullname)
setEmail(values.email);
setBio(values.bio)
setPhone(values.phone)
setCity(values.city)
setState(values.state)
setStreet(values.street)
setZip(values.zip)
}}
>
{(props) => {
const { values } = props;
return (
<>
<Form>
<h3 className="newColor">{t("personalPage.title0")}</h3>
<div className="row d-flex justify-content-around mt-4">
</div>
<div className="row d-flex justify-content-around mt-4">
<div>
<Field
placeholder={t("personalPage.placeholder2")}
type="tel"
name="phone"
className="shadow inputStyle"
/>
<div className="error">
<ErrorMessage name="phone" />
</div>
</div>
<div>
<Field
placeholder={t("personalPage.placeholder3")}
name="bio"
as="textarea"
className="shadow inputStyle"
/>
<div className="error">
<ErrorMessage name="bio" />
</div>
</div>
</div>
<div className="mt-4">
<h3 className="newColor">{t("personalPage.title1")}</h3>
<div className="row d-flex justify-content-around mt-4 ">
<div>
<Field
component="select"
id="city"
name="city"
multiple={false}
className="shadow inputStyle"
>
<option value="">{t("personalPage.dropdown")}</option>
{cities.map((city) => {
return (
<option name="city">{city.name}</option>
);
})}
</Field>
<div className="error">
<ErrorMessage name="city" />
</div>
</div>
<div>
<Field
placeholder={t("personalPage.placeholder5")}
type="text"
name="state"
className="shadow inputStyle"
/>
<div className="error">
<ErrorMessage name="state" />
</div>
</div>
</div>
<div className="row d-flex justify-content-around mt-4 ">
<div>
<Field
placeholder={t("personalPage.placeholder6")}
type="text"
name="street"
className="shadow inputStyle"
/>
<div className="error">
<ErrorMessage name="street" />
</div>
</div>
<div>
<Field
placeholder={t("personalPage.placeholder7")}
type="text"
name="zip"
className="shadow inputStyle"
/>
<div className="error">
<ErrorMessage name="zip" />
</div>
</div>
</div>
<div className="row d-flex mt-5 justify-content-center">
<button
className="m-2 button"
type="submit"
>
{t("personalPage.button0")}{" "}
</button>
<button
className="m-2 button cancelBtn"
onClick={clearInfo}
type="button"
>
{t("personalPage.button1")}{" "}
</button>
</div>
</div>
</Form>
</>
);
}}
</Formik>
</div>
</Col>
</Row>
</Container>
</Container>
);
};
export default PersonalDetails;

Filter fetch data react

Why filter by search work but by drop-down list not?
I don't know why this is so, maybe someone sees some error.
I would like to filter tags using checkboxes. It was hard for me to find a tutorial on the internet, I was able to find filtering by searching. It turned out that everything was set up successfully, then I wanted to set filtering by list, but here I have a problem. I don't know why the list search doesn't work - even though it seems to work on the console.
demo here:
https://codesandbox.io/s/adoring-wu-rt4wd?file=/src/styles.css
const [filterParam, setFilterParam] = useState(['All'])
const [q, setQ] = useState('')
const [searchParam] = useState(['tags'])
function search(data) {
return data.filter((item) => {
if (item.tags == filterParam) {
return searchParam.some((newItem) => {
return (
item[newItem].toString().toLowerCase().indexOf(q.toLowerCase()) > -1
)
})
} else if (filterParam == 'All') {
return searchParam.some((newItem) => {
return (
item[newItem].toString().toLowerCase().indexOf(q.toLowerCase()) > -1
)
})
}
})
}
return (
<>
<div>
<label htmlFor='search-form'>
<input
type='search'
name='search-form'
id='search-form'
className='search-input'
placeholder='Search for...'
value={q}
onChange={(e) => setQ(e.target.value)}
/>
<span className='sr-only'>Search countries here</span>
</label>
</div>
<div className='select'>
<select
onChange={(e) => {
setFilterParam(e.target.value)
// console.log(setFilterParam(e.target.value.toString()))
console.log(e.target.value.toString())
}}
aria-label='Filter Countries By Region'
>
<option value='All'>All</option>
<option value='accessibility'>accessibility</option>
<option value='javascript'>javascript</option>
<option value='css'>css</option>
<option value='advanced'>advanced</option>
<option value='svg'>svg</option>
</select>
</div>
<section className={styles.main}>
{search(data).map((item) => (
<div className={styles.card}>
<div>
<div className={styles.card__first}>
<div className={styles.card__name}>
<FaTwitter className={styles.card__icon} />
<span className={styles.card__author}>{item.authorId}</span>
</div>
<div className={styles.card__price}>
<p>{item.price}</p>
</div>
</div>
<div className={styles.card__title}>
<h1>{item.title}</h1>
</div>
<div>
<p className={styles.card__desc}>{item.description}</p>
</div>
</div>
<div className={styles.card__tags}>
{item.tags.map((t) => {
return (
<div className={styles.card__tag}>
<p>{t}</p>
</div>
)
})}
</div>
</div>
))}
</section>
</>
)
}
export default Page
You have to change a lot of things, you can try this example
import "./styles.css";
import { useState, useEffect } from "react";
import styles from "./App.module.css";
export default function App() {
const [data, setData] = useState([]);
const [filterParam, setFilterParam] = useState("All");
const [q, setQ] = useState("");
const [searchParam, setSearchParam] = useState([]);
const getData = () => {
fetch("data.json", {
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
})
.then(function (response) {
console.log(response);
return response.json();
})
.then(function (myJson) {
console.log(myJson);
setData(myJson);
});
};
useEffect(() => {
getData();
}, []);
function search(data) {
return data.filter(
(item) =>
(filterParam === "All" || item.tags.includes(filterParam)) &&
(searchParam.length === 0 ||
(searchParam.every((tag) => item.tags.includes(tag)) &&
JSON.stringify(item).toLowerCase().indexOf(q.toLowerCase()) > -1))
);
}
const inputChangedHandler = (event) => {
const value = event.target.value;
const index = searchParam.indexOf(value);
if (index > -1) {
const updatedParam = [...searchParam];
updatedParam.splice(index, 1);
setSearchParam(updatedParam);
} else {
setSearchParam([...searchParam, event.target.value]);
}
};
return (
<>
<div>
<label htmlFor="search-form">
<input
type="search"
name="search-form"
id="search-form"
className="search-input"
placeholder="Search for..."
value={q}
onChange={(e) => setQ(e.target.value)}
/>
<span className="sr-only">Search countries here</span>
</label>
</div>
<div className="select">
<select
onChange={(e) => {
setFilterParam(e.target.value);
// console.log(setFilterParam(e.target.value.toString()))
console.log(e.target.value.toString());
}}
aria-label="Filter Countries By Region"
>
<option value="All">All</option>
<option value="accessibility">accessibility</option>
<option value="javascript">javascript</option>
<option value="css">css</option>
<option value="advanced">advanced</option>
<option value="svg">svg</option>
</select>
</div>
<div>
<input
type="checkbox"
id="topping"
name="advanced"
value="advanced"
onChange={inputChangedHandler}
/>
advanced
</div>
<div>
<input
type="checkbox"
id="topping"
name="javascript"
value="javascript"
onChange={inputChangedHandler}
/>
javascript
</div>
<div>
<input
type="checkbox"
id="topping"
name="fundamentals"
value="fundamentals"
onChange={inputChangedHandler}
/>
fundamentals
</div>
<div>
<input
type="checkbox"
id="topping"
name="css"
value="css"
onChange={inputChangedHandler}
/>
css
</div>
<div>
<input
type="checkbox"
id="topping"
name="svg"
value="svg"
onChange={inputChangedHandler}
/>
svg
</div>
<div>
<input
type="checkbox"
id="topping"
name="accessibility"
value="accessibility"
onChange={inputChangedHandler}
/>
accessibility
</div>
<section className={styles.main}>
{search(data).map((item) => (
<div className={styles.card}>
<div>
<div className={styles.card__first}>
<div className={styles.card__name}>
<p className={styles.card__icon}>ICON</p>
<span className={styles.card__author}>{item.authorId}</span>
</div>
<div className={styles.card__price}>
<p>{item.price}</p>
</div>
</div>
<div className={styles.card__title}>
<h1>{item.title}</h1>
</div>
<div>
<p className={styles.card__desc}>{item.description}</p>
</div>
</div>
<div className={styles.card__tags}>
{item.tags.map((t) => {
return (
<div className={styles.card__tag}>
<p>{t}</p>
</div>
);
})}
</div>
</div>
))}
</section>
{/* <Margins>
<Header data={data} />
<Main data={data} />
</Margins> */}
</>
);
}
enter link description here

React function Component Validation

I am a beginner in react. I was working on the react function component with forms using hooks. Can anyone please tell how can I apply validation on email text when it is invalid or empty, and disable the continue button if the form is not valid.
import React, { useState } from "react";
const ForgotPassowrd = () => {
const [emailId, setemailId] = useState("");
const forgotPasswordClick = (event) => {};
return (
<div>
<div className="NewPassword-form form_wrapper">
<div className="form-body">
<form action="#">
<div>
<div className="form-group">
<label htmlFor="password">Email-Id</label>
<div className="input-group">
<input type="text" className="form-control" value={emailId} onChange={(event)=>
setemailId(event.target.value)}/>
</div>
</div>
<button type="button" onClick={forgotPasswordClick} className="btn btn-lg
btn-block">Continue</button>
</div>
</form>
</div>
</div>
</div>
);
};
export default ForgotPassowrd;
**Try it.This may be helpfull for you! If you can any queries comment below.**
const LoginV2 = ({}) => {
// state
const [loginForm, setLoginForm] = useState({
email: undefined,
password: undefined,
emailValid: false,
passwordValid: false,
});
const [error, setError] = useState({ email: undefined, password: undefined });
// state update
const handleLoginForm = (e) => {
checkValidity(e.target.name, e.target.value);
setLoginForm({ ...loginForm, [e.target.name]: e.target.value });
};
// validation function
const checkValidity = (inputName, inputValue) => {
switch (inputName) {
case "email":
let pattern = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
loginForm.emailValid = pattern.test(inputValue);
break;
case "password":
loginForm.passwordValid = inputValue.length >= 6;
break;
default:
break;
}
};
// form submit
const onSubmitLoginForm = () => {
console.log(loginForm);
if (!loginForm.emailValid) {
setError(prevError => {
return {
...prevError,
email: "Invalid Email Address"
}
});
}
if (!loginForm.passwordValid) {
setError(prevError => {
return {
...prevError,
password: "Password must be at least six characters long"
}
});
}
return (
<div class="row">
<div class="form">
<div class="col span-1-of-2">
<div class="username">
<p class="login-para text-align-center">LOG IN VIA EMAIL</p>
<form method="post" action="#" class="login-form">
{error.email && (
<div class="alert alert-danger">
<p>
{" "}
<strong> {alertText} </strong> {error.email}
</p>
</div>
)}
{error.password && (
<div class="alert alert-danger">
<p>
{" "}
<strong> {alertText} </strong> {error.password}
</p>
</div>
)}
<div class="info-box">
{icon && <i class="fas fa-user-alt login-icon"></i>}
<input
type="text"
name="email"
placeholder="Your Email"
onChangeText={(e) => handleLoginForm(e)}
inputValue={loginForm.email}
/>
</div>
<div class="info-box">
{icon && <i class="fas fa-user-alt login-icon"></i>}
<input
type="password"
name="password"
placeholder="Your Password"
onChangeText={(e) => handleLoginForm(e)}
inputValue={loginForm.password}
/>
</div>
<div class="buttons">
<input type="checkbox" />
<label class="remember" for="#">
Remember me
</label>
<div class="form-btn-disabled" onClick={onSubmitLoginForm}
>
LOGIN NOW
</div>
</div>
</form>
</div>
</div>
</div>
</div>
);
};
export default LoginV2;
Try below. I have added inline comments for better understanding. Comment your queries if you have any.
// Regex to check valid email
const validEmail = /^[\w-\.]+#([\w-]+\.)+[\w-]{2,4}$/g
import React, { useState } from "react";
const ForgotPassowrd = () => {
const [emailId, setemailId] = useState("");
//State to disable/enable continue button
const [disableBtn, setDisableBtn] = useState(false);
const forgotPasswordClick = (event) => {};
const handleSubmit = e => {
e.preventDefault();
// Do whatever you want to do after you click submit button
}
const handleChange = e => {
setemailId(event.target.value);
setDisableBtn(validEmail.test(e.target.value));
}
return (
<div>
<div className="NewPassword-form form_wrapper">
<div className="form-body">
{/* Remove action and use onSubmit handler*/}
<form onSubmit={handleSubmit}>
<div>
<div className="form-group">
<label htmlFor="password">Email-Id</label>
<div className="input-group">
{/* Introduced name attribute to help you with handleSubmit handler*/}
<input name="email" type="text" className="form-control" value={emailId} onChange={(event)=>
setemailId(event.target.value)}/>
</div>
</div>
<button onClick={forgotPasswordClick} className="btn btn-lg
btn-block" disabled={disableBtn}>Continue</button>
</div>
</form>
</div>
</div>
</div>
);
};
export default ForgotPassowrd;

Uncaught DOMException: This input element accepts a filename, which may only be programmatically set to the empty string

I already upload and get the list of product successful but Update product show for me an error. I do not know how to update my image and data on Firebase in Reactjs.
This is my code in ProductForm.js
import React, { useState, useEffect } from 'react';
import Gongcha from '../asses/gongcha.jpg'
const ProductForm = (props) => {
const initialFieldValues = {
image: '',
name: '',
category: '',
price: ''
};
var [values, setValues] = useState(initialFieldValues);
var [imageFile, setImageAsFile] = useState();
useEffect(() => {
if (props.currentId == '') setValues({ ...initialFieldValues });
else
setValues({
...props.productObjects[props.currentId],
});
}, [props.currentId, props.productObjects]);
const handleInputChange = (e) => {
var { name, value } = e.target;
setValues({
...values,
[name]: value,
});
};
const handleFormSubmit = (e) => {
e.preventDefault();
props.addOrEdit(values, imageFile);
};
const handleImageAsFile = (e) => {
console.log("file image",e);
const image = e.target.files[0]
setImageAsFile(imageFile => (image))
}
return (
<form autoComplete="off" onSubmit={handleFormSubmit}>
<div className="form-group input-group">
<div className="input-group-prepend">
<div className="input-group-text">
<i className="fas fa-image"></i>
</div>
</div>
<input
className="form-control"
type="file"
name="image"
placeholder="Image"
value={values.image}
onChange={handleImageAsFile}
/>
</div>
<div className="form-row">
<div className="form-group input-group col-md-6">
<div className="input-group-prepend">
<div className="input-group-text">
<i className="fas fa-mug-hot"></i>
</div>
</div>
<input
className="form-control"
name="name"
placeholder="Name"
value={values.name}
onChange={handleInputChange}
/>
</div>
<div className="form-group input-group col-md-6">
<div className="input-group-prepend">
<div className="input-group-text">
<i className="fas fa-list-alt"></i>
</div>
</div>
<input
className="form-control"
name="category"
placeholder="Category"
value={values.category}
onChange={handleInputChange}
/>
</div>
</div>
<div className="form-group input-group">
<div className="input-group-prepend">
<div className="input-group-text">
<i className="fas fa-money-check-alt"></i>
</div>
</div>
<input
className="form-control"
name="price"
placeholder="Price"
value={values.price}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<input
type="submit"
value={props.currentId == '' ? 'Save' : 'Update'}
className="btn btn-primary btn-block"
/>
</div>
</form>
);
};
export default ProductForm;
And this is the table, which the place I showed all list of product and also Action (Edit and Delete)
import React, { useState, useEffect } from 'react';
import { Card, Button, Imgage } from 'react-bootstrap'
import ProductForm from './ProductForm';
import { DB, Storage } from '../firebase';
const Products = () => {
var [currentId, setCurrentId] = useState('');
var [productObjects, setProductObjects] = useState({});
const [ImageAsUrl, setImageAsUrl] = useState()
useEffect(() => {
DB.ref().child('products').on('value', (snapshot) => {
if (snapshot.val() != null) {
setProductObjects({
...snapshot.val(),
});
}
});
}, []);
const addOrEdit = (obj, image_url) => {
let upload = Storage.ref().child(`product-img/${image_url.name}`).put(image_url)
upload.on('state_changed',
(snapShot) => {
console.log(snapShot)
}, (err) => {
console.log(err)
}, () => {
Storage.ref('product-img').child(image_url.name).getDownloadURL()
.then(fireBaseUrl => {
DB.ref().child('products').push({ name: obj.name, image: fireBaseUrl, category: obj.category, price: obj.price }, (err) => {
if (err) console.log(err);
else setCurrentId('');
})
})
})
console.log("log imgage link", ImageAsUrl);
};
const onDelete = (id) => {
if (window.confirm('Are you sure to delete this record?')) {
DB.ref().child(`products/${id}`).remove((err) => {
if (err) console.log(err);
else setCurrentId('');
});
}
};
return (
<>
<div className="jumbotron jumbotron-fluid">
<div className="container">
<h1 className="display-4 text-center">Products Manager</h1>
</div>
</div>
<div className="row">
<div className="col-md-5">
<ProductForm {...{ currentId, productObjects, addOrEdit }} />
</div>
<div className="col-md-7">
<table className="table table-borderless table-stripped">
<thead className="thead-light">
<tr>
<th>Image</th>
<th>Name</th>
<th>Category</th>
<th>Price</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{Object.keys(productObjects).map((key) => (
<tr key={key}>
<td>{productObjects[key].image}</td>
<td>{productObjects[key].name}</td>
<td>{productObjects[key].category}</td>
<td>{productObjects[key].price}</td>
<td className="bg-light">
<a
type="button"
className="btn text-primary"
onClick={() => {
setCurrentId(key);
}}
>
<i className="fas fa-pencil-alt"></i>
</a>
<a
type="button"
className="btn text-danger"
onClick={() => {
onDelete(key);
}}
>
<i className="far fa-trash-alt"></i>
</a>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</>
);
};
export default Products;
This is an Error show for me when I clicked Update icon:
Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.
Can anyone help me with this problem? I really do not know how to fix it. Please? Your help is my pleasure
As the error explains, you can not set a value property on an input / file element. Short example:
<input type="file" value="this throws an error" />
That means, you can not "pre-populate" the input field if the user already uploaded a file. You could show the file (if it's an image) and add a delete option (e.g button) next to it.

how to append formdata of array of objects having image file and title

I have a state of images array in which there are multiple objects like below
[ {title:'' , image:''} , {title:'' , image:''} ]
But I can't pass it in JSON format to the server for that I have to convert it into FormData.
How can I do that.. I have tried it with just simple array of images which was working but with an object having title and image it is not working for me.
sample:
https://codesandbox.io/s/wizardly-engelbart-4rt6m?file=/src/App.js
I am using multer on the server-side for image capturing & storing.
export default function AddCity() {
const [images, setimages] = useState([{ title: "", image: "" }]);
const handleImages = (e, index) => {
const { name, value } = e.target;
const list = [...images];
list[index][name] = value;
setimages(list);
};
const AddImages = () => {
setimages([...images, { title: "", contact: "" }]);
};
const RemoveImages = index => {
const list = [...images];
list.splice(index, 1);
setimages(list);
};
//handle Submit
const handleSubmit = async e => {
e.preventDefault();
var formdata = new FormData();
for(let i=0 ; i<images.length ;i++){
////formdata.append('Images', images[i].image , images[i].image.name )
}
const url = process.env.REACT_APP_API_HOST;
axios
.post(`${url}/city/create`, formdata, {
headers: {
"Content-Type": "multipart/form-data"
}
})
.then(res => {
console.log(res);
})
.catch(error => {
console.log(error);
});
};
return (
<div className="App">
<form className="container mt-5">
<div className="form-group row ">
<label htmlFor="rating" className="col-sm-2 col-form-label text-left">
Images
</label>
<div className="col-auto">
{images.map((item, i) => {
return (
<div className="input-group mb-3">
<input
type="text"
name="title"
value={item.title}
placeholder="Title"
onChange={e => handleImages(e, i)}
className="form-control"
aria-label="Text input with segmented dropdown button"
/>
<div className="input-group-append">
<input
type="file"
className="form-control-file mt-2 ml-1"
id="images"
onChange={e => handleImages(e, i)}
/>
{images.length - 1 === i && (
<button
type="button"
className="btn btn-outline-info"
onClick={AddImages}
>
Add
</button>
)}
{images.length !== 1 && (
<button
type="button"
className="btn btn-outline-danger"
onClick={() => RemoveImages(i, images)}
>
Remove
</button>
)}
<br />
<br />
<br />
</div>
</div>
);
})}
</div>
</div>
<br />
<br />
<button
type="submit"
onClick={handleSubmit}
className="btn btn-primary form-group"
>
Submit
</button>
</form>
</div>
);
}
This should work
var formdata = new FormData();
images.map(image => {
formdata.append(image.title, image.image)
)}

Resources