Skip to content

Commit

Permalink
Merge pull request #267 from mmrtnz/radio-revamp
Browse files Browse the repository at this point in the history
RadioButton update and new component: RadioButtonGroup
  • Loading branch information
Hai Nguyen committed Jan 23, 2015
2 parents 0b8c0ec + 7ec8c8a commit 7261169
Show file tree
Hide file tree
Showing 11 changed files with 361 additions and 120 deletions.
136 changes: 88 additions & 48 deletions docs/src/app/components/pages/components/switches.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ var React = require('react');
var mui = require('mui');
var Checkbox = mui.Checkbox;
var RadioButton = mui.RadioButton;
var RadioButtonGroup = mui.RadioButtonGroup;
var Toggle = mui.Toggle;
var CodeExample = require('../../code-example/code-example.jsx');
var ComponentDoc = require('../../component-doc.jsx');
var RaisedButton = mui.RaisedButton;

var SwitchesPage = React.createClass({

Expand All @@ -27,19 +29,21 @@ var SwitchesPage = React.createClass({
' label="built a house on the moon"\n' +
' disabled={true} />\n\n' +
'//Radio Buttons\n' +
'<RadioButton\n' +
' name="shipSpeed1"\n' +
' value="light"\n' +
' label="prepare for light speed" />\n' +
'<RadioButton\n' +
' name="shipSpeed2"\n' +
' value="not_light"\n' +
' label="light speed too slow"\n' +
' defaultChecked={true} />\n' +
'<RadioButton\n' +
' name="shipSpeed3"\n' +
' value="ludicrous"\n' +
' label="go to ludicous speed" />\n\n' +
'<RadioButtonGroup \n' +
' name="shipSpeed"\n' +
' defaultSelected="not_light">\n' +
' <RadioButton\n' +
' value="light"\n' +
' label="prepare for light speed" />\n' +
' <RadioButton\n' +
' value="not_light"\n' +
' label="light speed too slow"\n' +
' defaultChecked={true} />\n' +
' <RadioButton\n' +
' value="ludicrous"\n' +
' label="go to ludicous speed"\n'+
' disabled={true}/>\n' +
'</RadioButtonGroup>\n\n' +
'//Toggle\n' +
'<Toggle\n' +
' name="toggleName1"\n' +
Expand Down Expand Up @@ -120,12 +124,6 @@ var SwitchesPage = React.createClass({
{
name: 'Radio Button',
infoArray: [
{
name: 'name',
type: 'string',
header: 'required',
desc: 'The name of the radio button component.'
},
{
name: 'value',
type: 'string',
Expand All @@ -146,6 +144,56 @@ var SwitchesPage = React.createClass({
}
]
},
{
name: 'Radio Button Group',
infoArray: [
{
name: 'name',
type: 'string',
header: 'required',
desc: 'The name that will be applied to all radio buttons inside it.'
},
{
name: 'defaultSelected',
type: 'string',
header: 'optional',
desc: 'Sets the default radio button to be the one whose value matches ' +
'defaultSelected (case-sensitive). This will override any individual radio ' +
'button with the defaultChecked or checked property stated.'
}
]
},
{
name: 'Radio Button Group Methods',
infoArray: [
{
name: 'getSelectedValue',
header: 'RadioButtonGroup.getSelectedValue()',
desc: 'Returns the string value of the radio button that is currently selected. If nothing ' +
'has been selected, an empty string is returned.'
},
{
name: 'setSelectedValue',
header: 'RadioButtonGroup.setSelectedValue(newSelection)',
desc: 'Sets the selected radio button to the radio button whose value matches ' +
'newSelection'
}
]
},
{
name: 'Radio Button Group Events',
infoArray: [
{
name: 'onChange',
type: 'function(e, selected)',
header: 'optional',
desc: 'Callback function that is fired when a radio button has been clicked. Returns ' +
'the event and the value of the radio button that has been selected.'
}
]
},


{
name: 'Toggle Props',
infoArray: [
Expand Down Expand Up @@ -225,11 +273,11 @@ var SwitchesPage = React.createClass({
desc={desc}
componentInfo={componentInfo}>

<div className="switches-examples">
<form className="switches-examples">
{this._getCheckboxExample()}
{this._getRadioButtonExample()}
{this._getToggleExample()}
</div>
</form>

</ComponentDoc>
);
Expand Down Expand Up @@ -314,30 +362,23 @@ var SwitchesPage = React.createClass({
<h2 className="mui-font-style-headline">Radio Buttons</h2>
</div>

<div className="switches-example-container">
<RadioButton
name="shipSpeed1"
value="light"
label="prepare for light speed"
onClick={this._onRadioButtonClick} />
</div>
<div className="switches-example-container">
<RadioButton
name="shipSpeed2"
value="not_light"
label="light speed too slow"
defaultChecked={true}
onClick={this._onRadioButtonClick} />
</div>
<div className="switches-example-container">
<RadioButton
name="shipSpeed3"
value="ludicrous"
label="go to ludicrous speed"
onClick={this._onRadioButtonClick} />
</div>
<RadioButtonGroup
name="shipSpeed"
defaultSelected="not_light"
onChange={this._onRadioButtonClick}>
<RadioButton
value="light"
label="prepare for light speed"/>
<RadioButton
value="not_light"
label="light speed too slow"/>
<RadioButton
value="ludicrous"
label="go to ludicrous speed"
disabled={true}/>
</RadioButtonGroup>

</div>
</div>
);
},

Expand All @@ -349,10 +390,9 @@ var SwitchesPage = React.createClass({
console.log('Toggled: ', toggled);
},

_onRadioButtonClick: function(e, checked) {
console.log('Clicked:', checked);
}

_onRadioButtonClick: function(e, selected) {
console.log('Selected: ', selected);
},
});

module.exports = SwitchesPage;
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = {
},
Paper: require('./js/paper.jsx'),
RadioButton: require('./js/radio-button.jsx'),
RadioButtonGroup: require('./js/radio-button-group.jsx'),
RaisedButton: require('./js/raised-button.jsx'),
Slider: require('./js/slider.jsx'),
Tab: require('./js/tabs/tab.jsx'),
Expand Down
2 changes: 1 addition & 1 deletion src/js/checkbox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ var Checkbox = React.createClass({
<EnhancedSwitch
{...other}
ref="enhancedSwitch"
switchType="checkbox"
inputType="checkbox"
className="mui-switch-checkbox"
onSwitch={this._onCheck}
defaultSwitched={this.props.defaultChecked} />
Expand Down
6 changes: 3 additions & 3 deletions src/js/enhanced-switch.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ var Paper = require('./paper.jsx');

var EnhancedSwitch = React.createClass({
propTypes: {
switchType: React.PropTypes.string.isRequired,
inputType: React.PropTypes.string.isRequired,
className: React.PropTypes.string.isRequired,
name: React.PropTypes.string.isRequired,
value: React.PropTypes.string.isRequired,
Expand Down Expand Up @@ -68,7 +68,7 @@ var EnhancedSwitch = React.createClass({
<input
{...other}
ref="checkbox"
type="checkbox"
type={this.props.inputType}
name={this.props.name}
value={this.props.value}
onChange={this.handleChange} />
Expand All @@ -82,7 +82,7 @@ var EnhancedSwitch = React.createClass({

// no callback here because there is no event
setSwitched: function(newSwitchedValue) {
if (!this.props.hasOwnProperty('checked')) {
if (!this.props.hasOwnProperty('checked') || this.props.checked == false) {
this.setState({switched: newSwitchedValue});
this.refs.checkbox.getDOMNode().checked = newSwitchedValue;
} else {
Expand Down
119 changes: 119 additions & 0 deletions src/js/radio-button-group.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
var React = require('react');
var Paper = require('./paper.jsx');
var Classable = require('./mixins/classable.js');
var EnhancedSwitch = require('./enhanced-switch.jsx');
var RadioButton = require('./radio-button.jsx');

var RadioButtonGroup = React.createClass({

mixins: [Classable],

propTypes: {
name: React.PropTypes.string.isRequired,
defaultSelected: React.PropTypes.string,
onChange: React.PropTypes.func
},

_hasCheckAttribute: function(radioButton) {
return radioButton.props.hasOwnProperty('checked') &&
radioButton.props.checked;
},

getInitialState: function() {
var initialSelection = '';

if (this.props.hasOwnProperty('defaultSelected')) {
initialSelection = this.props.defaultSelected;
} else {
this.props.children.forEach(function(option) {
if (this._hasCheckAttribute(option) || option.props.defaultChecked) initialSelection = option.props.value;
}, this);
}

return {
numberCheckedRadioButtons: 0,
selected: initialSelection
};
},

componentWillMount: function() {
var cnt = 0;

this.props.children.forEach(function(option) {
if (this._hasCheckAttribute(option)) cnt++;
}, this);

this.setState({numberCheckedRadioButtons: cnt});
},

componentWillReceiveProps: function(nextProps) {
var newSelection = '';

nextProps.children.forEach(function(option) {
if (this._hasCheckAttribute(option) || option.props.defaultChecked) newSelection = option.props.value;
}, this);

this.setState({selected: newSelection});
},

render: function() {
var options = this.props.children.map(function(option) {

var {
name,
value,
label,
onCheck,
...other
} = option.props;

return <RadioButton
{...other}
ref={option.props.value}
name={this.props.name}
key={option.props.value}
value={option.props.value}
label={option.props.label}
onCheck={this._onChange}
checked={option.props.value == this.state.selected}/>

}, this);

return (
<div>
{options}
</div>
);
},

_updateRadioButtons: function(newSelection) {
if (this.state.numberCheckedRadioButtons == 0) {

this.setState({selected: newSelection});

} else {
var message = "Cannot select a different radio button while another radio button " +
"has the 'checked' property set to true.";
console.error(message);
}
},

_onChange: function(e, newSelection) {
this._updateRadioButtons(newSelection);

// Successful update
if (this.state.numberCheckedRadioButtons == 0) {
if (this.props.onChange) this.props.onChange(e, newSelection);
}
},

getSelectedValue: function() {
return this.state.selected;
},

setSelectedValue: function(newSelection) {
this._updateRadioButtons(newSelection);
}
});

module.exports = RadioButtonGroup;
Loading

0 comments on commit 7261169

Please sign in to comment.