Get the clicked object and fill the inputs in ReactJS - 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

Related

html2canvas does not show form's input properly

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)

Passing values between components in React

I m beginner to reactJS and I m having so much trouble with self learning.
I want to print the data I get from first page.
I used 2 .js files
This is userpage.js:
import resultPage from "./resultPage";
// JS
//const input = document.getElementById('myText');
//const inputValue = input.value
// React
// value, onChange
const Multi = () => {
const [person, setPerson] = useState({ firstName: "", email: "", age: "" });
const [people, setPeople] = useState([]);
const handleChange = (e) => {
const name = e.target.name;
const value = e.target.value;
setPerson({ ...person, [name]: value });
};
const handleSubmit = (e) => {
//e.preventDefault();
if (person.firstName && person.email && person.age) {
const newPerson = { ...person, id: new Date().getTime().toString() };
setPeople([...people, newPerson]);
setPerson({ firstName: "", email: "", age: "" });
resultPage(people, person);
}
};
return (
<>
<article className="form">
<form>
<div className="form-control">
<label htmlFor="firstName">Name : </label>
<input
type="text"
id="firstName"
name="firstName"
value={person.firstName}
onChange={handleChange}
/>
</div>
<div className="form-control">
<label htmlFor="email">Email : </label>
<input
type="email"
id="email"
name="email"
value={person.email}
onChange={handleChange}
/>
</div>
<div className="form-control">
<label htmlFor="age">Age : </label>
<input
type="number"
id="age"
name="age"
value={person.age}
onChange={handleChange}
/>
</div>
<button type="submit" className="btn" onClick={handleSubmit}>
add person
</button>
</form>
</article>
</>
);
};
export default Multi;
This has 2 textboxes and a submit button.
This code is from resultPage.js:
function resultPage(people, person) {
return (
<article>
{people.map((person) => {
const { id, firstName, email, age } = person;
return (
<div key={id} className="item">
<h4>{firstName}</h4>
<p>{email}</p>
<p>{age}</p>
</div>
);
})}
</article>
);
}
export default resultPage;
What am I doing wrong? I m new to reactjs. So kindly spare my obvious mistakes and help me.
From React documentation
HTML form elements work a bit differently from other DOM elements in React, because form elements naturally keep some internal state.
You need to add handleSubmit to your form, and it'll work. As #Halcyon suggested, using a Capital case for a component is good. It's tough to distinguish between HTML elements and components if you use lowercase. Read this for more details.
I am attaching a working sandbox for your code.
You're calling resultPage in handleSubmit. That's not going to work. You want resultPage to be part of the rendering, probably conditionally.
Consider something like:
return <>
{person.firstName !== "" && <resultPage people={people} person={person} />}
{person.firstName === "" && <>
// the form
</>}
</>;
Also since resultPage is a component, it's best to capitalize it.
I think you probably want a 3rd component:
const MyComponent = () => {
const [ people, setPeople ] = React.useState([]);
const [ isEditing, setIsEditing ] = React.useState(false);
return <>
{isEditing && <Multi setPeople={(people) => {
setPeople(people);
setIsEditing(false);
}}
{isEditing === false && <resultPage people={people} />}
</>;
}
Mutli now accepts a prop setPeople that is called in handleSubmit.

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

Trying to get a innerhtml functionality to work in react todo list

I am aiming for new tasks to show as user clicks "add task", simple I know, but still learning react.
My goal was to use a ternary operator until its no longer null, and then map through the array each time a user clicks add task.
Issue:
I believe the renderTasks array isn't set by the time it tries to map over it, I get an error...
renderTasks.map is not a function
Is there a way I could utilize the useEffect for what I am trying to do, or any better ideas that could help? Thanks
Here's the code snippet of App.js
function App() {
const [tasks, setTasks] = useState([]);
const [renderTasks, setRenderTasks] = useState(null);
const handleAddTask = () => {
setRenderTasks(tasks);
};
const handleOnChange = (e) => {
setTasks({
...tasks,
[e.target.name]: e.target.value,
});
};
return (
<>
<div className="overview">
<label className="my-todos">My Todos</label>
<div className="input-div">
<div className="input-container">
<label className="title-desc">Title</label>
<input
name="title"
onChange={handleOnChange}
className="input-values"
type="text"
></input>
</div>
<div className="input-container">
<label className="title-desc">Description</label>
<input
name="description"
onChange={handleOnChange}
className="input-values"
type="text"
></input>
</div>
<button onClick={handleAddTask} className="add-task">
Add Task
</button>
</div>
{renderTasks !== null ? (
<ul>
{renderTasks.map((x) => {
return <li>{x.title - x.description}</li>;
})}
</ul>
) : null}
</div>
</>
);
}
export default App;
There were few issues in your implementation like how you destructing tasks, trying to access an object as an array and abusing the useState. You don't need useEffect or two useState to do the trick.
import React from "react";
import React, { useState } from 'react';
import "./style.css";
function App() {
const [tasks, setTasks] = useState([]);
const task = {};
const handleOnChange = (e) => {
task[e.target.name] = e.target.value;
};
const onClickHandler = (e)=>{
(task.title) && setTasks( [...tasks, task]);
}
return (
<>
<div className="overview">
<label className="my-todos">My Todos</label>
<div className="input-div">
<div className="input-container">
<label className="title-desc">Title</label>
<input
name="title"
onChange={handleOnChange}
className="input-values"
type="text"
></input>
</div>
<div className="input-container">
<label className="title-desc">Description</label>
<input
name="description"
onChange={handleOnChange}
className="input-values"
type="text"
></input>
</div>
<button onClick={onClickHandler} className="add-task">
Add Task
</button>
</div>
<ul>
{tasks.map((x) => {return <li>{x.title} - {x.description}</li> })}
</ul>
</div>
</>
);
}
export default App;
Even though you are initialising tasks to be an array, in handleOnChange you are setting it to an Object like this -
setTasks({
...tasks,
[e.target.name]: e.target.value,
});
This same tasks object you are trying to set for renderTasks in handleAddTask. So renderTasks is assigned to an Object and not an array and only arrays have map function and hence you are facing the issue renderTasks.map is not a function error
Try doing
Object.keys(renderTasks).map((x) => {
return <li>{x.title - x.description}</li>;
})

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

Resources