647 lines
23 KiB
JavaScript
647 lines
23 KiB
JavaScript
/**
|
|
* @file
|
|
* JavaScript behaviors for custom webform #states.
|
|
*/
|
|
|
|
(function ($, Drupal) {
|
|
|
|
'use strict';
|
|
|
|
Drupal.webform = Drupal.webform || {};
|
|
Drupal.webform.states = Drupal.webform.states || {};
|
|
Drupal.webform.states.slideDown = Drupal.webform.states.slideDown || {};
|
|
Drupal.webform.states.slideDown.duration = 'slow';
|
|
Drupal.webform.states.slideUp = Drupal.webform.states.slideUp || {};
|
|
Drupal.webform.states.slideUp.duration = 'fast';
|
|
|
|
/* ************************************************************************ */
|
|
// jQuery functions.
|
|
/* ************************************************************************ */
|
|
|
|
/**
|
|
* Check if an element has a specified data attribute.
|
|
*
|
|
* @param {string} data
|
|
* The data attribute name.
|
|
*
|
|
* @return {boolean}
|
|
* TRUE if an element has a specified data attribute.
|
|
*/
|
|
$.fn.hasData = function (data) {
|
|
return (typeof this.data(data) !== 'undefined');
|
|
};
|
|
|
|
/**
|
|
* Check if element is within the webform or not.
|
|
*
|
|
* @return {boolean}
|
|
* TRUE if element is within the webform.
|
|
*/
|
|
$.fn.isWebform = function () {
|
|
return $(this).closest('form.webform-submission-form, form[id^="webform"], form[data-is-webform]').length ? true : false;
|
|
};
|
|
|
|
/**
|
|
* Check if element is to be treated as a webform element.
|
|
*
|
|
* @return {boolean}
|
|
* TRUE if element is to be treated as a webform element.
|
|
*/
|
|
$.fn.isWebformElement = function () {
|
|
return ($(this).isWebform() || $(this).closest('[data-is-webform-element]').length) ? true : false;
|
|
};
|
|
|
|
/* ************************************************************************ */
|
|
// Trigger.
|
|
/* ************************************************************************ */
|
|
|
|
// The change event is triggered by cut-n-paste and select menus.
|
|
// Issue #2445271: #states element empty check not triggered on mouse
|
|
// based paste.
|
|
// @see https://www.drupal.org/node/2445271
|
|
Drupal.states.Trigger.states.empty.change = function change() {
|
|
return this.val() === '';
|
|
};
|
|
|
|
/* ************************************************************************ */
|
|
// Dependents.
|
|
/* ************************************************************************ */
|
|
|
|
// Apply solution included in #1962800 patch.
|
|
// Issue #1962800: Form #states not working with literal integers as
|
|
// values in IE11.
|
|
// @see https://www.drupal.org/project/drupal/issues/1962800
|
|
// @see https://www.drupal.org/files/issues/core-states-not-working-with-integers-ie11_1962800_46.patch
|
|
//
|
|
// This issue causes pattern, less than, and greater than support to break.
|
|
// @see https://www.drupal.org/project/webform/issues/2981724
|
|
var states = Drupal.states;
|
|
Drupal.states.Dependent.prototype.compare = function compare(reference, selector, state) {
|
|
var value = this.values[selector][state.name];
|
|
|
|
var name = reference.constructor.name;
|
|
if (!name) {
|
|
name = $.type(reference);
|
|
|
|
name = name.charAt(0).toUpperCase() + name.slice(1);
|
|
}
|
|
if (name in states.Dependent.comparisons) {
|
|
return states.Dependent.comparisons[name](reference, value);
|
|
}
|
|
|
|
if (reference.constructor.name in states.Dependent.comparisons) {
|
|
return states.Dependent.comparisons[reference.constructor.name](reference, value);
|
|
}
|
|
|
|
return _compare2(reference, value);
|
|
};
|
|
function _compare2(a, b) {
|
|
if (a === b) {
|
|
return typeof a === 'undefined' ? a : true;
|
|
}
|
|
|
|
return typeof a === 'undefined' || typeof b === 'undefined';
|
|
}
|
|
|
|
// Adds pattern, less than, and greater than support to #state API.
|
|
// @see http://drupalsun.com/julia-evans/2012/03/09/extending-form-api-states-regular-expressions
|
|
Drupal.states.Dependent.comparisons.Object = function (reference, value) {
|
|
if ('pattern' in reference) {
|
|
return (new RegExp(reference['pattern'])).test(value);
|
|
}
|
|
else if ('!pattern' in reference) {
|
|
return !((new RegExp(reference['!pattern'])).test(value));
|
|
}
|
|
else if ('less' in reference) {
|
|
return (value !== '' && parseFloat(reference['less']) > parseFloat(value));
|
|
}
|
|
else if ('less_equal' in reference) {
|
|
return (value !== '' && parseFloat(reference['less_equal']) >= parseFloat(value));
|
|
}
|
|
else if ('greater' in reference) {
|
|
return (value !== '' && parseFloat(reference['greater']) < parseFloat(value));
|
|
}
|
|
else if ('greater_equal' in reference) {
|
|
return (value !== '' && parseFloat(reference['greater_equal']) <= parseFloat(value));
|
|
}
|
|
else if ('between' in reference || '!between' in reference) {
|
|
if (value === '') {
|
|
return false;
|
|
}
|
|
|
|
var between = reference['between'] || reference['!between'];
|
|
var betweenParts = between.split(':');
|
|
var greater = betweenParts[0];
|
|
var less = (typeof betweenParts[1] !== 'undefined') ? betweenParts[1] : null;
|
|
var isGreaterThan = (greater === null || greater === '' || parseFloat(value) >= parseFloat(greater));
|
|
var isLessThan = (less === null || less === '' || parseFloat(value) <= parseFloat(less));
|
|
var result = (isGreaterThan && isLessThan);
|
|
return (reference['!between']) ? !result : result;
|
|
}
|
|
else {
|
|
return reference.indexOf(value) !== false;
|
|
}
|
|
};
|
|
|
|
/* ************************************************************************ */
|
|
// States events.
|
|
/* ************************************************************************ */
|
|
|
|
var $document = $(document);
|
|
|
|
$document.on('state:required', function (e) {
|
|
if (e.trigger && $(e.target).isWebformElement()) {
|
|
var $target = $(e.target);
|
|
// Fix #required file upload.
|
|
// @see Issue #2860529: Conditional required File upload field don't work.
|
|
toggleRequired($target.find('input[type="file"]'), e.value);
|
|
|
|
// Fix #required for radios and likert.
|
|
// @see Issue #2856795: If radio buttons are required but not filled form is nevertheless submitted.
|
|
if ($target.is('.js-form-type-radios, .js-form-type-webform-radios-other, .js-webform-type-radios, .js-webform-type-webform-radios-other, .js-webform-type-webform-entity-radios, .webform-likert-table')) {
|
|
$target.toggleClass('required', e.value);
|
|
toggleRequired($target.find('input[type="radio"]'), e.value);
|
|
}
|
|
|
|
// Fix #required for checkboxes.
|
|
// @see Issue #2938414: Checkboxes don't support #states required.
|
|
// @see checkboxRequiredhandler
|
|
if ($target.is('.js-form-type-checkboxes, .js-form-type-webform-checkboxes-other, .js-webform-type-checkboxes, .js-webform-type-webform-checkboxes-other')) {
|
|
$target.toggleClass('required', e.value);
|
|
var $checkboxes = $target.find('input[type="checkbox"]');
|
|
if (e.value) {
|
|
// Add event handler.
|
|
$checkboxes.on('click', statesCheckboxesRequiredEventHandler);
|
|
// Initialize and add required attribute.
|
|
checkboxesRequired($target);
|
|
}
|
|
else {
|
|
// Remove event handler.
|
|
$checkboxes.off('click', statesCheckboxesRequiredEventHandler);
|
|
// Remove required attribute.
|
|
toggleRequired($checkboxes, false);
|
|
}
|
|
}
|
|
|
|
// Fix #required for tableselect.
|
|
// @see Issue #3212581: Table select does not trigger client side validation
|
|
if ($target.is('.js-webform-tableselect')) {
|
|
$target.toggleClass('required', e.value);
|
|
var isMultiple = $target.is('[multiple]');
|
|
if (isMultiple) {
|
|
// Checkboxes.
|
|
var $tbody = $target.find('tbody');
|
|
var $checkboxes = $tbody.find('input[type="checkbox"]');
|
|
copyRequireMessage($target, $checkboxes);
|
|
if (e.value) {
|
|
$checkboxes.on('click change', statesCheckboxesRequiredEventHandler);
|
|
checkboxesRequired($tbody);
|
|
}
|
|
else {
|
|
$checkboxes.off('click change ', statesCheckboxesRequiredEventHandler);
|
|
toggleRequired($tbody, false);
|
|
}
|
|
}
|
|
else {
|
|
// Radios.
|
|
var $radios = $target.find('input[type="radio"]');
|
|
copyRequireMessage($target, $radios);
|
|
toggleRequired($radios, e.value);
|
|
}
|
|
}
|
|
|
|
// Fix required label for elements without the for attribute.
|
|
// @see Issue #3145300: Conditional Visible Select Other not working.
|
|
if ($target.is('.js-form-type-webform-select-other, .js-webform-type-webform-select-other')) {
|
|
var $select = $target.find('select');
|
|
toggleRequired($select, e.value);
|
|
copyRequireMessage($target, $select);
|
|
}
|
|
if ($target.find('> label:not([for])').length) {
|
|
$target.find('> label').toggleClass('js-form-required form-required', e.value);
|
|
}
|
|
|
|
// Fix required label for checkboxes and radios.
|
|
// @see Issue #2938414: Checkboxes don't support #states required
|
|
// @see Issue #2731991: Setting required on radios marks all options required.
|
|
// @see Issue #2856315: Conditional Logic - Requiring Radios in a Fieldset.
|
|
// Fix #required for fieldsets.
|
|
// @see Issue #2977569: Hidden fieldsets that become visible with conditional logic cannot be made required.
|
|
if ($target.is('.js-webform-type-radios, .js-webform-type-checkboxes, fieldset')) {
|
|
$target.find('legend span.fieldset-legend:not(.visually-hidden)').toggleClass('js-form-required form-required', e.value);
|
|
}
|
|
|
|
// Issue #2986017: Fieldsets shouldn't have required attribute.
|
|
if ($target.is('fieldset')) {
|
|
$target.removeAttr('required aria-required');
|
|
}
|
|
}
|
|
});
|
|
|
|
$document.on('state:checked', function (e) {
|
|
if (e.trigger) {
|
|
$(e.target).trigger('change');
|
|
}
|
|
});
|
|
|
|
$document.on('state:readonly', function (e) {
|
|
if (e.trigger && $(e.target).isWebformElement()) {
|
|
$(e.target).prop('readonly', e.value).closest('.js-form-item, .js-form-wrapper').toggleClass('webform-readonly', e.value).find('input, textarea').prop('readonly', e.value);
|
|
|
|
// Trigger webform:readonly.
|
|
$(e.target).trigger('webform:readonly')
|
|
.find('select, input, textarea, button').trigger('webform:readonly');
|
|
}
|
|
});
|
|
|
|
$document.on('state:visible state:visible-slide', function (e) {
|
|
if (e.trigger && $(e.target).isWebformElement()) {
|
|
if (e.value) {
|
|
$(':input', e.target).addBack().each(function () {
|
|
restoreValueAndRequired(this);
|
|
triggerEventHandlers(this);
|
|
});
|
|
}
|
|
else {
|
|
// @see https://www.sitepoint.com/jquery-function-clear-form-data/
|
|
$(':input', e.target).addBack().each(function () {
|
|
backupValueAndRequired(this);
|
|
clearValueAndRequired(this);
|
|
triggerEventHandlers(this);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
$document.on('state:visible-slide', function (e) {
|
|
if (e.trigger && $(e.target).isWebformElement()) {
|
|
var effect = e.value ? 'slideDown' : 'slideUp';
|
|
var duration = Drupal.webform.states[effect].duration;
|
|
$(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper')[effect](duration);
|
|
}
|
|
});
|
|
Drupal.states.State.aliases['invisible-slide'] = '!visible-slide';
|
|
|
|
$document.on('state:disabled', function (e) {
|
|
if (e.trigger && $(e.target).isWebformElement()) {
|
|
// Make sure disabled property is set before triggering webform:disabled.
|
|
// Copied from: core/misc/states.js
|
|
$(e.target)
|
|
.prop('disabled', e.value)
|
|
.closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value)
|
|
.find('select, input, textarea, button').prop('disabled', e.value);
|
|
|
|
// Never disable hidden file[fids] because the existing values will
|
|
// be completely lost when the webform is submitted.
|
|
var fileElements = $(e.target)
|
|
.find(':input[type="hidden"][name$="[fids]"]');
|
|
if (fileElements.length) {
|
|
// Remove 'disabled' attribute from fieldset which will block
|
|
// all disabled elements from being submitted.
|
|
if ($(e.target).is('fieldset')) {
|
|
$(e.target).prop('disabled', false);
|
|
}
|
|
fileElements.removeAttr('disabled');
|
|
}
|
|
|
|
// Trigger webform:disabled.
|
|
$(e.target).trigger('webform:disabled')
|
|
.find('select, input, textarea, button').trigger('webform:disabled');
|
|
}
|
|
});
|
|
|
|
/* ************************************************************************ */
|
|
// Behaviors.
|
|
/* ************************************************************************ */
|
|
|
|
/**
|
|
* Adds HTML5 validation to required checkboxes.
|
|
*
|
|
* @type {Drupal~behavior}
|
|
*
|
|
* @see https://www.drupal.org/project/webform/issues/3068998
|
|
*/
|
|
Drupal.behaviors.webformCheckboxesRequired = {
|
|
attach: function (context) {
|
|
$('.js-form-type-checkboxes.required, .js-form-type-webform-checkboxes-other.required, .js-webform-type-checkboxes.required, .js-webform-type-webform-checkboxes-other.required, .js-webform-type-webform-radios-other.checkboxes', context)
|
|
.once('webform-checkboxes-required')
|
|
.each(function () {
|
|
var $element = $(this);
|
|
$element.find('input[type="checkbox"]').on('click', statesCheckboxesRequiredEventHandler);
|
|
setTimeout(function () {checkboxesRequired($element);});
|
|
});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Adds HTML5 validation to required radios.
|
|
*
|
|
* @type {Drupal~behavior}
|
|
*
|
|
* @see https://www.drupal.org/project/webform/issues/2856795
|
|
*/
|
|
Drupal.behaviors.webformRadiosRequired = {
|
|
attach: function (context) {
|
|
$('.js-form-type-radios, .js-form-type-webform-radios-other, .js-webform-type-radios, .js-webform-type-webform-radios-other, .js-webform-type-webform-entity-radios, .js-webform-type-webform-scale', context)
|
|
.once('webform-radios-required')
|
|
.each(function () {
|
|
var $element = $(this);
|
|
setTimeout(function () {radiosRequired($element);});
|
|
});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Adds HTML5 validation to required table select.
|
|
*
|
|
* @type {Drupal~behavior}
|
|
*
|
|
* @see https://www.drupal.org/project/webform/issues/2856795
|
|
*/
|
|
Drupal.behaviors.webformTableSelectRequired = {
|
|
attach: function (context) {
|
|
$('.js-webform-tableselect.required', context)
|
|
.once('webform-tableselect-required')
|
|
.each(function () {
|
|
var $element = $(this);
|
|
var $tbody = $element.find('tbody');
|
|
var isMultiple = $element.is('[multiple]');
|
|
|
|
if (isMultiple) {
|
|
// Check all checkbox triggers checkbox 'change' event on
|
|
// select and deselect all.
|
|
// @see Drupal.tableSelect
|
|
$tbody.find('input[type="checkbox"]').on('click change', function () {
|
|
checkboxesRequired($tbody);
|
|
});
|
|
}
|
|
|
|
setTimeout(function () {
|
|
isMultiple ? checkboxesRequired($tbody) : radiosRequired($element);
|
|
});
|
|
});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Add HTML5 multiple checkboxes required validation.
|
|
*
|
|
* @param {jQuery} $element
|
|
* An jQuery object containing HTML5 radios.
|
|
*
|
|
* @see https://stackoverflow.com/a/37825072/145846
|
|
*/
|
|
function checkboxesRequired($element) {
|
|
var $firstCheckbox = $element.find('input[type="checkbox"]').first();
|
|
var isChecked = $element.find('input[type="checkbox"]').is(':checked');
|
|
toggleRequired($firstCheckbox, !isChecked);
|
|
copyRequireMessage($element, $firstCheckbox);
|
|
}
|
|
|
|
/**
|
|
* Add HTML5 radios required validation.
|
|
*
|
|
* @param {jQuery} $element
|
|
* An jQuery object containing HTML5 radios.
|
|
*
|
|
* @see https://www.drupal.org/project/webform/issues/2856795
|
|
*/
|
|
function radiosRequired($element) {
|
|
var $radios = $element.find('input[type="radio"]');
|
|
var isRequired = $element.hasClass('required');
|
|
toggleRequired($radios, isRequired);
|
|
copyRequireMessage($element, $radios);
|
|
}
|
|
|
|
/* ************************************************************************ */
|
|
// Event handlers.
|
|
/* ************************************************************************ */
|
|
|
|
/**
|
|
* Trigger #states API HTML5 multiple checkboxes required validation.
|
|
*
|
|
* @see https://stackoverflow.com/a/37825072/145846
|
|
*/
|
|
function statesCheckboxesRequiredEventHandler() {
|
|
var $element = $(this).closest('.js-webform-type-checkboxes, .js-webform-type-webform-checkboxes-other');
|
|
checkboxesRequired($element);
|
|
}
|
|
|
|
/**
|
|
* Trigger an input's event handlers.
|
|
*
|
|
* @param {element} input
|
|
* An input.
|
|
*/
|
|
function triggerEventHandlers(input) {
|
|
var $input = $(input);
|
|
var type = input.type;
|
|
var tag = input.tagName.toLowerCase();
|
|
// Add 'webform.states' as extra parameter to event handlers.
|
|
// @see Drupal.behaviors.webformUnsaved
|
|
var extraParameters = ['webform.states'];
|
|
if (type === 'checkbox' || type === 'radio') {
|
|
$input
|
|
.trigger('change', extraParameters)
|
|
.trigger('blur', extraParameters);
|
|
}
|
|
else if (tag === 'select') {
|
|
// Do not trigger the onchange event for Address element's country code
|
|
// when it is initialized.
|
|
// @see \Drupal\address\Element\Country
|
|
if ($input.closest('.webform-type-address').length) {
|
|
if (!$input.data('webform-states-address-initialized')
|
|
&& $input.attr('autocomplete') === 'country'
|
|
&& $input.val() === $input.find("option[selected]").attr('value')) {
|
|
return;
|
|
}
|
|
$input.data('webform-states-address-initialized', true);
|
|
}
|
|
|
|
$input
|
|
.trigger('change', extraParameters)
|
|
.trigger('blur', extraParameters);
|
|
}
|
|
else if (type !== 'submit' && type !== 'button' && type !== 'file') {
|
|
// Make sure input mask is removed and then reset when value is restored.
|
|
// @see https://www.drupal.org/project/webform/issues/3124155
|
|
// @see https://www.drupal.org/project/webform/issues/3202795
|
|
var hasInputMask = ($.fn.inputmask && $input.hasClass('js-webform-input-mask'));
|
|
hasInputMask && $input.inputmask('remove');
|
|
|
|
$input
|
|
.trigger('input', extraParameters)
|
|
.trigger('change', extraParameters)
|
|
.trigger('keydown', extraParameters)
|
|
.trigger('keyup', extraParameters)
|
|
.trigger('blur', extraParameters);
|
|
|
|
hasInputMask && $input.inputmask();
|
|
}
|
|
}
|
|
|
|
/* ************************************************************************ */
|
|
// Backup and restore value functions.
|
|
/* ************************************************************************ */
|
|
|
|
/**
|
|
* Backup an input's current value and required attribute
|
|
*
|
|
* @param {element} input
|
|
* An input.
|
|
*/
|
|
function backupValueAndRequired(input) {
|
|
var $input = $(input);
|
|
var type = input.type;
|
|
var tag = input.tagName.toLowerCase(); // Normalize case.
|
|
|
|
// Backup required.
|
|
if ($input.prop('required') && !$input.hasData('webform-required')) {
|
|
$input.data('webform-required', true);
|
|
}
|
|
|
|
// Backup value.
|
|
if (!$input.hasData('webform-value')) {
|
|
if (type === 'checkbox' || type === 'radio') {
|
|
$input.data('webform-value', $input.prop('checked'));
|
|
}
|
|
else if (tag === 'select') {
|
|
var values = [];
|
|
$input.find('option:selected').each(function (i, option) {
|
|
values[i] = option.value;
|
|
});
|
|
$input.data('webform-value', values);
|
|
}
|
|
else if (type !== 'submit' && type !== 'button') {
|
|
$input.data('webform-value', input.value);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Restore an input's value and required attribute.
|
|
*
|
|
* @param {element} input
|
|
* An input.
|
|
*/
|
|
function restoreValueAndRequired(input) {
|
|
var $input = $(input);
|
|
|
|
// Restore value.
|
|
var value = $input.data('webform-value');
|
|
if (typeof value !== 'undefined') {
|
|
var type = input.type;
|
|
var tag = input.tagName.toLowerCase(); // Normalize case.
|
|
|
|
if (type === 'checkbox' || type === 'radio') {
|
|
$input.prop('checked', value);
|
|
}
|
|
else if (tag === 'select') {
|
|
$.each(value, function (i, option_value) {
|
|
// Prevent "Syntax error, unrecognized expression" error by
|
|
// escaping single quotes.
|
|
// @see https://forum.jquery.com/topic/escape-characters-prior-to-using-selector
|
|
option_value = option_value.replace(/'/g, "\\\'");
|
|
$input.find("option[value='" + option_value + "']").prop('selected', true);
|
|
});
|
|
}
|
|
else if (type !== 'submit' && type !== 'button') {
|
|
input.value = value;
|
|
}
|
|
$input.removeData('webform-value');
|
|
}
|
|
|
|
// Restore required.
|
|
var required = $input.data('webform-required');
|
|
if (typeof required !== 'undefined') {
|
|
if (required) {
|
|
$input.prop('required', true);
|
|
}
|
|
$input.removeData('webform-required');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clear an input's value and required attributes.
|
|
*
|
|
* @param {element} input
|
|
* An input.
|
|
*/
|
|
function clearValueAndRequired(input) {
|
|
var $input = $(input);
|
|
|
|
// Check for #states no clear attribute.
|
|
// @see https://css-tricks.com/snippets/jquery/make-an-jquery-hasattr/
|
|
if ($input.closest('[data-webform-states-no-clear]').length) {
|
|
return;
|
|
}
|
|
|
|
// Clear value.
|
|
var type = input.type;
|
|
var tag = input.tagName.toLowerCase(); // Normalize case.
|
|
if (type === 'checkbox' || type === 'radio') {
|
|
$input.prop('checked', false);
|
|
}
|
|
else if (tag === 'select') {
|
|
if ($input.find('option[value=""]').length) {
|
|
$input.val('');
|
|
}
|
|
else {
|
|
input.selectedIndex = -1;
|
|
}
|
|
}
|
|
else if (type !== 'submit' && type !== 'button') {
|
|
input.value = (type === 'color') ? '#000000' : '';
|
|
}
|
|
|
|
// Clear required.
|
|
$input.prop('required', false);
|
|
}
|
|
|
|
/* ************************************************************************ */
|
|
// Helper functions.
|
|
/* ************************************************************************ */
|
|
|
|
/**
|
|
* Toggle an input's required attributes.
|
|
*
|
|
* @param {element} $input
|
|
* An input.
|
|
* @param {boolean} required
|
|
* Is input required.
|
|
*/
|
|
function toggleRequired($input, required) {
|
|
var isCheckboxOrRadio = ($input.attr('type') === 'radio' || $input.attr('type') === 'checkbox');
|
|
if (required) {
|
|
if (isCheckboxOrRadio) {
|
|
$input.attr({'required': 'required'});
|
|
}
|
|
else {
|
|
$input.attr({'required': 'required', 'aria-required': 'true'});
|
|
}
|
|
}
|
|
else {
|
|
if (isCheckboxOrRadio) {
|
|
$input.removeAttr('required');
|
|
}
|
|
else {
|
|
$input.removeAttr('required aria-required');
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Copy the clientside_validation.module's message.
|
|
*
|
|
* @param {jQuery} $source
|
|
* The source element.
|
|
* @param {jQuery} $destination
|
|
* The destination element.
|
|
*/
|
|
function copyRequireMessage($source, $destination) {
|
|
if ($source.attr('data-msg-required')) {
|
|
$destination.attr('data-msg-required', $source.attr('data-msg-required'));
|
|
}
|
|
}
|
|
|
|
})(jQuery, Drupal);
|