1
0
mirror of https://github.com/ascribe/onion.git synced 2024-11-15 09:35:10 +01:00
onion/js/components/ascribe_forms/input_checkbox.js

94 lines
3.3 KiB
JavaScript
Raw Normal View History

'use strict';
2015-06-01 13:02:53 +02:00
import React from 'react';
2015-07-28 15:46:55 +02:00
/**
* This component can be used as a custom input element for form properties.
* It exposes its state via state.value and can be considered as a reference implementation
* for custom input components that live inside of properties.
*/
2015-06-01 13:02:53 +02:00
let InputCheckbox = React.createClass({
propTypes: {
2015-07-28 12:03:45 +02:00
required: React.PropTypes.bool,
2015-07-28 15:46:55 +02:00
// As can be read here: https://facebook.github.io/react/docs/forms.html
// inputs of type="checkbox" define their state via checked.
// Their default state is defined via defaultChecked.
//
// Since this component even has checkbox in its name, it felt wrong to expose defaultValue
// as the default-setting prop to other developers, which is why we choose defaultChecked.
2015-07-28 12:03:45 +02:00
defaultChecked: React.PropTypes.bool,
2015-07-14 19:53:49 +02:00
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element
2015-07-28 15:33:47 +02:00
])
},
2015-07-28 15:33:47 +02:00
2015-07-28 15:46:55 +02:00
// As HTML inputs, we're setting the default value for an input to checked === false
2015-07-27 14:39:19 +02:00
getDefaultProps() {
return {
2015-07-28 15:33:47 +02:00
defaultChecked: false
2015-07-27 14:39:19 +02:00
};
},
2015-06-01 13:02:53 +02:00
2015-07-28 15:46:55 +02:00
// Setting value to null in initialState is essentially since we're deriving a certain state from
// value === null as can be seen in componentWillReceiveProps.
2015-06-01 13:02:53 +02:00
getInitialState() {
return {
2015-07-28 15:33:47 +02:00
value: null
2015-06-01 13:02:53 +02:00
};
},
2015-07-10 15:56:54 +02:00
2015-07-28 15:33:47 +02:00
componentWillReceiveProps(nextProps) {
2015-07-28 15:46:55 +02:00
// Developer's are used to define defaultValues for inputs via defaultValue, but since this is a
// input of type checkbox we warn the dev to not do that.
2015-07-28 15:33:47 +02:00
if(this.props.defaultValue) {
2015-07-28 15:46:55 +02:00
console.warn('InputCheckbox is of type checkbox. Therefore its value is represented by checked and defaultChecked. defaultValue will do nothing!');
2015-07-28 15:33:47 +02:00
}
2015-07-28 15:46:55 +02:00
// The first time InputCheckbox is rendered, we want to set its value to the value of defaultChecked.
// This needs to be done in order to expose it for the Property component.
// We can determine the first render by checking if value still has it's initialState(from getInitialState)
2015-07-28 15:33:47 +02:00
if(this.state.value === null) {
2015-07-28 15:46:55 +02:00
this.setState({value: nextProps.defaultChecked });
2015-07-28 15:33:47 +02:00
}
2015-07-28 12:03:45 +02:00
},
onChange() {
2015-07-28 15:46:55 +02:00
// On every change, we're inversing the input's value
2015-07-28 15:33:47 +02:00
let inverseValue = !this.refs.checkbox.getDOMNode().checked;
2015-07-28 15:46:55 +02:00
// pass it to the state
2015-07-28 15:33:47 +02:00
this.setState({value: inverseValue});
2015-07-28 15:46:55 +02:00
// and also call Property's onChange method
// (in this case we're mocking event.target.value, since we can not use the event
// coming from onChange. Its coming from the span (user is clicking on the span) and not the input)
2015-07-28 12:03:45 +02:00
this.props.onChange({
target: {
2015-07-28 15:33:47 +02:00
value: inverseValue
2015-07-28 12:03:45 +02:00
}
});
2015-07-28 15:33:47 +02:00
2015-06-01 13:02:53 +02:00
},
2015-06-01 13:02:53 +02:00
render() {
return (
2015-07-10 15:56:54 +02:00
<span
2015-07-27 14:39:19 +02:00
onClick={this.onChange}>
<input
type="checkbox"
ref="checkbox"
onChange={this.onChange}
2015-07-28 12:03:45 +02:00
checked={this.state.value}
defaultChecked={this.props.defaultChecked}/>
2015-07-10 15:56:54 +02:00
<span className="checkbox">
2015-07-14 19:53:49 +02:00
{this.props.children}
2015-07-10 15:56:54 +02:00
</span>
</span>
2015-06-01 13:02:53 +02:00
);
}
});
export default InputCheckbox;