I'm trying to make a group of react-bootstrap buttons into a radio button set. I can easily do this with bootstrap with <input type="radio"> elements, but can't figure out how to do this with react-bootstrap. The following code allows the user to select every button, instead of just one.
JS:
const operationButtons = (
<ButtonGroup>
<Button active>Radio 1</Button>
<Button>Radio 2</Button>
</ButtonGroup>
);
React.render(operationButtons, document.getElementById('operationButtonsDiv'));
HTML:
<div name="operationButtonsDiv" id="operationButtonsDiv" data-toggle="buttons"/>
The framework has changed since the accepted answer and they have now replicated the option group behavior of Bootstrap framework. All you need to do now is to add a group name to each option in the group:
<Radio name="groupOptions">Option 1</Radio>
<Radio name="groupOptions">Option 2</Radio>
<Radio name="groupOptions">Option 3</Radio>
So I ended up nesting a radio Input in the Button like you would normally do in Bootstrap.
render() {
return (
<ButtonGroup>
<Button active>Radio 1
<Input ref="input1" type="radio" name="radioButtonSet" value='input1' standalone defaultChecked/>
</Button>
<Button>Radio 2
<Input ref="input2" type="radio" name="radioButtonSet" value='input2' standalone/>
</Button>
</ButtonGroup>
)
}
I also overrode the default .radio css to fix how it's displayed.
.radio {
margin-top: 0;
margin-bottom: 0;
}
React-bootstrap has plans to implement RadioGroup eventually:
https://github.com/react-bootstrap/react-bootstrap/issues/342
Some of the answers on this page don't work. Maybe things have changed since then.
I put together this with the help of React Bootstrap website.
<Col>
<InputGroup>
<InputGroup.Prepend>
<InputGroup.Radio name="group1"/>
<InputGroup.Text >London</InputGroup.Text>
</InputGroup.Prepend>
<FormControl/>
</InputGroup>
<InputGroup>
<InputGroup.Prepend>
<InputGroup.Radio name="group1"/>
<InputGroup.Text >New York</InputGroup.Text>
</InputGroup.Prepend>
<FormControl/>
</InputGroup>
<InputGroup>
<InputGroup.Prepend>
<InputGroup.Radio name="group1"/>
<InputGroup.Text >Colombo</InputGroup.Text>
</InputGroup.Prepend>
<FormControl/>
</InputGroup>
To make the radio button set function as a single group you have to give them a name (so that only one radio button is selected at any given time).
Adding a form control makes the edges of the input nicely rounded off but it also makes the radio button label editable. If this is a problem you can leave out the form control.
If you want a different look and feel you can try this.
<Form.Check
type="radio"
label="London"
name="group2"
id="radio1"
/>
<Form.Check
type="radio"
label="New York"
name="group2"
id="radio2"
/>
<Form.Check
type="radio"
label="Colombo"
name="group2"
id="radio3"
/>
However with these getting the value and handling onChange was difficult. Eventually I used another control.
This is a npm package called react-radio-group. You have to install it by running this line on the command.
npm install react-radio-group
Then import it in your file.
import { Radio, RadioGroup} from 'react-radio-group'
Here's the code for the button group.
<RadioGroup name="fruits" onChange={(e) => handleOnChange(e)}>
<div className="radio-button-background">
<Radio value="Apple" className="radio-button" />Apple
</div>
<div className="radio-button-background">
<Radio value="Orange" className="radio-button" />Orange
</div>
<div className="radio-button-background">
<Radio value="Banana" className="radio-button" />Banana
</div>
</RadioGroup>
classNames are where I have given the styles.
I've just encountered the same problem and solved it by using the the component's state:
_onOptionChange(option) {
this.setState({
option: option
});
}
render() {
render (
<ButtonGroup>
<Button onClick={this._onOptionChange.bind(this, 'optionA')} active={this.state.option === 'optionA'}>Option A</Button>
<Button onClick={this._onOptionChange.bind(this, 'optionB')} active={this.state.option === 'optionB'}>Option B</Button>
</ButtonGroup>
);
}
Just using the tags worked for me. Make sure they all have the same name="radio-group-value-here". To get one of the buttons to be selected on render use checked={bool}. I also used disabled={bool} to show but disallow some choices. I settled on using onClick which seems to be working. Lastly, this is all in a dialog and the offset was needed to keep the radio buttons from smushing up against the left edge.
<Row>
<Col sm={11} smOffset={1} >
<Radio name="changeset-chooser"
checked={this.state.checked === 'current'}
disabled={this.props.changeset.status === "pending"}
onClick={ (e) => { /* event handler */ } } >
Current Data
</Radio>
</Col>
</Row>
<Row>
<Col sm={3} smOffset={1} >
<Radio name="changeset-chooser"
onClick={ (e) => { /* event handler */ } } >
History
</Radio>
</Col>
<Col sm={7} >
<NotPartOfSample />
</Col>
</Row>
This is in 2022, so the library has moved.
Here is how yo would create a yes/no radio:
<Form>
<Form.Check
type="radio"
name="group1"
id={`default-radio`}
label={`Yes!`}
/>
<Form.Check
type="radio"
name="group1"
id={`default-radio`}
label={`No`}
/>
</Form>
The name="group1" makes the buttons TOGGLE. If you don't want to toggle, give them different names or no names.
Hope this helps someone who might stumble across this question like I did.
Related
Hi im trying to make a switch button (checkbox) with default checked and also disabled in react.
but somehow if I only put checked={true} it will be checked but the moment i add disabled="disabled", the switch button is unchecked and disabled (even if there is checked attribute). Could anyone please advise? thank you
<label htmlFor="disabled-on" className="switch__label">
<input
type="checkbox"
name="disabled-on"
id="disabled-on"
checked={true}
disabled="disabled" /* if added disabled it's not working with checked" */
className="switch__input switch__input--disabled-on"
/>
It is probably something wrong in your code somewhere else, please check this code - all looks fine.
class TodoApp extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<div>
<ul>
<li>
<label htmlFor="disabled-on" className="switch__label">
custom checkbox 1
<input
type="checkbox"
name="disabled-on"
id="disabled-on"
checked={true}
disabled="disabled"
className="switch__input switch__input--disabled-on"
/>
</label>
</li><li>
<label htmlFor="disabled-on" className="switch__label">
custom checkbox 2
<input
type="checkbox"
name="disabled-off"
id="disabled-off"
checked={true}
className="switch__input switch__input--disabled-on"
/>
</label>
</li>
</ul>
</div>
)
}
}
ReactDOM.render(<TodoApp />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
According to twitter bootstrap, this is how we do a radio:
<div class="radio">
<label>
<input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
Option one is this and that—be sure to include why it's great
</label>
</div>
And this is my code:
$browser->click('#menu-reports')
->waitForText('Users')
->click('#menu-reports-users')
->radio('sitesActive', '2')
->radio('includeDisabled', '2')
->radio('includeNonCertifiable', '2')
->press('Apply')
->waitForText('Showing 0 to 0 of 0 entries')
;
With the input inside the label tag. But the problem is that Dusk (actually Facebook Webdriver) is not able to find it this way. It keeps raising:
Facebook\WebDriver\Exception\ElementNotVisibleException: element not visible
To make it work I have put the input outside the label, but then, of course, the boostrap radio does not show as it should anymore.
<div class="radio">
<input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
<label>
Option one is this and that—be sure to include why it's great
</label>
</div>
Does not work using IDs either:
Not even setting an ID to the input:
<input
type="radio"
name="sitesActive"
id="sitesActive3"
value="2"
>
And trying to select it this way:
->radio('#sitesActive3', '2')
The problem is that Dusk (Webdriver) cannot even see the element in the page, as this simple like fails the exact same way:
$browser->waitFor('#sitesActive3');
Resulting in:
Facebook\WebDriver\Exception\TimeOutException: Waited 5 seconds for selector [#sitesActive3].
And that happens every time I have a form with an input with a label surrounding it, if I take the input out of the label, it works. But that's not as simple with radios, as it was with some other inputs, radios.
This is a properly coded radio:
This is a radio with the input outside the label tag:
So, how are you doing this?
My form has a radio button. This how I checked it.
userCreate.blade.php
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Gender</label>
<div>
<label class="radio-inline">
<input type="radio" id="gender" name="gender" value="m">Male
</label>
<label class="radio-inline">
<input type="radio" id="gender" name="gender" value="f">Female
</label>
</div>
</div>
</div>
</div>
CreateUserTest.php
class CreateUserTest extends DuskTestCase
{
public function testCreateForm()
{
$this->browse(function (Browser $browser) {
$browser->visit('/user/create')
->radio('#gender', 'm')
->click('button[type="submit"]')
->assertSee('Successfully created user.');
});
}
}
This works for me. I think this will help you.
simplest way is to click on the parent
$el = $this->resolver->resolveForRadioSelection($field, $value);
$el = $el->findElement(WebDriverBy::xpath(".."));
$el->click();
Since the radio is not visible dusk cannot click on it
You may create a trait like the following if you are using bootstrap in your project
trait BootstrapInteraction
{
/**
* Undocumented variable
* #var \Laravel\Dusk\ElementResolver $resolver
*/
public $resolver;
public function radioB($field, $value)
{
/**
* #var RemoteWebElement $el
*/
$radio = $this->resolver->resolveForRadioSelection($field, $value);
// click on parent
$el = $radio->findElement(WebDriverBy::xpath(".."));
$el->click();
// if not selected click on label
if (!$radio->isSelected()) {
$el = $el->findElement(WebDriverBy::cssSelector("label"));
$el->click();
}
PHPUnit::assertTrue(
$radio->isSelected(),
"Not able to select Radio [{$field}] within value [{$value}]."
);
return $this;
}
You may not be happy to edit your views for the sake of your test script but if you are open to that, what about adding a class to the
<input type="radio" ... >
and then using
->click('.yourClass')
in your Dusk test?
The Dusk docs say:
To "select" a radio button option, you may use the radio method. Like many other input related methods, a full CSS selector is not required. If an exact selector match can't be found, Dusk will search for a radio with matching name and value attributes: $browser->radio('version', 'php7');
In my case, Dusk was working fine for most of my radio buttons, but it would not work for:
->radio('Field728', 'Know it\'s what anyone committed to this dream would do if she found a great program that features a proven process and supportive community')
I also tried using double-quotes, but that didn't work either. (Maybe the value is too long? I don't know.)
So instead I did this:
->radio('#Field728_0', true)//this is the specific ID of the first radio button of this group
I am using ASP.net for a program with a number of check boxes and a submit button which initiates an action depending on the selected check boxes.
However, one of my check boxes should behave as this submit button, i.e, upon selecting/deselecting this check box, the same action as the button must be triggered. Can someone please help me in doing this (or perhaps direct me to a tutorial)
I have a controller class and model.
Thanks you
EDIT
The program look like:
#using(Html.BeginForm("controllername", FormMethod.Get)) {
#html.CheckBox("check1");
#HTMl.Checkbos("check2");
<input type="submit" value="Submit" />
}
Everything else is pretty much handled in the controller.
You can use javascript to listen to the check event of your check box and then invoke the form submit.
Assuming your markup of view is like this
<form id="yourFormId" action="user/post">
<input type="checkbox" class="optionChk" value="1" /> One
<input type="checkbox" class="optionChk" value="2" /> Two
<input type="checkbox" class="optionChk" value="3" /> Three
</form>
<script type="text/javascript">
$(function(){
$(".optionChk").click(function(){
var item=$(this);
if(item.val()=="2") //check your condition here
{
item.closest("form").submit();
}
});
});
</script>
EDIT : As per the question edit.
Change the CheckBox Helper method usage like the below to add a css class to the checkbox so that we can use that for the jQuery selection.
#Html.CheckBox("check1",new { #class="optionChk"})
imagining you have something like this:
#using(Html.BeginForm()) {
<label class="checkbox">
<input type="checkbox" name="chb_a" id="chb_a"> Option A
</label>
<label class="checkbox">
<input type="checkbox" name="chb_b" id="chb_b"> Option B
</label>
<label class="checkbox">
<input type="checkbox" name="chb_c" id="chb_c"> Option C
</label>
<label class="checkbox">
<input type="checkbox" name="chb_d" id="chb_d"> Option D
</label>
<button type="submit" class="btn">Submit</button>
}
you can write a simple jQuery to complement:
$(".submit").click(function() {
// find the <form> the element belongs and submit it
$(this).closest('form').submit();
});
and with this, all you need is to add a class named submit to any checkbox or more buttons if you want them to submit
for example:
<label class="checkbox">
<input type="checkbox" name="chb_e" id="chb_e" class="submit"> Option E
</label>
You can bind the click events on the checkboxes.
$( '.myCheckboxes' ).click(function () {
var clickedBox = $( this );
// now do something based on the clicked box...
});
If you need to know which checkboxes are checked, that's just another selector.
$( '.myCheckboxes:checked' ).each(function () {
// Now you have access to each checked box.
// Maybe you want to grab their values.
});
Just bind the checkbox to a click event. Assuming you have a way of uniquely identifying the checkbox that submits the form.
$( '#formSubmitCheckbox' ).click(function() {
$( '#myForm' ).submit();
});
I have this problem :
I have a submit button defined as follows :
<input type="submit" name="actionName" value="search" />
<input type="submit" name="actionName" value="New" />
both submit buttons are included in an Ajax beginForm:
#using (Ajax.BeginForm("PFSearch", "Payer", ajaxOptions))
In the controller ... based on the actionName string provided .. i do different actions based on the value of button pressed within my Ajax befin form :
if (actionName="search")
{
//do something
}
And everything works like a charm .. until i want to add i want to add an image to the class of my submit button :
<input class="search" type="submit" name="actionName" value="search" />
<input class="search" type="submit" name="actionName" value="New" />
My search tab looks like this :
As you can clearly see my main impediment is that by adding value ... the text appears over my image.
How can i make those button act differently within my ajax begin form considering that giving value to the buttons doesn't work ? Any alternatives or workarounds are appreciated. Thanks !
Can you please give us a link to your project's demo? And try to use some margin, padding and background-position:center;
I have a problem with checkbox. I have a list of checkbox, and I want to mark only one check and unmark other.
I want do that this in the same view , is it posible?
How can I do that?
<div><input type="checkbox" id="<%= id %>" onchange='submit();'/> </div>
thanks
Sounds like you really need a radio button instead. Radio buttons are mutually exclusive if you give them the same name:
<input type="radio" name="something" ... />
<input type="radio" name="something" ... />
If you really want checkboxes you will have to write some JavaScript logic.
Use radio buttons, not checkboxes.
<div>
foreach (var foo in model.Foos) {
<input type="radio" name="foo" id="foo_#foo.Id" value="#foo.Id" />
<label for="foo_#foo.Id">#foo.Value</label> <br />
}
</div>
Something like that should create a list of radio buttons.
Also, why are you submitting when the selection is changed? You should be using jQuery to do any selection-based manipulation to the page on the client side.
You could use jQuery. on document.Ready you'll have to bind a change event on checkboxes to some function, then in your function you want to reset all other checkboxes. That's assuming you don't want to use radio buttons as suggested above.