I'm trying to write this custom React component for my main Formik react form.
I want to create a 'select All' checkbox that, when selected or unselected, selects or deselects all the other checkboxes.
I got it to recognize that I'm clicking the 'Select All' checkbox using the onChange event.
But when I do this, it always stays selected.
I am also not sure how to automatically select and deselect the other checkboxes.
Another thing is, this component doesn't use state because state is handled by Formik in my my form page. Formik just looks for which checkbox is checked and adds it to state.
Is there a way to do this?
Thanks!
Here is my code:
const EngineList = () => {
const handleEngineChange = (e) => {
console.log('set engines to All -- ', e);
}
return (
<>
<label>
<Field type="checkbox" name="engines" onChange={handleEngineChange} value="1" selected />
Select All
</label>
<label>
<Field type="checkbox" name="engines" value="2" />
Formula One
</label>
<label>
<Field type="checkbox" name="engines" value="3" />
Nascar
</label>
</>
);
}
export default EngineList;
Since Formik handles state, you have to use the API to change state. There's setFieldValue, which you can use.
Related
I would like to show a checked box that's not clickable for a show page within my React-Redux application. So I'm familiar with building a form for adding and editing purposes but for a form that just shows the data, I'm unfamiliar as to how to go about that.
<label>Check if they ever were a World Champion</label>
<input
type="checkbox"
name="champion"
defaultChecked={true}
value={champion}
onChange={handleChange}
/>
<br></br>
This is what I have in my adding a fighter and updating forms:
return (
<div>
<h1>{list.attributes.title}</h1>
<Link to={`/lists/${list.id}/edit`}>Edit This List Name</Link>
<ol>{list.attributes.fighters.map(fighter =>
<li>
<p>{fighter.name}</p>
<p>{fighter.alias}</p>
<p>{fighter.nationality}</p>
<p>{fighter.division}</p>
<p>{fighter.stance}</p>
<p>{fighter.height}</p>
<p>{fighter.reach}</p>
<p>{fighter.status}</p>
**<???>{fighter.champion}</???>**
<p>{fighter.win}</p>
<p>{fighter.loss}</p>
<p>{fighter.draw}</p>
<p>{fighter.ko}</p>
</li>
)}</ol>
</div>
)
This snippet is from my ListCard in which the user can see the fighters for their particular list but can not edit that information on this page.
Are you looking for a way to disable a checkbox? So yes then you can do this by adding "disabled" in your element. Or if you want to handle it with the condition then you need to import Input from reactstrap and then you can do this by adding disabled=true or false.
install the package:
npm install reactstrap
and write a code:
Import { Input } from reactstrap;
<label>Check if they ever were a World Champion</label>
<Input
type="checkbox"
name="champion"
defaultChecked={true}
value={champion}
onChange={handleChange}
disabled=true
/>
<br></br>
I've built one of Bootstrap 4's custom checkboxes which looks like this:
<div className="custom-control custom-checkbox">
<input onChange={ (evt) => { console.log("CHANGED") }}
type="checkbox"
className="custom-control-input"
id="barChartsCheckbox" />
<label className="custom-control-label" htmlFor="barChartsCheckbox">Bar Charts</label>
</div>
I'm using React, so I want to detect a change in state to re-render the page, but the onChange event is not triggered.
As far as I understand, Bootstrap's custom checkboxes work by applying a :checked pseudoclass, so is it possible to catch that change via an onChange function?
EDIT
It seems that applying an onChange listener via jQuery works, as per this question
$('.custom-control-input').on('change', evt => {
console.log("test");
})
So why doesn't the onChange attribute work in React?
I've two react-select custom components used in react-redux form. Once I change a select on a select field, I need to clear the value of other select field component. dispatch(change) didn't help on this.
<Field name='towerNo' onChange={this.handleTowerChange} disabled={this.state.isTower} selectedValue={''} label='Tower' component={SearchBox} validate={[]} data={this.state.towers} selectkey={'towerName'} />
<Field name='floorNo' onChange={this.handleFloorChange} disabled={this.state.isFloor} selectedValue={''} label='Floor' component={SearchBox} validate={[]} data={this.state.floors} selectkey={'floorNumber'} />
I have a problem with VueJS when setting the value of an input radio AND v-model. I cant understand why I can not setting dynamically a value to an input and use a model to retrive what input the user selected.
In code is easier to understand:
export default {
props: ["question", "currentQuestion"],
data() {
return {
answer: undefined
}
},
computed: {
isCurrent() {
return this.currentQuestion && this.currentQuestion.id == this.question.id;
}
},
methods: {
groupName(question) {
return 'question_id_' + question.id
},
inputType(question) {
if (question.question_type_id == 2) return "checkbox";
return "radio";
}
},
mounted() {
console.log('Component mounted.')
}
}
<template>
<ul v-if="question.question_type_id != 4">
<li v-for="option in question.options" :key="option.id">
<div class="form-group">
<label>
<input v-model="answer" :value="option.id" :type="inputType(question)"
:name="groupName(question)" />
{{option.option}}
</label>
</div>
</li>
</ul>
</template>
So, in case there are 4 options, the user would see 4 radio buttons, each one with the "option.id" as a value and, WHEN the user clicks the radio button, the model "answer" would be populated with that value.
Now, when I try to compile this file, I get this error message:
:value="option.id" conflicts with v-model on the same element because the latter already expands to a value binding internally
So, could anyone help me understand how do I dynamically set a value to an input AND asssociate a model to retrieve the value when the input is selected?
By the way, VueJS documentation at this page says exactly what I am trying to do:
https://v2.vuejs.org/v2/guide/forms.html
Any help is very appreciated.
The main issue here is that you have a dynamic type on the input element, so I expect Vue is getting a little confused. value is not valid in combination with v-model for a checkbox input, unless you are binding to an array.
You can solve that by using a v-if/v-else.
<label>
<input v-if="question.question_type_id == 2"
v-model="answer"
type="checkbox"
:name="groupName(question)" />
<input v-else
v-model="answer"
:value="option.id"
type="radio"
:name="groupName(question)" />
{{option.option}}
</label>
Working example.
There are other issues, but this addresses the error you mention in the question. For one, it doesn't make much sense for more than one checkbox to be bound to a single v-model, unless you are binding to an array. In that case, you would have to swap what type answer is based on whether is a radio, a checkbox with a single value or a checkbox with multiple values. Seems like it would get complicated.
the proper way is to use placeholder.
<input :placeholder="option.id" v-model="answer" #input="functionToChangeValue($event)"/>
! DO NOT USE VALUE AND V-MODEL TOGETHER
it is because v-model create two way biding and your code brake
Here is a little background on what I'm trying to do. When the user clicks on add trip, I am using Redux Form Field Arrays to create fields.
The problem I am facing is that I want the form in the field array to change based on what option the user selects for the trip type (Point-to-Point, Local Transportation). So, I followed an example off of the Redux Form API website for Selecting Form Values. This did not work for me because the field names are dynamic and I have no idea on how to do this with the dynamic field names. Here is the code I've tried and any help would be appreciated. Thanks!
Code for service type radio buttons:
<fieldset className="row">
<div className="col">
<Field name={`${member}.serviceType`} className="with-gap" component="input" type="radio" value="Point" id="trip1_choice1"/>
<label htmlFor="trip1_choice1">
Point-to-Point
</label>
</div>
<div className="col">
<Field name={`${member}.serviceType`} className="with-gap" component="input" type="radio" value="Local" id="trip1_choice2" />
<label htmlFor="trip1_choice2">
Local Transport
</label>
</div>
</fieldset>
Code for changing forms based on which radio button is selected:
{[`${member}.serviceType`] === "Point" &&
//HTML Form Code goes here
}
As you can see I'm having trouble with accessing the value of the dynamic field array. [${member}.serviceType] does not work.
If anyone faces the same problem here is an example on github of how it should be done.
The following is the code I implemented.
This shows how I was able to get a specific value and it also shows how you can get all the values of the dynamic form.
// Get values from form
const selector2 = getFormValues('wizard');
const selector = formValueSelector("wizard");
Member = connect((state, props) => ({
serviceTypeDyno: selector(state, `${props.member}.serviceType`),
formValuesDyno: selector2(state)
}))(Member);
The if statement would then be:
{serviceTypeDyno === "Point" && (
//HTML Form Code goes here
)}
If you're using getFormValues Selector:
{formValuesDyno.serviceType === "Point" && (
//HTML Form Code goes here
)}
Use ref's, ejem.
<Field ref='fieldName' name={`${member}.serviceType`} className="with-gap" component="input" type="radio" value="Point" id="trip1_choice1"/>
To access them use: this.refs.fieldName.getRenderedComponent().refs.input
Check this issue #1933 on redux-form repository