React useForm get value from TextBox - reactjs

I am using React useForm hook to submit data from my form. The requirement is the user should see the sample data in a preview div before he submits. How can i get the value from input text boxes and display it in a div next to the input. In the documentation there is getValue method can that be used?
<form>
<div class="mb-6">
<label class="block mb-2">Enter Title: </label>
<input type="text" id="page_text" class="text-white" placeholder="Enter Title" {...register('page_Title',{ required: "Enter Your Title", maxLength: {value:255,message:"Cannot Exceed more 255 Characters" } })}/>
</div>
</form>
<div className= "text-white text-center rounded-xl shadow-xl">
<h1>Preview</h1>
<h3>{getValues("page_Title")}</h3>
</div>

I've created a sandbox here: https://codesandbox.io/s/angry-wave-nef2jo
Basically the issue is getValues doesn't automatically update when you enter text (onChange). You need to use the watch method as described in the documentation here: https://react-hook-form.com/api/useform/watch
For example:
const pageTitle = watch("page_Title", false);
Then:
<h3>{pageTitle}</h3>

inside the form put a button and trigger the getValues() method. like below
<button
type="button"
onClick={() => {
const values = getValues(); // { page_title: "someValue", test1: "test1-input", ... }
console.log({values});
}}
>
Get Values
</button>
Have a look at this basic example from the docs link too

Related

URL search parameters gets replaced - Remix Run

I'm working on a search UI where I have quite a few filters which I want as URL parameters when someone selects/checks the options. I've used the technique as advised on the Remix.run docs to come up with multiple forms within the filters. Each time a group of Filters gets submitted, the selected old parameters get disappeared. Heres my code,
<Panel header="Status" key="status">
<Form
name="search"
action='/search'
method="get"
onChange={(e) => submit(e.currentTarget, { replace: false })}
>
<ul>
<li>
<Checkbox
name="status"
value="buy_now"
defaultChecked={status.includes('buy_now')}
>
Buy Now
</Checkbox>
</li>
<li>
<Checkbox
name="status"
value="on_auction"
defaultChecked={status.includes('on_auction')}
>
On Auction
</Checkbox>
</li>
</ul>
</Form>
</Panel>
<Panel header="Price" key="price">
<Form name="search" action='/search' method="get">
<Select
name="blockchain"
value={
blockchain
? options.filter((a) => a.value === blockchain)
: undefined
}
options={options}
placeholder="Blockchain"
type="white"
/>
<div className="d-flex align-center price">
<TextInput
value={min ? min : undefined}
name="min"
placeholder="Min"
/>
<span>to</span>
<TextInput
value={max ? max : undefined}
name="max"
placeholder="Max"
/>
</div>
<button
onClick={(e) => {
e.stopPropagation()
submit(e.currentTarget, { replace: false })
}}
className="btn primary-btn btn-lg w-100"
>
Apply
</button>
</Form>
</Panel>
How Can I get around this to have all the parameters without having to manage them on my own using React state?
Edit:- I want the first filter to be submitted automatically and the latter to be submitted on a button click.
Bit of a UI of what I'm trying to achieve,
Answer: After investing enough time to look through for shortcuts, finally understood that it's not one of the magic that remix.run does. use something like formik and update the state imparatively.
When you submit a form, the only values included are the one under the submitted form. The values from any other form are not included (fortunately!).
So I'd use a single Form with all the inputs under it (checkboxes as well as text inputs).
Then instead of a onChange on the Form, you can add something like an onChange handler on the checkboxes and submit the form inside imperatively (using a ref click on the submit button or something, I think using a ref on the form you need to submit all values in the submit function so a button ref click may be simpler).
Keep in mind that if you want to "restore" the field values after submitting, you need to return them from the loader function like this:
// Loader function
const url = new URL(request.url);
return {
results: [...],
values: Object.fromEntries(url.searchParams.entries())
};
Then in the component, use values from useLoaderData:
<input type="text" name="max" defaultValue={values.max || ""}/>
Added benefit: if you come back to this page (by clicking browser back for example), your search parameters and search results are still there!
I actually put up a stackblitz for you but I lost all my changes :(
It seems like you could just keep all fields in a single form and submit that form when the submit button is pressed.
Then onChange, check if the target's name is 'status', and submit the form anyway.
export default function App() {
const submit = (form) => {
form.submit();
};
return (
<form
name="search"
action="/search"
method="get"
onChange={(e) => {
if (e.target.name === "status") {
submit(e.currentTarget);
}
}}
>
<fieldset>
<legend>status</legend>
<label>
<input type="checkbox" name="status" value="buy_now" />
buy_now
</label>
<label>
<input type="checkbox" name="status" value="on_auction" />
on_auction
</label>
</fieldset>
<fieldset>
<legend>price</legend>
<label>
<div>blockchain</div>
<select name="blockchain">
<option value="option_1">Blockchain Option 1</option>
<option value="option_2">Blockchain Option 2</option>
</select>
</label>
<label>
min <input type="number" name="min" />
</label>
<label>
max <input type="number" name="max" />
</label>
</fieldset>
<button type="submit">Apply</button>
</form>
);
}
demo
Note: not sure what your motivation is to want to separate this into separate forms, but I think the magic you're referring to is that server state, URLSearchParams, FormData and UI are all aligned because they are using the same underlying data using only common web APIs.

How to click on a ref in react

I am creating a file uploader using react. I want to hide the default file input element and trigger it when user click on a div.
<div style={{position:"relative",width:"500px",height:"300px",background:"gray",marginLeft:"auto",marginRight:"auto",border:"2px
dotted white"}}
onClick={this.clickOnFakeUploader}
>
<div style={{float:"left",marginTop:"100px",width:"100%"}}>
<h4 style={{color:"white",marginLeft:"auto",marginRight:"auto"}}>Drag & Drop Files Here!
</h4>
</div>
</div>
<label className="btn btn-default" style={{display:"none"}}>
<input ref={this.fileUploader} type="file" multiple onChange={this.selectFiles} />
</label>
this.fileUploader = React.createRef();
this.clickOnFakeUploader = () =>{
this.fileUploader.click();
}
I am getting TypeError: this.fileUploader.click is not a function error.
this.fileUploader.current.click()
you need to address it with current

React validation on multiple checkboxes

anyone can point me to an example of a react multiple checkboxes validation? I have some questions, every one of them has a checkbox when it's done and when all are checked, a continue button must be activated.. I know how to do this with only one checkbox, but don't know how to handle more of them. I would rather do this in plain react and not by installing any package. Any help will be appreciated.
You can control all your inputs using useState. Example for two inputs.
import React, { useState } from "react"
const ControlledCheckboxes = () => {
const [ firstCheckbox, setFirstCheckbox ] = useState(false);
const [ secondCheckbox, setSecondCheckbox ] = useState(false);
return(
<form>
<div >
<div className="form-check">
<input type="checkbox" id="first" className="form-check-input"
onClick={()=>setFirstCheckbox(!firstCheckbox)}
value={firstCheckbox}
/>
<label className="form-check-label" htmlFor="first">FIRST</label>
</div>
<div className="form-check">
<input type="checkbox" id="second" className="form-check-input"
onClick={()=>setSecondCheckbox(!secondCheckbox)}
value={secondCheckbox}
/>
<label className="form-check-label" htmlFor="second">SECOND</label>
</div>
</div>
<button type="submit" className="btn btn-outline-success" disabled={ !(firstCheckbox && secondCheckbox) } >SUBMIT</button>
</form>
)
};
You can achieve this by using controlled inputs.
Basically you would make the value of the checkboxes correspond to variables in the state of your component. After that it is as simple as if (boolean1 && boolean2) with a conditionally rendered save button.
Controlled inputs
Conditional rendering
You can achieve most of what you want with just HTML.
<form>
<input type="checkbox" required />
<input type="checkbox" required />
<button>submit</button>
</form>
The form cannot be submitted until all checkboxes are checked.
Let's say that's not enough, you want to access the form validity in your render logic to apply styles or whatever so you need component state.
const [valid, setValid] = useState(false);
All form control change events bubble up to their form (unless explicitly stopped). We can spy on form control changes by adding a change event listener that updates component state to the form element.
event => setValid(event.target.form.checkValidity())
If your form isn't as simple as my example and you need to specifically check certain checkboxes you can find all form controls in event.target.form.elements. You can use the elements property to not even need HTML form validation.
event => setValid(Array.from(event.target.form.elements).every(
input => input.type !== 'checkbox' || input.checked
))
You can then pass valid as a prop to your submit button.

a button to link AND submit a form in react.js. I've tried href, link, to, onClick, history.push, and I am looking for another idea

I have tried to add Link, to, href, a href, onClick to add a link to the button. This is the front end to a book-index project. I also tried history.push, I the button is in a form to submit. I want the button then take it to a landing page saying "book added" If I add a Link to the button, it will link to the page then the submit doesn't load. I can get one to work or the other, but not both. The code I have is for the submit.
this is in a react.js class component
render() {
return (
<div style={{padding:"10px"}}>
<h1 style={{textAlign:"center"}}>Add a Book Below</h1>
{console.log("state", this.state)}
<form onSubmit = {this.handleSubmit}>
<div className="add-title" style={{textAlign:"center", paddingBottom:"10px"}}>
<label>Title:</label>
<input
type="text"
name = "title"
value={this.state.title}
onChange={this.handleChange}
/>
</div>
<div className="add-author" style={{textAlign:"center", paddingBottom:"10px"}}>
<label>Author:</label>
<input
type="text"
name = "author"
value={this.state.author}
onChange={this.handleChange}
/>
</div>
<div className="submit" style={{textAlign:"center", paddingBottom:'100px'}}>
<button
type="submit"
value="submit"
>Submit</button>

Showing red color for required field controls after calling form.reset() in angular material

Attached screenshot for more information about error
I am using FormGroup to create form Controls and after submitting filled data to the server I am calling form.reset() Method to clear current data.
So what I want, that all controls should be rendered as like when a component initializes for the first time
Html file code:
<mat-form-field>
<input matInput id="title" placeholder="Enter your title"
formControlName="title">
</mat-form-field>
TS file code:
title: new FormControl("", Validators.compose([
Validators.required,
])),
This is angular5:
<form [formGroup]="myform" novalidate (ngSubmit)="onSubmit()">
<button type="submit" class="btn btn-primary">Submit</button>
</form>
js
onSubmit()
{
if(this.myform.valid)
{
console.log("form submitted",this.myform.value)
this.myform.reset();
}
}
see this link for more check the link

Resources