diff --git a/Gruntfile.js b/Gruntfile.js index 440e56d..68e7cb0 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -3,9 +3,24 @@ module.exports = function(grunt) { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), + concat: { + main: { + src: [ + 'js/plugins/*.js', + 'js/<%= pkg.slug %>.js' + ], + dest: 'dist/js/<%= pkg.slug %>.js', + } + }, + uglify: { + main: { + src: 'dist/js/<%= pkg.slug %>.js', + dest: 'dist/js/<%= pkg.slug %>.min.js' + } + }, copy: { main: { - src: ['*.html', 'mail/**', 'js/**', 'img/**'], + src: ['*.html', 'mail/**', 'img/**'], dest: 'dist/', }, jquery: { @@ -77,21 +92,28 @@ module.exports = function(grunt) { banner: '<%= banner %>' }, files: { - src: ['dist/css/<%= pkg.slug %>.css', 'dist/css/<%= pkg.slug %>.min.css', 'dist/js/<%= pkg.slug %>.js'] + src: ['dist/css/<%= pkg.slug %>.css', 'dist/css/<%= pkg.slug %>.min.css', 'dist/js/<%= pkg.slug %>.js', 'dist/js/<%= pkg.slug %>.min.js'] } } }, watch: { - less: { - files: ['less/*.less'], - tasks: ['less'], + scripts: { + files: ['js/*.js', 'js/**/*.js'], + tasks: ['concat', 'uglify'], + options: { + spawn: false, + }, + }, + copy: { + files: ['*.html', 'mail/**', 'img/**'], + tasks: ['copy'], options: { spawn: false, } }, - copy: { - files: ['*.html', 'mail/**', 'js/**', 'img/**'], - tasks: ['copy'], + less: { + files: ['less/*.less'], + tasks: ['less'], options: { spawn: false, } @@ -100,12 +122,14 @@ module.exports = function(grunt) { }); // Load the plugins. + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-less'); grunt.loadNpmTasks('grunt-banner'); grunt.loadNpmTasks('grunt-contrib-watch'); // Default task(s). - grunt.registerTask('default', ['copy', 'less', 'usebanner']); + grunt.registerTask('default', ['concat', 'uglify', 'copy', 'less', 'usebanner']); }; diff --git a/dist/css/agency.css b/dist/css/agency.css index 74002ae..ed8b8ea 100644 --- a/dist/css/agency.css +++ b/dist/css/agency.css @@ -1,5 +1,5 @@ /*! - * Agency v1.0.0 (http://startbootstrap.com) + * Agency v0.0.1 (http://startbootstrap.com) * Copyright 2014 Start Bootstrap * Licensed under Apache 2.0 (https://github.com/IronSummitMedia/startbootstrap/blob/gh-pages/LICENSE) */ diff --git a/dist/css/agency.min.css b/dist/css/agency.min.css index f609b20..3741dcb 100644 --- a/dist/css/agency.min.css +++ b/dist/css/agency.min.css @@ -1,5 +1,5 @@ /*! - * Agency v1.0.0 (http://startbootstrap.com) + * Agency v0.0.1 (http://startbootstrap.com) * Copyright 2014 Start Bootstrap * Licensed under Apache 2.0 (https://github.com/IronSummitMedia/startbootstrap/blob/gh-pages/LICENSE) */ diff --git a/dist/index.html b/dist/index.html index 33c653e..2fab33d 100644 --- a/dist/index.html +++ b/dist/index.html @@ -647,15 +647,9 @@ - - - - - - - + diff --git a/dist/js/agency.js b/dist/js/agency.js index 0f239ef..186fcf9 100644 --- a/dist/js/agency.js +++ b/dist/js/agency.js @@ -1,14 +1,1117 @@ /*! - * Agency v1.0.0 (http://startbootstrap.com) + * Agency v0.0.1 (http://startbootstrap.com) * Copyright 2014 Start Bootstrap * Licensed under Apache 2.0 (https://github.com/IronSummitMedia/startbootstrap/blob/gh-pages/LICENSE) */ -/*! - * Start Bootstrap - Agnecy Bootstrap Theme (http://startbootstrap.com) - * Code licensed under the Apache License v2.0. - * For details, see http://www.apache.org/licenses/LICENSE-2.0. +/** + * cbpAnimatedHeader.js v1.0.0 + * http://www.codrops.com + * + * Licensed under the MIT license. + * http://www.opensource.org/licenses/mit-license.php + * + * Copyright 2013, Codrops + * http://www.codrops.com */ +var cbpAnimatedHeader = (function() { + + var docElem = document.documentElement, + header = document.querySelector( '.navbar-default' ), + didScroll = false, + changeHeaderOn = 300; + + function init() { + window.addEventListener( 'scroll', function( event ) { + if( !didScroll ) { + didScroll = true; + setTimeout( scrollPage, 250 ); + } + }, false ); + } + + function scrollPage() { + var sy = scrollY(); + if ( sy >= changeHeaderOn ) { + classie.add( header, 'navbar-shrink' ); + } + else { + classie.remove( header, 'navbar-shrink' ); + } + didScroll = false; + } + + function scrollY() { + return window.pageYOffset || docElem.scrollTop; + } + + init(); + +})(); +/*! + * classie - class helper functions + * from bonzo https://github.com/ded/bonzo + * + * classie.has( elem, 'my-class' ) -> true/false + * classie.add( elem, 'my-new-class' ) + * classie.remove( elem, 'my-unwanted-class' ) + * classie.toggle( elem, 'my-class' ) + */ + +/*jshint browser: true, strict: true, undef: true */ +/*global define: false */ + +( function( window ) { + +'use strict'; + +// class helper functions from bonzo https://github.com/ded/bonzo + +function classReg( className ) { + return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); +} + +// classList support for class management +// altho to be fair, the api sucks because it won't accept multiple classes at once +var hasClass, addClass, removeClass; + +if ( 'classList' in document.documentElement ) { + hasClass = function( elem, c ) { + return elem.classList.contains( c ); + }; + addClass = function( elem, c ) { + elem.classList.add( c ); + }; + removeClass = function( elem, c ) { + elem.classList.remove( c ); + }; +} +else { + hasClass = function( elem, c ) { + return classReg( c ).test( elem.className ); + }; + addClass = function( elem, c ) { + if ( !hasClass( elem, c ) ) { + elem.className = elem.className + ' ' + c; + } + }; + removeClass = function( elem, c ) { + elem.className = elem.className.replace( classReg( c ), ' ' ); + }; +} + +function toggleClass( elem, c ) { + var fn = hasClass( elem, c ) ? removeClass : addClass; + fn( elem, c ); +} + +var classie = { + // full names + hasClass: hasClass, + addClass: addClass, + removeClass: removeClass, + toggleClass: toggleClass, + // short names + has: hasClass, + add: addClass, + remove: removeClass, + toggle: toggleClass +}; + +// transport +if ( typeof define === 'function' && define.amd ) { + // AMD + define( classie ); +} else { + // browser global + window.classie = classie; +} + +})( window ); + +$(function() { + + $("input,textarea").jqBootstrapValidation({ + preventSubmit: true, + submitError: function($form, event, errors) { + // additional error messages or events + }, + submitSuccess: function($form, event) { + event.preventDefault(); // prevent default submit behaviour + // get values from FORM + var name = $("input#name").val(); + var email = $("input#email").val(); + var phone = $("input#phone").val(); + var message = $("textarea#message").val(); + var firstName = name; // For Success/Failure Message + // Check for white space in name for Success/Fail message + if (firstName.indexOf(' ') >= 0) { + firstName = name.split(' ').slice(0, -1).join(' '); + } + $.ajax({ + url: "././mail/contact_me.php", + type: "POST", + data: { + name: name, + phone: phone, + email: email, + message: message + }, + cache: false, + success: function() { + // Success message + $('#success').html("
"); + $('#success > .alert-success').html(""); + $('#success > .alert-success') + .append("Your message has been sent. "); + $('#success > .alert-success') + .append('
'); + + //clear all fields + $('#contactForm').trigger("reset"); + }, + error: function() { + // Fail message + $('#success').html("
"); + $('#success > .alert-danger').html(""); + $('#success > .alert-danger').append("Sorry " + firstName + ", it seems that my mail server is not responding. Please try again later!"); + $('#success > .alert-danger').append('
'); + //clear all fields + $('#contactForm').trigger("reset"); + }, + }) + }, + filter: function() { + return $(this).is(":visible"); + }, + }); + + $("a[data-toggle=\"tab\"]").click(function(e) { + e.preventDefault(); + $(this).tab("show"); + }); +}); + + +/*When clicking on Full hide fail/success boxes */ +$('#name').focus(function() { + $('#success').html(''); +}); + +/* jqBootstrapValidation + * A plugin for automating validation on Twitter Bootstrap formatted forms. + * + * v1.3.6 + * + * License: MIT - see LICENSE file + * + * http://ReactiveRaven.github.com/jqBootstrapValidation/ + */ + +(function( $ ){ + + var createdElements = []; + + var defaults = { + options: { + prependExistingHelpBlock: false, + sniffHtml: true, // sniff for 'required', 'maxlength', etc + preventSubmit: true, // stop the form submit event from firing if validation fails + submitError: false, // function called if there is an error when trying to submit + submitSuccess: false, // function called just before a successful submit event is sent to the server + semanticallyStrict: false, // set to true to tidy up generated HTML output + autoAdd: { + helpBlocks: true + }, + filter: function () { + // return $(this).is(":visible"); // only validate elements you can see + return true; // validate everything + } + }, + methods: { + init : function( options ) { + + var settings = $.extend(true, {}, defaults); + + settings.options = $.extend(true, settings.options, options); + + var $siblingElements = this; + + var uniqueForms = $.unique( + $siblingElements.map( function () { + return $(this).parents("form")[0]; + }).toArray() + ); + + $(uniqueForms).bind("submit", function (e) { + var $form = $(this); + var warningsFound = 0; + var $inputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter); + $inputs.trigger("submit.validation").trigger("validationLostFocus.validation"); + + $inputs.each(function (i, el) { + var $this = $(el), + $controlGroup = $this.parents(".form-group").first(); + if ( + $controlGroup.hasClass("warning") + ) { + $controlGroup.removeClass("warning").addClass("error"); + warningsFound++; + } + }); + + $inputs.trigger("validationLostFocus.validation"); + + if (warningsFound) { + if (settings.options.preventSubmit) { + e.preventDefault(); + } + $form.addClass("error"); + if ($.isFunction(settings.options.submitError)) { + settings.options.submitError($form, e, $inputs.jqBootstrapValidation("collectErrors", true)); + } + } else { + $form.removeClass("error"); + if ($.isFunction(settings.options.submitSuccess)) { + settings.options.submitSuccess($form, e); + } + } + }); + + return this.each(function(){ + + // Get references to everything we're interested in + var $this = $(this), + $controlGroup = $this.parents(".form-group").first(), + $helpBlock = $controlGroup.find(".help-block").first(), + $form = $this.parents("form").first(), + validatorNames = []; + + // create message container if not exists + if (!$helpBlock.length && settings.options.autoAdd && settings.options.autoAdd.helpBlocks) { + $helpBlock = $('
'); + $controlGroup.find('.controls').append($helpBlock); + createdElements.push($helpBlock[0]); + } + + // ============================================================= + // SNIFF HTML FOR VALIDATORS + // ============================================================= + + // *snort sniff snuffle* + + if (settings.options.sniffHtml) { + var message = ""; + // --------------------------------------------------------- + // PATTERN + // --------------------------------------------------------- + if ($this.attr("pattern") !== undefined) { + message = "Not in the expected format"; + if ($this.data("validationPatternMessage")) { + message = $this.data("validationPatternMessage"); + } + $this.data("validationPatternMessage", message); + $this.data("validationPatternRegex", $this.attr("pattern")); + } + // --------------------------------------------------------- + // MAX + // --------------------------------------------------------- + if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) { + var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax")); + message = "Too high: Maximum of '" + max + "'"; + if ($this.data("validationMaxMessage")) { + message = $this.data("validationMaxMessage"); + } + $this.data("validationMaxMessage", message); + $this.data("validationMaxMax", max); + } + // --------------------------------------------------------- + // MIN + // --------------------------------------------------------- + if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) { + var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin")); + message = "Too low: Minimum of '" + min + "'"; + if ($this.data("validationMinMessage")) { + message = $this.data("validationMinMessage"); + } + $this.data("validationMinMessage", message); + $this.data("validationMinMin", min); + } + // --------------------------------------------------------- + // MAXLENGTH + // --------------------------------------------------------- + if ($this.attr("maxlength") !== undefined) { + message = "Too long: Maximum of '" + $this.attr("maxlength") + "' characters"; + if ($this.data("validationMaxlengthMessage")) { + message = $this.data("validationMaxlengthMessage"); + } + $this.data("validationMaxlengthMessage", message); + $this.data("validationMaxlengthMaxlength", $this.attr("maxlength")); + } + // --------------------------------------------------------- + // MINLENGTH + // --------------------------------------------------------- + if ($this.attr("minlength") !== undefined) { + message = "Too short: Minimum of '" + $this.attr("minlength") + "' characters"; + if ($this.data("validationMinlengthMessage")) { + message = $this.data("validationMinlengthMessage"); + } + $this.data("validationMinlengthMessage", message); + $this.data("validationMinlengthMinlength", $this.attr("minlength")); + } + // --------------------------------------------------------- + // REQUIRED + // --------------------------------------------------------- + if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) { + message = settings.builtInValidators.required.message; + if ($this.data("validationRequiredMessage")) { + message = $this.data("validationRequiredMessage"); + } + $this.data("validationRequiredMessage", message); + } + // --------------------------------------------------------- + // NUMBER + // --------------------------------------------------------- + if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") { + message = settings.builtInValidators.number.message; + if ($this.data("validationNumberMessage")) { + message = $this.data("validationNumberMessage"); + } + $this.data("validationNumberMessage", message); + } + // --------------------------------------------------------- + // EMAIL + // --------------------------------------------------------- + if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") { + message = "Not a valid email address"; + if ($this.data("validationValidemailMessage")) { + message = $this.data("validationValidemailMessage"); + } else if ($this.data("validationEmailMessage")) { + message = $this.data("validationEmailMessage"); + } + $this.data("validationValidemailMessage", message); + } + // --------------------------------------------------------- + // MINCHECKED + // --------------------------------------------------------- + if ($this.attr("minchecked") !== undefined) { + message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required"; + if ($this.data("validationMincheckedMessage")) { + message = $this.data("validationMincheckedMessage"); + } + $this.data("validationMincheckedMessage", message); + $this.data("validationMincheckedMinchecked", $this.attr("minchecked")); + } + // --------------------------------------------------------- + // MAXCHECKED + // --------------------------------------------------------- + if ($this.attr("maxchecked") !== undefined) { + message = "Too many options checked; Maximum of '" + $this.attr("maxchecked") + "' required"; + if ($this.data("validationMaxcheckedMessage")) { + message = $this.data("validationMaxcheckedMessage"); + } + $this.data("validationMaxcheckedMessage", message); + $this.data("validationMaxcheckedMaxchecked", $this.attr("maxchecked")); + } + } + + // ============================================================= + // COLLECT VALIDATOR NAMES + // ============================================================= + + // Get named validators + if ($this.data("validation") !== undefined) { + validatorNames = $this.data("validation").split(","); + } + + // Get extra ones defined on the element's data attributes + $.each($this.data(), function (i, el) { + var parts = i.replace(/([A-Z])/g, ",$1").split(","); + if (parts[0] === "validation" && parts[1]) { + validatorNames.push(parts[1]); + } + }); + + // ============================================================= + // NORMALISE VALIDATOR NAMES + // ============================================================= + + var validatorNamesToInspect = validatorNames; + var newValidatorNamesToInspect = []; + + do // repeatedly expand 'shortcut' validators into their real validators + { + // Uppercase only the first letter of each name + $.each(validatorNames, function (i, el) { + validatorNames[i] = formatValidatorName(el); + }); + + // Remove duplicate validator names + validatorNames = $.unique(validatorNames); + + // Pull out the new validator names from each shortcut + newValidatorNamesToInspect = []; + $.each(validatorNamesToInspect, function(i, el) { + if ($this.data("validation" + el + "Shortcut") !== undefined) { + // Are these custom validators? + // Pull them out! + $.each($this.data("validation" + el + "Shortcut").split(","), function(i2, el2) { + newValidatorNamesToInspect.push(el2); + }); + } else if (settings.builtInValidators[el.toLowerCase()]) { + // Is this a recognised built-in? + // Pull it out! + var validator = settings.builtInValidators[el.toLowerCase()]; + if (validator.type.toLowerCase() === "shortcut") { + $.each(validator.shortcut.split(","), function (i, el) { + el = formatValidatorName(el); + newValidatorNamesToInspect.push(el); + validatorNames.push(el); + }); + } + } + }); + + validatorNamesToInspect = newValidatorNamesToInspect; + + } while (validatorNamesToInspect.length > 0) + + // ============================================================= + // SET UP VALIDATOR ARRAYS + // ============================================================= + + var validators = {}; + + $.each(validatorNames, function (i, el) { + // Set up the 'override' message + var message = $this.data("validation" + el + "Message"); + var hasOverrideMessage = (message !== undefined); + var foundValidator = false; + message = + ( + message + ? message + : "'" + el + "' validation failed " + ) + ; + + $.each( + settings.validatorTypes, + function (validatorType, validatorTemplate) { + if (validators[validatorType] === undefined) { + validators[validatorType] = []; + } + if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) { + validators[validatorType].push( + $.extend( + true, + { + name: formatValidatorName(validatorTemplate.name), + message: message + }, + validatorTemplate.init($this, el) + ) + ); + foundValidator = true; + } + } + ); + + if (!foundValidator && settings.builtInValidators[el.toLowerCase()]) { + + var validator = $.extend(true, {}, settings.builtInValidators[el.toLowerCase()]); + if (hasOverrideMessage) { + validator.message = message; + } + var validatorType = validator.type.toLowerCase(); + + if (validatorType === "shortcut") { + foundValidator = true; + } else { + $.each( + settings.validatorTypes, + function (validatorTemplateType, validatorTemplate) { + if (validators[validatorTemplateType] === undefined) { + validators[validatorTemplateType] = []; + } + if (!foundValidator && validatorType === validatorTemplateType.toLowerCase()) { + $this.data("validation" + el + formatValidatorName(validatorTemplate.name), validator[validatorTemplate.name.toLowerCase()]); + validators[validatorType].push( + $.extend( + validator, + validatorTemplate.init($this, el) + ) + ); + foundValidator = true; + } + } + ); + } + } + + if (! foundValidator) { + $.error("Cannot find validation info for '" + el + "'"); + } + }); + + // ============================================================= + // STORE FALLBACK VALUES + // ============================================================= + + $helpBlock.data( + "original-contents", + ( + $helpBlock.data("original-contents") + ? $helpBlock.data("original-contents") + : $helpBlock.html() + ) + ); + + $helpBlock.data( + "original-role", + ( + $helpBlock.data("original-role") + ? $helpBlock.data("original-role") + : $helpBlock.attr("role") + ) + ); + + $controlGroup.data( + "original-classes", + ( + $controlGroup.data("original-clases") + ? $controlGroup.data("original-classes") + : $controlGroup.attr("class") + ) + ); + + $this.data( + "original-aria-invalid", + ( + $this.data("original-aria-invalid") + ? $this.data("original-aria-invalid") + : $this.attr("aria-invalid") + ) + ); + + // ============================================================= + // VALIDATION + // ============================================================= + + $this.bind( + "validation.validation", + function (event, params) { + + var value = getValue($this); + + // Get a list of the errors to apply + var errorsFound = []; + + $.each(validators, function (validatorType, validatorTypeArray) { + if (value || value.length || (params && params.includeEmpty) || (!!settings.validatorTypes[validatorType].blockSubmit && params && !!params.submitting)) { + $.each(validatorTypeArray, function (i, validator) { + if (settings.validatorTypes[validatorType].validate($this, value, validator)) { + errorsFound.push(validator.message); + } + }); + } + }); + + return errorsFound; + } + ); + + $this.bind( + "getValidators.validation", + function () { + return validators; + } + ); + + // ============================================================= + // WATCH FOR CHANGES + // ============================================================= + $this.bind( + "submit.validation", + function () { + return $this.triggerHandler("change.validation", {submitting: true}); + } + ); + $this.bind( + [ + "keyup", + "focus", + "blur", + "click", + "keydown", + "keypress", + "change" + ].join(".validation ") + ".validation", + function (e, params) { + + var value = getValue($this); + + var errorsFound = []; + + $controlGroup.find("input,textarea,select").each(function (i, el) { + var oldCount = errorsFound.length; + $.each($(el).triggerHandler("validation.validation", params), function (j, message) { + errorsFound.push(message); + }); + if (errorsFound.length > oldCount) { + $(el).attr("aria-invalid", "true"); + } else { + var original = $this.data("original-aria-invalid"); + $(el).attr("aria-invalid", (original !== undefined ? original : false)); + } + }); + + $form.find("input,select,textarea").not($this).not("[name=\"" + $this.attr("name") + "\"]").trigger("validationLostFocus.validation"); + + errorsFound = $.unique(errorsFound.sort()); + + // Were there any errors? + if (errorsFound.length) { + // Better flag it up as a warning. + $controlGroup.removeClass("success error").addClass("warning"); + + // How many errors did we find? + if (settings.options.semanticallyStrict && errorsFound.length === 1) { + // Only one? Being strict? Just output it. + $helpBlock.html(errorsFound[0] + + ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" )); + } else { + // Multiple? Being sloppy? Glue them together into an UL. + $helpBlock.html("
  • " + errorsFound.join("
  • ") + "
" + + ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" )); + } + } else { + $controlGroup.removeClass("warning error success"); + if (value.length > 0) { + $controlGroup.addClass("success"); + } + $helpBlock.html($helpBlock.data("original-contents")); + } + + if (e.type === "blur") { + $controlGroup.removeClass("success"); + } + } + ); + $this.bind("validationLostFocus.validation", function () { + $controlGroup.removeClass("success"); + }); + }); + }, + destroy : function( ) { + + return this.each( + function() { + + var + $this = $(this), + $controlGroup = $this.parents(".form-group").first(), + $helpBlock = $controlGroup.find(".help-block").first(); + + // remove our events + $this.unbind('.validation'); // events are namespaced. + // reset help text + $helpBlock.html($helpBlock.data("original-contents")); + // reset classes + $controlGroup.attr("class", $controlGroup.data("original-classes")); + // reset aria + $this.attr("aria-invalid", $this.data("original-aria-invalid")); + // reset role + $helpBlock.attr("role", $this.data("original-role")); + // remove all elements we created + if (createdElements.indexOf($helpBlock[0]) > -1) { + $helpBlock.remove(); + } + + } + ); + + }, + collectErrors : function(includeEmpty) { + + var errorMessages = {}; + this.each(function (i, el) { + var $el = $(el); + var name = $el.attr("name"); + var errors = $el.triggerHandler("validation.validation", {includeEmpty: true}); + errorMessages[name] = $.extend(true, errors, errorMessages[name]); + }); + + $.each(errorMessages, function (i, el) { + if (el.length === 0) { + delete errorMessages[i]; + } + }); + + return errorMessages; + + }, + hasErrors: function() { + + var errorMessages = []; + + this.each(function (i, el) { + errorMessages = errorMessages.concat( + $(el).triggerHandler("getValidators.validation") ? $(el).triggerHandler("validation.validation", {submitting: true}) : [] + ); + }); + + return (errorMessages.length > 0); + }, + override : function (newDefaults) { + defaults = $.extend(true, defaults, newDefaults); + } + }, + validatorTypes: { + callback: { + name: "callback", + init: function ($this, name) { + return { + validatorName: name, + callback: $this.data("validation" + name + "Callback"), + lastValue: $this.val(), + lastValid: true, + lastFinished: true + }; + }, + validate: function ($this, value, validator) { + if (validator.lastValue === value && validator.lastFinished) { + return !validator.lastValid; + } + + if (validator.lastFinished === true) + { + validator.lastValue = value; + validator.lastValid = true; + validator.lastFinished = false; + + var rrjqbvValidator = validator; + var rrjqbvThis = $this; + executeFunctionByName( + validator.callback, + window, + $this, + value, + function (data) { + if (rrjqbvValidator.lastValue === data.value) { + rrjqbvValidator.lastValid = data.valid; + if (data.message) { + rrjqbvValidator.message = data.message; + } + rrjqbvValidator.lastFinished = true; + rrjqbvThis.data("validation" + rrjqbvValidator.validatorName + "Message", rrjqbvValidator.message); + // Timeout is set to avoid problems with the events being considered 'already fired' + setTimeout(function () { + rrjqbvThis.trigger("change.validation"); + }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst + } + } + ); + } + + return false; + + } + }, + ajax: { + name: "ajax", + init: function ($this, name) { + return { + validatorName: name, + url: $this.data("validation" + name + "Ajax"), + lastValue: $this.val(), + lastValid: true, + lastFinished: true + }; + }, + validate: function ($this, value, validator) { + if (""+validator.lastValue === ""+value && validator.lastFinished === true) { + return validator.lastValid === false; + } + + if (validator.lastFinished === true) + { + validator.lastValue = value; + validator.lastValid = true; + validator.lastFinished = false; + $.ajax({ + url: validator.url, + data: "value=" + value + "&field=" + $this.attr("name"), + dataType: "json", + success: function (data) { + if (""+validator.lastValue === ""+data.value) { + validator.lastValid = !!(data.valid); + if (data.message) { + validator.message = data.message; + } + validator.lastFinished = true; + $this.data("validation" + validator.validatorName + "Message", validator.message); + // Timeout is set to avoid problems with the events being considered 'already fired' + setTimeout(function () { + $this.trigger("change.validation"); + }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst + } + }, + failure: function () { + validator.lastValid = true; + validator.message = "ajax call failed"; + validator.lastFinished = true; + $this.data("validation" + validator.validatorName + "Message", validator.message); + // Timeout is set to avoid problems with the events being considered 'already fired' + setTimeout(function () { + $this.trigger("change.validation"); + }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst + } + }); + } + + return false; + + } + }, + regex: { + name: "regex", + init: function ($this, name) { + return {regex: regexFromString($this.data("validation" + name + "Regex"))}; + }, + validate: function ($this, value, validator) { + return (!validator.regex.test(value) && ! validator.negative) + || (validator.regex.test(value) && validator.negative); + } + }, + required: { + name: "required", + init: function ($this, name) { + return {}; + }, + validate: function ($this, value, validator) { + return !!(value.length === 0 && ! validator.negative) + || !!(value.length > 0 && validator.negative); + }, + blockSubmit: true + }, + match: { + name: "match", + init: function ($this, name) { + var element = $this.parents("form").first().find("[name=\"" + $this.data("validation" + name + "Match") + "\"]").first(); + element.bind("validation.validation", function () { + $this.trigger("change.validation", {submitting: true}); + }); + return {"element": element}; + }, + validate: function ($this, value, validator) { + return (value !== validator.element.val() && ! validator.negative) + || (value === validator.element.val() && validator.negative); + }, + blockSubmit: true + }, + max: { + name: "max", + init: function ($this, name) { + return {max: $this.data("validation" + name + "Max")}; + }, + validate: function ($this, value, validator) { + return (parseFloat(value, 10) > parseFloat(validator.max, 10) && ! validator.negative) + || (parseFloat(value, 10) <= parseFloat(validator.max, 10) && validator.negative); + } + }, + min: { + name: "min", + init: function ($this, name) { + return {min: $this.data("validation" + name + "Min")}; + }, + validate: function ($this, value, validator) { + return (parseFloat(value) < parseFloat(validator.min) && ! validator.negative) + || (parseFloat(value) >= parseFloat(validator.min) && validator.negative); + } + }, + maxlength: { + name: "maxlength", + init: function ($this, name) { + return {maxlength: $this.data("validation" + name + "Maxlength")}; + }, + validate: function ($this, value, validator) { + return ((value.length > validator.maxlength) && ! validator.negative) + || ((value.length <= validator.maxlength) && validator.negative); + } + }, + minlength: { + name: "minlength", + init: function ($this, name) { + return {minlength: $this.data("validation" + name + "Minlength")}; + }, + validate: function ($this, value, validator) { + return ((value.length < validator.minlength) && ! validator.negative) + || ((value.length >= validator.minlength) && validator.negative); + } + }, + maxchecked: { + name: "maxchecked", + init: function ($this, name) { + var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); + elements.bind("click.validation", function () { + $this.trigger("change.validation", {includeEmpty: true}); + }); + return {maxchecked: $this.data("validation" + name + "Maxchecked"), elements: elements}; + }, + validate: function ($this, value, validator) { + return (validator.elements.filter(":checked").length > validator.maxchecked && ! validator.negative) + || (validator.elements.filter(":checked").length <= validator.maxchecked && validator.negative); + }, + blockSubmit: true + }, + minchecked: { + name: "minchecked", + init: function ($this, name) { + var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); + elements.bind("click.validation", function () { + $this.trigger("change.validation", {includeEmpty: true}); + }); + return {minchecked: $this.data("validation" + name + "Minchecked"), elements: elements}; + }, + validate: function ($this, value, validator) { + return (validator.elements.filter(":checked").length < validator.minchecked && ! validator.negative) + || (validator.elements.filter(":checked").length >= validator.minchecked && validator.negative); + }, + blockSubmit: true + } + }, + builtInValidators: { + email: { + name: "Email", + type: "shortcut", + shortcut: "validemail" + }, + validemail: { + name: "Validemail", + type: "regex", + regex: "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\.[A-Za-z]{2,4}", + message: "Not a valid email address" + }, + passwordagain: { + name: "Passwordagain", + type: "match", + match: "password", + message: "Does not match the given password" + }, + positive: { + name: "Positive", + type: "shortcut", + shortcut: "number,positivenumber" + }, + negative: { + name: "Negative", + type: "shortcut", + shortcut: "number,negativenumber" + }, + number: { + name: "Number", + type: "regex", + regex: "([+-]?\\\d+(\\\.\\\d*)?([eE][+-]?[0-9]+)?)?", + message: "Must be a number" + }, + integer: { + name: "Integer", + type: "regex", + regex: "[+-]?\\\d+", + message: "No decimal places allowed" + }, + positivenumber: { + name: "Positivenumber", + type: "min", + min: 0, + message: "Must be a positive number" + }, + negativenumber: { + name: "Negativenumber", + type: "max", + max: 0, + message: "Must be a negative number" + }, + required: { + name: "Required", + type: "required", + message: "This is required" + }, + checkone: { + name: "Checkone", + type: "minchecked", + minchecked: 1, + message: "Check at least one option" + } + } + }; + + var formatValidatorName = function (name) { + return name + .toLowerCase() + .replace( + /(^|\s)([a-z])/g , + function(m,p1,p2) { + return p1+p2.toUpperCase(); + } + ) + ; + }; + + var getValue = function ($this) { + // Extract the value we're talking about + var value = $this.val(); + var type = $this.attr("type"); + if (type === "checkbox") { + value = ($this.is(":checked") ? value : ""); + } + if (type === "radio") { + value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? value : ""); + } + return value; + }; + + function regexFromString(inputstring) { + return new RegExp("^" + inputstring + "$"); + } + + /** + * Thanks to Jason Bunting via StackOverflow.com + * + * http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string#answer-359910 + * Short link: http://tinyurl.com/executeFunctionByName + **/ + function executeFunctionByName(functionName, context /*, args*/) { + var args = Array.prototype.slice.call(arguments).splice(2); + var namespaces = functionName.split("."); + var func = namespaces.pop(); + for(var i = 0; i < namespaces.length; i++) { + context = context[namespaces[i]]; + } + return context[func].apply(this, args); + } + + $.fn.jqBootstrapValidation = function( method ) { + + if ( defaults.methods[method] ) { + return defaults.methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); + } else if ( typeof method === 'object' || ! method ) { + return defaults.methods.init.apply( this, arguments ); + } else { + $.error( 'Method ' + method + ' does not exist on jQuery.jqBootstrapValidation' ); + return null; + } + + }; + + $.jqBootstrapValidation = function (options) { + $(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments); + }; + +})( jQuery ); // jQuery for page scrolling feature - requires jQuery Easing plugin $(function() { diff --git a/dist/js/plugins/cbpAnimatedHeader.js b/dist/js/plugins/cbpAnimatedHeader.js deleted file mode 100644 index 4554e2e..0000000 --- a/dist/js/plugins/cbpAnimatedHeader.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * cbpAnimatedHeader.js v1.0.0 - * http://www.codrops.com - * - * Licensed under the MIT license. - * http://www.opensource.org/licenses/mit-license.php - * - * Copyright 2013, Codrops - * http://www.codrops.com - */ -var cbpAnimatedHeader = (function() { - - var docElem = document.documentElement, - header = document.querySelector( '.navbar-default' ), - didScroll = false, - changeHeaderOn = 300; - - function init() { - window.addEventListener( 'scroll', function( event ) { - if( !didScroll ) { - didScroll = true; - setTimeout( scrollPage, 250 ); - } - }, false ); - } - - function scrollPage() { - var sy = scrollY(); - if ( sy >= changeHeaderOn ) { - classie.add( header, 'navbar-shrink' ); - } - else { - classie.remove( header, 'navbar-shrink' ); - } - didScroll = false; - } - - function scrollY() { - return window.pageYOffset || docElem.scrollTop; - } - - init(); - -})(); \ No newline at end of file diff --git a/dist/js/plugins/classie.js b/dist/js/plugins/classie.js deleted file mode 100644 index a967554..0000000 --- a/dist/js/plugins/classie.js +++ /dev/null @@ -1,80 +0,0 @@ -/*! - * classie - class helper functions - * from bonzo https://github.com/ded/bonzo - * - * classie.has( elem, 'my-class' ) -> true/false - * classie.add( elem, 'my-new-class' ) - * classie.remove( elem, 'my-unwanted-class' ) - * classie.toggle( elem, 'my-class' ) - */ - -/*jshint browser: true, strict: true, undef: true */ -/*global define: false */ - -( function( window ) { - -'use strict'; - -// class helper functions from bonzo https://github.com/ded/bonzo - -function classReg( className ) { - return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); -} - -// classList support for class management -// altho to be fair, the api sucks because it won't accept multiple classes at once -var hasClass, addClass, removeClass; - -if ( 'classList' in document.documentElement ) { - hasClass = function( elem, c ) { - return elem.classList.contains( c ); - }; - addClass = function( elem, c ) { - elem.classList.add( c ); - }; - removeClass = function( elem, c ) { - elem.classList.remove( c ); - }; -} -else { - hasClass = function( elem, c ) { - return classReg( c ).test( elem.className ); - }; - addClass = function( elem, c ) { - if ( !hasClass( elem, c ) ) { - elem.className = elem.className + ' ' + c; - } - }; - removeClass = function( elem, c ) { - elem.className = elem.className.replace( classReg( c ), ' ' ); - }; -} - -function toggleClass( elem, c ) { - var fn = hasClass( elem, c ) ? removeClass : addClass; - fn( elem, c ); -} - -var classie = { - // full names - hasClass: hasClass, - addClass: addClass, - removeClass: removeClass, - toggleClass: toggleClass, - // short names - has: hasClass, - add: addClass, - remove: removeClass, - toggle: toggleClass -}; - -// transport -if ( typeof define === 'function' && define.amd ) { - // AMD - define( classie ); -} else { - // browser global - window.classie = classie; -} - -})( window ); diff --git a/dist/js/plugins/contact_me.js b/dist/js/plugins/contact_me.js deleted file mode 100644 index 0567067..0000000 --- a/dist/js/plugins/contact_me.js +++ /dev/null @@ -1,70 +0,0 @@ -$(function() { - - $("input,textarea").jqBootstrapValidation({ - preventSubmit: true, - submitError: function($form, event, errors) { - // additional error messages or events - }, - submitSuccess: function($form, event) { - event.preventDefault(); // prevent default submit behaviour - // get values from FORM - var name = $("input#name").val(); - var email = $("input#email").val(); - var phone = $("input#phone").val(); - var message = $("textarea#message").val(); - var firstName = name; // For Success/Failure Message - // Check for white space in name for Success/Fail message - if (firstName.indexOf(' ') >= 0) { - firstName = name.split(' ').slice(0, -1).join(' '); - } - $.ajax({ - url: "././mail/contact_me.php", - type: "POST", - data: { - name: name, - phone: phone, - email: email, - message: message - }, - cache: false, - success: function() { - // Success message - $('#success').html("
"); - $('#success > .alert-success').html(""); - $('#success > .alert-success') - .append("Your message has been sent. "); - $('#success > .alert-success') - .append('
'); - - //clear all fields - $('#contactForm').trigger("reset"); - }, - error: function() { - // Fail message - $('#success').html("
"); - $('#success > .alert-danger').html(""); - $('#success > .alert-danger').append("Sorry " + firstName + ", it seems that my mail server is not responding. Please try again later!"); - $('#success > .alert-danger').append('
'); - //clear all fields - $('#contactForm').trigger("reset"); - }, - }) - }, - filter: function() { - return $(this).is(":visible"); - }, - }); - - $("a[data-toggle=\"tab\"]").click(function(e) { - e.preventDefault(); - $(this).tab("show"); - }); -}); - - -/*When clicking on Full hide fail/success boxes */ -$('#name').focus(function() { - $('#success').html(''); -}); diff --git a/dist/js/plugins/jqBootstrapValidation.js b/dist/js/plugins/jqBootstrapValidation.js deleted file mode 100644 index 7b3b922..0000000 --- a/dist/js/plugins/jqBootstrapValidation.js +++ /dev/null @@ -1,912 +0,0 @@ -/* jqBootstrapValidation - * A plugin for automating validation on Twitter Bootstrap formatted forms. - * - * v1.3.6 - * - * License: MIT - see LICENSE file - * - * http://ReactiveRaven.github.com/jqBootstrapValidation/ - */ - -(function( $ ){ - - var createdElements = []; - - var defaults = { - options: { - prependExistingHelpBlock: false, - sniffHtml: true, // sniff for 'required', 'maxlength', etc - preventSubmit: true, // stop the form submit event from firing if validation fails - submitError: false, // function called if there is an error when trying to submit - submitSuccess: false, // function called just before a successful submit event is sent to the server - semanticallyStrict: false, // set to true to tidy up generated HTML output - autoAdd: { - helpBlocks: true - }, - filter: function () { - // return $(this).is(":visible"); // only validate elements you can see - return true; // validate everything - } - }, - methods: { - init : function( options ) { - - var settings = $.extend(true, {}, defaults); - - settings.options = $.extend(true, settings.options, options); - - var $siblingElements = this; - - var uniqueForms = $.unique( - $siblingElements.map( function () { - return $(this).parents("form")[0]; - }).toArray() - ); - - $(uniqueForms).bind("submit", function (e) { - var $form = $(this); - var warningsFound = 0; - var $inputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter); - $inputs.trigger("submit.validation").trigger("validationLostFocus.validation"); - - $inputs.each(function (i, el) { - var $this = $(el), - $controlGroup = $this.parents(".form-group").first(); - if ( - $controlGroup.hasClass("warning") - ) { - $controlGroup.removeClass("warning").addClass("error"); - warningsFound++; - } - }); - - $inputs.trigger("validationLostFocus.validation"); - - if (warningsFound) { - if (settings.options.preventSubmit) { - e.preventDefault(); - } - $form.addClass("error"); - if ($.isFunction(settings.options.submitError)) { - settings.options.submitError($form, e, $inputs.jqBootstrapValidation("collectErrors", true)); - } - } else { - $form.removeClass("error"); - if ($.isFunction(settings.options.submitSuccess)) { - settings.options.submitSuccess($form, e); - } - } - }); - - return this.each(function(){ - - // Get references to everything we're interested in - var $this = $(this), - $controlGroup = $this.parents(".form-group").first(), - $helpBlock = $controlGroup.find(".help-block").first(), - $form = $this.parents("form").first(), - validatorNames = []; - - // create message container if not exists - if (!$helpBlock.length && settings.options.autoAdd && settings.options.autoAdd.helpBlocks) { - $helpBlock = $('
'); - $controlGroup.find('.controls').append($helpBlock); - createdElements.push($helpBlock[0]); - } - - // ============================================================= - // SNIFF HTML FOR VALIDATORS - // ============================================================= - - // *snort sniff snuffle* - - if (settings.options.sniffHtml) { - var message = ""; - // --------------------------------------------------------- - // PATTERN - // --------------------------------------------------------- - if ($this.attr("pattern") !== undefined) { - message = "Not in the expected format"; - if ($this.data("validationPatternMessage")) { - message = $this.data("validationPatternMessage"); - } - $this.data("validationPatternMessage", message); - $this.data("validationPatternRegex", $this.attr("pattern")); - } - // --------------------------------------------------------- - // MAX - // --------------------------------------------------------- - if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) { - var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax")); - message = "Too high: Maximum of '" + max + "'"; - if ($this.data("validationMaxMessage")) { - message = $this.data("validationMaxMessage"); - } - $this.data("validationMaxMessage", message); - $this.data("validationMaxMax", max); - } - // --------------------------------------------------------- - // MIN - // --------------------------------------------------------- - if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) { - var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin")); - message = "Too low: Minimum of '" + min + "'"; - if ($this.data("validationMinMessage")) { - message = $this.data("validationMinMessage"); - } - $this.data("validationMinMessage", message); - $this.data("validationMinMin", min); - } - // --------------------------------------------------------- - // MAXLENGTH - // --------------------------------------------------------- - if ($this.attr("maxlength") !== undefined) { - message = "Too long: Maximum of '" + $this.attr("maxlength") + "' characters"; - if ($this.data("validationMaxlengthMessage")) { - message = $this.data("validationMaxlengthMessage"); - } - $this.data("validationMaxlengthMessage", message); - $this.data("validationMaxlengthMaxlength", $this.attr("maxlength")); - } - // --------------------------------------------------------- - // MINLENGTH - // --------------------------------------------------------- - if ($this.attr("minlength") !== undefined) { - message = "Too short: Minimum of '" + $this.attr("minlength") + "' characters"; - if ($this.data("validationMinlengthMessage")) { - message = $this.data("validationMinlengthMessage"); - } - $this.data("validationMinlengthMessage", message); - $this.data("validationMinlengthMinlength", $this.attr("minlength")); - } - // --------------------------------------------------------- - // REQUIRED - // --------------------------------------------------------- - if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) { - message = settings.builtInValidators.required.message; - if ($this.data("validationRequiredMessage")) { - message = $this.data("validationRequiredMessage"); - } - $this.data("validationRequiredMessage", message); - } - // --------------------------------------------------------- - // NUMBER - // --------------------------------------------------------- - if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") { - message = settings.builtInValidators.number.message; - if ($this.data("validationNumberMessage")) { - message = $this.data("validationNumberMessage"); - } - $this.data("validationNumberMessage", message); - } - // --------------------------------------------------------- - // EMAIL - // --------------------------------------------------------- - if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") { - message = "Not a valid email address"; - if ($this.data("validationValidemailMessage")) { - message = $this.data("validationValidemailMessage"); - } else if ($this.data("validationEmailMessage")) { - message = $this.data("validationEmailMessage"); - } - $this.data("validationValidemailMessage", message); - } - // --------------------------------------------------------- - // MINCHECKED - // --------------------------------------------------------- - if ($this.attr("minchecked") !== undefined) { - message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required"; - if ($this.data("validationMincheckedMessage")) { - message = $this.data("validationMincheckedMessage"); - } - $this.data("validationMincheckedMessage", message); - $this.data("validationMincheckedMinchecked", $this.attr("minchecked")); - } - // --------------------------------------------------------- - // MAXCHECKED - // --------------------------------------------------------- - if ($this.attr("maxchecked") !== undefined) { - message = "Too many options checked; Maximum of '" + $this.attr("maxchecked") + "' required"; - if ($this.data("validationMaxcheckedMessage")) { - message = $this.data("validationMaxcheckedMessage"); - } - $this.data("validationMaxcheckedMessage", message); - $this.data("validationMaxcheckedMaxchecked", $this.attr("maxchecked")); - } - } - - // ============================================================= - // COLLECT VALIDATOR NAMES - // ============================================================= - - // Get named validators - if ($this.data("validation") !== undefined) { - validatorNames = $this.data("validation").split(","); - } - - // Get extra ones defined on the element's data attributes - $.each($this.data(), function (i, el) { - var parts = i.replace(/([A-Z])/g, ",$1").split(","); - if (parts[0] === "validation" && parts[1]) { - validatorNames.push(parts[1]); - } - }); - - // ============================================================= - // NORMALISE VALIDATOR NAMES - // ============================================================= - - var validatorNamesToInspect = validatorNames; - var newValidatorNamesToInspect = []; - - do // repeatedly expand 'shortcut' validators into their real validators - { - // Uppercase only the first letter of each name - $.each(validatorNames, function (i, el) { - validatorNames[i] = formatValidatorName(el); - }); - - // Remove duplicate validator names - validatorNames = $.unique(validatorNames); - - // Pull out the new validator names from each shortcut - newValidatorNamesToInspect = []; - $.each(validatorNamesToInspect, function(i, el) { - if ($this.data("validation" + el + "Shortcut") !== undefined) { - // Are these custom validators? - // Pull them out! - $.each($this.data("validation" + el + "Shortcut").split(","), function(i2, el2) { - newValidatorNamesToInspect.push(el2); - }); - } else if (settings.builtInValidators[el.toLowerCase()]) { - // Is this a recognised built-in? - // Pull it out! - var validator = settings.builtInValidators[el.toLowerCase()]; - if (validator.type.toLowerCase() === "shortcut") { - $.each(validator.shortcut.split(","), function (i, el) { - el = formatValidatorName(el); - newValidatorNamesToInspect.push(el); - validatorNames.push(el); - }); - } - } - }); - - validatorNamesToInspect = newValidatorNamesToInspect; - - } while (validatorNamesToInspect.length > 0) - - // ============================================================= - // SET UP VALIDATOR ARRAYS - // ============================================================= - - var validators = {}; - - $.each(validatorNames, function (i, el) { - // Set up the 'override' message - var message = $this.data("validation" + el + "Message"); - var hasOverrideMessage = (message !== undefined); - var foundValidator = false; - message = - ( - message - ? message - : "'" + el + "' validation failed " - ) - ; - - $.each( - settings.validatorTypes, - function (validatorType, validatorTemplate) { - if (validators[validatorType] === undefined) { - validators[validatorType] = []; - } - if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) { - validators[validatorType].push( - $.extend( - true, - { - name: formatValidatorName(validatorTemplate.name), - message: message - }, - validatorTemplate.init($this, el) - ) - ); - foundValidator = true; - } - } - ); - - if (!foundValidator && settings.builtInValidators[el.toLowerCase()]) { - - var validator = $.extend(true, {}, settings.builtInValidators[el.toLowerCase()]); - if (hasOverrideMessage) { - validator.message = message; - } - var validatorType = validator.type.toLowerCase(); - - if (validatorType === "shortcut") { - foundValidator = true; - } else { - $.each( - settings.validatorTypes, - function (validatorTemplateType, validatorTemplate) { - if (validators[validatorTemplateType] === undefined) { - validators[validatorTemplateType] = []; - } - if (!foundValidator && validatorType === validatorTemplateType.toLowerCase()) { - $this.data("validation" + el + formatValidatorName(validatorTemplate.name), validator[validatorTemplate.name.toLowerCase()]); - validators[validatorType].push( - $.extend( - validator, - validatorTemplate.init($this, el) - ) - ); - foundValidator = true; - } - } - ); - } - } - - if (! foundValidator) { - $.error("Cannot find validation info for '" + el + "'"); - } - }); - - // ============================================================= - // STORE FALLBACK VALUES - // ============================================================= - - $helpBlock.data( - "original-contents", - ( - $helpBlock.data("original-contents") - ? $helpBlock.data("original-contents") - : $helpBlock.html() - ) - ); - - $helpBlock.data( - "original-role", - ( - $helpBlock.data("original-role") - ? $helpBlock.data("original-role") - : $helpBlock.attr("role") - ) - ); - - $controlGroup.data( - "original-classes", - ( - $controlGroup.data("original-clases") - ? $controlGroup.data("original-classes") - : $controlGroup.attr("class") - ) - ); - - $this.data( - "original-aria-invalid", - ( - $this.data("original-aria-invalid") - ? $this.data("original-aria-invalid") - : $this.attr("aria-invalid") - ) - ); - - // ============================================================= - // VALIDATION - // ============================================================= - - $this.bind( - "validation.validation", - function (event, params) { - - var value = getValue($this); - - // Get a list of the errors to apply - var errorsFound = []; - - $.each(validators, function (validatorType, validatorTypeArray) { - if (value || value.length || (params && params.includeEmpty) || (!!settings.validatorTypes[validatorType].blockSubmit && params && !!params.submitting)) { - $.each(validatorTypeArray, function (i, validator) { - if (settings.validatorTypes[validatorType].validate($this, value, validator)) { - errorsFound.push(validator.message); - } - }); - } - }); - - return errorsFound; - } - ); - - $this.bind( - "getValidators.validation", - function () { - return validators; - } - ); - - // ============================================================= - // WATCH FOR CHANGES - // ============================================================= - $this.bind( - "submit.validation", - function () { - return $this.triggerHandler("change.validation", {submitting: true}); - } - ); - $this.bind( - [ - "keyup", - "focus", - "blur", - "click", - "keydown", - "keypress", - "change" - ].join(".validation ") + ".validation", - function (e, params) { - - var value = getValue($this); - - var errorsFound = []; - - $controlGroup.find("input,textarea,select").each(function (i, el) { - var oldCount = errorsFound.length; - $.each($(el).triggerHandler("validation.validation", params), function (j, message) { - errorsFound.push(message); - }); - if (errorsFound.length > oldCount) { - $(el).attr("aria-invalid", "true"); - } else { - var original = $this.data("original-aria-invalid"); - $(el).attr("aria-invalid", (original !== undefined ? original : false)); - } - }); - - $form.find("input,select,textarea").not($this).not("[name=\"" + $this.attr("name") + "\"]").trigger("validationLostFocus.validation"); - - errorsFound = $.unique(errorsFound.sort()); - - // Were there any errors? - if (errorsFound.length) { - // Better flag it up as a warning. - $controlGroup.removeClass("success error").addClass("warning"); - - // How many errors did we find? - if (settings.options.semanticallyStrict && errorsFound.length === 1) { - // Only one? Being strict? Just output it. - $helpBlock.html(errorsFound[0] + - ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" )); - } else { - // Multiple? Being sloppy? Glue them together into an UL. - $helpBlock.html("
  • " + errorsFound.join("
  • ") + "
" + - ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" )); - } - } else { - $controlGroup.removeClass("warning error success"); - if (value.length > 0) { - $controlGroup.addClass("success"); - } - $helpBlock.html($helpBlock.data("original-contents")); - } - - if (e.type === "blur") { - $controlGroup.removeClass("success"); - } - } - ); - $this.bind("validationLostFocus.validation", function () { - $controlGroup.removeClass("success"); - }); - }); - }, - destroy : function( ) { - - return this.each( - function() { - - var - $this = $(this), - $controlGroup = $this.parents(".form-group").first(), - $helpBlock = $controlGroup.find(".help-block").first(); - - // remove our events - $this.unbind('.validation'); // events are namespaced. - // reset help text - $helpBlock.html($helpBlock.data("original-contents")); - // reset classes - $controlGroup.attr("class", $controlGroup.data("original-classes")); - // reset aria - $this.attr("aria-invalid", $this.data("original-aria-invalid")); - // reset role - $helpBlock.attr("role", $this.data("original-role")); - // remove all elements we created - if (createdElements.indexOf($helpBlock[0]) > -1) { - $helpBlock.remove(); - } - - } - ); - - }, - collectErrors : function(includeEmpty) { - - var errorMessages = {}; - this.each(function (i, el) { - var $el = $(el); - var name = $el.attr("name"); - var errors = $el.triggerHandler("validation.validation", {includeEmpty: true}); - errorMessages[name] = $.extend(true, errors, errorMessages[name]); - }); - - $.each(errorMessages, function (i, el) { - if (el.length === 0) { - delete errorMessages[i]; - } - }); - - return errorMessages; - - }, - hasErrors: function() { - - var errorMessages = []; - - this.each(function (i, el) { - errorMessages = errorMessages.concat( - $(el).triggerHandler("getValidators.validation") ? $(el).triggerHandler("validation.validation", {submitting: true}) : [] - ); - }); - - return (errorMessages.length > 0); - }, - override : function (newDefaults) { - defaults = $.extend(true, defaults, newDefaults); - } - }, - validatorTypes: { - callback: { - name: "callback", - init: function ($this, name) { - return { - validatorName: name, - callback: $this.data("validation" + name + "Callback"), - lastValue: $this.val(), - lastValid: true, - lastFinished: true - }; - }, - validate: function ($this, value, validator) { - if (validator.lastValue === value && validator.lastFinished) { - return !validator.lastValid; - } - - if (validator.lastFinished === true) - { - validator.lastValue = value; - validator.lastValid = true; - validator.lastFinished = false; - - var rrjqbvValidator = validator; - var rrjqbvThis = $this; - executeFunctionByName( - validator.callback, - window, - $this, - value, - function (data) { - if (rrjqbvValidator.lastValue === data.value) { - rrjqbvValidator.lastValid = data.valid; - if (data.message) { - rrjqbvValidator.message = data.message; - } - rrjqbvValidator.lastFinished = true; - rrjqbvThis.data("validation" + rrjqbvValidator.validatorName + "Message", rrjqbvValidator.message); - // Timeout is set to avoid problems with the events being considered 'already fired' - setTimeout(function () { - rrjqbvThis.trigger("change.validation"); - }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst - } - } - ); - } - - return false; - - } - }, - ajax: { - name: "ajax", - init: function ($this, name) { - return { - validatorName: name, - url: $this.data("validation" + name + "Ajax"), - lastValue: $this.val(), - lastValid: true, - lastFinished: true - }; - }, - validate: function ($this, value, validator) { - if (""+validator.lastValue === ""+value && validator.lastFinished === true) { - return validator.lastValid === false; - } - - if (validator.lastFinished === true) - { - validator.lastValue = value; - validator.lastValid = true; - validator.lastFinished = false; - $.ajax({ - url: validator.url, - data: "value=" + value + "&field=" + $this.attr("name"), - dataType: "json", - success: function (data) { - if (""+validator.lastValue === ""+data.value) { - validator.lastValid = !!(data.valid); - if (data.message) { - validator.message = data.message; - } - validator.lastFinished = true; - $this.data("validation" + validator.validatorName + "Message", validator.message); - // Timeout is set to avoid problems with the events being considered 'already fired' - setTimeout(function () { - $this.trigger("change.validation"); - }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst - } - }, - failure: function () { - validator.lastValid = true; - validator.message = "ajax call failed"; - validator.lastFinished = true; - $this.data("validation" + validator.validatorName + "Message", validator.message); - // Timeout is set to avoid problems with the events being considered 'already fired' - setTimeout(function () { - $this.trigger("change.validation"); - }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst - } - }); - } - - return false; - - } - }, - regex: { - name: "regex", - init: function ($this, name) { - return {regex: regexFromString($this.data("validation" + name + "Regex"))}; - }, - validate: function ($this, value, validator) { - return (!validator.regex.test(value) && ! validator.negative) - || (validator.regex.test(value) && validator.negative); - } - }, - required: { - name: "required", - init: function ($this, name) { - return {}; - }, - validate: function ($this, value, validator) { - return !!(value.length === 0 && ! validator.negative) - || !!(value.length > 0 && validator.negative); - }, - blockSubmit: true - }, - match: { - name: "match", - init: function ($this, name) { - var element = $this.parents("form").first().find("[name=\"" + $this.data("validation" + name + "Match") + "\"]").first(); - element.bind("validation.validation", function () { - $this.trigger("change.validation", {submitting: true}); - }); - return {"element": element}; - }, - validate: function ($this, value, validator) { - return (value !== validator.element.val() && ! validator.negative) - || (value === validator.element.val() && validator.negative); - }, - blockSubmit: true - }, - max: { - name: "max", - init: function ($this, name) { - return {max: $this.data("validation" + name + "Max")}; - }, - validate: function ($this, value, validator) { - return (parseFloat(value, 10) > parseFloat(validator.max, 10) && ! validator.negative) - || (parseFloat(value, 10) <= parseFloat(validator.max, 10) && validator.negative); - } - }, - min: { - name: "min", - init: function ($this, name) { - return {min: $this.data("validation" + name + "Min")}; - }, - validate: function ($this, value, validator) { - return (parseFloat(value) < parseFloat(validator.min) && ! validator.negative) - || (parseFloat(value) >= parseFloat(validator.min) && validator.negative); - } - }, - maxlength: { - name: "maxlength", - init: function ($this, name) { - return {maxlength: $this.data("validation" + name + "Maxlength")}; - }, - validate: function ($this, value, validator) { - return ((value.length > validator.maxlength) && ! validator.negative) - || ((value.length <= validator.maxlength) && validator.negative); - } - }, - minlength: { - name: "minlength", - init: function ($this, name) { - return {minlength: $this.data("validation" + name + "Minlength")}; - }, - validate: function ($this, value, validator) { - return ((value.length < validator.minlength) && ! validator.negative) - || ((value.length >= validator.minlength) && validator.negative); - } - }, - maxchecked: { - name: "maxchecked", - init: function ($this, name) { - var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); - elements.bind("click.validation", function () { - $this.trigger("change.validation", {includeEmpty: true}); - }); - return {maxchecked: $this.data("validation" + name + "Maxchecked"), elements: elements}; - }, - validate: function ($this, value, validator) { - return (validator.elements.filter(":checked").length > validator.maxchecked && ! validator.negative) - || (validator.elements.filter(":checked").length <= validator.maxchecked && validator.negative); - }, - blockSubmit: true - }, - minchecked: { - name: "minchecked", - init: function ($this, name) { - var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); - elements.bind("click.validation", function () { - $this.trigger("change.validation", {includeEmpty: true}); - }); - return {minchecked: $this.data("validation" + name + "Minchecked"), elements: elements}; - }, - validate: function ($this, value, validator) { - return (validator.elements.filter(":checked").length < validator.minchecked && ! validator.negative) - || (validator.elements.filter(":checked").length >= validator.minchecked && validator.negative); - }, - blockSubmit: true - } - }, - builtInValidators: { - email: { - name: "Email", - type: "shortcut", - shortcut: "validemail" - }, - validemail: { - name: "Validemail", - type: "regex", - regex: "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\.[A-Za-z]{2,4}", - message: "Not a valid email address" - }, - passwordagain: { - name: "Passwordagain", - type: "match", - match: "password", - message: "Does not match the given password" - }, - positive: { - name: "Positive", - type: "shortcut", - shortcut: "number,positivenumber" - }, - negative: { - name: "Negative", - type: "shortcut", - shortcut: "number,negativenumber" - }, - number: { - name: "Number", - type: "regex", - regex: "([+-]?\\\d+(\\\.\\\d*)?([eE][+-]?[0-9]+)?)?", - message: "Must be a number" - }, - integer: { - name: "Integer", - type: "regex", - regex: "[+-]?\\\d+", - message: "No decimal places allowed" - }, - positivenumber: { - name: "Positivenumber", - type: "min", - min: 0, - message: "Must be a positive number" - }, - negativenumber: { - name: "Negativenumber", - type: "max", - max: 0, - message: "Must be a negative number" - }, - required: { - name: "Required", - type: "required", - message: "This is required" - }, - checkone: { - name: "Checkone", - type: "minchecked", - minchecked: 1, - message: "Check at least one option" - } - } - }; - - var formatValidatorName = function (name) { - return name - .toLowerCase() - .replace( - /(^|\s)([a-z])/g , - function(m,p1,p2) { - return p1+p2.toUpperCase(); - } - ) - ; - }; - - var getValue = function ($this) { - // Extract the value we're talking about - var value = $this.val(); - var type = $this.attr("type"); - if (type === "checkbox") { - value = ($this.is(":checked") ? value : ""); - } - if (type === "radio") { - value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? value : ""); - } - return value; - }; - - function regexFromString(inputstring) { - return new RegExp("^" + inputstring + "$"); - } - - /** - * Thanks to Jason Bunting via StackOverflow.com - * - * http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string#answer-359910 - * Short link: http://tinyurl.com/executeFunctionByName - **/ - function executeFunctionByName(functionName, context /*, args*/) { - var args = Array.prototype.slice.call(arguments).splice(2); - var namespaces = functionName.split("."); - var func = namespaces.pop(); - for(var i = 0; i < namespaces.length; i++) { - context = context[namespaces[i]]; - } - return context[func].apply(this, args); - } - - $.fn.jqBootstrapValidation = function( method ) { - - if ( defaults.methods[method] ) { - return defaults.methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); - } else if ( typeof method === 'object' || ! method ) { - return defaults.methods.init.apply( this, arguments ); - } else { - $.error( 'Method ' + method + ' does not exist on jQuery.jqBootstrapValidation' ); - return null; - } - - }; - - $.jqBootstrapValidation = function (options) { - $(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments); - }; - -})( jQuery ); diff --git a/index.html b/index.html index 33c653e..2fab33d 100644 --- a/index.html +++ b/index.html @@ -647,15 +647,9 @@ - - - - - - - + diff --git a/js/agency.js b/js/agency.js index 30dffa0..290d97a 100644 --- a/js/agency.js +++ b/js/agency.js @@ -1,9 +1,3 @@ -/*! - * Start Bootstrap - Agnecy Bootstrap Theme (http://startbootstrap.com) - * Code licensed under the Apache License v2.0. - * For details, see http://www.apache.org/licenses/LICENSE-2.0. - */ - // jQuery for page scrolling feature - requires jQuery Easing plugin $(function() { $('a.page-scroll').bind('click', function(event) { diff --git a/package.json b/package.json index 5a66e6a..c188e9c 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,20 @@ { - "name": "Agency", - "slug": "agency", - "version": "0.0.1", - "homepage": "http://startbootstrap.com", - "author": "Start Bootstrap", - "license": { - "type": "Apache 2.0", - "url": "https://github.com/IronSummitMedia/startbootstrap/blob/gh-pages/LICENSE" - }, - "devDependencies": { - "grunt": "~0.4.5", - "grunt-contrib-copy": "~0.5.0", - "grunt-contrib-less": "~0.11.4", - "grunt-contrib-watch": "~0.6.1", - "grunt-banner": "~0.2.3" - } + "name": "Agency", + "slug": "agency", + "version": "0.0.1", + "homepage": "http://startbootstrap.com", + "author": "Start Bootstrap", + "license": { + "type": "Apache 2.0", + "url": "https://github.com/IronSummitMedia/startbootstrap/blob/gh-pages/LICENSE" + }, + "devDependencies": { + "grunt": "~0.4.5", + "grunt-contrib-copy": "~0.5.0", + "grunt-contrib-less": "~0.11.4", + "grunt-contrib-watch": "~0.6.1", + "grunt-banner": "~0.2.3", + "grunt-contrib-concat": "~0.5.0", + "grunt-contrib-uglify": "~0.5.1" + } }