diff --git a/js/components/ascribe_buttons/form_submit_button.js b/js/components/ascribe_buttons/form_submit_button.js new file mode 100644 index 00000000..087061d9 --- /dev/null +++ b/js/components/ascribe_buttons/form_submit_button.js @@ -0,0 +1,58 @@ +'use strict'; + +import React from 'react/addons'; + +const { string, object } = React.PropTypes; + +/** + * Originally, this button was introduced for `RegisterPieceForm`. + * The underlying problem that lead to the implementation was that multiple `InputFineuploader`s + * where displayed in one form. + * For the form's submit button always to represent an applicable state we had to save + * the ready states of the multiple uploaders in `RegisterPieceForm`. + * However, on each invocation of `this.setState`, we were re-rendering the form again, + * which caused (if the user had the file-selector open) a detachment between user input and + * displayed page. + * + * This button helps to outsource the state of the form's readiness to another component, + * to solve the problem. + */ +const FormSubmitButton = React.createClass({ + propTypes: { + defaultReadyStates: object.isRequired, + label: string.isRequired + }, + + getInitialState() { + return { + readyStates: this.props.defaultReadyStates + }; + }, + + setReadyStateForKey(key, state) { + const readyStates = React.addons.update(this.state.readyStates, { [key]: { $set: state } }); + this.setState({ readyStates }); + }, + + render() { + const { label } = this.props; + const { readyStates } = this.state; + + // Reduce all readyStates to a single boolean + const ready = Object.keys(readyStates) + .reduce((defaultState, stateKey) => { + return defaultState && readyStates[stateKey]; + }, true); + + return ( + + ); + } +}); + +export default FormSubmitButton; \ No newline at end of file diff --git a/js/components/ascribe_forms/form_register_piece.js b/js/components/ascribe_forms/form_register_piece.js index 39dd925d..76bbd68e 100644 --- a/js/components/ascribe_forms/form_register_piece.js +++ b/js/components/ascribe_forms/form_register_piece.js @@ -9,6 +9,7 @@ import Form from './form'; import Property from './property'; import InputFineUploader from './input_fineuploader'; import UploadButton from '../ascribe_uploader/ascribe_upload_button/upload_button'; +import FormSubmitButton from '../ascribe_buttons/form_submit_button'; import ApiUrls from '../../constants/api_urls'; import AppConstants from '../../constants/application_constants'; @@ -77,9 +78,9 @@ let RegisterPieceForm = React.createClass({ */ setIsUploadReady(uploaderKey) { return (isUploadReady) => { - this.setState({ - [uploaderKey]: isUploadReady - }); + // See documentation of `FormSubmitButton` for more detailed information + // on this. + this.refs.submitButton.setReadyStateForKey(uploaderKey, isUploadReady); }; }, @@ -89,7 +90,7 @@ let RegisterPieceForm = React.createClass({ if(validFiles.length > 0) { const { type: mimeType } = validFiles[0]; const mimeSubType = mimeType && mimeType.split('/').length ? mimeType.split('/')[1] - : 'unknown'; + : 'unknown'; const thumbnailKeyDialogExpanded = AppConstants.supportedThumbnailFileFormats.indexOf(mimeSubType) === -1; this.setState({ thumbnailKeyDialogExpanded }); } else { @@ -122,8 +123,6 @@ let RegisterPieceForm = React.createClass({ children, enableLocalHashing } = this.props; const { currentUser, - digitalWorkKeyReady, - thumbnailKeyReady, thumbnailKeyDialogExpanded } = this.state; const profileHashLocally = currentUser && currentUser.profile ? currentUser.profile.hash_locally : false; @@ -137,12 +136,13 @@ let RegisterPieceForm = React.createClass({ url={ApiUrls.pieces_list} handleSuccess={handleSuccess} buttons={ - + } spinner={