mirror of
https://github.com/silverstripe/silverstripe-userforms.git
synced 2024-10-22 17:05:42 +02:00
port features
- hide field labels - date picker
This commit is contained in:
parent
97eb8b0255
commit
3217695713
@ -5,18 +5,43 @@ 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: {}
|
||||
FORM_ID: 'UserForm_Form', // $Form.FormName.JS
|
||||
ERROR_CONTAINER_ID: '', // $ErrorContainerID.JS
|
||||
ENABLE_LIVE_VALIDATION: false, // $EnableLiveValidation
|
||||
DISPLAY_ERROR_MESSAGES_AT_TOP: true, // $DisplayErrorMessagesAtTop
|
||||
HIDE_FIELD_LABELS: false, // $HideFieldLabels
|
||||
MESSAGES: {} // var meaasges
|
||||
};
|
||||
|
||||
// TODO
|
||||
// var messages = {<% loop $Fields %><% if $ErrorMessage && not $SetsOwnError %><% if $ClassName == 'EditableCheckboxGroupField' %>
|
||||
// '{$Name.JS}[]': '{$ErrorMessage.JS}'<% if not Last %>,<% end_if %><% else %>
|
||||
// '{$Name.JS}': '{$ErrorMessage.JS}'<% if not Last %>,<% end_if %><% end_if %><% end_if %><% end_loop %>
|
||||
// };
|
||||
|
||||
// Common functions that extend multiple classes.
|
||||
var commonMixin = {
|
||||
/**
|
||||
* @func show
|
||||
* @desc Show the form step. Looks after aria attributes too.
|
||||
*/
|
||||
show: function () {
|
||||
this.$el.attr('aria-hidden', false).show();
|
||||
},
|
||||
/**
|
||||
* @func hide
|
||||
* @desc Hide the form step. Looks after aria attributes too.
|
||||
*/
|
||||
hide: function () {
|
||||
this.$el.attr('aria-hidden', true).hide();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @func UserForm
|
||||
* @constructor
|
||||
* @param object element
|
||||
* @return object - The UserForm instance.
|
||||
* @param {object} element
|
||||
* @return {object} - The UserForm instance.
|
||||
* @desc The form
|
||||
*/
|
||||
function UserForm(element) {
|
||||
@ -43,7 +68,7 @@ jQuery(function ($) {
|
||||
|
||||
/**
|
||||
* @func UserForm.addStep
|
||||
* @param object step - An instance of FormStep.
|
||||
* @param {object} step - An instance of FormStep.
|
||||
* @desc Adds a step to the UserForm.
|
||||
*/
|
||||
UserForm.prototype.addStep = function (step) {
|
||||
@ -57,7 +82,7 @@ jQuery(function ($) {
|
||||
|
||||
/**
|
||||
* @func UserForm.setCurrentStep
|
||||
* @param object step - An instance of FormStep.
|
||||
* @param {object} step - An instance of FormStep.
|
||||
* @desc Sets the step the user is currently on.
|
||||
*/
|
||||
UserForm.prototype.setCurrentStep = function (step) {
|
||||
@ -76,7 +101,7 @@ jQuery(function ($) {
|
||||
|
||||
/**
|
||||
* @func UserForm.jumpToStep
|
||||
* @param number stepNumber
|
||||
* @param {number} stepNumber
|
||||
* @desc Jumps to a specific form step.
|
||||
*/
|
||||
UserForm.prototype.jumpToStep = function (stepNumber) {
|
||||
@ -116,11 +141,83 @@ jQuery(function ($) {
|
||||
this.jumpToStep(this.steps.indexOf(this.currentStep) - 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* @func ErrorContainer
|
||||
* @constructor
|
||||
* @param {object} element - The error container element.
|
||||
* @return {object} - The ErrorContainer instance.
|
||||
* @desc Creates an error container. Used to display step error messages at the top.
|
||||
*/
|
||||
function ErrorContainer(element) {
|
||||
this.$el = element instanceof jQuery ? element : $(element);
|
||||
|
||||
// Set the error container's heading.
|
||||
this.$el.find('h4').text(ss.i18n._t('UserForms.ERROR_CONTAINER_HEADER', 'Please correct the following errors and try again:'));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @func ErrorContainer.updateErrorMessage
|
||||
* @param {object} input - The jQuery input object which contains the field to validate.
|
||||
* @param {object} message - The error message to display (html escaped).
|
||||
* @desc Update an error message (displayed at the top of the form).
|
||||
*/
|
||||
ErrorContainer.prototype.updateErrorMessage = function (input, message) {
|
||||
var inputID = input.attr('id'),
|
||||
anchor = '#' + inputID,
|
||||
elementID = inputID + '-top-error',
|
||||
messageElement = $('#' + elementID),
|
||||
describedBy = input.attr('aria-describedby');
|
||||
|
||||
// The 'message' param will be an empty string if the field is valid.
|
||||
if (!message) {
|
||||
// Style issues as fixed if they already exist
|
||||
messageElement.addClass('fixed');
|
||||
return;
|
||||
}
|
||||
|
||||
messageElement.removeClass('fixed');
|
||||
|
||||
this.show();
|
||||
|
||||
if (messageElement.length === 1) {
|
||||
// Update the existing error message.
|
||||
messageElement.show().find('a').html(message);
|
||||
} else {
|
||||
// Generate better link to field
|
||||
input.closest('.field[id]').each(function(){
|
||||
anchor = '#' + $(this).attr('id');
|
||||
});
|
||||
|
||||
// Add a new error message
|
||||
messageElement = $('<li><a></a></li>');
|
||||
messageElement
|
||||
.attr('id', elementID)
|
||||
.find('a')
|
||||
.attr('href', location.pathname + location.search + anchor)
|
||||
.html(message);
|
||||
|
||||
this.$el.find('ul').append(messageElement);
|
||||
|
||||
// link back to original input via aria
|
||||
// Respect existing non-error aria-describedby
|
||||
if ( !describedBy ) {
|
||||
describedBy = elementID;
|
||||
} else if ( !describedBy.match( new RegExp( "\\b" + elementID + "\\b" ) ) ) {
|
||||
// Add to end of list if not already present
|
||||
describedBy += " " + elementID;
|
||||
}
|
||||
|
||||
input.attr('aria-describedby', describedBy);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @func FormStep
|
||||
* @constructor
|
||||
* @param object element
|
||||
* @return object - The FormStep instance.
|
||||
* @param {object} element
|
||||
* @return {object} - The FormStep instance.
|
||||
* @desc Creates a form step.
|
||||
*/
|
||||
function FormStep(element) {
|
||||
@ -128,6 +225,10 @@ jQuery(function ($) {
|
||||
|
||||
this.$el = element instanceof jQuery ? element : $(element);
|
||||
|
||||
if (CONSTANTS.DISPLAY_ERROR_MESSAGES_AT_TOP) {
|
||||
this.errorContainer = new ErrorContainer(this.$el.find('.error-container'));
|
||||
}
|
||||
|
||||
// Has the step been viewed by the user?
|
||||
this.viewed = false;
|
||||
|
||||
@ -157,6 +258,7 @@ jQuery(function ($) {
|
||||
errorClass: 'required',
|
||||
errorElement: 'span',
|
||||
errorPlacement: function (error, element) {
|
||||
debugger;
|
||||
error.addClass('message');
|
||||
|
||||
if(element.is(':radio') || element.parents('.checkboxset').length > 0) {
|
||||
@ -167,7 +269,7 @@ jQuery(function ($) {
|
||||
|
||||
if (CONSTANTS.DISPLAY_ERROR_MESSAGES_AT_TOP) {
|
||||
// TODO
|
||||
//applyTopErrorMessage(element, error.html());
|
||||
this.errorContainer.updateErrorMessage(element, error.html());
|
||||
}
|
||||
|
||||
},
|
||||
@ -187,27 +289,11 @@ jQuery(function ($) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @func FormStep.show
|
||||
* @desc Show the form step. Looks after aria attributes too.
|
||||
*/
|
||||
FormStep.prototype.show = function () {
|
||||
this.$el.attr('aria-hidden', false).show();
|
||||
};
|
||||
|
||||
/**
|
||||
* @func FormStep.hide
|
||||
* @desc Hide the form step. Looks after aria attributes too.
|
||||
*/
|
||||
FormStep.prototype.hide = function () {
|
||||
this.$el.attr('aria-hidden', true).hide();
|
||||
};
|
||||
|
||||
/**
|
||||
* @func ProgressBar
|
||||
* @constructor
|
||||
* @param object element
|
||||
* @return object - The Progress bar instance.
|
||||
* @param {object} element
|
||||
* @return {object} - The Progress bar instance.
|
||||
* @desc Creates a progress bar.
|
||||
*/
|
||||
function ProgressBar(element) {
|
||||
@ -236,7 +322,7 @@ jQuery(function ($) {
|
||||
|
||||
/**
|
||||
* @func ProgressBar.update
|
||||
* @param number newStep
|
||||
* @param {number} newStep
|
||||
* @desc Update the progress element to show a new step.
|
||||
*/
|
||||
ProgressBar.prototype.update = function (newStep) {
|
||||
@ -277,6 +363,10 @@ jQuery(function ($) {
|
||||
var userform = new UserForm($('.userform')),
|
||||
progressBar = new ProgressBar($('#userform-progress'));
|
||||
|
||||
// Extend classes with common functionality.
|
||||
$.extend(FormStep.prototype, commonMixin);
|
||||
$.extend(ErrorContainer.prototype, commonMixin);
|
||||
|
||||
// Extend the default validation options with conditional options
|
||||
// that are set by the user in the CMS.
|
||||
if (CONSTANTS.ENABLE_LIVE_VALIDATION) {
|
||||
@ -299,13 +389,23 @@ jQuery(function ($) {
|
||||
|
||||
$.each(validator.errorList, function () {
|
||||
// TODO
|
||||
//applyTopErrorMessage($(this.element), this.message);
|
||||
this.errorContainer.updateErrorMessage($(this.element), this.message);
|
||||
});
|
||||
},
|
||||
onfocusout: false
|
||||
});
|
||||
}
|
||||
|
||||
// Conditionally hide field labels and use HTML5 placeholder instead.
|
||||
if (CONSTANTS.HIDE_FIELD_LABELS) {
|
||||
$('#' + CONSTANTS.FORM_ID + ' label.left').each(function () {
|
||||
var $label = $(this);
|
||||
|
||||
$('[name="' + $label.attr('for') + '"]').attr('placeholder', $label.text());
|
||||
$label.remove();
|
||||
});
|
||||
}
|
||||
|
||||
// Display all the things that are hidden when JavaScript is disabled.
|
||||
$.each(['#userform-progress', '.step-navigation'], function (i, selector) {
|
||||
$(selector).attr('aria-hidden', false).show();
|
||||
@ -327,6 +427,17 @@ jQuery(function ($) {
|
||||
userform.$el.children('.Actions').attr('aria-hidden', true).hide();
|
||||
}
|
||||
|
||||
// Enable jQuery UI datepickers
|
||||
$(document).on('click', 'input.text[data-showcalendar]', function() {
|
||||
var $element = $(this);
|
||||
|
||||
$element.ssDatepicker();
|
||||
|
||||
if($element.data('datepicker')) {
|
||||
$element.datepicker('show');
|
||||
}
|
||||
});
|
||||
|
||||
// Make sure the form doesn't expire on the user. Pings every 3 mins.
|
||||
setInterval(function () {
|
||||
$.ajax({ url: 'UserDefinedForm_Controller/ping' });
|
||||
|
@ -5,7 +5,7 @@
|
||||
<% if $Message %>
|
||||
<p id="{$FormName}_error" class="message $MessageType">$Message</p>
|
||||
<% else %>
|
||||
<p id="{$FormName}_error" class="message $MessageType" style="display: none"></p>
|
||||
<p id="{$FormName}_error" class="message $MessageType" aria-hidden="true" style="display: none;"></p>
|
||||
<% end_if %>
|
||||
|
||||
<fieldset>
|
||||
@ -13,10 +13,21 @@
|
||||
|
||||
<% loop $FormSteps %>
|
||||
<fieldset class="form-step">
|
||||
<% if $DisplayErrorMessagesAtTop %>
|
||||
<fieldset class="error-container" aria-hidden="true" style="display: none;">
|
||||
<div>
|
||||
<h4></h4>
|
||||
<ul></ul>
|
||||
</div>
|
||||
</fieldset>
|
||||
<% end_if %>
|
||||
|
||||
<h2>$Title</h2>
|
||||
|
||||
<% loop $Fields %>
|
||||
$FieldHolder
|
||||
<% end_loop %>
|
||||
|
||||
<% include UserFormStepNav ContainingPage=$Top %>
|
||||
</fieldset>
|
||||
<% end_loop %>
|
||||
|
Loading…
Reference in New Issue
Block a user