html2canvas does not show form's input properly - reactjs

I'm trying to use html2canvas in order to take a screenshot of a form. The code is working but the input does not display properly for me. It wouldn't be a problem but I need to read the text from the image itself.
const TransactionForm = () => {
const [canvasArray, setCanvasArray] = useState([])
const captureRef = useRef();
const getScreenshotHandler = () => {
html2canvas(captureRef.current).then(canvas =>
setCanvasArray(
[canvas.toDataURL()]
),
);
};
const renderCanvas = () => {
return canvasArray.map((canvas, i) => {
return <img key={i} src={canvas} alt="screenshot" />;
});
};
return(
<>
<form>
<div ref = {captureRef} className="to-capture">
<label>sender bank number</label>
<input type="text" />
<br />
<label>address bank number</label>
<input type="text"/>
<br />
<label>how much money to send</label>
<input type="number"/>
<br />
</div>
<Button fluid onClick={getScreenshotHandler}>
send
</Button>
</form>
{renderCanvas()}
);
}
[![the form looks like this](https://i.stack.imgur.com/zvCxU.png)](https://i.stack.imgur.com/zvCxU.png)
[![and the image looks like this](https://i.stack.imgur.com/P8anY.png)](https://i.stack.imgur.com/P8anY.png)

Related

how to get the data from a component within a form in react

I have a with the following structure in react...
<form>
<div>
<label>Name</label>
<input />
</div>
<div>
<label>Age</label>
<input />
</div>
<div>
<label>Gender</label>
<input />
</div>
<AddressComponent />
<button type='submit'>
Submit
</button>
</form>
Does anyone know if there is a way for me to pass the AddressComponent data up to the parent form component onSubmit? The AddressComponent has a lot of state to manage and a load of functions and it appears a few more times across my website and so I don't want to keep repeating the same code over and over again.
Anyone know if there's a way for me to pass the AddressComponent state up to the parent form component onSubmit?
you can use ref to get access to the child functions so:
const AddressComponent = ({}, ref) => {
const [data, setData] = useState();
useImperativeHandle(ref, () => ({
getData: getData,
}));
const getData = () => {
return data;
}
return <div></div>;
};
export default React.forwardRef(AddressComponent);
and you can get data in your parent and in submit like this:
const ParentComponent = () => {
const AddressRef = useRef(null);
const handleSubmit = (event) => {
event.preventDefault();
const data = AddressRef.current.getData();
}
return (
<form onSubmit={handleSubmit}>
<div>
<label>Name</label>
<input />
</div>
<div>
<label>Age</label>
<input />
</div>
<div>
<label>Gender</label>
<input />
</div>
<AddressComponent ref={AddressRef} />
<button type='submit'>
Submit
</button>
</form>
)
}

Get the clicked object and fill the inputs in ReactJS

What I want to achieve is to be able to get all the new data on the next object that is added, also be able to click on the printed divs and get that current object to edit. I've built something, but the key logic is missing.
Problems:
Show current input fields
Be able to switch to the div (objects) and get the values in the input so I can edit
import { useState, useEffect } from 'react';
export default function AddQuiz() {
const [current, setCurrent] = useState(1);
const [questions, setQuestions] = useState([]);
function add_question() {
const dumb = {
id: `${Math.floor(100000 + Math.random() * 900000)}`,
question: `${Math.random().toString(36).substr(2, 5)}`,
anwser1: `${Math.random().toString(36).substr(2, 5)}`,
anwser2: `${Math.random().toString(36).substr(2, 5)}`,
anwser3: `${Math.random().toString(36).substr(2, 5)}`,
anwser4: `${Math.random().toString(36).substr(2, 5)}`,
};
setQuestions([...questions, dumb]);
}
return (
<>
<pre>
{' '}
{questions.map((item) => (
<div>
question: {item.question} anwser1: {item.anwser1} anwser2: {item.anwser2} anwser3: {item.anwser3} anwser4:{' '}
{item.anwser4}
</div>
))}{' '}
</pre>
<button onClick={() => add_question()}>add dump question</button>
<br />
<br />
<hr />
{questions.length !== 0 ? (
<form>
<input type="text" value={questions[0].question} />
<input type="text" value={questions[0].anwser1} />
<input type="text" value={questions[0].anwser2} />
<input type="text" value={questions[0].anwser3} />
<input type="text" value={questions[0].anwser4} />
</form>
) : (
'please add some question'
)}
</>
);
}
You need to add onChange in your input field and use it properly.
Here I've created a codesandbox, that you're looking for. https://codesandbox.io/s/redux-shop-cart-forked-z891d?file=/src/App.js
how about this:
const [que1, setQue1] = useState("");
function add_question() {
const dumb = {
question: que1 ? que1 : Math.random().toString(36).substr(2, 5),
};
setQuestions([...questions, dumb]);
}
<input
type="text"
onChange={(e) => setQue1(e.target.value)}
defaultValue={questions[0].question}
/>
try:
example

The input value codes refused to work in react js

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>
);
}

Clear form after submit React

In my app, I am making a form to add animal for adoption with React. The data is stored in Mongo if this is important to know.
But I can not figure out how, I tried to look and nothing works for me. Maybe there is something wrong with the form. I would be very thankful if someone can tell me how to clear or reset the form after submitting. I simplified it so it would be easy to see what I have. Here is my form:
import React, { useState } from "react";
import { useDispatch } from "react-redux";
import { addAnimal } from "../redux/actions";
const AddAnimalForm = () => {
const dispatch = useDispatch();
const [name, setName] = useState("");
const [kind, setKind] = useState("");
const [displayForm, setDisplayForm] = useState(false);
const dispatchAddAnimal = () => {
dispatch(
addAnimal(
{
name,
kind
},
"_id name kind sex age city author phone info"
)
);
};
const onShowButtonClicked = () => {
setDisplayForm(true);
};
const onHideButtonClicked = () => {
setDisplayForm(false);
};
return !displayForm ? (
<button className="col-xs-12 col-md-3" onClick={onShowButtonClicked}>
add
</button>
) : (
<React.Fragment>
<div className="col-xs-12 col-sm-9">
<button className="col-xs-12 col-md-3" onClick={onHideButtonClicked}>
hide{" "}
</button>
<form>
<div className="form-row">
<div className="form-group col-md-6">
<label htmlFor="animal-name">name</label>
<input
type="text"
className="form-control"
onChange={e => setName(e.target.value)}
id="animal-name"
/>
</div>
<div className="form-group col-md-6">
<label htmlFor="kind">kind</label>
<input
type="text"
onChange={e => setKind(e.target.value)}
className="form-control"
id="kind"
/>
</div>
</div>
<button
type="button"
className="btn btn-primary"
onClick={dispatchAddAnimal}
>
add animal
</button>
</form>
</div>
</React.Fragment>
);
};
export default AddAnimalForm;
define a variable at the top just below you imports
let exampleRef = React.createRef()
hi first you have to create a reference to that form like this :-
<form ref={(el) => myFormRef = el;}>
<input />
<input />
...
<input />
</form>
and after that, while submitting your form you just use the reset() method provided by the form reference like this
const dispatchAddAnimal = () => {
myFormRef.reset();
dispatch(
addAnimal(
{
name,
kind
},
"_id name kind sex age city author phone info"
)
);
};
let me know if it works for you or not.
there is also a great library React Advanced Form which handle lots of thing on its own like validation and other stuff check this out if you feel free

How do I send multiple form inputs in a post request react

I'm trying to build an app like pinterest that takes an image, a title, and a description (as well as user info but im not there yet) and sends a post request from the NewImage.jsx page, allowing it to display on the Home.jsx page.
NewImage.jsx
return (
<div className="newimage-page">
<form>
<div className="placement">
<div className="alignRow">
<div className="addphoto">
<AddNew></AddNew>
</div>
<div className="info">
<SaveButton />
<div className="expandingArea">
<textarea wrap="soft"
placeholder="Add Your Title"
className="title"
rows="1"
maxchars="100"
></textarea>
<textarea placeholder="Description"
className="description"
rows="1"
maxchars="500"></textarea>
</div>
</div>
</div>
</div>
</form>
</div>
I am trying to get the value of both text areas, as well as the photo infomation from the AddNew component
AddNew.jsx
const AddNew = () => {
const [file, setFile] = useState('')
const handleChange = (event) => {
setFile(event.target.files[0]);
}
return (
<div className="addNew">
<div className="uploadstyle">
<img src={file ? URL.createObjectURL(file) : null} alt={file ? file.name : null} />
<input className="upload" type="file" onChange={handleChange} />
</div>
</div>
)
}
how can i make it so when i click the save button component (which currently does nothing) i can post the values of all these items at once?
Maintain the form form data in your main form.
Pass a handler for fileOnSelect to your AddNew component.
Make use of FormData
Working copy of your code is here. You can take it forward and enhance or tweak it to your needs
Main Form Component
export const Form = () => {
const [file, setFile] = useState(null);
const [title, setTitle] = useState('');
const [description, setDescription] = useState('');
const onSave = (e) => {
e.preventDefault();
const formData = new FormData();
formData.append('file', file);
formData.append('title', title);
formData.append('description', description);
console.log('formData', formData);
fetch('/url', {method: 'POST',body: formData}).then(response => console.log(response));
};
return (
<div className="newimage-page">
<form>
<div className="placement">
<div className="alignRow">
<div className="addphoto">
<AddNew onFileSelected={setFile}/>
</div>
<div className="info">
{/*<SaveButton onSave={onSave}/>*/}
<button onClick={onSave}>Save</button>
<div className="expandingArea">
<textarea wrap="soft"
// onChange={e => setForm(prevState => ({...prevState, title: e.target.value}))}
onChange={e => setTitle(e.target.value)}
placeholder="Add Your Title"
className="title"
rows="1"
maxchars="100"
/>
<textarea placeholder="Description"
onChange={e => setDescription(e.target.value)}
className="description"
rows="1"
value={description}
maxchars="500"/>
</div>
</div>
</div>
</div>
</form>
</div>)
};
**AddNew Component** where you have the file input
```js
//separate file
const AddNew = ({onFileSelected}) => {
const [file, setFile] = useState('');
const handleChange = (event) => {
setFile(event.target.files[0]);
onFileSelected(event.target.files[0])//single file select
};
return (
<div className="addNew">
<div className="uploadstyle">
<img src={file ? URL.createObjectURL(file) : null} alt={file ? file.name : null} />
<input className="upload" type="file" onChange={handleChange} />
</div>
</div>
)
}

Resources