From bd28450619c789aedb337f950ac2c57c9346d40c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Tue, 28 Jul 2015 15:46:55 +0200 Subject: [PATCH] add documentation for input checkbox --- js/components/ascribe_forms/form_signup.js | 3 +- js/components/ascribe_forms/input_checkbox.js | 32 +++++++++++++++++-- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/js/components/ascribe_forms/form_signup.js b/js/components/ascribe_forms/form_signup.js index 5fa81c50..238cd74e 100644 --- a/js/components/ascribe_forms/form_signup.js +++ b/js/components/ascribe_forms/form_signup.js @@ -120,8 +120,7 @@ let SignupForm = React.createClass({ name="terms" className="ascribe-settings-property-collapsible-toggle" style={{paddingBottom: 0}}> - + {' ' + getLangText('I agree to the Terms of Service') + ' '} ( diff --git a/js/components/ascribe_forms/input_checkbox.js b/js/components/ascribe_forms/input_checkbox.js index 44ec4103..a71dd4b6 100644 --- a/js/components/ascribe_forms/input_checkbox.js +++ b/js/components/ascribe_forms/input_checkbox.js @@ -2,9 +2,21 @@ import React from 'react'; +/** + * 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. + */ let InputCheckbox = React.createClass({ propTypes: { required: React.PropTypes.bool, + + // 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. defaultChecked: React.PropTypes.bool, children: React.PropTypes.oneOfType([ React.PropTypes.arrayOf(React.PropTypes.element), @@ -12,12 +24,15 @@ let InputCheckbox = React.createClass({ ]) }, + // As HTML inputs, we're setting the default value for an input to checked === false getDefaultProps() { return { defaultChecked: false }; }, + // Setting value to null in initialState is essentially since we're deriving a certain state from + // value === null as can be seen in componentWillReceiveProps. getInitialState() { return { value: null @@ -25,20 +40,31 @@ let InputCheckbox = React.createClass({ }, componentWillReceiveProps(nextProps) { + + // 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. if(this.props.defaultValue) { - console.warn('InputCheckbox is of type checkbox. Therefore its value is represented by checked and defaultChecked.'); + console.warn('InputCheckbox is of type checkbox. Therefore its value is represented by checked and defaultChecked. defaultValue will do nothing!'); } + // 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) if(this.state.value === null) { - this.setState({value: !!nextProps.defaultChecked }); + this.setState({value: nextProps.defaultChecked }); } }, onChange() { + // On every change, we're inversing the input's value let inverseValue = !this.refs.checkbox.getDOMNode().checked; + // pass it to the state this.setState({value: inverseValue}); - + + // 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) this.props.onChange({ target: { value: inverseValue