Persist values after reload react-hook-form - reactjs

I have a Form with several components:
return (
<>
<FormProvider {...methods} >
<div className="mt-12">
<form onSubmit={handleSubmit(onSubmit)} action="#" method="POST" >
<Email/>
<Personal/>
<h2 className='font-semibold text-xl'>Geburtsdaten</h2>
<p className='mb-5 text-gray-400 text-sm'>Du musst mindestens 18 Jahre alt sein, um online einen Vertrag abzuschließen.</p>
<div className="sm:col-span-2 grid grid-cols-3 gap-4 mb-5">
<div className="mt-1">
< SelectBirthYear
years={years}
value={selectedYear}
onChange={setSelectedYear}/>
</div>
<div className="mt-1">
< SelectBirthMonth
startYear={startYear}
selectedYear={selectedYear}
months={months}
value={selectedMonth}
reducedMonths={reducedMonths}
onChange={monthSelect}/>
</div>
<div className="mt-1">
<SelectBirthDay
startYear={startYear}
selectedYear={selectedYear}
selectedMonth={selectedMonth}
monthNow={monthNow}
days={days}
value={selectedDay}
reducedDays={reducedDays}
onChange={daySelect}
/>
</div>
</div>
<Contact/>
<BankDetails/>
<Checkboxes />
<div className="sm:col-span-2">
</div>
<div className="mt-5 sm:mt-8 sm:flex sm:justify-center lg:justify-center">
<div className="rounded-md shadow">
<a role="button" tabIndex={0}
onClick={prevFormStep}
className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-white bg-yellow-500 hover:bg-yallow-600 md:py-4 md:text-lg md:px-10"
>
Zurück
</a>
</div>
<div className="mt-3 sm:mt-0 sm:ml-3">
<input
type='submit'
value='Vertrag abschließen'
className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-white bg-yellow-500 hover:bg-yallow-600 md:py-4 md:text-lg md:px-10"
/>
</div>
</div>
</form>
</div>
</FormProvider>
</>
)
For my From validations I already use react-hook-form:
const methods = useForm({ mode: 'onTouched' });
const { handleSubmit } = methods;
So now, looking into documentation, I can't see the possibility of persisting values on input change. In the console I can access the _formValues in the control, but in my App I can't even manage to console.log those. Also, about control it is said: This object contains methods for registering components into React Hook Form. Important: do not access any of the properties inside this object directly. It's for internal usage only.
My thinking was, if I can access the formValues, then I could save those into Local Storage. But I am not getting that far. Also, having form with a lot of components, naming each where I wish to save the Value on every change woudn't be dry. So is there any strategy to get all values out of my Form and to add those to local storage, so if for whatever reason User reloads or goes back in the browser history, the filles out form persists?

Related

Responsive Media React Tailwind

So i have component that i try to make it responsive, but when it comes to media below md: it not working at all and i have some problem on turning the view into what i want
Here is the look on the web view:
and here is the problem :
is that posible to make the button into this when it comes to phone view?
Here is my try:
const CardCalculation = () => {
return (
<div className="ml-2">
<div className="mx-auto lg:flex lg:items-center lg:justify-between">
<h2 className="tracking-tight text-gray-900 sm:text-xl">
<div className="gap-2">
<div className="w-[120px] h-[110px] absolute bg-[#d9d9d9] lg:mb-10"></div>
<div className="text-xl ml-32 text-left text-[#e44]">
Mie Goleng
</div>
<div className="ml-32 text-left text-[#b4b4b4]">Plant K103.</div>
<div className="ml-32 text-left text-[#b4b4b4]">500.02 UOG.</div>
</div>
</h2>
<div className="mt-4 flex lg:mt-0 lg:flex-shrink-0 md:mt-4 sm:mt-8">
<div>
<div className="rounded-md mb-2 shadow">
<a
href="#"
className="inline-flex items-center justify-center rounded-md border border-transparent bg-indigo-600 px-5 py-3 text-base font-medium text-white hover:bg-indigo-700"
>
Get started
</a>
</div>
<div className="rounded-md shadow">
<a
href="#"
className="inline-flex items-center justify-center rounded-md border border-transparent bg-indigo-600 px-5 py-3 text-base font-medium text-indigo-600 hover:bg-indigo-50"
>
Learn more
</a>
</div>
</div>
</div>
</div>
</div>
);
};
export default CardCalculation;
can someone explained to me why it not responsive to the screen and does it possible to turn the button into horizontal when it comes to phone view as below?
Use the following code:
<div class="p-2">
<div class="flex flex-col md:flex-row md:justify-between">
<div class="flex gap-4">
<div name="grey window" class="h-[110px] w-[120px] bg-[#d9d9d9]"></div>
<div name="text" class="pt-2 md:flex md:flex-col md:justify-evenly md:pt-4">
<div class="text-xl text-[#e44] md:text-3xl">Mie Goleng</div>
<div class="mt-2 text-[#b4b4b4] md:text-xl">Plant K103.</div>
<div class="mt-2 text-[#b4b4b4] md:text-xl">500.02 UOG.</div>
</div>
</div>
<div name="Buttons">
<div class="flex gap-4 md:flex-col p-4 md:p-0">
<div class="rounded-md shadow">
Get started
</div>
<div class="rounded-md shadow">
Learn more
</div>
</div>
</div>
</div>
</div>
Output on large devices:
Output on small devices:
Tailwind play

I can not use className here in my organization, and it is not working with tw

I am trying to create tooltip here by using Tailwind css and displaying it on Pebble SVG
<div className="relative items-center group">
<span tw="flex items-center gap-1">
Payment method
<Pebble />
</span>
<div tw="bottom-0 flex flex-col items-center hidden group-hover:flex">
<span tw="relative p-2 text-sm text-inkWhite-100 bg-inkBlack-100">
If you'd like to change your payment method, go to section.
</span>
<div tw="w-3 h-3 -mt-2 rotate-45 bg-black"></div>
</div
Any other way around for it?

How can I do to put the edit input into my react project?

Hello I have that edit input :
<link rel="stylesheet" href="https://unpkg.com/boxicons#2.0.7/css/boxicons.min.css" />
<script defer src="https://unpkg.com/alpinejs#3.9.1/dist/cdn.min.js"></script>
<main class="flex min-h-screen w-full items-center justify-center bg-gray-100">
<div x-data="{ open : false }" class="p-2 bg-white border shadow rounded w-96">
<div x-show="!open" class="flex justify-between items-center">
<div class="ml-2">Hafiz Haziq</div>
<button type="button" class="btn bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 font-medium rounded "
#click="open = !open">Edit</button>
</div>
<!-- container after clicked "EDIT" -->
<div x-show="open" class="flex justify-between items-center">
<input type="text" class="w-full bg-gray-100 rounded p-2 mr-4" value="Hafiz Haziq">
<div class="flex justify-center items-center space-x-2">
<button type="button" class="rounded bg-emerald-500 hover:bg-emerald-600 w-10 h-10 text-white text-3xl">
<i class='bx bx-check'></i>
</button>
<button type="button" class="rounded bg-red-500 hover:bg-red-600 text-white w-10 h-10 text-3xl"
#click="open = false">
<i class='bx bx-x'></i>
</button>
</div>
</div>
</div>
</main>
that I found here : The edit input
And I would like to put it into my react project :
I tried that :
import "./styles.css";
const App = ()=> {
return (
<main class="flex min-h-screen w-full items-center justify-center bg-gray-100">
<div x-data="{ open : false }" class="p-2 bg-white border shadow rounded w-96">
<div x-show="!open" class="flex justify-between items-center">
<div class="ml-2">Hafiz Haziq</div>
<button type="button" class="btn bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 font-medium rounded "
#click="open = !open">Edit</button>
</div>
{/*<!-- container after clicked "EDIT" --> */}
<div x-show="open" class="flex justify-between items-center">
<input type="text" class="w-full bg-gray-100 rounded p-2 mr-4" value="Hafiz Haziq" />
<div class="flex justify-center items-center space-x-2">
<button type="button" class="rounded bg-emerald-500 hover:bg-emerald-600 w-10 h-10 text-white text-3xl">
<i class='bx bx-check'></i>
</button>
<button type="button" class="rounded bg-red-500 hover:bg-red-600 text-white w-10 h-10 text-3xl"
#click="open = false">
<i class='bx bx-x'></i>
</button>
</div>
</div>
</div>
</main>
);
}
export default App;
The code of the full project is there : My project
But it does not work ...
Could you help me please ?
Thank you very much !
It is not working, because this is not a React code. You would need to change few things in there.
You need use useState to keep track of open state
const [open, setOpen] = useState(false);
To handle click events on button you should use onClick instead of #click
<button onClick={() => setOpen(true)}>
Edit
</button>
Change places where you are defining classes for HTML elements. In react you should use className keyword for that.
<div className="ml-2">Hafiz Haziq</div>
You can also remove x-data and x-show attributes
<div x-show="!open" class="flex justify-between items-center">

Access JSX react variables in a button

I have mapped a list of responses from my backend mongodb to my frontend. For each response, I have also added a button. I want to add an voteResponse function for my vote button. How can I continue to have access to my {response.respondee} and {response.response} in my voteResponse function?
{responses.map((response) => (
<div
key={response._id}
className='py-8 px-12 mb-12 bg-gray-50 border-b border-gray-100 transform transition duration-300 ease-in-out hover:-translate-y-2'
>
<NextLink href={`/responses/${response.response}`} passHref>
<div>
<div className='inline-block text-gray-900 mb-4'></div>
<h3 className='text-lg leading-normal mb-2 font-semibold text-black'>
{response.response}
</h3>
<p className='text-gray-500'>
{response.respondee.slice(0, 5)}...
{response.respondee.slice(38)}
</p>
</div>
</NextLink>
<div>
<button
type='submit'
className='inline-flex justify-center mt-3 py-1 px-3 border border-transparent shadow text-base font-medium rounded-md text-white bg-cyan-600 hover:bg-cyan-700 focus:outline-none'
onClick={voteResponse}
>
Vote
</button>
</div>
</div>
))}
You can do this by 2 ways. First is by making a separate component which is being rendered in map function and pass response in it through props then each component will have access to it's response.response and response.respondee.
funtion Response({response}){
const voteResponse = () =>{
console.log(response.response, response.respondee)
}
return(
<div key={response._id} className='py-8 px-12 mb-12 bg-gray-50 border-b border-gray-100 transform transition duration-300 ease-in-out hover:-translate-y-2'>
<NextLink href={`/responses/${response.response}`} passHref>
<div>
<div className='inline-block text-gray-900 mb-4'></div>
<h3 className='text-lg leading-normal mb-2 font-semibold text-black'>
{response.response}
</h3>
<p className='text-gray-500'>
{response.respondee.slice(0, 5)}... {response.respondee.slice(38)}
</p>
</div>
</NextLink>
<div>
<button type='submit' className='inline-flex justify-center mt-3 py-1 px-3 border border-transparent shadow text-base font-medium rounded-md text-white bg-cyan-600 hover:bg-cyan-700 focus:outline-none' onClick={voteResponse}>
Vote
</button>
</div>
</div>
)
}
//use it like this
{responses.map((response) => (
<Response response={response} key={response._id} />
))}
Second way to pass the index in voteResponse function and then through that index you can access the those variables like responses[index].response and responses[index].respondee.
{responses.map((response, index) => (
<div key={response._id} className='py-8 px-12 mb-12 bg-gray-50 border-b border-gray-100 transform transition duration-300 ease-in-out hover:-translate-y-2'>
<NextLink href={`/responses/${response.response}`} passHref>
<div>
<div className='inline-block text-gray-900 mb-4'></div>
<h3 className='text-lg leading-normal mb-2 font-semibold text-black'>
{response.response}
</h3>
<p className='text-gray-500'>
{response.respondee.slice(0, 5)}... {response.respondee.slice(38)}
</p>
</div>
</NextLink>
<div>
<button type='submit' className='inline-flex justify-center mt-3 py-1 px-3 border border-transparent shadow text-base font-medium rounded-md text-white bg-cyan-600 hover:bg-cyan-700 focus:outline-none' onClick={voteResponse}>
Vote
</button>
</div>
</div>
))}
Pass value to onClick prop: onClick={() => voteResponse(response)} and use it as parameter of voteResponse function:
const voteResponse = (res) => {
console.log("response.respondee is: ", res.respondee) //<=== response.respondee value is res.respondee value
console.log("response.response is: ", res.response)
}
{responses.map((response) => (
<div
key={response._id}
className='py-8 px-12 mb-12 bg-gray-50 border-b border-gray-100 transform transition duration-300 ease-in-out hover:-translate-y-2'
>
<NextLink href={`/responses/${response.response}`} passHref>
<div>
<div className='inline-block text-gray-900 mb-4'></div>
<h3 className='text-lg leading-normal mb-2 font-semibold text-black'>
{response.response}
</h3>
<p className='text-gray-500'>
{response.respondee.slice(0, 5)}...
{response.respondee.slice(38)}
</p>
</div>
</NextLink>
<div>
<button
type='submit'
className='inline-flex justify-center mt-3 py-1 px-3 border border-transparent shadow text-base font-medium rounded-md text-white bg-cyan-600 hover:bg-cyan-700 focus:outline-none'
onClick={() => voteResponse(response)
>
Vote
</button>
</div>
</div>
))}

Conditionally render download button in react

I have a download button from which the user can download the assets. but I want only authenticated users can download. If the user is not authenticated and click on the download button I want to show them a modal with a login button on it. I have a modal component. I am using React.
Please help me.
Getting currently authenticated user from the firebase.
const {currentUser} = useAuth();
This is my code for the download button.
<a className="bg-secondary text-white font-bold py-3
px-5 rounded text-2xl focus:outline-none mt-3 block w-48" href="YOUR_URL">
<i className="animate-bounce fas fa-arrow-down mr-2"></i>
Download
</a>
Modal Code:
import React from "react";
import { useState } from "react";
export default function Modal() {
const [showModal, setShowModal] = useState(true);
console.log('modal');
return (
<>
{showModal ? (
<>
<div
className="justify-center items-center flex overflow-x-hidden overflow-y-auto fixed inset-0 z-50 outline-none focus:outline-none"
onClick={() => setShowModal(false)}
>
<div className="relative w-auto my-6 mx-auto max-w-3xl">
{/*content*/}
<div className="border-0 rounded-lg shadow-lg relative flex flex-col w-full bg-white outline-none focus:outline-none">
{/*header*/}
<div className="flex items-start justify-between p-5 border-b border-solid border-gray-300 rounded-t">
<h3 className="text-3xl font-semibold">
Modal Title
</h3>
<button
className="p-1 ml-auto bg-transparent border-0 text-black opacity-5 float-right text-3xl leading-none font-semibold outline-none focus:outline-none"
onClick={() => setShowModal(false)}
>
<span className="bg-transparent text-black opacity-5 h-6 w-6 text-2xl block outline-none focus:outline-none">
×
</span>
</button>
</div>
{/*body*/}
<div className="relative p-6 flex-auto">
<p className="my-4 text-gray-600 text-lg leading-relaxed">
I always felt like I could do anything. That’s the main
thing people are controlled by! Thoughts- their perception
of themselves! They're slowed down by their perception of
themselves. If you're taught you can’t do anything, you
won’t do anything. I was taught I could do everything.
</p>
</div>
{/*footer*/}
<div className="flex items-center justify-end p-6 border-t border-solid border-gray-300 rounded-b">
<button
className="text-red-500 background-transparent font-bold uppercase px-6 py-2 text-sm outline-none focus:outline-none mr-1 mb-1"
type="button"
style={{ transition: "all .15s ease" }}
onClick={() => setShowModal(false)}
>
Close
</button>
<button
className="bg-green-500 text-white active:bg-green-600 font-bold uppercase text-sm px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1"
type="button"
style={{ transition: "all .15s ease" }}
onClick={() => setShowModal(false)}
>
Save Changes
</button>
</div>
</div>
</div>
</div>
<div className="opacity-25 fixed inset-0 z-40 bg-black"></div>
</>
) : null}
</>
);
}
You could use button instead of a and use onClick to check if currentUser exists when you click button.
This is final code:
function x {
const {currentUser} = useAuth();
const downloadAssets = () => {
if(currentUser){
window.open("url assets here", '_blank', 'noopener,noreferrer')
}else{
// Open modal here
alert("User not authenticated");
}
}
return {
<>
...
<button onClick={downloadAssets}><i className="animate-bounce fas fa-arrow-down mr-2"></I>Download</button>
...
</>
}

Resources