Initial validation

This commit is contained in:
David Craig 2015-08-06 17:47:14 +12:00 committed by Damian Mooyman
parent 10c86bcbc1
commit 97eb8b0255
2 changed files with 102 additions and 10 deletions

View File

@ -3,6 +3,15 @@
*/ */
jQuery(function ($) { jQuery(function ($) {
// Settings that come from the CMS.
var CONSTANTS = {
ERROR_CONTAINER_ID: '',
ENABLE_LIVE_VALIDATION: false,
DISPLAY_ERROR_MESSAGES_AT_TOP: false,
HIDE_FIELD_LABELS: false,
MESSAGES: {}
};
/** /**
* @func UserForm * @func UserForm
* @constructor * @constructor
@ -59,6 +68,10 @@ jQuery(function ($) {
this.currentStep = step; this.currentStep = step;
this.currentStep.show(); this.currentStep.show();
// Record the user has viewed the step.
step.viewed = true;
step.$el.addClass('viewed');
}; };
/** /**
@ -74,6 +87,13 @@ jQuery(function ($) {
return; return;
} }
// Validate the current section.
// Users can navigate to step's they've already viewed
// even if the current step is invalid.
if (!this.$el.valid() && targetStep.viewed === false) {
return;
}
this.currentStep.hide(); this.currentStep.hide();
this.setCurrentStep(targetStep); this.setCurrentStep(targetStep);
@ -108,6 +128,11 @@ jQuery(function ($) {
this.$el = element instanceof jQuery ? element : $(element); this.$el = element instanceof jQuery ? element : $(element);
// Has the step been viewed by the user?
this.viewed = false;
this.hide();
// Bind the step navigation event listeners. // Bind the step navigation event listeners.
this.$el.find('.step-button-prev').on('click', function (e) { this.$el.find('.step-button-prev').on('click', function (e) {
e.preventDefault(); e.preventDefault();
@ -118,11 +143,50 @@ jQuery(function ($) {
self.$el.trigger('userform.step.next'); self.$el.trigger('userform.step.next');
}); });
this.hide(); // Set up validation for the step.
this.$el.validate(this.validationOptions);
return this; return this;
} }
/*
* Default options for step validation. These get extended in main().
*/
FormStep.prototype.validationOptions = {
ignore: ':hidden',
errorClass: 'required',
errorElement: 'span',
errorPlacement: function (error, element) {
error.addClass('message');
if(element.is(':radio') || element.parents('.checkboxset').length > 0) {
error.insertAfter(element.closest('ul'));
} else {
error.insertAfter(element);
}
if (CONSTANTS.DISPLAY_ERROR_MESSAGES_AT_TOP) {
// TODO
//applyTopErrorMessage(element, error.html());
}
},
success: function (error) {
error.remove();
},
messages: CONSTANTS.MESSAGES,
rules: {
// TODO
// <% loop $Fields %>
// <% if $Validation %><% if ClassName == EditableCheckboxGroupField %>
// '{$Name.JS}[]': {$ValidationJSON.RAW},
// <% else %>
// '{$Name.JS}': {$ValidationJSON.RAW},
// <% end_if %><% end_if %>
// <% end_loop %>
}
};
/** /**
* @func FormStep.show * @func FormStep.show
* @desc Show the form step. Looks after aria attributes too. * @desc Show the form step. Looks after aria attributes too.
@ -155,12 +219,8 @@ jQuery(function ($) {
// Update the progress bar when 'step' buttons are clicked. // Update the progress bar when 'step' buttons are clicked.
this.$buttons.each(function (i, stepButton) { this.$buttons.each(function (i, stepButton) {
$(stepButton).on('click', function (e) { $(stepButton).on('click', function (e) {
var newStepNumber = parseInt($(this).text(), 10);
e.preventDefault(); e.preventDefault();
self.$el.trigger('userform.progress.changestep', [parseInt($(this).text(), 10)]);
self.update(newStepNumber);
self.$el.trigger('userform.progress.changestep', [newStepNumber]);
}); });
}); });
@ -192,10 +252,13 @@ jQuery(function ($) {
// Update the CSS classes on step buttons. // Update the CSS classes on step buttons.
this.$buttons.each(function (i, element) { this.$buttons.each(function (i, element) {
var $item = $(element).parent(); var $element = $(element),
$item = $element.parent();
if (parseInt($element.text(), 10) === newStep) {
$item.addClass('current viewed');
$element.removeAttr('disabled');
if (parseInt($(element).text(), 10) === newStep) {
$item.addClass('current');
return; return;
} }
@ -214,6 +277,35 @@ jQuery(function ($) {
var userform = new UserForm($('.userform')), var userform = new UserForm($('.userform')),
progressBar = new ProgressBar($('#userform-progress')); progressBar = new ProgressBar($('#userform-progress'));
// Extend the default validation options with conditional options
// that are set by the user in the CMS.
if (CONSTANTS.ENABLE_LIVE_VALIDATION) {
$.extend(FormStep.prototype.validationOptions, {
onfocusout: function (element) {
this.element(element);
}
});
}
if (CONSTANTS.DISPLAY_ERROR_MESSAGES_AT_TOP) {
$.extend(FormStep.prototype.validationOptions, {
invalidHandler: function (event, validator) {
var errorList = $('#' + CONSTANTS.ERROR_CONTAINER_ID + ' ul');
// Update the error list with errors from the validator.
// We do this because top messages are not part of the regular
// error message life cycle, which jquery.validate handles for us.
errorList.empty();
$.each(validator.errorList, function () {
// TODO
//applyTopErrorMessage($(this.element), this.message);
});
},
onfocusout: false
});
}
// Display all the things that are hidden when JavaScript is disabled. // Display all the things that are hidden when JavaScript is disabled.
$.each(['#userform-progress', '.step-navigation'], function (i, selector) { $.each(['#userform-progress', '.step-navigation'], function (i, selector) {
$(selector).attr('aria-hidden', false).show(); $(selector).attr('aria-hidden', false).show();

View File

@ -9,7 +9,7 @@
<ul class="step-buttons"> <ul class="step-buttons">
<% loop $NumberOfSteps %> <% loop $NumberOfSteps %>
<li class="step-button-wrapper<% if $Pos == '1' %> current<% end_if %>"> <li class="step-button-wrapper<% if $Pos == '1' %> current<% end_if %>">
<button class="step-button-jump">$Pos</button> <button class="step-button-jump" disabled="disabled">$Pos</button>
</li> </li>
<% end_loop %> <% end_loop %>
<ul> <ul>