Conditionally remember radio button selection in React - reactjs

I am creating a modal to filter for profiles, on react-bootstrap and redux.
I need to filter to remember it's previous selection every time the user reopen it, even if he returns from another page. It works fine with value based components, such as "range slider" or "text search" because I can grab the previous saved redux store and plug into the component's attribute, such as:
value={rangeValue}
But for radio buttons, I am not sure since the attribute itself, "checked", is its own value.
<Form.Check
inline
label="male"
name="male"
checked <-----------
onChange={(e) => onRadioChange(e)}
/>
I want it to show "checked" only if the user has previously done so. I already have the user choice (whether checked or not) saved in my store, but don't know how to plug it in conditionally.
The returned JSX below
import React, { useState } from "react";
import { Form, Button } from "react-bootstrap";
...
<Form>
<div className="form_content_wrap">
<Form.Group>
<Form.Label htmlFor="formControlRange">Age: {rangeValue}</Form.Label>
<Form.Control
type="range"
className="form-control-range"
id="formControlRange"
min="0"
max="100"
value={rangeValue}
onChange={(e) => setRangeValue(e.currentTarget.value)}
/>
</Form.Group>
<Form.Group>
<Form.Label htmlFor="formControlRange">Gender: </Form.Label>
<Form.Check
inline
label="female"
name="female"
onChange={(e) => onRadioChange(e)}
/>
<Form.Check
inline
label="male"
name="male"
checked <<<------- THIS IS WHERE I WANT TO CHANGE
onChange={(e) => onRadioChange(e)}
/>
</Form.Group>
<Form.Group>
<Form.Label>Keyword</Form.Label>
<Form.Control
type="text"
placeholder="search description"
value={descValue}
onChange={(e) => setDescValue(e.currentTarget.value)}
/>
</Form.Group>
<Button
variant="primary"
type="submit"
onClick={onFormSubmit}
style={{ marginRight: "10px" }}
>
Submit
</Button>
<Button variant="primary" type="submit" onClick={onFormClear}>
Clear
</Button>[enter image description here][1]
</div>
</Form>
Thanks

React appears to be smart enough automatically remove the attribute if you set it equal to a Javascript expression that is not truthy. You should be able to just pull this state from your store. See this question for more details.
<Form.Check checked={true} />
<Form.Check checked={false} />

Related

Need validation in MDB inputs

I using MDB package. I have login page. I need validation for the page
<MDBValidation className='row g-3' isValidated>
<MDBValidationItem >
<MDBInput
wrapperClass='mb-4'
label='Email address'
id='validationCustom01'
type='email'
value={formValue.email}
name='email'
required
onChange={onChange}
autoComplete='off' />
</MDBValidationItem>
<MDBValidationItem >
<MDBInput
wrapperClass='mb-4'
label='Password'
id='validationCustom02'
type='password'
value={formValue.password}
name='password'
required
onChange={onChange}
autoComplete='off' />
</MDBValidationItem>
<div className="text-center pt-1 mb-5 pb-1">
<MDBBtn className="mb-4 w-100 gradient-custom-2" type='submit' onClick={() => { alert("Successfully Logged in") }}>Sign in</MDBBtn>
</MDBValidation>
I wrote the code. But doesn't works fine as I expected. Even if i don't enter the password I can get the success alert on the submit button click. I want to works it fine as antd form. Can anyone please help.
What you have done is right. but in onsubmit function you have to add below codes to validate
if (!event.target.checkValidity()) {
event.target.reportValidity();
event.target.className += " was-validated";
event.preventDefault();
return;
}
It will restrict the code execution if you have empty required fields.
For custom errors you can use MDBValidationItem component. it having property called feedback where you can mention your error text

First React-Bootstrap Radio Button Click is not triggering "touched" in Formik Form

Sandbox: https://codesandbox.io/s/nervous-bogdan-rdf1q
I have a React-Bootstrap radio group inside a Formik form. If you click on Option 2 you'll notice that I correctly get a validation error on that field right away, but I do not get touched on that field right away, which I should. Instead I have to click the Option 2 radio button again to get it inside the Formik touched array. So the touch is not registering on my 1st click if I start from that radiobutton, although the error is (correctly). The touch is registering on subsequent clicks.
<Form.Group>
<Form.Control type="radio"
id="option1"
name="group"
value="Y"
onChange={handleChange}
onBlur={handleBlur}
/>
<Form.Label htmlFor="option1">Option 1 </Form.Label>
</Form.Group>
<Form.Group>
<Form.Control type="radio"
id="option2"
name="group"
value="N"
onChange={handleChange}
onBlur={handleBlur}
/>
<Form.Label htmlFor="option2">Option 2 </Form.Label>
</Form.Group>
Validation:
<Formik
initialValues={{
}}
validationSchema={Yup.object().shape({
group: Yup.string().nullable().required('Required')
.matches(/^Y$/,'Option 1 must be selected')
})}
>
I found the problem. Radiobuttons stay focused after selection, so the first update of .touched will only happen when you click somewhere else to blur the control after your 1st click.
This can be fixed by doing
onChange={e => {
// Note: Since radio buttons remain focused after selection,
// we need to manually blur them to immediately update .touched
// (including the first click)
e.currentTarget.blur();
handleChange(e);
}}

How to set a radiobutton checked by default in react native?

how can I set a default checked radiobutton in react native? I'm trying to have a radio button already activated when the user enters the screen. Thanks for your help. II lready read that I have to use the value prop, but I do not now where to place it correctly, so that its working.
render(){
return (
<form>
<View>
<label>
<input
type="radio"
name="category"
value="anfaenger"
checked={this.state.selectedOption === "anfaenger"}
onChange={this.onValueChange}
/>
Anfänger
</label>
</View>
<View style={{marginTop:10}}>
<label>
<input
type="radio"
name="category"
value="geuebt"
checked={this.state.selectedOption === "geuebt"}
onChange={this.onValueChange}
/>
Geübt
</label>
</View>
<View style={{marginTop:10}}>
<label>
<input
type="radio"
name="category"
value="eingeschraenkt"
checked={this.state.selectedOption === "eingeschraenkt"}
onChange={this.onValueChange}
/>
Eingeschränkt
</label>
</View>
</form>
</View>
<View style={{magrinTop:'40'}}>
<button className="btn btn-default" type="submit">
Sichere Auswahl
</button>
<Button title="Erstelle meinen Plan" onPress={() => this.props.navigation.navigate('Uebungen', {
category: this.state.selectedOption,
}) }/>
</View>
</ScrollView>
</View>
);
}
}
You can pass a defaultChecked prop to a radio button component like so
export default function App() {
return (
<form>
<View>
<label>
<input
type="radio"
name="category"
value="anfaenger"
onChange={this.onValueChange}
defaultChecked
/>
Anfanger
</label>
</View>
<View style={{ marginTop: 10 }}>
<label>
<input
type="radio"
name="category"
value="geuebt"
onChange={this.onValueChange}
/>
Geubt
</label>
</View>
<View style={{ marginTop: 10 }}>
<label>
<input
type="radio"
name="category"
value="eingeschraenkt"
onChange={this.onValueChange}
/>
Eingeschrnkt
</label>
</View>
</form>
);
}
The value prop is passed on to the next page when the form is submitted. So if the first option is selected, 'anfaenger' will appear in the form results.
Edit:
You're right, the defaultChecked prop is only compatible with Web devices, not iOS and Android devices. When running on iOS and Android, I also noticed that some of the tags you used aren't compatible with React-Native, such as <forms>, <input>, <label>, unless there is a library that supports this. However, I wasn't able to find a library where you could import these components from.
Here is an Expo Snack I made that holds some code for radio buttons (styling need a bit of work, but maybe you can find a better UI library other than react-native-paper).
Basically, I set my React Hook's initial state to the first option in the form. This means that when the user opens the form, the first option should always be checked, since that is the state of the Hook.
If in fact your code does work as originally posted, I'd recommend setting your components selectedOption state variable to one of the options in the form.
state = {
selectedOption: 'anfaenger', // or 'geuebt' or 'eingeschraenkt' or any value you want to be the default
}
That way, when it checks for the state being a value in the radio button's status, it will be met and marked. However, if you need selectedOption to initialize to some value other than those in the radio buttons, then you can do boolean logic like so:
(Assuming selectedOption initializes to '' a.k.a empty string):
checked={this.state.selectedOption === "" || this.state.selectedOption === "anfaenger"}

Form.Control.Feedback is not working for file input

i am working with React-bootstrap 1.4.0, issue is that Form.Control.Feedback is not displaying the error, this is the image
click to see image
its working fine for input of type text.....
this is the code :
<Row className="my-2">
<Form.Group as={Col} controlId="admin-pdf-file">
<Form.File id="cf_fileInput" custom>
<Form.File.Input id="cf_fileInput" name="pdfFile" type="file" className="form-control border-radius-edit bg-secondary" onChange={handleFileSelect} required />
<Form.File.Label htmlFor="cf_fileInput" data-browse="Upload">
{pdfFileName.map(name => name.name)}
</Form.File.Label>
<Form.Control.Feedback type="isvalid" isInvalid={Boolean(errors !== null)}>{errors != null ? errors.map(error => (
error.msg.param === "fileUpload" && error.msg.message
)) : "Please Upload File"}</Form.Control.Feedback>
</Form.File>
</Form.Group>
</Row>
Remove required in your Form.File.Input.
Required is evaluated before bootstrap's style.
As described in react boostrap documentation example it lacks Form.Group component.
This is the implementation:
<Form.Group controlId="admin-pdf-file">
<Form.File custom>
<Form.File.Label>File name</Form.File.Label>
<Form.File.Input isInvalid />
<Form.Control.Feedback type="invalid">Please Upload File</Form.Control.Feedback>
</FormFile>
</Form.Group>

ReactJS Multiple lines of input using Form

I am implementing an input form and I am hoping that it could have a fix line limit. For example, for one box, it would be a 3-line input box. If more than 3 lines, there will be ideally a scroll bar on y-axis (i.e., no overflow in x axis). My current code is
<Form>
<FormGroup>
<ControlLabel>
Label
</ControlLabel>
<InputGroup>
<FormControl value='default' onChange={<some function>} />
</InputGroup>
</FormGroup>
</Form>
but it only rendered one line's input.
Edited: using textarea, the font seems to be very tiny.
The following snippet fixes the described issue:
<Form.Group controlId="exampleForm.ControlTextarea1">
<Form.Label>Example textarea</Form.Label>
<Form.Control as="textarea" rows="3" />
</Form.Group>
The componentClass prop of a FormControl is "input" by default, which renders a text input.
A text input is single line.
So try setting the componentClass prop of FormControl to "textarea":
<Form>
<FormGroup>
<ControlLabel>
Label
</ControlLabel>
<InputGroup>
<FormControl componentClass="textarea" value='default' onChange={<some function>} />
</InputGroup>
</FormGroup>
</Form>

Resources