The problem: I have a selection of 3 radio buttons, and I need to allow users to unselect a radio button they have previously selected by clicking on it (toggle state based on user selection of radio button). Adding a "none" or "clear selections" button is not an option. So this needs to be either radio buttons that allow un-selecting, or checkboxes that allow only 1 selection.
How on earth do I do this in react cleanly? Semi-cleanly?
Disclaimers:
I have searched google and SO and found nothing that answers my questions, either b/c they don't solve my particular problem, or I am unknowingly misunderstanding them.
Yes I know this is not what radio buttons/checkboxes are designed to do, but this is what the client wants and I cannot push back on this decision any further
I'm very new to react, so apologies if the answer is obvious and I just missed it.
Mhm, this solution is not great, but, you can do the following:
onChange -> you just switch the state
onClick -> verify if the value is the one that you're already having in the state. If so, set the state to null.
Look at this CodeSandbox
Or, you can use a checkbox, and always keep 1 item in state at a time. And once that is clicked again, just clear the state.
import React from 'react'
const ExclusiveCheckBoxes = (props) => {
const allUnchecked = {option1:false, option2:false, option3:false};
const [options, setOptions] = React.useState(allUnchecked);
const chkChanged = e => {
setOptions({...allUnchecked, [e.target.name]: e.target.checked});
}
return (
<div>
<h1>ExclusiveCheckBoxes</h1>
<input type="checkbox" name="option1"
checked={options.option1} onChange={chkChanged}/>
<input type="checkbox" name="option2"
checked={options.option2} onChange={chkChanged}/>
<input type="checkbox" name="option3"
checked={options.option3} onChange={chkChanged}/>
</div>
)
}
export default ExclusiveCheckBoxes
Related
I'm working on a React app with a button to reset a form. When the user clicks the "Reset" button, all the states revert to their original values. But a checkmark remains selected even after all the other data clears. It does appear to reset the state, but the checkmark is still visible and confusing to the user. I understand that defaultChecked is read on the initial load, but the checkmark remains even if I remove defaultChecked completely, so I'm not sure where the problem is. I suspect the solution might involve onChange, but I haven't been able to get that to work. Any help appreciated.
const [checked, setChecked] = useState(false);
const clearSearch = () => {
setResults([]);
setQuery("");
setFormat("");
setChecked(false);
}
<label>
<input
type="checkbox"
id="searchAll"
defaultChecked={checked}
onChange={() => setChecked(!checked)}
/>
Search all formats
</label>
<button className="btn btn-danger"
onClick={event => {
event.preventDefault();
clearSearch();
}}>
Reset
</button>
App.js on GitHub https://github.com/irene-rojas/loc/blob/master/src/App.js
Your checkbox is actually an uncontrolled input, which probably isn't what you want (it usually isn't in React). That is because, although you've got the onChange event wired up to a handler which sets state, you're not reading back from that state into the input. Except in the defaultChecked attribute - which doesn't control whether it's actually checked or not.
You need to use the checked attribute, which for a checkbox is essentially equivalent to the value attribute of a text or numeric input:
<input
type="checkbox"
id="searchAll"
checked={checked}
onChange={() => setChecked(!checked)}
/>
(I've removed your defaultChecked attribute, as I don't think you want it - but feel free to put it back in if you do. The important thing is having a checked attribute that reads from the checked state value.)
Please take a look at my code for Dropdown,
I'm using the semantic ui react dropdown on an EditProfile component. I have pasted a sample code here, https://codesandbox.io/s/m4288nx4z8, but I could not get it to work because I'm not very familiar with functional components in React, I've always used Class component. But you can check the full code for the whole component below in the github gist.
https://gist.github.com/mayordwells/b0cbb7b63af85269091f1f98296fd9bb
Please, I need help on inserting values from multiple select options of a Dropdown into the Database and also a way to display that back upon viewing the profile edit page again.
I'm using semantic-ui-react in react + rails app.
Also when I insert a value using a normal drop down without multiple select, the value gets persisted into the database.
<Dropdown
placeholder='Select Country'
fluid
search
selection
options={countryOptions}
name='country'
defaultValue={this.state.extraInfo.country}
onChange={(e) => this.handleExtraInfoChange('country', e)}
/>
This code handles change for the dropdown elements.
handleExtraInfoChange = (name, event) => {
let value;
if (event.target.value !== undefined) {
value = event.target.value;
} else {
value = event.target.textContent;
}
let newExtraInfo = Object.assign(this.state.extraInfo, { [name]: value })
this.setState({ extraInfo: newExtraInfo});
}
But when I visit the page again, I get a white blank in the input box. Here's a screen pic for that. When I comment out the defaultValue or value property(i have tried with defaultValue and value), the white blank disappears, but the value picked by a user is also not seen.
Please advice what is a possible solution to this misbehavior? And what is the best way to insert multiple values into the Database?
Thanks in advance for your time.
A functional component does not have state, it's used for composition; you want to store state, so you either have to create a Component class or you need an external state container like redux.
I want to put some text in to the radio field (with Redux form).
I have fields like this:
<Field
name={some.name1}
value={'text1'}
component={renderRadioElement}
type="radio"
/>
<Field
name={some.name2}
value={'text2'}
component={renderRadioElement}
type="radio"
/>
...
Everything works correctly until the first value change.
If I want to change the value several times: state -> form -> ... -> values -> some does not update values.
My question is - how to correctly enter a text value into a radio field?
If I understood correctly your comment you have a value on your component state where youve decleared the form and you wnat to pass in that value to your field.
If thats it what you want to do is dispatch the value to the redux-form store.
To do that in your class you are receiving a prop which is change. injected by redux-form. what you want to do is use that function to set the value
const { change } = this.props;
change('some.name2', this.state.yourValue)
hope it helps
I have a react project, a recipe box, which includes the ability to open a recipe and add/delete ingredients. Here is a fiddle. You can click the recipe name to open the recipe. There is an edit button which reveals the delete button and gives the option to change the name of the ingredients. When the 'delete ingredient' button is pressed, the last ingredient appears to always be deleted, regardless of which ingredient is selected, but when the 'done' button is clicked and the editable input boxes change back to text, the correct change is shown, the proper ingredient deleted and the last ingredient remains. Though this works functionally, it's obviously not very UI friendly, and I wondered why this was happening. Any help would be great.
jsFiddle
class Input extends React.Component {
render() {
const array = this.props.update;
let booleanButton = null;
if (this.props.ingr) {
////////////////////////////
// here is the button's JSX
booleanButton = <button onClick=
{this.props.handleDeleteIngredient.bind(this, array)}>delete
ingredient</button>;
///////////////////////////
}
return (<div><form><input type="text" defaultValue={this.props.text}
onChange={this.props.onChange.bind(this, array)} /></form>{booleanButton}
</div>)
}
}
And the handler:
handleDeleteIngredient(data, e ) {
var key = data[2];
var ingrs = this.state.ingrs;
ingrs.splice(key, 1);
this.setState({ingrs:ingrs});
}
Your description is quiet confusing, and according the your fiddle code I think your problem is caused by not setting a good key for your list Item.
from what it looks in this line, you don't have a key={ingrs[i]} props, try set it to id see it will work, but making ingrediant name as key is probably not a good idea, try to give an actual id.
ingrList.push(<Input key={ingrs[i]} handleDeleteIngredient={this.handleDeleteIngredient.bind(this)} id={id} update={[this.props.objectIndex, "ingrs", i]} onChange={this.onInputChangeIng.bind(this)} text={ingrs[i]} />);
I know that this has been spoken about in some Google Threads but I still can't find the right solution to bind my radio inputs to a model (in clean'n simple manner),
Currently I have HTML:
<input ng-model="searchByRma" type="radio" name="search-type">
<input ng-model="searchByDelivery" type="radio" name="search-type">
And in Controller:
$scope.searchByRma = true;
$scope.searchByDelivery = false;
This does not work (as it would with the checkboxes)...
Any ideas on how to set the default value on the first radio button without loosing data-binding?
Thanks!
I think you should use same variable with different values in those
two radio buttons.
<input ng-model="searchBy" value="Rma" type="radio" name="search-type">
<input ng-model="searchBy" value="Delivery" type="radio" name="search-type">
Then, you should have searchBy set either "Rma" or "Delivery" depending on
user input.
What has worked for me is to set the model variable to { } and that will reset the radio buttons to their default (not selected) state. Of course, this will only work if you have your radio button tags correct as in tosh's answer.
In your case:
$scope.searchBy = { };