af4001ed80001db5185bbc7a64208d0976698679
[aai/sparky-fe.git] / src / generic-components / input / validation / ValidationForm.jsx
1 /*
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2017 Amdocs
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *       http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  *
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  */
23 /**
24         * ValidationForm should be used in order to have a form that handles it's
25         * internal validation state. All ValidationInputs inside the form are checked
26         * for validity and the styling and submit buttons are updated accordingly.
27         *
28         * The properties that ahould be given to the form:
29         * labledButtons - whether or not use icons only as the form default buttons or
30         * use buttons with labels onSubmit - function for click on the submit button
31         * onReset - function for click on the reset button
32         */
33 import React from 'react';
34 import ValidationButtons from './ValidationButtons.jsx';
35
36 class ValidationForm extends React.Component {
37                 
38                 static childContextTypes = {
39                                 validationParent: React.PropTypes.any,
40                                 isReadOnlyMode: React.PropTypes.bool
41                 };
42                 
43                 static defaultProps = {
44                                 hasButtons: true,
45                                 onSubmit: null,
46                                 onReset: null,
47                                 labledButtons: true,
48                                 onValidChange: null,
49                                 isValid: true
50                 };
51                 
52                 static propTypes = {
53                                 isValid: React.PropTypes.bool,
54                                 hasButtons: React.PropTypes.bool,
55                                 onSubmit: React.PropTypes.func,
56                                 onReset: React.PropTypes.func,
57                                 labledButtons: React.PropTypes.bool,
58                                 onValidChange: React.PropTypes.func
59                 };
60                 
61                 state = {
62                                 isValid: this.props.isValid
63                 };
64                 
65                 constructor(props) {
66                                 super(props);
67                                 this.validationComponents = [];
68                 }
69                 
70                 render() {
71                                 var buttons = (this.props.hasButtons) ?
72                                               <ValidationButtons labledButtons={this.props.labledButtons}
73                                                                  ref='buttons'
74                                                                  isReadOnlyMode={this.props.isReadOnlyMode}/>
75                                                 : null;
76                                 return (
77                                                 <form {...this.props} onSubmit={event => this.handleFormSubmit(event)}>
78                                                                 <div className='validation-form-content'>{this.props.children}</div>
79                                                                 {buttons}
80                                                 </form>
81                                 );
82                 }
83                 
84                 handleFormSubmit(event) {
85                                 event.preventDefault();
86                                 let isFormValid = true;
87                                 this.validationComponents.forEach(validationComponent => {
88                                                 const isInputValid = validationComponent.validate().isValid;
89                                                 isFormValid = isInputValid && isFormValid;
90                                 });
91                                 if (isFormValid && this.props.onSubmit) {
92                                                 this.props.onSubmit(event);
93                                 } else if (!isFormValid) {
94                                                 this.setState({isValid: false});
95                                 }
96                 };
97                 
98                 componentDidUpdate(prevProps, prevState) {
99                                 // only handling this programatically if the validation of the form is done
100                                 // outside of the view (example with a form that is dependent on the state
101                                 // of other forms)
102                                 if (prevProps.isValid !== this.props.isValid) {
103                                                 if (this.props.hasButtons) {
104                                                                 this.refs.buttons.setState({isValid: this.state.isValid});
105                                                 }
106                                 } else if (this.state.isValid !== prevState.isValid) {
107                                                 if (this.props.hasButtons) {
108                                                                 this.refs.buttons.setState({isValid: this.state.isValid});
109                                                 }
110                                                 // callback in case form is part of bigger picture in view
111                                                 if (this.props.onValidChange) {
112                                                                 this.props.onValidChange(this.state.isValid);
113                                                 }
114                                 }
115                 }
116                 
117                 componentDidMount() {
118                                 if (this.props.hasButtons) {
119                                                 this.refs.buttons.setState({isValid: this.state.isValid});
120                                 }
121                 }
122                 
123                 
124                 getChildContext() {
125                                 return {
126                                                 validationParent: this,
127                                                 isReadOnlyMode: this.props.isReadOnlyMode
128                                 };
129                 }
130                 
131                 
132                 /***
133                         * Used by ValidationInput in order to let the (parent) form know
134                         * the valid state. If there is a change in the state of the form,
135                         * the buttons will be updated.
136                         *
137                         * @param validationComponent
138                         * @param isValid
139                         */
140                 childValidStateChanged(validationComponent, isValid) {
141                                 if (isValid !== this.state.isValid) {
142                                                 let oldState = this.state.isValid;
143                                                 let newState = isValid &&
144                                                                 this.validationComponents.filter(
145                                                                                 otherValidationComponent => validationComponent !==
146                                                                                 otherValidationComponent).every(otherValidationComponent => {
147                                                                                 return otherValidationComponent.isValid();
148                                                                 });
149                                                 
150                                                 if (oldState !== newState) {
151                                                                 this.setState({isValid: newState});
152                                                 }
153                                 }
154                 }
155                 
156                 register(validationComponent) {
157                                 this.validationComponents.push(validationComponent);
158                 }
159                 
160                 unregister(validationComponent) {
161                                 this.childValidStateChanged(validationComponent, true);
162                                 this.validationComponents =
163                                                 this.validationComponents.filter(
164                                                                 otherValidationComponent => validationComponent !==
165                                                                 otherValidationComponent);
166                 }
167 }
168
169
170 export default ValidationForm;