%PDF- %PDF-
Direktori : /home1/lightco1/www/media/system/js/ |
Current File : //home1/lightco1/www/media/system/js/html5fallback-uncompressed.js |
/** * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ /** * Unobtrusive Form Validation and HTML5 Form polyfill library * * Inspired by: Ryan Seddon <http://thecssninja.com/javascript/H5F> * * @package Joomla.Framework * @subpackage Forms */ ( function( $, document, undefined ) { "use strict"; // Utility function if ( typeof Object.create !== 'function' ) { Object.create = function( obj ) { function F() {} F.prototype = obj; return new F(); }; } var features = ( function( el, item ) { var attributes = [ 'required', 'pattern', 'placeholder', 'autofocus', 'formnovalidate' ], types = [ 'email', 'url', 'number', 'range' ], result = { attributes: {}, types: {} }; while ( item = attributes.pop() ) { result.attributes[ item ] = !!( item in el ); } while ( item = types.pop() ) { el.setAttribute( 'type', item ); result.types[ item ] = ( el.type == item ); } return result; }( document.createElement( "input" ) ) ); var H5Form = { /** * Init function, prepares the form for for validation * * @param object options Some options to override the defaults. * @param Element elem The form or element to validate. * * @return void */ init: function( options, elem ) { var self = this; self.elem = elem; self.$elem = $( elem ); elem.H5Form = self; self.options = $.extend( {}, $.fn.h5f.options, options ); // Check whether the element is form or not if ( elem.nodeName.toLowerCase() === "form" ) { self.bindWithForm( self.elem, self.$elem ); } }, /** * Attach the validation behaviors to the form * * @param Element form The form element * @param jQuery $form A jQuery object containing the form * * @return void */ bindWithForm: function( form, $form ) { var self = this, novalidate = !!$form.attr( 'novalidate' ), f = form.elements, flen = f.length, formnovalidate; if ( self.options.formValidationEvent === "onSubmit" ) { $form.on( 'submit', function( e ) { formnovalidate = this.H5Form.donotValidate !== undefined ? this.H5Form.donotValidate : false; if ( !formnovalidate && !novalidate && !self.validateForm( self ) ) { // Prevent form from submit e.preventDefault(); this.donotValidate = false; } else { $form.find( ':input' ) .each( function() { self.placeholder( self, this, 'submit' ); } ); } }); } $form.on( 'focusout focusin', function( event ) { self.placeholder( self, event.target, event.type ); }); $form.on( 'focusout change', self.validateField ); $form.find( 'fieldset' ) .on( 'change', function() { self.validateField( this ); }); if ( !features.attributes.formnovalidate ) { $form.find( ':submit[formnovalidate]' ) .on( 'click', function() { self.donotValidate = true; }); } while ( flen-- ) { // Assign graphical polyfills self.polyfill( f[ flen ] ); self.autofocus( self, f[ flen ] ); } }, /** * Apply the polyfills where applicable * * @param Element elem The element to apply polyfills to * * @return void */ polyfill: function( elem ) { if ( elem.nodeName.toLowerCase() === 'form' ) return true; var self = elem.form.H5Form; self.placeholder( self, elem ); self.numberType( self, elem ); }, /** * Validate the form * * @return boolean True if the form is valid, False if not */ validateForm: function() { var self = this, form = self.elem, f = form.elements, flen = f.length, isFieldValid = true, i, elem; form.isValid = true; for ( i = 0; i < flen; i++ ) { elem = f[ i ]; elem.isRequired = !!elem.required; if (elem.isDisabled) { elem.isDisabled = !!elem.disabled; } //Do Validation if ( !elem.isDisabled ) { isFieldValid = self.validateField( elem ); // Set focus to first invalid field if ( form.isValid && !isFieldValid ) { self.setFocusOn( elem ); } form.isValid = isFieldValid && form.isValid; } } if ( self.options.doRenderMessage ) { self.renderErrorMessages( self, form ); } return form.isValid; }, /** * Validate a field * * @param mixed e Either an Event or Element * * @return mixed True if the field is valid, False if not, null if the field has no form. */ validateField: function( e ) { var elem = e.target || e, isMissing = false, isRequired = false, isDisabled = false, isPatternMismatched = false, self, $elem, $labelref; if ( elem.form === undefined ) { return null; } self = elem.form.H5Form; $elem = $( elem ); isRequired = !!$elem.attr( "required" ); isDisabled = !!$elem.attr( "disabled" ); if ( !elem.isDisabled ) { isMissing = !features.attributes.required && isRequired && self.isValueMissing( self, elem ); isPatternMismatched = !features.attributes.pattern && self.matchPattern( self, elem ); } elem.validityState = { valueMissing: isMissing, patternMismatch: isPatternMismatched, valid: ( elem.isDisabled || !( isMissing || isPatternMismatched ) ) }; if ( !features.attributes.required ) { if ( elem.validityState.valueMissing ) { $elem.addClass( self.options.requiredClass ); } else { $elem.removeClass( self.options.requiredClass ); } } if ( !features.attributespattern ) { if ( elem.validityState.patternMismatch ) { $elem.addClass( self.options.patternClass ); } else { $elem.removeClass( self.options.patternClass ); } } if ( !elem.validityState.valid ) { $elem.addClass( self.options.invalidClass ); $labelref = self.findLabel( $elem ); $labelref.addClass( self.options.invalidClass ); $labelref.attr( 'aria-invalid', 'true' ); } else { $elem.removeClass( self.options.invalidClass ); $labelref = self.findLabel( $elem ); $labelref.removeClass( self.options.invalidClass ); $labelref.attr( 'aria-invalid', 'false' ); } return elem.validityState.valid; }, /** * Check if the field has no value * * @param H5Form self This * @param Element elem A field element to check * * @return Boolean */ isValueMissing: function( self, elem ) { var $elem = $( elem ), type = elem.type !== undefined ? elem.type : elem.tagName.toLowerCase(), isSpecialType = /^(checkbox|radio|fieldset)$/i.test( type ), isIgnoredType = /^submit$/i.test( type ), elements, i, l; if ( isIgnoredType ) { return false; } if ( !isSpecialType ) { if ( $elem.val() === "" || ( !features.attributes.placeholder && $elem.hasClass( self.options.placeholderClass ) ) ) { return true; } } else { if ( type === "checkbox" ) { return !$elem.is( ':checked' ); } else { elements = ( type === "fieldset" ) ? $elem.find( 'input' ) : document.getElementsByName( elem.name ); for ( i = 0, l = elements.length; i < l; i++ ) { if ( $( elements[ i ] ).is( ':checked' ) ) { return false; } } // Since no checkbox or radio box is checked value is missing. return true; } } return false; }, /** * Check if a pattern is not matched * * @param H5Form self This * @param Element elem A field element to check * * @return boolean True if the pattern does not match. */ matchPattern: function( self, elem ) { var $elem = $( elem ), val = $elem.attr( 'value' ), pattern = $elem.attr( 'pattern' ), type = $elem.attr( 'type' ), i, l; if ( features.attributes.placeholder || !$elem.attr( 'placeholder' ) || !$elem.hasClass( self.options.placeholderClass ) ) { val = $elem.attr( 'value' ); } if ( val === "" ) { return false; } if ( type === "email" ) { if ( $elem.attr( 'multiple' ) !== undefined ) { val = val.split( self.options.mutipleDelimiter ); for ( i = 0, l = val.length; i < l; i++ ) { if ( !self.options.emailPatt.test( val[ i ].replace( /[ ]*/g, '' ) ) ) return true; } } else { return !self.options.emailPatt.test( val ); } } else if ( type === "url" ) { return !self.options.urlPatt.test( val ); } else if ( type === 'text' ) { if ( pattern !== undefined ) { usrPatt = new RegExp( '^(?:' + pattern + ')$' ); return !usrPatt.test( val ); } } return false; }, /** * Placeholder polyfill * * @param H5Form self This * @param Element elem A field element to fill * @param Event event Event object * * @return void */ placeholder: function( self, elem, event ) { var $elem = $( elem ), placeholder = $elem.attr( "placeholder" ), expectEmpty = /^(focusin|submit)$/i.test( event ), isInput = /^(input|textarea)$/i.test( elem.nodeName ), isIgnored = /^password$/i.test( elem.type ), isNative = features.attributes.placeholder; if ( isNative || !isInput || isIgnored || placeholder === undefined ) { return; } if ( elem.value === "" && !expectEmpty ) { elem.value = placeholder; $elem.addClass( self.options.placeholderClass ); } else if ( elem.value === placeholder && expectEmpty ) { elem.value = ""; $elem.removeClass( self.options.placeholderClass ); } }, /** * Polyfill for number type fields * * @param H5Form self This * @param Element elem A field element to replace * * @return void */ numberType: function( self, elem ) { var $elem = $( elem ), type = $elem.attr( 'type' ), isInput = /^input$/i.test( elem.nodeName ), isType = /^(number|range)$/i.test( type ), min, max, step, value, attributes, $select, $option, i; if ( !isInput || !isType || ( type == "number" && features.types.number ) || ( type == "range" && features.types.range ) ) { return; } min = parseInt( $elem.attr( 'min' ) ); max = parseInt( $elem.attr( 'max' ) ); step = parseInt( $elem.attr( 'step' ) ); value = parseInt( $elem.attr( 'value' ) ); attributes = $elem.prop( "attributes" ); $select = $( '<select>' ); min = isNaN( min ) ? -100 : min; for ( i = min; i <= max; i += step ) { $option = $( '<option value="' + i + '">' + i + '</option>' ); if ( value == i || ( value > i && value < i + step ) ) { $option.attr( 'selected', '' ); } $select.append( $option ); } $.each( attributes, function() { $select.attr( this.name, this.value ); }); $elem.replaceWith( $select ); }, /** * Autofocus polyfill * * @param H5Form self This * @param Element elem A field element to autofocus * * @return void */ autofocus: function( self, elem ) { var $elem = $( elem ), doAutofocus = !!$elem.attr( "autofocus" ), canFocus = /^(input|textarea|select|fieldset)$/i.test( elem.nodeName ), isIgnored = /^submit$/i.test( elem.type ), isNative = features.attributes.autofocus; if ( !isNative && canFocus && !isIgnored && doAutofocus ) { $(function() { self.setFocusOn( elem ); }); } }, /** * Find an element's label. * * @param Element $elem Some kind of input element * * @return Element A label element */ findLabel: function( $elem ) { var $label = $( 'label[for="' + $elem.attr( 'id' ) + '"]' ), $parentElem; if ( $label.length <= 0 ) { $parentElem = $elem.parent(); if ( $parentElem.get( 0 ) .tagName.toLowerCase() == "label" ) { $label = $parentElem; } } return $label; }, /** * Set focus on an element. * * @param Element elem The element to focus on. */ setFocusOn: function( elem ) { if ( elem.tagName.toLowerCase() === "fieldset" ) { $( elem ) .find( ":first" ) .focus(); } else { $( elem ) .focus(); } }, /** * Renders any error messages * * @param H5Form self This * @param Element form A form element * * @return void */ renderErrorMessages: function( self, form ) { var f = form.elements, flen = f.length, error = { errors: [] }, $elem, $label; while ( flen-- ) { $elem = $( f[ flen ] ); $label = self.findLabel( $elem ); if ( $elem.hasClass( self.options.requiredClass ) ) { error.errors[ flen ] = $label.text() .replace( "*", "" ) + self.options.requiredMessage; } if ( $elem.hasClass( self.options.patternClass ) ) { error.errors[ flen ] = $label.text() .replace( "*", "" ) + self.options.patternMessage; } } if ( error.errors.length > 0 ) { Joomla.renderMessages( error ); } } }; $.fn.h5f = function( options ) { return this.each(function() { Object.create( H5Form ) .init( options, this ); }); }; $.fn.h5f.options = { invalidClass: "invalid", requiredClass: "required", requiredMessage: " is required.", placeholderClass: "placeholder", patternClass: "pattern", patternMessage: " doesn't match pattern.", doRenderMessage: false, formValidationEvent: 'onSubmit', emailPatt: /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/, urlPatt: /[a-z][\-\.+a-z]*:\/\//i }; $( function() { $( 'form' ) .h5f({ doRenderMessage: true, requiredClass: "musthavevalue" }); }); })( jQuery, document );