diff --git a/js/components/ascribe_forms/form.js b/js/components/ascribe_forms/form.js index f54ab06d..6d99d2f6 100644 --- a/js/components/ascribe_forms/form.js +++ b/js/components/ascribe_forms/form.js @@ -65,12 +65,12 @@ let Form = React.createClass({ reset() { // If onReset prop is defined from outside, // notify component that a form reset is happening. - if(this.props.onReset && typeof this.props.onReset === 'function') { + if(typeof this.props.onReset === 'function') { this.props.onReset(); } for(let ref in this.refs) { - if (this.refs[ref].reset && typeof this.refs[ref].reset === 'function'){ + if(typeof this.refs[ref].reset === 'function') { this.refs[ref].reset(); } } @@ -109,11 +109,12 @@ let Form = React.createClass({ getFormData() { let data = {}; - for(let ref in this.refs){ + + for(let ref in this.refs) { data[this.refs[ref].props.name] = this.refs[ref].state.value; } - if (this.props.getFormData && typeof this.props.getFormData === 'function'){ + if(typeof this.props.getFormData === 'function') { data = mergeOptionsWithDuplicates(data, this.props.getFormData()); } @@ -121,16 +122,16 @@ let Form = React.createClass({ }, handleChangeChild(){ - this.setState({edited: true}); + this.setState({ edited: true }); }, handleSuccess(response){ - if(this.props.handleSuccess && typeof this.props.handleSuccess === 'function') { + if(typeof this.props.handleSuccess === 'function') { this.props.handleSuccess(response); } for(let ref in this.refs) { - if(this.refs[ref] && this.refs[ref].handleSuccess && typeof this.refs[ref].handleSuccess === 'function'){ + if(this.refs[ref] && typeof this.refs[ref].handleSuccess === 'function'){ this.refs[ref].handleSuccess(); } } @@ -149,8 +150,7 @@ let Form = React.createClass({ this.setState({errors: this.state.errors.concat(err.json.errors[input])}); } } - } - else { + } else { let formData = this.getFormData(); // sentry shouldn't post the user's password @@ -173,7 +173,7 @@ let Form = React.createClass({ clearErrors(){ for(let ref in this.refs){ - if (this.refs[ref] && this.refs[ref].clearErrors && typeof this.refs[ref].clearErrors === 'function'){ + if (this.refs[ref] && typeof this.refs[ref].clearErrors === 'function'){ this.refs[ref].clearErrors(); } } diff --git a/js/components/ascribe_forms/property.js b/js/components/ascribe_forms/property.js index 61c5c96e..f446b64f 100644 --- a/js/components/ascribe_forms/property.js +++ b/js/components/ascribe_forms/property.js @@ -6,8 +6,11 @@ import ReactAddons from 'react/addons'; import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger'; import Tooltip from 'react-bootstrap/lib/Tooltip'; +import AppConstants from '../../constants/application_constants'; + import { mergeOptions } from '../../utils/general_utils'; + let Property = React.createClass({ propTypes: { hidden: React.PropTypes.bool, @@ -90,29 +93,41 @@ let Property = React.createClass({ }, reset() { + let input = this.refs.input; + // maybe do reset by reload instead of front end state? this.setState({value: this.state.initialValue}); - // resets the value of a custom react component input - this.refs.input.state.value = this.state.initialValue; + if(input.state && input.state.value) { + // resets the value of a custom react component input + input.state.value = this.state.initialValue; + } - // resets the value of a plain HTML5 input - this.refs.input.getDOMNode().value = this.state.initialValue; + // For some reason, if we set the value of a non HTML element (but a custom input), + // after a reset, the value will be be propagated to this component. + // + // Therefore we have to make sure only to reset the initial value + // of HTML inputs (which we determine by checking if there 'type' attribute matches + // the ones included in AppConstants.possibleInputTypes). + let inputDOMNode = input.getDOMNode(); + if(inputDOMNode.type && typeof inputDOMNode.type === 'string' && + AppConstants.possibleInputTypes.indexOf(inputDOMNode.type.toLowerCase()) > -1) { + inputDOMNode.value = this.state.initialValue; + } // For some inputs, reseting state.value is not enough to visually reset the // component. // // So if the input actually needs a visual reset, it needs to implement // a dedicated reset method. - if(this.refs.input.reset && typeof this.refs.input.reset === 'function') { - this.refs.input.reset(); + if(typeof input.reset === 'function') { + input.reset(); } }, handleChange(event) { - this.props.handleChange(event); - if (this.props.onChange && typeof this.props.onChange === 'function') { + if (typeof this.props.onChange === 'function') { this.props.onChange(event); } @@ -128,7 +143,7 @@ let Property = React.createClass({ // if onClick is defined from the outside, // just call it - if(this.props.onClick && typeof this.props.onClick === 'function') { + if(typeof this.props.onClick === 'function') { this.props.onClick(); } @@ -143,7 +158,7 @@ let Property = React.createClass({ isFocused: false }); - if(this.props.onBlur && typeof this.props.onBlur === 'function') { + if(typeof this.props.onBlur === 'function') { this.props.onBlur(event); } }, @@ -235,7 +250,7 @@ let Property = React.createClass({ overlay={tooltip}>
{this.state.errors} - { this.props.label} + {this.props.label} {this.renderChildren(style)} {footer}
diff --git a/js/components/ascribe_uploader/react_s3_fine_uploader.js b/js/components/ascribe_uploader/react_s3_fine_uploader.js index 32a60e66..854b2805 100644 --- a/js/components/ascribe_uploader/react_s3_fine_uploader.js +++ b/js/components/ascribe_uploader/react_s3_fine_uploader.js @@ -603,7 +603,7 @@ var ReactS3FineUploader = React.createClass({ files = validFiles; // Call this method to signal the outside component that an upload is in progress - if(this.props.uploadStarted && typeof this.props.uploadStarted === 'function' && files.length > 0) { + if(typeof this.props.uploadStarted === 'function' && files.length > 0) { this.props.uploadStarted(); } diff --git a/js/constants/application_constants.js b/js/constants/application_constants.js index a1b0a157..f1455029 100644 --- a/js/constants/application_constants.js +++ b/js/constants/application_constants.js @@ -53,6 +53,10 @@ let constants = { 'ga': 'UA-60614729-2' }, + // These are all possible types that are currently supported in HTML5 for the input element + // Source: http://www.w3schools.com/tags/att_input_type.asp + 'possibleInputTypes': ['button', 'checkbox', 'color', 'date', 'datetime', 'datetime-local', 'email', 'file', 'hidden', 'image', 'month', 'number', 'password', 'radio', 'range', 'reset', 'search', 'submit', 'tel', 'text', 'time', 'url', 'week'], + // in case of whitelabel customization, we store stuff here 'whitelabel': {}, 'raven': {