1'use strict'; 2const FORM_VALIDATION_DELEGATOR = { 3 instances: {}, 4 delegateToSelector: function ( name ) { 5 return this.instances[name] || ("[name='" + name + "']"); 6 } 7}; 8 9function triggerBrowserValidation( $FormElement ) 10{ 11 let tempSubmitButton = document.createElement( 'button' ); 12 13 $FormElement[0].appendChild( tempSubmitButton ); 14 15 tempSubmitButton.click(); 16 17 $FormElement[0].removeChild( tempSubmitButton ); 18} 19 20function markInvalidInput( $input, errorMessage, takeFocus ) 21{ 22 $input.handleValidationResult( { 23 errorMessage: errorMessage, 24 value: $input.val(), 25 isValid: false, 26 takeFocus: takeFocus === undefined ? true : takeFocus 27 } ); 28} 29 30(function ( $ ) { 31 $.fn.handleValidationResult = function ( options ) { 32 let parameters = $.extend( { 33 isValid: false, 34 value: undefined, 35 errorMessage: '', 36 takeFocus: false 37 }, options ); 38 39 const $targetInputElement = this; 40 41 function appendValidationMessage( $additions ) 42 { 43 const $inputParent = $targetInputElement.parent(); 44 // additions should follow after the input group 45 if ( $inputParent.hasClass( 'input-group' ) ) 46 { 47 // do not display cross-sign in the input groups 48 $additions.filter( '.glyphicon-remove' ).css( 'display', 'none' ); 49 $inputParent.after( $additions ); 50 } 51 else if ( ($inputParent.prop( 'tagName' ).toUpperCase() === 'LABEL' && $targetInputElement.attr( 'type' ) === 'checkbox') 52 || ($inputParent.hasClass( 'multiselect-native-select' )) ) 53 { 54 // workaround for checkbox with bootstrap layout 55 $inputParent.append( $additions ); 56 } 57 else 58 { 59 $targetInputElement.after( $additions ); 60 } 61 } 62 63 if ( $targetInputElement.length && $targetInputElement.is( ':visible' ) ) 64 { 65 const inputSelectorObj = CONSTANTS.inputElementSelectorFn( $targetInputElement ); 66 let inputSelectorAttribute = inputSelectorObj.selectorAttribute; 67 let inputSelector = inputSelectorObj.selector; 68 let isTextInput = $targetInputElement.prop( 'tagName' ) === 'INPUT' 69 && CONSTANTS.EDITABLE_INPUTS_REGEX.test( $targetInputElement.attr( 'type' ) ); 70 let isEditable = isTextInput || $targetInputElement.prop( 'tagName' ) === 'TEXTAREA'; 71 72 // set editable values 73 if ( isEditable && parameters.value != null ) 74 { 75 $targetInputElement.val( parameters.value ); 76 } 77 78 if ( !parameters.isValid ) 79 { 80 // additions 81 let errorAdditionsMarkerClass = CONSTANTS.errorAdditionMarkerClassFn( inputSelectorAttribute ); 82 83 // remove if already has error additions 84 $( '.' + errorAdditionsMarkerClass ).remove(); 85 86 // adding new additions 87 let $additions = $( isTextInput ? CONSTANTS.TEXT_INPUT_ERROR_ADDITIONS : CONSTANTS.OTHER_INPUT_ERROR_ADDITIONS ); 88 89 // add error message addition 90 let $formValidationErrorMessageAddition = $additions.filter( CONSTANTS.FORM_VALIDATION_ERROR_MESSAGE_SELECTOR ).first(); 91 $formValidationErrorMessageAddition.addClass( errorAdditionsMarkerClass ); 92 $formValidationErrorMessageAddition.text( parameters.errorMessage ); 93 94 // add cross-sign addition for the text input 95 if ( isTextInput ) 96 { 97 let $formValidationAreaDescriberAddition = $additions.filter( CONSTANTS.FORM_VALIDATION_AREA_DESCRIBER_SELECTOR ).first(); 98 let formValidationAreaDescriberAdditionId = CONSTANTS.areaDescriberAdditionIdFn( inputSelectorAttribute ); 99 $formValidationAreaDescriberAddition.attr( 'id', formValidationAreaDescriberAdditionId ); 100 $formValidationAreaDescriberAddition.addClass( errorAdditionsMarkerClass ); 101 $targetInputElement.attr( 'aria-describedby', formValidationAreaDescriberAdditionId ); 102 } 103 104 appendValidationMessage( $additions ); 105 106 // styles 107 let $inputElementContainer = $targetInputElement.closest( CONSTANTS.FORM_VALIDATION_INPUT_CONTAINER_SELECTOR ); 108 109 const bootstrapDropDown = $inputElementContainer.find( 'button.multiselect' ); 110 111 if ( bootstrapDropDown.length > 0 ) 112 { 113 $inputElementContainer = bootstrapDropDown; 114 } 115 116 $inputElementContainer.addClass( CONSTANTS.ERROR_CLASSES ); 117 118 // wait until user action and remove errors 119 let resetValidation = function () { 120 let errorMessageSelector = bootstrapDropDown.length > 0 ? 121 $inputElementContainer.closest( '.multiselect-native-select' ).find( CONSTANTS.FORM_VALIDATION_ADDITION_SELECTOR ) : 122 $inputElementContainer.find( CONSTANTS.FORM_VALIDATION_ADDITION_SELECTOR ); 123 124 errorMessageSelector.fadeOut( 'fast', function () { 125 $inputElementContainer.removeClass( CONSTANTS.ERROR_CLASSES ); 126 $( this ).remove(); 127 } ); 128 129 $( 'body' ).off( isEditable ? 'input change disable resetValidation' : 'change disable resetValidation', inputSelector, resetValidation ); 130 }; 131 132 $( 'body' ).on( isEditable ? 'input change disable resetValidation' : 'change disable resetValidation', inputSelector, resetValidation ); 133 134 if ( parameters.takeFocus ) 135 { 136 // focus workaround for the case when input is enabled in javascript on document load 137 setTimeout( function () { 138 $targetInputElement.trigger( 'focus' ); 139 } ) 140 } 141 } 142 } 143 144 $( document ).trigger( "formValidation:handled", parameters ); 145 }; 146 147 const CONSTANTS = { 148 // strings 149 EDITABLE_INPUTS_REGEX: /^(?:text|email|number|search|tel|url|password)$/i, 150 ERROR_CLASSES: 'has-error has-feedback', 151 FORM_VALIDATION_ADDITION_SELECTOR: '.formValidation-addition', 152 FORM_VALIDATION_ERROR_MESSAGE_SELECTOR: '.formValidation-errorMessage', 153 FORM_VALIDATION_AREA_DESCRIBER_SELECTOR: '.formValidation-areaDescriber', 154 FORM_VALIDATION_INPUT_CONTAINER_SELECTOR: '.form-group,.row,.bs__form_control__block,.validationMessageContainer', 155 156 // functions 157 errorAdditionMarkerClassFn: function ( inputName ) { 158 return 'formValidation-additions-for-' + inputName; 159 }, 160 areaDescriberAdditionIdFn: function ( inputName ) { 161 return 'formValidation-areaDescriber-addition-for-' + inputName; 162 }, 163 inputElementSelectorFn: function ( $targetInputElement ) { 164 165 const inputName = $targetInputElement.attr( 'name' ); 166 167 if ( !isBlank( inputName ) ) 168 { 169 return { 170 selectorAttribute: inputName, 171 selector: "[name='" + inputName + "']" 172 } 173 } 174 else 175 { 176 const inputId = $targetInputElement.attr( 'id' ); 177 178 return { 179 selectorAttribute: inputId, 180 selector: "#" + inputId 181 } 182 } 183 }, 184 185 // templates 186 TEXT_INPUT_ERROR_ADDITIONS: '<span class="glyphicon glyphicon-remove form-control-feedback formValidation-addition" aria-hidden="true"></span>\
187 <span class="text-danger formValidation-addition formValidation-errorMessage">Error Message</span>\ 188 <span class="sr-only formValidation-addition formValidation-areaDescriber">(error)</span>', 189 OTHER_INPUT_ERROR_ADDITIONS: '<span class="text-danger formValidation-addition formValidation-errorMessage">Error Message</span>' 190 } 191}( jQuery ));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.