diff options
author | Michael Lando <ml636r@att.com> | 2017-02-19 12:57:33 +0200 |
---|---|---|
committer | Michael Lando <ml636r@att.com> | 2017-02-19 13:47:13 +0200 |
commit | efa037d34be7b1570efdc767c79fad8d4005f10e (patch) | |
tree | cf1036ba2728dea8a61492b678fa91954e629403 /openecomp-ui/src/nfvo-components/input/validation/ValidationForm.jsx | |
parent | f5f13c4f6b6fe3b4d98e349dfd7db59339803436 (diff) |
Add new code new version
Change-Id: Ic02a76313503b526f17c3df29eb387a29fe6a42a
Signed-off-by: Michael Lando <ml636r@att.com>
Diffstat (limited to 'openecomp-ui/src/nfvo-components/input/validation/ValidationForm.jsx')
-rw-r--r-- | openecomp-ui/src/nfvo-components/input/validation/ValidationForm.jsx | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/openecomp-ui/src/nfvo-components/input/validation/ValidationForm.jsx b/openecomp-ui/src/nfvo-components/input/validation/ValidationForm.jsx new file mode 100644 index 0000000000..098ccf1fd4 --- /dev/null +++ b/openecomp-ui/src/nfvo-components/input/validation/ValidationForm.jsx @@ -0,0 +1,200 @@ +/** + * ValidationForm should be used in order to have a form that handles it's internal validation state. + * All ValidationInputs inside the form are checked for validity and the styling and submit buttons + * are updated accordingly. + * + * The properties that ahould be given to the form: + * labledButtons - whether or not use icons only as the form default buttons or use buttons with labels + * onSubmit - function for click on the submit button + * onReset - function for click on the reset button + */ +import React from 'react'; +import JSONSchema from 'nfvo-utils/json/JSONSchema.js'; +import JSONPointer from 'nfvo-utils/json/JSONPointer.js'; +import ValidationButtons from './ValidationButtons.jsx'; + +class ValidationForm extends React.Component { + + static childContextTypes = { + validationParent: React.PropTypes.any, + isReadOnlyMode: React.PropTypes.bool, + validationSchema: React.PropTypes.instanceOf(JSONSchema), + validationData: React.PropTypes.object + }; + + static defaultProps = { + hasButtons : true, + onSubmit : null, + onReset : null, + labledButtons: true, + onValidChange : null, + isValid: true + }; + + static propTypes = { + isValid : React.PropTypes.bool, + isReadOnlyMode : React.PropTypes.bool, + hasButtons : React.PropTypes.bool, + onSubmit : React.PropTypes.func, + onReset : React.PropTypes.func, + labledButtons: React.PropTypes.bool, + onValidChange : React.PropTypes.func, + onValidityChanged: React.PropTypes.func, + schema: React.PropTypes.object, + data: React.PropTypes.object + }; + + state = { + isValid: this.props.isValid + }; + + constructor(props) { + super(props); + this.validationComponents = []; + } + + componentWillMount() { + let {schema, data} = this.props; + if (schema) { + this.processSchema(schema, data); + } + } + + componentWillReceiveProps(nextProps) { + let {schema, data} = this.props; + let {schema: nextSchema, data: nextData} = nextProps; + + if (schema !== nextSchema || data !== nextData) { + if (!schema || !nextSchema) { + throw new Error('ValidationForm: dynamically adding/removing schema is not supported'); + } + + if (schema !== nextSchema) { + this.processSchema(nextSchema, nextData); + } else { + this.setState({data: nextData}); + } + } + } + + processSchema(rawSchema, rawData) { + let schema = new JSONSchema(); + schema.setSchema(rawSchema); + let data = schema.processData(rawData); + this.setState({ + schema, + data + }); + } + + render() { + // eslint-disable-next-line no-unused-vars + let {isValid, isReadOnlyMode, hasButtons, onSubmit, labledButtons, onValidChange, onValidityChanged, schema, data, children, ...formProps} = this.props; + return ( + <form {...formProps} onSubmit={event => this.handleFormSubmit(event)}> + <div className='validation-form-content'>{children}</div> + {hasButtons && <ValidationButtons labledButtons={labledButtons} ref='buttons' isReadOnlyMode={isReadOnlyMode}/>} + </form> + ); + } + + handleFormSubmit(event) { + event.preventDefault(); + let isFormValid = true; + this.validationComponents.forEach(validationComponent => { + const isInputValid = validationComponent.validate().isValid; + isFormValid = isInputValid && isFormValid; + }); + if(isFormValid && this.props.onSubmit) { + return this.props.onSubmit(event); + } else if(!isFormValid) { + this.setState({isValid: false}); + } + } + + componentWillUpdate(nextProps, nextState) { + if(this.state.isValid !== nextState.isValid && this.props.onValidityChanged) { + this.props.onValidityChanged(nextState.isValid); + } + } + + componentDidUpdate(prevProps, prevState) { + // only handling this programatically if the validation of the form is done outside of the view + // (example with a form that is dependent on the state of other forms) + if (prevProps.isValid !== this.props.isValid) { + if (this.props.hasButtons) { + this.refs.buttons.setState({isValid: this.state.isValid}); + } + } else if(this.state.isValid !== prevState.isValid) { + if (this.props.hasButtons) { + this.refs.buttons.setState({isValid: this.state.isValid}); + } + // callback in case form is part of bigger picture in view + if (this.props.onValidChange) { + this.props.onValidChange(this.state.isValid); + } + } + } + + componentDidMount() { + if (this.props.hasButtons) { + this.refs.buttons.setState({isValid: this.state.isValid}); + } + } + + + getChildContext() { + return { + validationParent: this, + isReadOnlyMode: this.props.isReadOnlyMode, + validationSchema: this.state.schema, + validationData: this.state.data + }; + } + + + /*** + * Used by ValidationInput in order to let the (parent) form know + * the valid state. If there is a change in the state of the form, + * the buttons will be updated. + * + * @param validationComponent + * @param isValid + */ + childValidStateChanged(validationComponent, isValid) { + if (isValid !== this.state.isValid) { + let oldState = this.state.isValid; + let newState = isValid && this.validationComponents.filter(otherValidationComponent => validationComponent !== otherValidationComponent).every(otherValidationComponent => { + return otherValidationComponent.isValid(); + }); + + if (oldState !== newState) { + this.setState({isValid: newState}); + } + } + } + + register(validationComponent) { + if (this.state.schema) { + // TODO: register + } else { + this.validationComponents.push(validationComponent); + } + } + + unregister(validationComponent) { + this.childValidStateChanged(validationComponent, true); + this.validationComponents = this.validationComponents.filter(otherValidationComponent => validationComponent !== otherValidationComponent); + } + + onValueChanged(pointer, value, isValid, error) { + this.props.onDataChanged({ + data: JSONPointer.setValue(this.props.data, pointer, value), + isValid, + error + }); + } +} + + +export default ValidationForm; |