| Conditions | 1 |
| Paths | 24 |
| Total Lines | 206 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 2 | ||
| Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | /** global: CustomEvent, GLSR, HTMLFormElement, StarRating */ |
||
| 2 | ;(function() { |
||
| 3 | |||
| 4 | 'use strict'; |
||
| 5 | |||
| 6 | var Form = function( formEl, buttonEl ) { // HTMLElement, HTMLElement |
||
| 7 | this.button = buttonEl; |
||
| 8 | this.enableButton = this.enableButton_.bind( this ); |
||
| 9 | this.form = formEl; |
||
| 10 | this.recaptcha = new GLSR.Recaptcha( this ); |
||
| 11 | this.submitForm = this.submitForm_.bind( this ); |
||
| 12 | this.init_(); |
||
| 13 | }; |
||
| 14 | |||
| 15 | Form.prototype = { |
||
| 16 | config: { |
||
| 17 | fieldErrorsClass: 'glsr-field-errors', |
||
| 18 | fieldSelector: '.glsr-field', |
||
| 19 | formMessagesClass: 'glsr-form-messages', |
||
| 20 | hasErrorClass: 'glsr-has-error', |
||
| 21 | }, |
||
| 22 | |||
| 23 | /** @return void */ |
||
| 24 | addRemoveClass_: function( el, classValue, bool ) { // HTMLElement, string, bool |
||
| 25 | el.classList[bool ? 'add' : 'remove']( classValue ); |
||
| 26 | }, |
||
| 27 | |||
| 28 | /** @return void */ |
||
| 29 | clearFieldError_: function( el ) { // HTMLElement |
||
| 30 | var fieldEl = el.closest( this.config.fieldSelector ); |
||
| 31 | if( fieldEl === null )return; |
||
| 32 | fieldEl.classList.remove( this.config.hasErrorClass ); |
||
| 33 | var errorEl = fieldEl.querySelector( this.config.fieldErrorsSelector ); |
||
| 34 | if( errorEl !== null ) { |
||
| 35 | errorEl.parentNode.removeChild( errorEl ); |
||
| 36 | } |
||
| 37 | }, |
||
| 38 | |||
| 39 | /** @return void */ |
||
| 40 | clearFormErrors_: function() { |
||
| 41 | this.getResultsEl_().innerHTML = ''; |
||
| 42 | for( var i = 0; i < this.form.length; i++ ) { |
||
| 43 | this.clearFieldError_( this.form[i] ); |
||
| 44 | } |
||
| 45 | }, |
||
| 46 | |||
| 47 | /** @return void */ |
||
| 48 | disableButton_: function() { |
||
| 49 | this.button.setAttribute( 'disabled', '' ); |
||
| 50 | }, |
||
| 51 | |||
| 52 | /** @return void */ |
||
| 53 | enableButton_: function() { |
||
| 54 | this.button.removeAttribute( 'disabled' ); |
||
| 55 | }, |
||
| 56 | |||
| 57 | /** @return void */ |
||
| 58 | fallbackSubmit_: function() { |
||
| 59 | if( GLSR.Ajax.isFileAPISupported() && GLSR.Ajax.isFormDataSupported() && GLSR.Ajax.isUploadSupported() )return; |
||
| 60 | this.form.submit(); |
||
| 61 | }, |
||
| 62 | |||
| 63 | /** @return void */ |
||
| 64 | handleResponse_: function( response ) { // object |
||
| 65 | console.log( response ); |
||
|
|
|||
| 66 | if( response.recaptcha === true ) { |
||
| 67 | console.log( 'executing recaptcha' ); |
||
| 68 | this.recaptcha.execute(); |
||
| 69 | return; |
||
| 70 | } |
||
| 71 | if( response.recaptcha === 'reset' ) { |
||
| 72 | console.log( 'reseting failed recaptcha' ); |
||
| 73 | this.recaptcha.reset(); |
||
| 74 | } |
||
| 75 | if( response.errors === false ) { |
||
| 76 | console.log( 'reseting recaptcha' ); |
||
| 77 | this.recaptcha.reset(); |
||
| 78 | this.form.reset(); |
||
| 79 | } |
||
| 80 | console.log( 'submission finished' ); |
||
| 81 | this.showFieldErrors_( response.errors ); |
||
| 82 | this.showResults_( response ); |
||
| 83 | this.enableButton_(); |
||
| 84 | response.form = this.form; |
||
| 85 | document.dispatchEvent( new CustomEvent( 'site-reviews/after/submission', { detail: response })); |
||
| 86 | }, |
||
| 87 | |||
| 88 | /** @return HTMLDivElement */ |
||
| 89 | getFieldErrorsEl_: function( fieldEl ) { // HTMLElement |
||
| 90 | var errorsEl = fieldEl.querySelector( '.' + this.config.fieldErrorsClass ); |
||
| 91 | if( errorsEl === null ) { |
||
| 92 | errorsEl = document.createElement( 'div' ); |
||
| 93 | errorsEl.setAttribute( 'class', this.config.fieldErrorsClass ); |
||
| 94 | fieldEl.appendChild( errorsEl ); |
||
| 95 | } |
||
| 96 | return errorsEl; |
||
| 97 | }, |
||
| 98 | |||
| 99 | /** @return object */ |
||
| 100 | getFormData_: function( recaptchaToken ) { // string|null |
||
| 101 | recaptchaToken = recaptchaToken || ''; |
||
| 102 | var formData = new FormData( this.form ); |
||
| 103 | formData.append( 'g-recaptcha-response', recaptchaToken ); |
||
| 104 | return formData; |
||
| 105 | }, |
||
| 106 | |||
| 107 | /** @return HTMLDivElement */ |
||
| 108 | getResultsEl_: function() { |
||
| 109 | var resultsEl = this.form.querySelector( '.' + this.config.formMessagesClass ); |
||
| 110 | if( resultsEl === null ) { |
||
| 111 | resultsEl = document.createElement( 'div' ); |
||
| 112 | resultsEl.setAttribute( 'class', this.config.formMessagesClass ); |
||
| 113 | this.button.parentNode.insertBefore( resultsEl, this.button.nextSibling ); |
||
| 114 | } |
||
| 115 | return resultsEl; |
||
| 116 | }, |
||
| 117 | |||
| 118 | /** @return void */ |
||
| 119 | init_: function() { |
||
| 120 | this.button.addEventListener( 'click', this.onClick_.bind( this )); |
||
| 121 | this.form.addEventListener( 'change', this.onChange_.bind( this )); |
||
| 122 | this.form.addEventListener( 'submit', this.onSubmit_.bind( this )); |
||
| 123 | this.initStarRatings_(); |
||
| 124 | }, |
||
| 125 | |||
| 126 | /** @return void */ |
||
| 127 | initStarRatings_: function() { |
||
| 128 | new StarRating( 'select.glsr-star-rating', { |
||
| 129 | clearable: false, |
||
| 130 | showText: false, |
||
| 131 | onClick: this.clearFieldError_.bind( this ), |
||
| 132 | }); |
||
| 133 | }, |
||
| 134 | |||
| 135 | /** @return void */ |
||
| 136 | onChange_: function( ev ) { // Event |
||
| 137 | this.clearFieldError_( ev.target ); |
||
| 138 | }, |
||
| 139 | |||
| 140 | /** |
||
| 141 | * This event method handles the mayhem caused by the invisible-recaptcha plugin |
||
| 142 | * and is triggered on the invisible-recaptcha callback |
||
| 143 | * @return void */ |
||
| 144 | onClick_: function() { |
||
| 145 | var form = this; |
||
| 146 | this.form.onsubmit = null; |
||
| 147 | HTMLFormElement.prototype._submit = HTMLFormElement.prototype.submit; |
||
| 148 | HTMLFormElement.prototype.submit = function() { |
||
| 149 | var token = this.querySelector( '#g-recaptcha-response' ); |
||
| 150 | if( null !== token && this.querySelector( form.config.fieldSelector )) { |
||
| 151 | form.submitForm_( token.value ); |
||
| 152 | return; |
||
| 153 | } |
||
| 154 | this._submit(); |
||
| 155 | }; |
||
| 156 | }, |
||
| 157 | |||
| 158 | /** @return void */ |
||
| 159 | onSubmit_: function( ev ) { // HTMLEvent |
||
| 160 | if( this.form.classList.contains( 'no-ajax' ))return; |
||
| 161 | ev.preventDefault(); |
||
| 162 | this.recaptcha.addListeners(); |
||
| 163 | this.clearFormErrors_(); |
||
| 164 | this.submitForm_(); |
||
| 165 | }, |
||
| 166 | |||
| 167 | /** @return void */ |
||
| 168 | showFieldErrors_: function( errors ) { // object |
||
| 169 | if( !errors )return; |
||
| 170 | var fieldEl, errorsEl; |
||
| 171 | for( var error in errors ) { |
||
| 172 | fieldEl = this.form.querySelector( '[name=' + error + ']' ).closest( this.config.fieldSelector ); |
||
| 173 | fieldEl.classList.add( this.config.hasErrorClass ); |
||
| 174 | errorsEl = this.getFieldErrorsEl_( fieldEl ); |
||
| 175 | for( var i = 0; i < errors[error].errors.length; i++ ) { |
||
| 176 | errorsEl.innerHTML += errors[error].errors[i]; |
||
| 177 | } |
||
| 178 | } |
||
| 179 | }, |
||
| 180 | |||
| 181 | /** @return void */ |
||
| 182 | showResults_: function( response ) { // object |
||
| 183 | var resultsEl = this.getResultsEl_(); |
||
| 184 | this.addRemoveClass_( resultsEl, 'gslr-has-errors', !!response.errors ); |
||
| 185 | resultsEl.innerHTML = response.message; |
||
| 186 | }, |
||
| 187 | |||
| 188 | /** @return void */ |
||
| 189 | submitForm_: function( recaptchaToken ) { // string|null |
||
| 190 | this.disableButton_(); |
||
| 191 | this.fallbackSubmit_(); |
||
| 192 | GLSR.Ajax.post( this.getFormData_( recaptchaToken ), this.handleResponse_.bind( this ), { |
||
| 193 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', |
||
| 194 | }); |
||
| 195 | }, |
||
| 196 | }; |
||
| 197 | |||
| 198 | GLSR.Forms = function() { |
||
| 199 | this.nodeList = document.querySelectorAll( 'form.glsr-form' ); |
||
| 200 | this.forms = []; |
||
| 201 | for( var i = 0; i < this.nodeList.length; i++ ) { |
||
| 202 | var submitButton = this.nodeList[i].querySelector( '[type=submit]' ); |
||
| 203 | if( !submitButton )continue; |
||
| 204 | this.forms.push( new Form( this.nodeList[i], submitButton )); |
||
| 205 | } |
||
| 206 | }; |
||
| 207 | })(); |
||
| 208 |