diff --git a/js/components/ascribe_forms/form.js b/js/components/ascribe_forms/form.js index fe9e8646..c95b206e 100644 --- a/js/components/ascribe_forms/form.js +++ b/js/components/ascribe_forms/form.js @@ -62,6 +62,11 @@ let Form = React.createClass({ }; }, + componentWillMount() { + // Set up internal storage for callback refs + this._refs = {}; + }, + reset() { // If onReset prop is defined from outside, // notify component that a form reset is happening. @@ -69,9 +74,9 @@ let Form = React.createClass({ this.props.onReset(); } - for(let ref in this.refs) { - if(typeof this.refs[ref].reset === 'function') { - this.refs[ref].reset(); + for(let ref in this._refs) { + if(typeof this._refs[ref].reset === 'function') { + this._refs[ref].reset(); } } this.setState(this.getInitialState()); @@ -124,8 +129,8 @@ let Form = React.createClass({ getFormData() { let data = {}; - for (let refName in this.refs) { - const ref = this.refs[refName]; + for (let refName in this._refs) { + const ref = this._refs[refName]; if (ref.state && 'value' in ref.state) { // An input can also provide an `Object` as a value @@ -154,9 +159,9 @@ let Form = React.createClass({ this.props.handleSuccess(response); } - for(let ref in this.refs) { - if(this.refs[ref] && typeof this.refs[ref].handleSuccess === 'function'){ - this.refs[ref].handleSuccess(response); + for(let ref in this._refs) { + if(this._refs[ref] && typeof this._refs[ref].handleSuccess === 'function'){ + this._refs[ref].handleSuccess(response); } } this.setState({ @@ -168,8 +173,8 @@ let Form = React.createClass({ handleError(err) { if (err.json) { for (let input in err.json.errors){ - if (this.refs && this.refs[input] && this.refs[input].state) { - this.refs[input].setErrors(err.json.errors[input]); + if (this._refs && this._refs[input] && this._refs[input].state) { + this._refs[input].setErrors(err.json.errors[input]); } else { this.setState({errors: this.state.errors.concat(err.json.errors[input])}); } @@ -196,9 +201,9 @@ let Form = React.createClass({ }, clearErrors() { - for(let ref in this.refs){ - if (this.refs[ref] && typeof this.refs[ref].clearErrors === 'function'){ - this.refs[ref].clearErrors(); + for(let ref in this._refs){ + if (this._refs[ref] && typeof this._refs[ref].clearErrors === 'function'){ + this._refs[ref].clearErrors(); } } this.setState({errors: []}); @@ -247,17 +252,19 @@ let Form = React.createClass({ renderChildren() { return ReactAddons.Children.map(this.props.children, (child, i) => { if (child) { - // Since refs will be overwritten by this functions return statement, - // we still want to be able to define refs for nested `Form` or `Property` - // children, which is why we're upfront simply invoking the callback-ref- - // function before overwriting it. - if(typeof child.ref === 'function' && this.refs[child.props.name]) { - child.ref(this.refs[child.props.name]); - } - return React.cloneElement(child, { handleChange: this.handleChangeChild, - ref: child.props.name, + ref: (ref) => { + this._refs[child.props.name] = ref; + + // Since refs will be overwritten by this functions return statement, + // we still want to be able to define refs for nested `Form` or `Property` + // children, which is why we're upfront simply invoking the callback-ref- + // function before overwriting it. + if (typeof child.ref === 'function') { + child.ref(ref); + } + }, key: i, // We need this in order to make editable be overridable when setting it directly // on Property @@ -338,10 +345,10 @@ let Form = React.createClass({ const validatedFormInputs = {}; Object - .keys(this.refs) + .keys(this._refs) .forEach((refName) => { let refToValidate = {}; - const property = this.refs[refName]; + const property = this._refs[refName]; const input = property.refs.input; const value = input.getDOMNode().value || input.state.value; const { max, diff --git a/js/components/ascribe_forms/form_register_piece.js b/js/components/ascribe_forms/form_register_piece.js index 97e89c3d..be4c8808 100644 --- a/js/components/ascribe_forms/form_register_piece.js +++ b/js/components/ascribe_forms/form_register_piece.js @@ -58,6 +58,11 @@ let RegisterPieceForm = React.createClass({ } }, + componentWillMount() { + // Set up internal storage for callback refs + this._refs = {}; + }, + /** * This method is overloaded so that we can track the ready-state * of each uploader in the component @@ -88,7 +93,7 @@ let RegisterPieceForm = React.createClass({ handleChangedThumbnail(thumbnailFile) { const { digitalWorkFile } = this.state; - const { fineuploader } = this.refs.digitalWorkFineUploader.refs; + const { fineuploader } = this._refs.digitalWorkFineUploader.refs; fineuploader.setThumbnailForFileId( digitalWorkFile.id, @@ -160,7 +165,7 @@ let RegisterPieceForm = React.createClass({ ignoreFocus={true} label={getLangText('Your Work')}> this.refs.digitalWorkFineUploader = ref} + ref={ref => this._refs.digitalWorkFineUploader = ref} keyRoutine={{ url: AppConstants.serverUrl + 's3/key/', fileClass: 'digitalwork' @@ -182,7 +187,7 @@ let RegisterPieceForm = React.createClass({ name="thumbnail_file" expanded={this.isThumbnailDialogExpanded()}> this.refs.thumbnailFineUploader = ref} + ref={ref => this._refs.thumbnailFineUploader = ref} fileInputElement={UploadButton({ className: 'btn btn-secondary btn-sm' })} createBlobRoutine={{ url: ApiUrls.blob_thumbnails diff --git a/js/components/ascribe_forms/property.js b/js/components/ascribe_forms/property.js index b8b90400..7450459a 100644 --- a/js/components/ascribe_forms/property.js +++ b/js/components/ascribe_forms/property.js @@ -77,6 +77,11 @@ const Property = React.createClass({ }; }, + componentWillMount() { + // Set up internal storage for callback refs + this._refs = {}; + }, + componentDidMount() { if(this.props.autoFocus) { this.handleFocus(); @@ -84,7 +89,7 @@ const Property = React.createClass({ }, componentWillReceiveProps(nextProps) { - let childInput = this.refs.input; + let childInput = this._refs.input; // For expanded there are actually three use cases: // @@ -124,7 +129,7 @@ const Property = React.createClass({ }, reset() { - let input = this.refs.input; + let input = this._refs.input; // maybe do reset by reload instead of front end state? this.setState({value: this.state.initialValue}); @@ -179,11 +184,11 @@ const Property = React.createClass({ } // skip the focus of non-input elements let nonInputHTMLElements = ['pre', 'div']; - if (this.refs.input && - nonInputHTMLElements.indexOf(this.refs.input.getDOMNode().nodeName.toLowerCase()) > -1 ) { + if (this._refs.input && + nonInputHTMLElements.indexOf(this._refs.input.getDOMNode().nodeName.toLowerCase()) > -1 ) { return; } - this.refs.input.getDOMNode().focus(); + this._refs.input.getDOMNode().focus(); this.setState({ isFocused: true }); @@ -205,7 +210,7 @@ const Property = React.createClass({ errors: null, // also update initialValue in case of the user updating and canceling its actions again - initialValue: this.refs.input.getDOMNode().value + initialValue: this._refs.input.getDOMNode().value }); }, @@ -262,25 +267,29 @@ const Property = React.createClass({ // if the component is actually being shown (!== 'expanded === false') if((this.state.expanded && this.props.checkboxLabel) || !this.props.checkboxLabel) { return ReactAddons.Children.map(this.props.children, (child) => { - // Since refs will be overriden by this functions return statement, - // we still want to be able to define refs for nested `Form` or `Property` - // children, which is why we're upfront simply invoking the callback-ref- - // function before overriding it. - if(typeof child.ref === 'function' && this.refs.input) { - child.ref(this.refs.input); - } - - return React.cloneElement(child, { + const childWithProps = React.cloneElement(child, { style, onChange: this.handleChange, onFocus: this.handleFocus, onBlur: this.handleBlur, setWarning: this.setWarning, disabled: !this.props.editable, - ref: 'input', + ref: (ref) => { + this._refs.input = ref; + + // Since refs will be overriden by this functions return statement, + // we still want to be able to define refs for nested `Form` or `Property` + // children, which is why we're upfront simply invoking the callback-ref- + // function before overriding it. + if (typeof child.ref === 'function') { + child.ref(ref); + } + }, name: this.props.name, setExpanded: this.setExpanded }); + + return childWithProps; }); } },