Skip to content
This repository has been archived by the owner on Aug 26, 2021. It is now read-only.

Commit

Permalink
Merge pull request #142 from govau/develop
Browse files Browse the repository at this point in the history
Update form template
  • Loading branch information
Adam Zerella authored May 1, 2019
2 parents a6d942a + c7733e9 commit 394114e
Show file tree
Hide file tree
Showing 8 changed files with 425 additions and 88 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,35 @@
# 1.3.2

- Updated `form` template to be the latest version


# 1.3.1

- Moved `index.html` home page template to `/templates/home/index.html`


# 1.2.1

- Bump dependencies


# 1.2.0

- Added Slack message preview URL.
- Spelling tweaks


# 1.1.0

- Implemented asyncronous functionality and Slack integration.


# 1.0.1

- Splitting files and tests into individual files
- New formatting for slack messages


# 1.0.0

- 🎉 Initial release
84 changes: 84 additions & 0 deletions assets/js/helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Add, Has and Remove class for IE8
function AddClass( element, elementClass ) {
return element.className += " " + elementClass;
}

function HasClass( element, elementClass ) {
return element.className.match( new RegExp( "(\\s|^)" + elementClass + "(\\s|$)") );
}

function RemoveClass( element, elementClass ) {
if( HasClass( element, elementClass ) ) {
// This adds a space every time a class is removed, we should fix this
var reg = new RegExp( "(\\s|^)" + elementClass + "(\\s|$)" );
element.className = element.className.replace( reg, " " );
}
}


// Change EventListener to attachEvent
function AddEvent( elements, event, onEvent ) {
if( elements ) {
// Create an array of elements if a singular or array of elements is passed in
if( elements.length === undefined ) {
elements = [ elements ];
}

// For each element add the correct event listener
for( var i = 0; i < elements.length; i++ ) {
if( typeof Element.prototype.addEventListener === "undefined" ) {

// Make sure that we pass this
( function( element, event ) {
element.attachEvent( "on" + event, function( actualEvent ) {
onEvent( actualEvent, element );
});
})( elements[ i ], event );
}
else {
( function( element, event ) {
element.addEventListener( event, function( actualEvent ) {
onEvent( actualEvent, element );
});
})( elements[ i ], event );
}
}
}
}


// Prevent event for IE8 and modern browsers
function PreventEvent( event ) {
event.preventDefault ? event.preventDefault() : ( event.returnValue = false );
}


// Get elements style
function GetStyle( element, property ) {
return (
typeof getComputedStyle !== 'undefined'
? getComputedStyle( element, null)
: element.currentStyle
)[ property ]; // avoid getPropertyValue altogether
}

//polyfill for IE
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim#Polyfill
if(typeof String.prototype.trim !== 'function') {
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g, '');
};
}

// polyfill for ie8
// https://developer.mozilla.org/en-US/docs/Web/API/NonDocumentTypeChildNode/nextElementSibling#Polyfill_for_Internet_Explorer_8
if(!("nextElementSibling" in document.documentElement)){
Object.defineProperty(Element.prototype, "nextElementSibling", {
get: function(){
var e = this.nextSibling;
while(e && 1 !== e.nodeType)
e = e.nextSibling;
return e;
}
});
}
251 changes: 251 additions & 0 deletions assets/js/validate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
let fullName = document.getElementById( 'name' );
let email = document.getElementById( 'email' );
let helpDescription = document.getElementById( 'help-comment' );
let formSubmit = document.getElementById( 'form-submit' );
let errorSummary = document.getElementById( 'error-summary' );
let errorSummaryMessages = document.getElementById( 'error-list' );
let errorMessageHeading = document.getElementById( 'error-heading' );
let errors = { name: '', email: '', 'help-comment': '' };


/**
* Add event listener when form submitted
*/
AddEvent( formSubmit, 'click', ( event, $this ) => {

// turn off form submission for chameleon, since submitting triggers server side parameter check.
PreventEvent( event );
if ( !validateForm() ) {
RemoveClass( errorSummary, 'hide_content' );
generateErrorSummary();
errorMessageHeading.focus();
}
});


/**
* Validate all fields on the form
*
*/
function validateForm() {
let isFormValid = false;
isFormValid = validateName();
isFormValid = validateEmail();
isFormValid = validateHelpDescription();
return isFormValid;
}


//--------------------------------------------------------------------------------------------------------------------------------------------------------------
// Field validation functions
//--------------------------------------------------------------------------------------------------------------------------------------------------------------


/**
* Validates name field
*/
function validateName() {
return isFieldEmpty( fullName );
}


/**
* Validates email field
*/
function validateEmail() {
if( isFieldEmpty( email ) ) return;
if( !matchExpression( email, 'EMAIL' ) ) return;
return true;
}


/**
* Validates description field
*/
function validateHelpDescription() {
if( isFieldEmpty( helpDescription ) ) return;
if( !meetLength( helpDescription, 10, 100 ) ) return;
return true;
}


//--------------------------------------------------------------------------------------------------------------------------------------------------------------
// UTILITY FUNCTIONS
//--------------------------------------------------------------------------------------------------------------------------------------------------------------


/**
* Checks to see if a text field is empty
*
* @param { HTMLInputElement } field - The html input element
*
* @return {boolean} - False if not empty
*/
function isFieldEmpty( field ) {
if ( field.value.trim() === '' ) {
// set field invalid
setInvalid( field, field.name + ' must not be empty');
return true;
}
// set field valid
setValid( field );
return false;

};


/**
* Displays error text and sets field to invalid
*
* @param { HTMLElement } field - The field to set invalid
* @param { string } message - The error message to be displayed
*/
function setInvalid( field, message ) {
if( !HasClass( field, 'au-text-input--invalid' ) ) {
AddClass( field, 'au-text-input--invalid' );
}

// the error span element
var errorField = field.nextElementSibling;
RemoveClass( errorField, 'hide_content' );
errorField.innerHTML = message;

field.setAttribute( 'aria-invalid', true );
AddError( field, message );
}


/**
* Sets a field to be valid. Removes any error messages and stylings
*
* @param { HTMLElement } field - The field to set valid
*/
function setValid( field ) {
// the error span element
let errorField = field.nextElementSibling;

if( !HasClass( errorField, 'hide_content' ) ) {
AddClass( errorField, 'hide_content' );
}

RemoveClass( field, 'au-text-input--invalid' );

errorField.innerHTML = '';
field.setAttribute( 'aria-invalid', false );
RemoveError( field );
}


/**
* Adds the error messages to an error message summary which is displayed when the form is submitted
*
* @param { HTMLElement } field - The field to add errors to
* @param { string } message - The error message to be shown in the error sumamry
*/
function AddError( field, message ) {
errors[ field.id ] = `<li><a onclick="stopUrlChange(event)" data-id="${ field.id }" href="#${ field.id }">${ message }</a></li>`;
}


/**
* Removes errors from the errors array if the field is valid
*
* @param { HTMLElement } field - The html form control to remove errors from
*/
function RemoveError( field ) {
errors[ field.id ] = '';
}


/**
* Checks to see if a field contains a pattern
*
* @param { HTMLElement } field - The field to be validated against
* @param { string } code - The type of
*/
function matchExpression( field, code ) {
let regEx;
switch ( code ) {
case 'EMAIL':
// Email pattern
// reg ex patter found here: https://emailregex.com/
regEx = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return matchWithRegEx( regEx, field, 'Enter an email in a valid format, like [email protected]' );
// another example
default:
return false;
}
}


/**
* Match
*
* @param {RegExp} regEx - The reg ex type to match the field with
* @param { HTMLElement } field - The text field to test against
* @param { string } message - The error message to be displayed if invalid
*/
function matchWithRegEx( regEx, field, message ) {
if( field.value.match( regEx ) ) {
setValid( field );
return true;
}
else {
setInvalid( field, message );
return false;
}
}


/**
* Checks if a field meets length requirements
*
* @param { HTMLElement } field - the field to check against
* @param { string } minLength - the minimum length of the field
* @param { string } maxLength - the maximum length of the field
*/
function meetLength( field, minLength, maxLength ) {
// If field length meets requirements
if( field.value.trim().length >= minLength && field.value.trim().length <= maxLength ) {
setValid( field );
return true;
}
else if( field.value.trim().length < minLength ) {
setInvalid( field, `${field.name } must be atleast ${ minLength } characters long` );
return false;
}
else {
setInvalid( field, `${field.name } must be less than ${ maxLength } characters long` );
}
}


/**
* Generates the error summary on top of page in the page alert
*/
function generateErrorSummary() {
let errorSummaryList = '';

// loop over the error array and generate a list of errors
for( let field in errors ) {
if( errors[ field ] ) {
errorSummaryList += errors[ field ];
}
}
// add the list of errors to the unordered list in the page alert
errorSummaryMessages.innerHTML = errorSummaryList;
}


/**
* Stop url changing when clicking in links in the error message summary and focus on selected field
*
* @param { Object } event
*/
function stopUrlChange( event ) {
PreventEvent( event );

// ie8 polyfill
let eventTarget = event.target || event.srcElement;
document.getElementById( eventTarget.getAttribute( 'data-id' ) ).focus();
}
Loading

0 comments on commit 394114e

Please sign in to comment.