mirror of
https://github.com/ascribe/onion.git
synced 2025-02-01 12:29:54 +01:00
Fix detachment of DOM <-> browser state
This commit is contained in:
parent
56d8268ceb
commit
59244f208a
58
js/components/ascribe_buttons/form_submit_button.js
Normal file
58
js/components/ascribe_buttons/form_submit_button.js
Normal file
@ -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 (
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-default btn-wide"
|
||||
disabled={!ready}>
|
||||
{label}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default FormSubmitButton;
|
@ -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={
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-default btn-wide"
|
||||
disabled={!(digitalWorkKeyReady && thumbnailKeyReady)}>
|
||||
{submitMessage}
|
||||
</button>
|
||||
<FormSubmitButton
|
||||
ref="submitButton"
|
||||
defaultReadyStates={{
|
||||
digitalWorkKeyReady: false,
|
||||
thumbnailKeyReady: true
|
||||
}}
|
||||
label={submitMessage}/>
|
||||
}
|
||||
spinner={
|
||||
<span className="btn btn-default btn-wide btn-spinner">
|
||||
|
Loading…
Reference in New Issue
Block a user