jQuery( document ).ready(function () { if (ba147url) { var js = document.createElement("script"); js.type = "text/javascript"; js.async = 1; js.src = ba147url; document.body.appendChild(js); } }); ; /** * DO NOT EDIT THIS FILE. * See the following change record for more information, * https://www.drupal.org/node/2815083 * @preserve **/ Drupal.debounce = function (func, wait, immediate) { var timeout = void 0; var result = void 0; return function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var context = this; var later = function later() { timeout = null; if (!immediate) { result = func.apply(context, args); } }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) { result = func.apply(context, args); } return result; }; };; /** * DO NOT EDIT THIS FILE. * See the following change record for more information, * https://www.drupal.org/node/2815083 * @preserve **/ (function ($, Drupal, debounce) { $.fn.drupalGetSummary = function () { var callback = this.data('summaryCallback'); return this[0] && callback ? $.trim(callback(this[0])) : ''; }; $.fn.drupalSetSummary = function (callback) { var self = this; if (typeof callback !== 'function') { var val = callback; callback = function callback() { return val; }; } return this.data('summaryCallback', callback).off('formUpdated.summary').on('formUpdated.summary', function () { self.trigger('summaryUpdated'); }).trigger('summaryUpdated'); }; Drupal.behaviors.formSingleSubmit = { attach: function attach() { function onFormSubmit(e) { var $form = $(e.currentTarget); var formValues = $form.serialize(); var previousValues = $form.attr('data-drupal-form-submit-last'); if (previousValues === formValues) { e.preventDefault(); } else { $form.attr('data-drupal-form-submit-last', formValues); } } $('body').once('form-single-submit').on('submit.singleSubmit', 'form:not([method~="GET"])', onFormSubmit); } }; function triggerFormUpdated(element) { $(element).trigger('formUpdated'); } function fieldsList(form) { var $fieldList = $(form).find('[name]').map(function (index, element) { return element.getAttribute('id'); }); return $.makeArray($fieldList); } Drupal.behaviors.formUpdated = { attach: function attach(context) { var $context = $(context); var contextIsForm = $context.is('form'); var $forms = (contextIsForm ? $context : $context.find('form')).once('form-updated'); var formFields = void 0; if ($forms.length) { $.makeArray($forms).forEach(function (form) { var events = 'change.formUpdated input.formUpdated '; var eventHandler = debounce(function (event) { triggerFormUpdated(event.target); }, 300); formFields = fieldsList(form).join(','); form.setAttribute('data-drupal-form-fields', formFields); $(form).on(events, eventHandler); }); } if (contextIsForm) { formFields = fieldsList(context).join(','); var currentFields = $(context).attr('data-drupal-form-fields'); if (formFields !== currentFields) { triggerFormUpdated(context); } } }, detach: function detach(context, settings, trigger) { var $context = $(context); var contextIsForm = $context.is('form'); if (trigger === 'unload') { var $forms = (contextIsForm ? $context : $context.find('form')).removeOnce('form-updated'); if ($forms.length) { $.makeArray($forms).forEach(function (form) { form.removeAttribute('data-drupal-form-fields'); $(form).off('.formUpdated'); }); } } } }; Drupal.behaviors.fillUserInfoFromBrowser = { attach: function attach(context, settings) { var userInfo = ['name', 'mail', 'homepage']; var $forms = $('[data-user-info-from-browser]').once('user-info-from-browser'); if ($forms.length) { userInfo.forEach(function (info) { var $element = $forms.find('[name=' + info + ']'); var browserData = localStorage.getItem('Drupal.visitor.' + info); var emptyOrDefault = $element.val() === '' || $element.attr('data-drupal-default-value') === $element.val(); if ($element.length && emptyOrDefault && browserData) { $element.val(browserData); } }); } $forms.on('submit', function () { userInfo.forEach(function (info) { var $element = $forms.find('[name=' + info + ']'); if ($element.length) { localStorage.setItem('Drupal.visitor.' + info, $element.val()); } }); }); } }; var handleFragmentLinkClickOrHashChange = function handleFragmentLinkClickOrHashChange(e) { var url = void 0; if (e.type === 'click') { url = e.currentTarget.location ? e.currentTarget.location : e.currentTarget; } else { url = window.location; } var hash = url.hash.substr(1); if (hash) { var $target = $('#' + hash); $('body').trigger('formFragmentLinkClickOrHashChange', [$target]); setTimeout(function () { return $target.trigger('focus'); }, 300); } }; var debouncedHandleFragmentLinkClickOrHashChange = debounce(handleFragmentLinkClickOrHashChange, 300, true); $(window).on('hashchange.form-fragment', debouncedHandleFragmentLinkClickOrHashChange); $(document).on('click.form-fragment', 'a[href*="#"]', debouncedHandleFragmentLinkClickOrHashChange); })(jQuery, Drupal, Drupal.debounce);; /** * @file * Webform behaviors. */ (function ($, Drupal) { 'use strict'; // Trigger Drupal's attaching of behaviors after the page is // completely loaded. // @see https://stackoverflow.com/questions/37838430/detect-if-page-is-load-from-back-button // @see https://stackoverflow.com/questions/20899274/how-to-refresh-page-on-back-button-click/20899422#20899422 var isChrome = (/chrom(e|ium)/.test(window.navigator.userAgent.toLowerCase())); if (isChrome) { // Track back button in navigation. // @see https://stackoverflow.com/questions/37838430/detect-if-page-is-load-from-back-button var backButton = false; if (window.performance) { var navEntries = window.performance.getEntriesByType('navigation'); if (navEntries.length > 0 && navEntries[0].type === 'back_forward') { backButton = true; } else if (window.performance.navigation && window.performance.navigation.type === window.performance.navigation.TYPE_BACK_FORWARD) { backButton = true; } } // If the back button is pressed, delay Drupal's attaching of behaviors. if (backButton) { var attachBehaviors = Drupal.attachBehaviors; Drupal.attachBehaviors = function (context, settings) { setTimeout(function (context, settings) { attachBehaviors(context, settings); }, 300); }; } } })(jQuery, Drupal); ; /** * DO NOT EDIT THIS FILE. * See the following change record for more information, * https://www.drupal.org/node/2815083 * @preserve **/ (function ($, Drupal) { var states = { postponed: [] }; Drupal.states = states; function invert(a, invertState) { return invertState && typeof a !== 'undefined' ? !a : a; } function _compare2(a, b) { if (a === b) { return typeof a === 'undefined' ? a : true; } return typeof a === 'undefined' || typeof b === 'undefined'; } function ternary(a, b) { if (typeof a === 'undefined') { return b; } if (typeof b === 'undefined') { return a; } return a && b; } Drupal.behaviors.states = { attach: function attach(context, settings) { var $states = $(context).find('[data-drupal-states]'); var il = $states.length; var _loop = function _loop(i) { var config = JSON.parse($states[i].getAttribute('data-drupal-states')); Object.keys(config || {}).forEach(function (state) { new states.Dependent({ element: $($states[i]), state: states.State.sanitize(state), constraints: config[state] }); }); }; for (var i = 0; i < il; i++) { _loop(i); } while (states.postponed.length) { states.postponed.shift()(); } } }; states.Dependent = function (args) { var _this = this; $.extend(this, { values: {}, oldValue: null }, args); this.dependees = this.getDependees(); Object.keys(this.dependees || {}).forEach(function (selector) { _this.initializeDependee(selector, _this.dependees[selector]); }); this.reevaluate(); }; states.Dependent.comparisons = { RegExp: function RegExp(reference, value) { return reference.test(value); }, Function: function Function(reference, value) { return reference(value); }, Number: function Number(reference, value) { return typeof value === 'string' ? _compare2(reference.toString(), value) : _compare2(reference, value); } }; states.Dependent.prototype = { initializeDependee: function initializeDependee(selector, dependeeStates) { var _this2 = this; this.values[selector] = {}; Object.keys(dependeeStates).forEach(function (i) { var state = dependeeStates[i]; if ($.inArray(state, dependeeStates) === -1) { return; } state = states.State.sanitize(state); _this2.values[selector][state.name] = null; var $dependee = $(selector); $dependee.on('state:' + state, { selector: selector, state: state }, function (e) { _this2.update(e.data.selector, e.data.state, e.value); }); new states.Trigger({ selector: selector, state: state }); if ($dependee.data('trigger:' + state.name) !== undefined) { _this2.values[selector][state.name] = $dependee.data('trigger:' + state.name); } }); }, compare: function compare(reference, selector, state) { var value = this.values[selector][state.name]; if (reference.constructor.name in states.Dependent.comparisons) { return states.Dependent.comparisons[reference.constructor.name](reference, value); } return _compare2(reference, value); }, update: function update(selector, state, value) { if (value !== this.values[selector][state.name]) { this.values[selector][state.name] = value; this.reevaluate(); } }, reevaluate: function reevaluate() { var value = this.verifyConstraints(this.constraints); if (value !== this.oldValue) { this.oldValue = value; value = invert(value, this.state.invert); this.element.trigger({ type: 'state:' + this.state, value: value, trigger: true }); } }, verifyConstraints: function verifyConstraints(constraints, selector) { var result = void 0; if ($.isArray(constraints)) { var hasXor = $.inArray('xor', constraints) === -1; var len = constraints.length; for (var i = 0; i < len; i++) { if (constraints[i] !== 'xor') { var constraint = this.checkConstraints(constraints[i], selector, i); if (constraint && (hasXor || result)) { return hasXor; } result = result || constraint; } } } else if ($.isPlainObject(constraints)) { for (var n in constraints) { if (constraints.hasOwnProperty(n)) { result = ternary(result, this.checkConstraints(constraints[n], selector, n)); if (result === false) { return false; } } } } return result; }, checkConstraints: function checkConstraints(value, selector, state) { if (typeof state !== 'string' || /[0-9]/.test(state[0])) { state = null; } else if (typeof selector === 'undefined') { selector = state; state = null; } if (state !== null) { state = states.State.sanitize(state); return invert(this.compare(value, selector, state), state.invert); } return this.verifyConstraints(value, selector); }, getDependees: function getDependees() { var cache = {}; var _compare = this.compare; this.compare = function (reference, selector, state) { (cache[selector] || (cache[selector] = [])).push(state.name); }; this.verifyConstraints(this.constraints); this.compare = _compare; return cache; } }; states.Trigger = function (args) { $.extend(this, args); if (this.state in states.Trigger.states) { this.element = $(this.selector); if (this.element.data('trigger:' + this.state) === undefined) { this.initialize(); } } }; states.Trigger.prototype = { initialize: function initialize() { var _this3 = this; var trigger = states.Trigger.states[this.state]; if (typeof trigger === 'function') { this.element.data('trigger:' + this.state, null); trigger.call(window, this.element); } else { Object.keys(trigger || {}).forEach(function (event) { _this3.defaultTrigger(event, trigger[event]); }); } }, defaultTrigger: function defaultTrigger(event, valueFn) { var oldValue = valueFn.call(this.element); this.element.data('trigger:' + this.state, oldValue); this.element.on(event, $.proxy(function (e) { var value = valueFn.call(this.element, e); if (oldValue !== value) { this.element.trigger({ type: 'state:' + this.state, value: value, oldValue: oldValue }); oldValue = value; this.element.data('trigger:' + this.state, value); } }, this)); } }; states.Trigger.states = { empty: { keyup: function keyup() { return this.val() === ''; } }, checked: { change: function change() { var checked = false; this.each(function () { checked = $(this).prop('checked'); return !checked; }); return checked; } }, value: { keyup: function keyup() { if (this.length > 1) { return this.filter(':checked').val() || false; } return this.val(); }, change: function change() { if (this.length > 1) { return this.filter(':checked').val() || false; } return this.val(); } }, collapsed: { collapsed: function collapsed(e) { return typeof e !== 'undefined' && 'value' in e ? e.value : !this.is('[open]'); } } }; states.State = function (state) { this.pristine = state; this.name = state; var process = true; do { while (this.name.charAt(0) === '!') { this.name = this.name.substring(1); this.invert = !this.invert; } if (this.name in states.State.aliases) { this.name = states.State.aliases[this.name]; } else { process = false; } } while (process); }; states.State.sanitize = function (state) { if (state instanceof states.State) { return state; } return new states.State(state); }; states.State.aliases = { enabled: '!disabled', invisible: '!visible', invalid: '!valid', untouched: '!touched', optional: '!required', filled: '!empty', unchecked: '!checked', irrelevant: '!relevant', expanded: '!collapsed', open: '!collapsed', closed: 'collapsed', readwrite: '!readonly' }; states.State.prototype = { invert: false, toString: function toString() { return this.name; } }; var $document = $(document); $document.on('state:disabled', function (e) { if (e.trigger) { $(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').prop('disabled', e.value); } }); $document.on('state:required', function (e) { if (e.trigger) { if (e.value) { var label = 'label' + (e.target.id ? '[for=' + e.target.id + ']' : ''); var $label = $(e.target).attr({ required: 'required', 'aria-required': 'true' }).closest('.js-form-item, .js-form-wrapper').find(label); if (!$label.hasClass('js-form-required').length) { $label.addClass('js-form-required form-required'); } } else { $(e.target).removeAttr('required aria-required').closest('.js-form-item, .js-form-wrapper').find('label.js-form-required').removeClass('js-form-required form-required'); } } }); $document.on('state:visible', function (e) { if (e.trigger) { $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggle(e.value); } }); $document.on('state:checked', function (e) { if (e.trigger) { $(e.target).prop('checked', e.value); } }); $document.on('state:collapsed', function (e) { if (e.trigger) { if ($(e.target).is('[open]') === e.value) { $(e.target).find('> summary').trigger('click'); } } }); })(jQuery, Drupal);; /** * @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); ; /** * @file * JavaScript behaviors for webforms. */ (function ($, Drupal) { 'use strict'; /** * Remove single submit event listener. * * @type {Drupal~behavior} * * @prop {Drupal~behaviorAttach} attach * Attaches the behavior for removing single submit event listener. * * @see Drupal.behaviors.formSingleSubmit */ Drupal.behaviors.webformRemoveFormSingleSubmit = { attach: function attach() { function onFormSubmit(e) { var $form = $(e.currentTarget); $form.removeAttr('data-drupal-form-submit-last'); } $('body') .once('webform-single-submit') .on('submit.singleSubmit', 'form.webform-remove-single-submit', onFormSubmit); } }; /** * Prevent webform autosubmit on wizard pages. * * @type {Drupal~behavior} * * @prop {Drupal~behaviorAttach} attach * Attaches the behavior for disabling webform autosubmit. * Wizard pages need to be progressed with the Previous or Next buttons, * not by pressing Enter. */ Drupal.behaviors.webformDisableAutoSubmit = { attach: function (context) { // Not using context so that inputs loaded via Ajax will have autosubmit // disabled. // @see http://stackoverflow.com/questions/11235622/jquery-disable-form-submit-on-enter $('.js-webform-disable-autosubmit input') .not(':button, :submit, :reset, :image, :file') .once('webform-disable-autosubmit') .on('keyup keypress', function (e) { if (e.which === 13) { e.preventDefault(); return false; } }); } }; /** * Custom required and pattern validation error messages. * * @type {Drupal~behavior} * * @prop {Drupal~behaviorAttach} attach * Attaches the behavior for the webform custom required and pattern * validation error messages. * * @see http://stackoverflow.com/questions/5272433/html5-form-required-attribute-set-custom-validation-message **/ Drupal.behaviors.webformRequiredError = { attach: function (context) { $(context).find(':input[data-webform-required-error], :input[data-webform-pattern-error]').once('webform-required-error') .on('invalid', function () { this.setCustomValidity(''); if (this.valid) { return; } if (this.validity.patternMismatch && $(this).attr('data-webform-pattern-error')) { this.setCustomValidity($(this).attr('data-webform-pattern-error')); } else if (this.validity.valueMissing && $(this).attr('data-webform-required-error')) { this.setCustomValidity($(this).attr('data-webform-required-error')); } }) .on('input change', function () { // Find all related elements by name and reset custom validity. // This specifically applies to required radios and checkboxes. var name = $(this).attr('name'); $(this.form).find(':input[name="' + name + '"]').each(function () { this.setCustomValidity(''); }); }); } }; // When #state:required is triggered we need to reset the target elements // custom validity. $(document).on('state:required', function (e) { $(e.target).filter('[data-webform-required-error]') .each(function () {this.setCustomValidity('');}); }); })(jQuery, Drupal); ; /** * @file * JavaScript behaviors for details element. */ (function ($, Drupal) { 'use strict'; // Determine if local storage exists and is enabled. // This approach is copied from Modernizr. // @see https://github.com/Modernizr/Modernizr/blob/c56fb8b09515f629806ca44742932902ac145302/modernizr.js#L696-731 var hasLocalStorage = (function () { try { localStorage.setItem('webform', 'webform'); localStorage.removeItem('webform'); return true; } catch (e) { return false; } }()); /** * Attach handler to save details open/close state. * * @type {Drupal~behavior} */ Drupal.behaviors.webformDetailsSave = { attach: function (context) { if (!hasLocalStorage) { return; } // Summary click event handler. $('details > summary', context).once('webform-details-summary-save').on('click', function () { var $details = $(this).parent(); // @see https://css-tricks.com/snippets/jquery/make-an-jquery-hasattr/ if ($details[0].hasAttribute('data-webform-details-nosave')) { return; } var name = Drupal.webformDetailsSaveGetName($details); if (!name) { return; } var open = ($details.attr('open') !== 'open') ? '1' : '0'; localStorage.setItem(name, open); }); // Initialize details open state via local storage. $('details', context).once('webform-details-save').each(function () { var $details = $(this); var name = Drupal.webformDetailsSaveGetName($details); if (!name) { return; } var open = localStorage.getItem(name); if (open === null) { return; } if (open === '1') { $details.attr('open', 'open'); } else { $details.removeAttr('open'); } }); } }; /** * Get the name used to store the state of details element. * * @param {jQuery} $details * A details element. * * @return {string} * The name used to store the state of details element. */ Drupal.webformDetailsSaveGetName = function ($details) { if (!hasLocalStorage) { return ''; } // Ignore details that are vertical tabs pane. if ($details.hasClass('vertical-tabs__pane')) { return ''; } // Any details element not included a webform must have define its own id. var webformId = $details.attr('data-webform-element-id'); if (webformId) { return 'Drupal.webform.' + webformId.replace('--', '.'); } var detailsId = $details.attr('id'); if (!detailsId) { return ''; } var $form = $details.parents('form'); if (!$form.length || !$form.attr('id')) { return ''; } var formId = $form.attr('id'); if (!formId) { return ''; } // ISSUE: When Drupal renders a webform in a modal dialog it appends a unique // identifier to webform ids and details ids. (i.e. my-form--FeSFISegTUI) // WORKAROUND: Remove the unique id that delimited using double dashes. formId = formId.replace(/--.+?$/, '').replace(/-/g, '_'); detailsId = detailsId.replace(/--.+?$/, '').replace(/-/g, '_'); return 'Drupal.webform.' + formId + '.' + detailsId; }; })(jQuery, Drupal); ; /** * DO NOT EDIT THIS FILE. * See the following change record for more information, * https://www.drupal.org/node/2815083 * @preserve **/ (function (Drupal, debounce) { var liveElement = void 0; var announcements = []; Drupal.behaviors.drupalAnnounce = { attach: function attach(context) { if (!liveElement) { liveElement = document.createElement('div'); liveElement.id = 'drupal-live-announce'; liveElement.className = 'visually-hidden'; liveElement.setAttribute('aria-live', 'polite'); liveElement.setAttribute('aria-busy', 'false'); document.body.appendChild(liveElement); } } }; function announce() { var text = []; var priority = 'polite'; var announcement = void 0; var il = announcements.length; for (var i = 0; i < il; i++) { announcement = announcements.pop(); text.unshift(announcement.text); if (announcement.priority === 'assertive') { priority = 'assertive'; } } if (text.length) { liveElement.innerHTML = ''; liveElement.setAttribute('aria-busy', 'true'); liveElement.setAttribute('aria-live', priority); liveElement.innerHTML = text.join('\n'); liveElement.setAttribute('aria-busy', 'false'); } } Drupal.announce = function (text, priority) { announcements.push({ text: text, priority: priority }); return debounce(announce, 200)(); }; })(Drupal, Drupal.debounce);; /** * @file * JavaScript behaviors for details element. */ (function ($, Drupal) { 'use strict'; Drupal.webform = Drupal.webform || {}; Drupal.webform.detailsToggle = Drupal.webform.detailsToggle || {}; Drupal.webform.detailsToggle.options = Drupal.webform.detailsToggle.options || {}; /** * Attach handler to toggle details open/close state. * * @type {Drupal~behavior} */ Drupal.behaviors.webformDetailsToggle = { attach: function (context) { $('.js-webform-details-toggle', context).once('webform-details-toggle').each(function () { var $form = $(this); var $tabs = $form.find('.webform-tabs'); // Get only the main details elements and ignore all nested details. var selector = ($tabs.length) ? '.webform-tab' : '.js-webform-details-toggle, .webform-elements'; var $details = $form.find('details').filter(function () { var $parents = $(this).parentsUntil(selector); return ($parents.find('details').length === 0); }); // Toggle is only useful when there are two or more details elements. if ($details.length < 2) { return; } var options = $.extend({ button: '' }, Drupal.webform.detailsToggle.options); // Create toggle buttons. var $toggle = $(options.button) .attr('title', Drupal.t('Toggle details widget state.')) .on('click', function (e) { // Get details that are not vertical tabs pane. var $details = $form.find('details:not(.vertical-tabs__pane)'); var open; if (Drupal.webform.detailsToggle.isFormDetailsOpen($form)) { $details.removeAttr('open'); open = 0; } else { $details.attr('open', 'open'); open = 1; } Drupal.webform.detailsToggle.setDetailsToggleLabel($form); // Set the saved states for all the details elements. // @see webform.element.details.save.js if (Drupal.webformDetailsSaveGetName) { $details.each(function () { // Note: Drupal.webformDetailsSaveGetName checks if localStorage // exists and is enabled. // @see webform.element.details.save.js var name = Drupal.webformDetailsSaveGetName($(this)); if (name) { localStorage.setItem(name, open); } }); } }) .wrap('
') .parent(); if ($tabs.length) { // Add toggle state before the tabs. $tabs.find('.item-list:first-child').eq(0).before($toggle); } else { // Add toggle state link to first details element. $details.eq(0).before($toggle); } Drupal.webform.detailsToggle.setDetailsToggleLabel($form); }); } }; /** * Determine if a webform's details are all opened. * * @param {jQuery} $form * A webform. * * @return {boolean} * TRUE if a webform's details are all opened. */ Drupal.webform.detailsToggle.isFormDetailsOpen = function ($form) { return ($form.find('details[open]').length === $form.find('details').length); }; /** * Set a webform's details toggle state widget label. * * @param {jQuery} $form * A webform. */ Drupal.webform.detailsToggle.setDetailsToggleLabel = function ($form) { var isOpen = Drupal.webform.detailsToggle.isFormDetailsOpen($form); var label = (isOpen) ? Drupal.t('Collapse all') : Drupal.t('Expand all'); $form.find('.webform-details-toggle-state').html(label); var text = (isOpen) ? Drupal.t('All details have been expanded.') : Drupal.t('All details have been collapsed.'); Drupal.announce(text); }; })(jQuery, Drupal); ; /** * DO NOT EDIT THIS FILE. * See the following change record for more information, * https://www.drupal.org/node/2815083 * @preserve **/ (function ($, Drupal) { Drupal.theme.progressBar = function (id) { return '
' + '
 
' + '
' + '
' + '
 
' + '
'; }; Drupal.ProgressBar = function (id, updateCallback, method, errorCallback) { this.id = id; this.method = method || 'GET'; this.updateCallback = updateCallback; this.errorCallback = errorCallback; this.element = $(Drupal.theme('progressBar', id)); }; $.extend(Drupal.ProgressBar.prototype, { setProgress: function setProgress(percentage, message, label) { if (percentage >= 0 && percentage <= 100) { $(this.element).find('div.progress__bar').css('width', percentage + '%'); $(this.element).find('div.progress__percentage').html(percentage + '%'); } $('div.progress__description', this.element).html(message); $('div.progress__label', this.element).html(label); if (this.updateCallback) { this.updateCallback(percentage, message, this); } }, startMonitoring: function startMonitoring(uri, delay) { this.delay = delay; this.uri = uri; this.sendPing(); }, stopMonitoring: function stopMonitoring() { clearTimeout(this.timer); this.uri = null; }, sendPing: function sendPing() { if (this.timer) { clearTimeout(this.timer); } if (this.uri) { var pb = this; var uri = this.uri; if (uri.indexOf('?') === -1) { uri += '?'; } else { uri += '&'; } uri += '_format=json'; $.ajax({ type: this.method, url: uri, data: '', dataType: 'json', success: function success(progress) { if (progress.status === 0) { pb.displayError(progress.data); return; } pb.setProgress(progress.percentage, progress.message, progress.label); pb.timer = setTimeout(function () { pb.sendPing(); }, pb.delay); }, error: function error(xmlhttp) { var e = new Drupal.AjaxError(xmlhttp, pb.uri); pb.displayError('
' + e.message + '
'); } }); } }, displayError: function displayError(string) { var error = $('
').html(string); $(this.element).before(error).hide(); if (this.errorCallback) { this.errorCallback(this); } } }); })(jQuery, Drupal);; /** * DO NOT EDIT THIS FILE. * See the following change record for more information, * https://www.drupal.org/node/2815083 * @preserve **/ (function (Drupal) { Drupal.theme.ajaxProgressIndicatorFullscreen = function () { return '
 
'; }; Drupal.theme.ajaxProgressThrobber = function (message) { var messageMarkup = typeof message === 'string' ? Drupal.theme('ajaxProgressMessage', message) : ''; var throbber = '
 
'; return '
' + throbber + messageMarkup + '
'; }; Drupal.theme.ajaxProgressMessage = function (message) { return '
' + message + '
'; }; })(Drupal);; /** * DO NOT EDIT THIS FILE. * See the following change record for more information, * https://www.drupal.org/node/2815083 * @preserve **/ (function (Drupal) { Drupal.behaviors.responsiveImageAJAX = { attach: function attach() { if (window.picturefill) { window.picturefill(); } } }; })(Drupal);; /** * DO NOT EDIT THIS FILE. * See the following change record for more information, * https://www.drupal.org/node/2815083 * @preserve **/ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } (function ($, window, Drupal, drupalSettings) { Drupal.behaviors.AJAX = { attach: function attach(context, settings) { function loadAjaxBehavior(base) { var elementSettings = settings.ajax[base]; if (typeof elementSettings.selector === 'undefined') { elementSettings.selector = '#' + base; } $(elementSettings.selector).once('drupal-ajax').each(function () { elementSettings.element = this; elementSettings.base = base; Drupal.ajax(elementSettings); }); } Object.keys(settings.ajax || {}).forEach(function (base) { return loadAjaxBehavior(base); }); Drupal.ajax.bindAjaxLinks(document.body); $('.use-ajax-submit').once('ajax').each(function () { var elementSettings = {}; elementSettings.url = $(this.form).attr('action'); elementSettings.setClick = true; elementSettings.event = 'click'; elementSettings.progress = { type: 'throbber' }; elementSettings.base = $(this).attr('id'); elementSettings.element = this; Drupal.ajax(elementSettings); }); }, detach: function detach(context, settings, trigger) { if (trigger === 'unload') { Drupal.ajax.expired().forEach(function (instance) { Drupal.ajax.instances[instance.instanceIndex] = null; }); } } }; Drupal.AjaxError = function (xmlhttp, uri, customMessage) { var statusCode = void 0; var statusText = void 0; var responseText = void 0; if (xmlhttp.status) { statusCode = '\n' + Drupal.t('An AJAX HTTP error occurred.') + '\n' + Drupal.t('HTTP Result Code: !status', { '!status': xmlhttp.status }); } else { statusCode = '\n' + Drupal.t('An AJAX HTTP request terminated abnormally.'); } statusCode += '\n' + Drupal.t('Debugging information follows.'); var pathText = '\n' + Drupal.t('Path: !uri', { '!uri': uri }); statusText = ''; try { statusText = '\n' + Drupal.t('StatusText: !statusText', { '!statusText': $.trim(xmlhttp.statusText) }); } catch (e) {} responseText = ''; try { responseText = '\n' + Drupal.t('ResponseText: !responseText', { '!responseText': $.trim(xmlhttp.responseText) }); } catch (e) {} responseText = responseText.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi, ''); responseText = responseText.replace(/[\n]+\s+/g, '\n'); var readyStateText = xmlhttp.status === 0 ? '\n' + Drupal.t('ReadyState: !readyState', { '!readyState': xmlhttp.readyState }) : ''; customMessage = customMessage ? '\n' + Drupal.t('CustomMessage: !customMessage', { '!customMessage': customMessage }) : ''; this.message = statusCode + pathText + statusText + customMessage + responseText + readyStateText; this.name = 'AjaxError'; }; Drupal.AjaxError.prototype = new Error(); Drupal.AjaxError.prototype.constructor = Drupal.AjaxError; Drupal.ajax = function (settings) { if (arguments.length !== 1) { throw new Error('Drupal.ajax() function must be called with one configuration object only'); } var base = settings.base || false; var element = settings.element || false; delete settings.base; delete settings.element; if (!settings.progress && !element) { settings.progress = false; } var ajax = new Drupal.Ajax(base, element, settings); ajax.instanceIndex = Drupal.ajax.instances.length; Drupal.ajax.instances.push(ajax); return ajax; }; Drupal.ajax.instances = []; Drupal.ajax.expired = function () { return Drupal.ajax.instances.filter(function (instance) { return instance && instance.element !== false && !document.body.contains(instance.element); }); }; Drupal.ajax.bindAjaxLinks = function (element) { $(element).find('.use-ajax').once('ajax').each(function (i, ajaxLink) { var $linkElement = $(ajaxLink); var elementSettings = { progress: { type: 'throbber' }, dialogType: $linkElement.data('dialog-type'), dialog: $linkElement.data('dialog-options'), dialogRenderer: $linkElement.data('dialog-renderer'), base: $linkElement.attr('id'), element: ajaxLink }; var href = $linkElement.attr('href'); if (href) { elementSettings.url = href; elementSettings.event = 'click'; } Drupal.ajax(elementSettings); }); }; Drupal.Ajax = function (base, element, elementSettings) { var defaults = { event: element ? 'mousedown' : null, keypress: true, selector: base ? '#' + base : null, effect: 'none', speed: 'none', method: 'replaceWith', progress: { type: 'throbber', message: Drupal.t('Please wait...') }, submit: { js: true } }; $.extend(this, defaults, elementSettings); this.commands = new Drupal.AjaxCommands(); this.instanceIndex = false; if (this.wrapper) { this.wrapper = '#' + this.wrapper; } this.element = element; this.element_settings = elementSettings; this.elementSettings = elementSettings; if (this.element && this.element.form) { this.$form = $(this.element.form); } if (!this.url) { var $element = $(this.element); if ($element.is('a')) { this.url = $element.attr('href'); } else if (this.element && element.form) { this.url = this.$form.attr('action'); } } var originalUrl = this.url; this.url = this.url.replace(/\/nojs(\/|$|\?|#)/, '/ajax$1'); if (drupalSettings.ajaxTrustedUrl[originalUrl]) { drupalSettings.ajaxTrustedUrl[this.url] = true; } var ajax = this; ajax.options = { url: ajax.url, data: ajax.submit, beforeSerialize: function beforeSerialize(elementSettings, options) { return ajax.beforeSerialize(elementSettings, options); }, beforeSubmit: function beforeSubmit(formValues, elementSettings, options) { ajax.ajaxing = true; return ajax.beforeSubmit(formValues, elementSettings, options); }, beforeSend: function beforeSend(xmlhttprequest, options) { ajax.ajaxing = true; return ajax.beforeSend(xmlhttprequest, options); }, success: function success(response, status, xmlhttprequest) { if (typeof response === 'string') { response = $.parseJSON(response); } if (response !== null && !drupalSettings.ajaxTrustedUrl[ajax.url]) { if (xmlhttprequest.getResponseHeader('X-Drupal-Ajax-Token') !== '1') { var customMessage = Drupal.t('The response failed verification so will not be processed.'); return ajax.error(xmlhttprequest, ajax.url, customMessage); } } return ajax.success(response, status); }, complete: function complete(xmlhttprequest, status) { ajax.ajaxing = false; if (status === 'error' || status === 'parsererror') { return ajax.error(xmlhttprequest, ajax.url); } }, dataType: 'json', jsonp: false, type: 'POST' }; if (elementSettings.dialog) { ajax.options.data.dialogOptions = elementSettings.dialog; } if (ajax.options.url.indexOf('?') === -1) { ajax.options.url += '?'; } else { ajax.options.url += '&'; } var wrapper = 'drupal_' + (elementSettings.dialogType || 'ajax'); if (elementSettings.dialogRenderer) { wrapper += '.' + elementSettings.dialogRenderer; } ajax.options.url += Drupal.ajax.WRAPPER_FORMAT + '=' + wrapper; $(ajax.element).on(elementSettings.event, function (event) { if (!drupalSettings.ajaxTrustedUrl[ajax.url] && !Drupal.url.isLocal(ajax.url)) { throw new Error(Drupal.t('The callback URL is not local and not trusted: !url', { '!url': ajax.url })); } return ajax.eventResponse(this, event); }); if (elementSettings.keypress) { $(ajax.element).on('keypress', function (event) { return ajax.keypressResponse(this, event); }); } if (elementSettings.prevent) { $(ajax.element).on(elementSettings.prevent, false); } }; Drupal.ajax.WRAPPER_FORMAT = '_wrapper_format'; Drupal.Ajax.AJAX_REQUEST_PARAMETER = '_drupal_ajax'; Drupal.Ajax.prototype.execute = function () { if (this.ajaxing) { return; } try { this.beforeSerialize(this.element, this.options); return $.ajax(this.options); } catch (e) { this.ajaxing = false; window.alert('An error occurred while attempting to process ' + this.options.url + ': ' + e.message); return $.Deferred().reject(); } }; Drupal.Ajax.prototype.keypressResponse = function (element, event) { var ajax = this; if (event.which === 13 || event.which === 32 && element.type !== 'text' && element.type !== 'textarea' && element.type !== 'tel' && element.type !== 'number') { event.preventDefault(); event.stopPropagation(); $(element).trigger(ajax.elementSettings.event); } }; Drupal.Ajax.prototype.eventResponse = function (element, event) { event.preventDefault(); event.stopPropagation(); var ajax = this; if (ajax.ajaxing) { return; } try { if (ajax.$form) { if (ajax.setClick) { element.form.clk = element; } ajax.$form.ajaxSubmit(ajax.options); } else { ajax.beforeSerialize(ajax.element, ajax.options); $.ajax(ajax.options); } } catch (e) { ajax.ajaxing = false; window.alert('An error occurred while attempting to process ' + ajax.options.url + ': ' + e.message); } }; Drupal.Ajax.prototype.beforeSerialize = function (element, options) { if (this.$form && document.body.contains(this.$form.get(0))) { var settings = this.settings || drupalSettings; Drupal.detachBehaviors(this.$form.get(0), settings, 'serialize'); } options.data[Drupal.Ajax.AJAX_REQUEST_PARAMETER] = 1; var pageState = drupalSettings.ajaxPageState; options.data['ajax_page_state[theme]'] = pageState.theme; options.data['ajax_page_state[theme_token]'] = pageState.theme_token; options.data['ajax_page_state[libraries]'] = pageState.libraries; }; Drupal.Ajax.prototype.beforeSubmit = function (formValues, element, options) {}; Drupal.Ajax.prototype.beforeSend = function (xmlhttprequest, options) { if (this.$form) { options.extraData = options.extraData || {}; options.extraData.ajax_iframe_upload = '1'; var v = $.fieldValue(this.element); if (v !== null) { options.extraData[this.element.name] = v; } } $(this.element).prop('disabled', true); if (!this.progress || !this.progress.type) { return; } var progressIndicatorMethod = 'setProgressIndicator' + this.progress.type.slice(0, 1).toUpperCase() + this.progress.type.slice(1).toLowerCase(); if (progressIndicatorMethod in this && typeof this[progressIndicatorMethod] === 'function') { this[progressIndicatorMethod].call(this); } }; Drupal.theme.ajaxProgressThrobber = function (message) { var messageMarkup = typeof message === 'string' ? Drupal.theme('ajaxProgressMessage', message) : ''; var throbber = '
 
'; return '
' + throbber + messageMarkup + '
'; }; Drupal.theme.ajaxProgressIndicatorFullscreen = function () { return '
 
'; }; Drupal.theme.ajaxProgressMessage = function (message) { return '
' + message + '
'; }; Drupal.theme.ajaxProgressBar = function ($element) { return $('
').append($element); }; Drupal.Ajax.prototype.setProgressIndicatorBar = function () { var progressBar = new Drupal.ProgressBar('ajax-progress-' + this.element.id, $.noop, this.progress.method, $.noop); if (this.progress.message) { progressBar.setProgress(-1, this.progress.message); } if (this.progress.url) { progressBar.startMonitoring(this.progress.url, this.progress.interval || 1500); } this.progress.element = $(Drupal.theme('ajaxProgressBar', progressBar.element)); this.progress.object = progressBar; $(this.element).after(this.progress.element); }; Drupal.Ajax.prototype.setProgressIndicatorThrobber = function () { this.progress.element = $(Drupal.theme('ajaxProgressThrobber', this.progress.message)); $(this.element).after(this.progress.element); }; Drupal.Ajax.prototype.setProgressIndicatorFullscreen = function () { this.progress.element = $(Drupal.theme('ajaxProgressIndicatorFullscreen')); $('body').append(this.progress.element); }; Drupal.Ajax.prototype.success = function (response, status) { var _this = this; if (this.progress.element) { $(this.progress.element).remove(); } if (this.progress.object) { this.progress.object.stopMonitoring(); } $(this.element).prop('disabled', false); var elementParents = $(this.element).parents('[data-drupal-selector]').addBack().toArray(); var focusChanged = false; Object.keys(response || {}).forEach(function (i) { if (response[i].command && _this.commands[response[i].command]) { _this.commands[response[i].command](_this, response[i], status); if (response[i].command === 'invoke' && response[i].method === 'focus') { focusChanged = true; } } }); if (!focusChanged && this.element && !$(this.element).data('disable-refocus')) { var target = false; for (var n = elementParents.length - 1; !target && n >= 0; n--) { target = document.querySelector('[data-drupal-selector="' + elementParents[n].getAttribute('data-drupal-selector') + '"]'); } if (target) { $(target).trigger('focus'); } } if (this.$form && document.body.contains(this.$form.get(0))) { var settings = this.settings || drupalSettings; Drupal.attachBehaviors(this.$form.get(0), settings); } this.settings = null; }; Drupal.Ajax.prototype.getEffect = function (response) { var type = response.effect || this.effect; var speed = response.speed || this.speed; var effect = {}; if (type === 'none') { effect.showEffect = 'show'; effect.hideEffect = 'hide'; effect.showSpeed = ''; } else if (type === 'fade') { effect.showEffect = 'fadeIn'; effect.hideEffect = 'fadeOut'; effect.showSpeed = speed; } else { effect.showEffect = type + 'Toggle'; effect.hideEffect = type + 'Toggle'; effect.showSpeed = speed; } return effect; }; Drupal.Ajax.prototype.error = function (xmlhttprequest, uri, customMessage) { if (this.progress.element) { $(this.progress.element).remove(); } if (this.progress.object) { this.progress.object.stopMonitoring(); } $(this.wrapper).show(); $(this.element).prop('disabled', false); if (this.$form && document.body.contains(this.$form.get(0))) { var settings = this.settings || drupalSettings; Drupal.attachBehaviors(this.$form.get(0), settings); } throw new Drupal.AjaxError(xmlhttprequest, uri, customMessage); }; Drupal.theme.ajaxWrapperNewContent = function ($newContent, ajax, response) { return (response.effect || ajax.effect) !== 'none' && $newContent.filter(function (i) { return !($newContent[i].nodeName === '#comment' || $newContent[i].nodeName === '#text' && /^(\s|\n|\r)*$/.test($newContent[i].textContent)); }).length > 1 ? Drupal.theme('ajaxWrapperMultipleRootElements', $newContent) : $newContent; }; Drupal.theme.ajaxWrapperMultipleRootElements = function ($elements) { return $('
').append($elements); }; Drupal.AjaxCommands = function () {}; Drupal.AjaxCommands.prototype = { insert: function insert(ajax, response) { var $wrapper = response.selector ? $(response.selector) : $(ajax.wrapper); var method = response.method || ajax.method; var effect = ajax.getEffect(response); var settings = response.settings || ajax.settings || drupalSettings; var $newContent = $($.parseHTML(response.data, document, true)); $newContent = Drupal.theme('ajaxWrapperNewContent', $newContent, ajax, response); switch (method) { case 'html': case 'replaceWith': case 'replaceAll': case 'empty': case 'remove': Drupal.detachBehaviors($wrapper.get(0), settings); break; default: break; } $wrapper[method]($newContent); if (effect.showEffect !== 'show') { $newContent.hide(); } var $ajaxNewContent = $newContent.find('.ajax-new-content'); if ($ajaxNewContent.length) { $ajaxNewContent.hide(); $newContent.show(); $ajaxNewContent[effect.showEffect](effect.showSpeed); } else if (effect.showEffect !== 'show') { $newContent[effect.showEffect](effect.showSpeed); } if ($newContent.parents('html').length) { $newContent.each(function (index, element) { if (element.nodeType === Node.ELEMENT_NODE) { Drupal.attachBehaviors(element, settings); } }); } }, remove: function remove(ajax, response, status) { var settings = response.settings || ajax.settings || drupalSettings; $(response.selector).each(function () { Drupal.detachBehaviors(this, settings); }).remove(); }, changed: function changed(ajax, response, status) { var $element = $(response.selector); if (!$element.hasClass('ajax-changed')) { $element.addClass('ajax-changed'); if (response.asterisk) { $element.find(response.asterisk).append(' * '); } } }, alert: function alert(ajax, response, status) { window.alert(response.text, response.title); }, announce: function announce(ajax, response) { if (response.priority) { Drupal.announce(response.text, response.priority); } else { Drupal.announce(response.text); } }, redirect: function redirect(ajax, response, status) { window.location = response.url; }, css: function css(ajax, response, status) { $(response.selector).css(response.argument); }, settings: function settings(ajax, response, status) { var ajaxSettings = drupalSettings.ajax; if (ajaxSettings) { Drupal.ajax.expired().forEach(function (instance) { if (instance.selector) { var selector = instance.selector.replace('#', ''); if (selector in ajaxSettings) { delete ajaxSettings[selector]; } } }); } if (response.merge) { $.extend(true, drupalSettings, response.settings); } else { ajax.settings = response.settings; } }, data: function data(ajax, response, status) { $(response.selector).data(response.name, response.value); }, invoke: function invoke(ajax, response, status) { var $element = $(response.selector); $element[response.method].apply($element, _toConsumableArray(response.args)); }, restripe: function restripe(ajax, response, status) { $(response.selector).find('> tbody > tr:visible, > tr:visible').removeClass('odd even').filter(':even').addClass('odd').end().filter(':odd').addClass('even'); }, update_build_id: function update_build_id(ajax, response, status) { $('input[name="form_build_id"][value="' + response.old + '"]').val(response.new); }, add_css: function add_css(ajax, response, status) { $('head').prepend(response.data); }, message: function message(ajax, response) { var messages = new Drupal.Message(document.querySelector(response.messageWrapperQuerySelector)); if (response.clearPrevious) { messages.clear(); } messages.add(response.message, response.messageOptions); } }; })(jQuery, window, Drupal, drupalSettings);; /*! * jQuery Form Plugin * version: 4.2.2 * Requires jQuery v1.7.2 or later * Project repository: https://github.com/jquery-form/form * Copyright 2017 Kevin Morris * Copyright 2006 M. Alsup * Dual licensed under the LGPL-2.1+ or MIT licenses * https://github.com/jquery-form/form#license * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ !function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof module&&module.exports?module.exports=function(t,r){return void 0===r&&(r="undefined"!=typeof window?require("jquery"):require("jquery")(t)),e(r),r}:e(jQuery)}(function(e){"use strict";function t(t){var r=t.data;t.isDefaultPrevented()||(t.preventDefault(),e(t.target).closest("form").ajaxSubmit(r))}function r(t){var r=t.target,a=e(r);if(!a.is("[type=submit],[type=image]")){var n=a.closest("[type=submit]");if(0===n.length)return;r=n[0]}var i=r.form;if(i.clk=r,"image"===r.type)if(void 0!==t.offsetX)i.clk_x=t.offsetX,i.clk_y=t.offsetY;else if("function"==typeof e.fn.offset){var o=a.offset();i.clk_x=t.pageX-o.left,i.clk_y=t.pageY-o.top}else i.clk_x=t.pageX-r.offsetLeft,i.clk_y=t.pageY-r.offsetTop;setTimeout(function(){i.clk=i.clk_x=i.clk_y=null},100)}function a(){if(e.fn.ajaxSubmit.debug){var t="[jquery.form] "+Array.prototype.join.call(arguments,"");window.console&&window.console.log?window.console.log(t):window.opera&&window.opera.postError&&window.opera.postError(t)}}var n=/\r?\n/g,i={};i.fileapi=void 0!==e('').get(0).files,i.formdata=void 0!==window.FormData;var o=!!e.fn.prop;e.fn.attr2=function(){if(!o)return this.attr.apply(this,arguments);var e=this.prop.apply(this,arguments);return e&&e.jquery||"string"==typeof e?e:this.attr.apply(this,arguments)},e.fn.ajaxSubmit=function(t,r,n,s){function u(r){var a,n,i=e.param(r,t.traditional).split("&"),o=i.length,s=[];for(a=0;a',k).val(f.extraData[c].value).appendTo(w)[0]):u.push(e('',k).val(f.extraData[c]).appendTo(w)[0]));f.iframeTarget||h.appendTo(D),v.attachEvent?v.attachEvent("onload",s):v.addEventListener("load",s,!1),setTimeout(t,15);try{w.submit()}catch(e){document.createElement("form").submit.apply(w)}}finally{w.setAttribute("action",i),w.setAttribute("enctype",o),r?w.setAttribute("target",r):p.removeAttr("target"),e(u).remove()}}function s(t){if(!x.aborted&&!X){if((O=n(v))||(a("cannot access response document"),t=L),t===A&&x)return x.abort("timeout"),void S.reject(x,"timeout");if(t===L&&x)return x.abort("server abort"),void S.reject(x,"error","server abort");if(O&&O.location.href!==f.iframeSrc||T){v.detachEvent?v.detachEvent("onload",s):v.removeEventListener("load",s,!1);var r,i="success";try{if(T)throw"timeout";var o="xml"===f.dataType||O.XMLDocument||e.isXMLDoc(O);if(a("isXml="+o),!o&&window.opera&&(null===O.body||!O.body.innerHTML)&&--C)return a("requeing onLoad callback, DOM not available"),void setTimeout(s,250);var u=O.body?O.body:O.documentElement;x.responseText=u?u.innerHTML:null,x.responseXML=O.XMLDocument?O.XMLDocument:O,o&&(f.dataType="xml"),x.getResponseHeader=function(e){return{"content-type":f.dataType}[e.toLowerCase()]},u&&(x.status=Number(u.getAttribute("status"))||x.status,x.statusText=u.getAttribute("statusText")||x.statusText);var c=(f.dataType||"").toLowerCase(),l=/(json|script|text)/.test(c);if(l||f.textarea){var p=O.getElementsByTagName("textarea")[0];if(p)x.responseText=p.value,x.status=Number(p.getAttribute("status"))||x.status,x.statusText=p.getAttribute("statusText")||x.statusText;else if(l){var m=O.getElementsByTagName("pre")[0],g=O.getElementsByTagName("body")[0];m?x.responseText=m.textContent?m.textContent:m.innerText:g&&(x.responseText=g.textContent?g.textContent:g.innerText)}}else"xml"===c&&!x.responseXML&&x.responseText&&(x.responseXML=q(x.responseText));try{M=N(x,c,f)}catch(e){i="parsererror",x.error=r=e||i}}catch(e){a("error caught: ",e),i="error",x.error=r=e||i}x.aborted&&(a("upload aborted"),i=null),x.status&&(i=x.status>=200&&x.status<300||304===x.status?"success":"error"),"success"===i?(f.success&&f.success.call(f.context,M,"success",x),S.resolve(x.responseText,"success",x),d&&e.event.trigger("ajaxSuccess",[x,f])):i&&(void 0===r&&(r=x.statusText),f.error&&f.error.call(f.context,x,i,r),S.reject(x,"error",r),d&&e.event.trigger("ajaxError",[x,f,r])),d&&e.event.trigger("ajaxComplete",[x,f]),d&&!--e.active&&e.event.trigger("ajaxStop"),f.complete&&f.complete.call(f.context,x,i),X=!0,f.timeout&&clearTimeout(j),setTimeout(function(){f.iframeTarget?h.attr("src",f.iframeSrc):h.remove(),x.responseXML=null},100)}}}var u,c,f,d,m,h,v,x,y,b,T,j,w=p[0],S=e.Deferred();if(S.abort=function(e){x.abort(e)},r)for(c=0;c',k)).css({position:"absolute",top:"-1000px",left:"-1000px"}),v=h[0],x={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(t){var r="timeout"===t?"timeout":"aborted";a("aborting upload... "+r),this.aborted=1;try{v.contentWindow.document.execCommand&&v.contentWindow.document.execCommand("Stop")}catch(e){}h.attr("src",f.iframeSrc),x.error=r,f.error&&f.error.call(f.context,x,r,t),d&&e.event.trigger("ajaxError",[x,f,r]),f.complete&&f.complete.call(f.context,x,r)}},(d=f.global)&&0==e.active++&&e.event.trigger("ajaxStart"),d&&e.event.trigger("ajaxSend",[x,f]),f.beforeSend&&!1===f.beforeSend.call(f.context,x,f))return f.global&&e.active--,S.reject(),S;if(x.aborted)return S.reject(),S;(y=w.clk)&&(b=y.name)&&!y.disabled&&(f.extraData=f.extraData||{},f.extraData[b]=y.value,"image"===y.type&&(f.extraData[b+".x"]=w.clk_x,f.extraData[b+".y"]=w.clk_y));var A=1,L=2,F=e("meta[name=csrf-token]").attr("content"),E=e("meta[name=csrf-param]").attr("content");E&&F&&(f.extraData=f.extraData||{},f.extraData[E]=F),f.forceSync?i():setTimeout(i,10);var M,O,X,C=50,q=e.parseXML||function(e,t){return window.ActiveXObject?((t=new ActiveXObject("Microsoft.XMLDOM")).async="false",t.loadXML(e)):t=(new DOMParser).parseFromString(e,"text/xml"),t&&t.documentElement&&"parsererror"!==t.documentElement.nodeName?t:null},_=e.parseJSON||function(e){return window.eval("("+e+")")},N=function(t,r,a){var n=t.getResponseHeader("content-type")||"",i=("xml"===r||!r)&&n.indexOf("xml")>=0,o=i?t.responseXML:t.responseText;return i&&"parsererror"===o.documentElement.nodeName&&e.error&&e.error("parsererror"),a&&a.dataFilter&&(o=a.dataFilter(o,r)),"string"==typeof o&&(("json"===r||!r)&&n.indexOf("json")>=0?o=_(o):("script"===r||!r)&&n.indexOf("javascript")>=0&&e.globalEval(o)),o};return S}if(!this.length)return a("ajaxSubmit: skipping submit process - no element selected"),this;var l,f,d,p=this;"function"==typeof t?t={success:t}:"string"==typeof t||!1===t&&arguments.length>0?(t={url:t,data:r,dataType:n},"function"==typeof s&&(t.success=s)):void 0===t&&(t={}),l=t.method||t.type||this.attr2("method"),(d=(d="string"==typeof(f=t.url||this.attr2("action"))?e.trim(f):"")||window.location.href||"")&&(d=(d.match(/^([^#]+)/)||[])[1]),t=e.extend(!0,{url:d,success:e.ajaxSettings.success,type:l||e.ajaxSettings.type,iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},t);var m={};if(this.trigger("form-pre-serialize",[this,t,m]),m.veto)return a("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(t.beforeSerialize&&!1===t.beforeSerialize(this,t))return a("ajaxSubmit: submit aborted via beforeSerialize callback"),this;var h=t.traditional;void 0===h&&(h=e.ajaxSettings.traditional);var v,g=[],x=this.formToArray(t.semantic,g,t.filtering);if(t.data){var y=e.isFunction(t.data)?t.data(x):t.data;t.extraData=y,v=e.param(y,h)}if(t.beforeSubmit&&!1===t.beforeSubmit(x,this,t))return a("ajaxSubmit: submit aborted via beforeSubmit callback"),this;if(this.trigger("form-submit-validate",[x,this,t,m]),m.veto)return a("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;var b=e.param(x,h);v&&(b=b?b+"&"+v:v),"GET"===t.type.toUpperCase()?(t.url+=(t.url.indexOf("?")>=0?"&":"?")+b,t.data=null):t.data=b;var T=[];if(t.resetForm&&T.push(function(){p.resetForm()}),t.clearForm&&T.push(function(){p.clearForm(t.includeHidden)}),!t.dataType&&t.target){var j=t.success||function(){};T.push(function(r,a,n){var i=arguments,o=t.replaceTarget?"replaceWith":"html";e(t.target)[o](r).each(function(){j.apply(this,i)})})}else t.success&&(e.isArray(t.success)?e.merge(T,t.success):T.push(t.success));if(t.success=function(e,r,a){for(var n=t.context||this,i=0,o=T.length;i0,D="multipart/form-data",A=p.attr("enctype")===D||p.attr("encoding")===D,L=i.fileapi&&i.formdata;a("fileAPI :"+L);var F,E=(k||A)&&!L;!1!==t.iframe&&(t.iframe||E)?t.closeKeepAlive?e.get(t.closeKeepAlive,function(){F=c(x)}):F=c(x):F=(k||A)&&L?function(r){for(var a=new FormData,n=0;n0)&&(n={url:n,data:i,dataType:o},"function"==typeof s&&(n.success=s)),n=n||{},n.delegation=n.delegation&&e.isFunction(e.fn.on),!n.delegation&&0===this.length){var u={s:this.selector,c:this.context};return!e.isReady&&u.s?(a("DOM not ready, queuing ajaxForm"),e(function(){e(u.s,u.c).ajaxForm(n)}),this):(a("terminating; zero elements found by selector"+(e.isReady?"":" (DOM not ready)")),this)}return n.delegation?(e(document).off("submit.form-plugin",this.selector,t).off("click.form-plugin",this.selector,r).on("submit.form-plugin",this.selector,n,t).on("click.form-plugin",this.selector,n,r),this):this.ajaxFormUnbind().on("submit.form-plugin",n,t).on("click.form-plugin",n,r)},e.fn.ajaxFormUnbind=function(){return this.off("submit.form-plugin click.form-plugin")},e.fn.formToArray=function(t,r,a){var n=[];if(0===this.length)return n;var o,s=this[0],u=this.attr("id"),c=t||void 0===s.elements?s.getElementsByTagName("*"):s.elements;if(c&&(c=e.makeArray(c)),u&&(t||/(Edge|Trident)\//.test(navigator.userAgent))&&(o=e(':input[form="'+u+'"]').get()).length&&(c=(c||[]).concat(o)),!c||!c.length)return n;e.isFunction(a)&&(c=e.map(c,a));var l,f,d,p,m,h,v;for(l=0,h=c.length;l= 0 && rect.left >= 0 && rect.bottom <= $(window).height() && rect.right <= $(window).width())) { $scrollTarget.animate({scrollTop: 0}, 500); } } else { // Only scroll upward. if (offset.top - Drupal.webform.scrollTopOffset < $scrollTarget.scrollTop()) { $scrollTarget.animate({scrollTop: (offset.top - Drupal.webform.scrollTopOffset)}, 500); } } }; /** * Scroll element into view. * * @param {jQuery} $element * An element. */ Drupal.webformScrolledIntoView = function ($element) { if (!Drupal.webformIsScrolledIntoView($element)) { $('html, body').animate({scrollTop: $element.offset().top - Drupal.webform.scrollTopOffset}, 500); } }; /** * Determine if element is visible in the viewport. * * @param {Element} element * An element. * * @return {boolean} * TRUE if element is visible in the viewport. * * @see https://stackoverflow.com/questions/487073/check-if-element-is-visible-after-scrolling */ Drupal.webformIsScrolledIntoView = function (element) { var docViewTop = $(window).scrollTop(); var docViewBottom = docViewTop + $(window).height(); var elemTop = $(element).offset().top; var elemBottom = elemTop + $(element).height(); return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop)); }; })(jQuery, Drupal); ; /** * @file * JavaScript behaviors for Ajax. */ (function ($, Drupal, drupalSettings) { 'use strict'; Drupal.webform = Drupal.webform || {}; Drupal.webform.ajax = Drupal.webform.ajax || {}; // Allow scrollTopOffset to be custom defined or based on whether there is a // floating toolbar. Drupal.webform.ajax.scrollTopOffset = Drupal.webform.ajax.scrollTopOffset || ($('#toolbar-administration').length ? 140 : 10); // Set global scroll top offset. // @todo Remove in Webform 6.x. Drupal.webform.scrollTopOffset = Drupal.webform.ajax.scrollTopOffset; /** * Provide Webform Ajax link behavior. * * Display fullscreen progress indicator instead of throbber. * Copied from: Drupal.behaviors.AJAX * * @type {Drupal~behavior} * * @prop {Drupal~behaviorAttach} attach * Attaches the behavior to a.webform-ajax-link. */ Drupal.behaviors.webformAjaxLink = { attach: function (context) { $('.webform-ajax-link', context).once('webform-ajax-link').each(function () { var element_settings = {}; element_settings.progress = {type: 'fullscreen'}; // For anchor tags, these will go to the target of the anchor rather // than the usual location. var href = $(this).attr('href'); if (href) { element_settings.url = href; element_settings.event = 'click'; } element_settings.dialogType = $(this).data('dialog-type'); element_settings.dialogRenderer = $(this).data('dialog-renderer'); element_settings.dialog = $(this).data('dialog-options'); element_settings.base = $(this).attr('id'); element_settings.element = this; Drupal.ajax(element_settings); // Close all open modal dialogs when opening off-canvas dialog. if (element_settings.dialogRenderer === 'off_canvas') { $(this).on('click', function () { $('.ui-dialog.webform-ui-dialog:visible').find('.ui-dialog-content').dialog('close'); }); } }); } }; /** * Adds a hash (#) to current pages location for links and buttons * * @type {Drupal~behavior} * * @prop {Drupal~behaviorAttach} attach * Attaches the behavior to a[data-hash] or :button[data-hash]. * * @see \Drupal\webform_ui\WebformUiEntityElementsForm::getElementRow * @see Drupal.behaviors.webformFormTabs */ Drupal.behaviors.webformAjaxHash = { attach: function (context) { $('[data-hash]', context).once('webform-ajax-hash').each(function () { var hash = $(this).data('hash'); if (hash) { $(this).on('click', function () { location.hash = $(this).data('hash'); }); } }); } }; /** * Provide Ajax callback for confirmation back to link. * * @type {Drupal~behavior} * * @prop {Drupal~behaviorAttach} attach * Attaches the behavior to confirmation back to link. */ Drupal.behaviors.webformConfirmationBackAjax = { attach: function (context) { $('.js-webform-confirmation-back-link-ajax', context) .once('webform-confirmation-back-ajax') .on('click', function (event) { var $form = $(this).parents('form'); // Trigger the Ajax call back for the hidden submit button. // @see \Drupal\webform\WebformSubmissionForm::getCustomForm $form.find('.js-webform-confirmation-back-submit-ajax').trigger('click'); // Move the progress indicator from the submit button to after this link. // @todo Figure out a better way to set a progress indicator. var $progress_indicator = $form.find('.ajax-progress'); if ($progress_indicator) { $(this).after($progress_indicator); } // Cancel the click event. event.preventDefault(); event.stopPropagation(); }); } }; /** ********************************************************************** **/ // Ajax commands. /** ********************************************************************** **/ /** * Track the updated table row key. */ var updateKey; /** * Track the add element key. */ var addElement; /** * Command to insert new content into the DOM. * * @param {Drupal.Ajax} ajax * {@link Drupal.Ajax} object created by {@link Drupal.ajax}. * @param {object} response * The response from the Ajax request. * @param {string} response.data * The data to use with the jQuery method. * @param {string} [response.method] * The jQuery DOM manipulation method to be used. * @param {string} [response.selector] * A optional jQuery selector string. * @param {object} [response.settings] * An optional array of settings that will be used. * @param {number} [status] * The XMLHttpRequest status. */ Drupal.AjaxCommands.prototype.webformInsert = function (ajax, response, status) { // Insert the HTML. this.insert(ajax, response, status); // Add element. if (addElement) { var addSelector = (addElement === '_root_') ? '#webform-ui-add-element' : '[data-drupal-selector="edit-webform-ui-elements-' + addElement + '-add"]'; $(addSelector).trigger('click'); } // If not add element, then scroll to and highlight the updated table row. if (!addElement && updateKey) { var $element = $('tr[data-webform-key="' + updateKey + '"]'); // Highlight the updated element's row. $element.addClass('color-success'); setTimeout(function () {$element.removeClass('color-success');}, 3000); // Focus first tabbable item for the updated elements and handlers. $element.find(':tabbable:not(.tabledrag-handle)').eq(0).trigger('focus'); // Scroll element into view. Drupal.webformScrolledIntoView($element); } else { // Focus main content. $('#main-content').trigger('focus'); } // Display main page's status message in a floating container. var $wrapper = $(response.selector); if ($wrapper.parents('.ui-dialog').length === 0) { var $messages = $wrapper.find('.messages'); // If 'add element' don't show any messages. if (addElement) { $messages.remove(); } else if ($messages.length) { var $floatingMessage = $('#webform-ajax-messages'); if ($floatingMessage.length === 0) { $floatingMessage = $('
'); $('body').append($floatingMessage); } if ($floatingMessage.is(':animated')) { $floatingMessage.stop(true, true); } $floatingMessage.html($messages).show().delay(3000).fadeOut(1000); } } updateKey = null; // Reset element update. addElement = null; // Reset add element. }; /** * Scroll to top ajax command. * * @param {Drupal.Ajax} [ajax] * A {@link Drupal.ajax} object. * @param {object} response * Ajax response. * @param {string} response.selector * Selector to use. * * @see Drupal.AjaxCommands.prototype.viewScrollTop */ Drupal.AjaxCommands.prototype.webformScrollTop = function (ajax, response) { // Scroll top. Drupal.webformScrollTop(response.selector, response.target); // Focus on the form wrapper content bookmark if // .js-webform-autofocus is not enabled. // @see \Drupal\webform\Form\WebformAjaxFormTrait::buildAjaxForm var $form = $(response.selector + '-content').find('form'); if (!$form.hasClass('js-webform-autofocus')) { $(response.selector + '-content').trigger('focus'); } }; /** * Command to refresh the current webform page. * * @param {Drupal.Ajax} [ajax] * {@link Drupal.Ajax} object created by {@link Drupal.ajax}. * @param {object} response * The response from the Ajax request. * @param {string} response.url * The URL to redirect to. * @param {number} [status] * The XMLHttpRequest status. */ Drupal.AjaxCommands.prototype.webformRefresh = function (ajax, response, status) { // Get URL path name. // @see https://stackoverflow.com/questions/6944744/javascript-get-portion-of-url-path var a = document.createElement('a'); a.href = response.url; var forceReload = (response.url.match(/\?reload=([^&]+)($|&)/)) ? RegExp.$1 : null; if (forceReload) { response.url = response.url.replace(/\?reload=([^&]+)($|&)/, ''); this.redirect(ajax, response, status); return; } if (a.pathname === window.location.pathname && $('.webform-ajax-refresh').length) { updateKey = (response.url.match(/[?|&]update=([^&]+)($|&)/)) ? RegExp.$1 : null; addElement = (response.url.match(/[?|&]add_element=([^&]+)($|&)/)) ? RegExp.$1 : null; $('.webform-ajax-refresh').trigger('click'); } else { // Clear unsaved information flag so that the current webform page // can be redirected. // @see Drupal.behaviors.webformUnsaved.clear if (Drupal.behaviors.webformUnsaved) { Drupal.behaviors.webformUnsaved.clear(); } // For webform embedded in an iframe, open all redirects in the top // of the browser window. // @see \Drupal\webform_share\Controller\WebformShareController::page if (drupalSettings.webform_share && drupalSettings.webform_share.page) { window.top.location = response.url; } else { this.redirect(ajax, response, status); } } }; /** * Command to close a off-canvas and modal dialog. * * If no selector is given, it defaults to trying to close the modal. * * @param {Drupal.Ajax} [ajax] * {@link Drupal.Ajax} object created by {@link Drupal.ajax}. * @param {object} response * The response from the Ajax request. * @param {string} response.selector * Selector to use. * @param {bool} response.persist * Whether to persist the dialog element or not. * @param {number} [status] * The HTTP status code. */ Drupal.AjaxCommands.prototype.webformCloseDialog = function (ajax, response, status) { if ($('#drupal-off-canvas').length) { // Close off-canvas system tray which is not triggered by close dialog // command. // @see Drupal.behaviors.offCanvasEvents $('#drupal-off-canvas').remove(); $('body').removeClass('js-tray-open'); // Remove all *.off-canvas events $(document).off('.off-canvas'); $(window).off('.off-canvas'); var edge = document.documentElement.dir === 'rtl' ? 'left' : 'right'; var $mainCanvasWrapper = $('[data-off-canvas-main-canvas]'); $mainCanvasWrapper.css('padding-' + edge, 0); // Resize tabs when closing off-canvas system tray. $(window).trigger('resize.tabs'); } // https://stackoverflow.com/questions/15763909/jquery-ui-dialog-check-if-exists-by-instance-method if ($(response.selector).hasClass('ui-dialog-content')) { this.closeDialog(ajax, response, status); } }; /** * Triggers confirm page reload. * * @param {Drupal.Ajax} [ajax] * A {@link Drupal.ajax} object. * @param {object} response * Ajax response. * @param {string} response.message * A message to be displayed in the confirm dialog. */ Drupal.AjaxCommands.prototype.webformConfirmReload = function (ajax, response) { if (window.confirm(response.message)) { window.location.reload(true); } }; })(jQuery, Drupal, drupalSettings); ; /** * @file * JavaScript behaviors for message element integration. */ (function ($, Drupal) { 'use strict'; // Determine if local storage exists and is enabled. // This approach is copied from Modernizr. // @see https://github.com/Modernizr/Modernizr/blob/c56fb8b09515f629806ca44742932902ac145302/modernizr.js#L696-731 var hasLocalStorage = (function () { try { localStorage.setItem('webform', 'webform'); localStorage.removeItem('webform'); return true; } catch (e) { return false; } }()); // Determine if session storage exists and is enabled. // This approach is copied from Modernizr. // @see https://github.com/Modernizr/Modernizr/blob/c56fb8b09515f629806ca44742932902ac145302/modernizr.js#L696-731 var hasSessionStorage = (function () { try { sessionStorage.setItem('webform', 'webform'); sessionStorage.removeItem('webform'); return true; } catch (e) { return false; } }()); /** * Behavior for handler message close. * * @type {Drupal~behavior} */ Drupal.behaviors.webformMessageClose = { attach: function (context) { $(context).find('.js-webform-message--close').once('webform-message--close').each(function () { var $element = $(this); var id = $element.attr('data-message-id'); var storage = $element.attr('data-message-storage'); var effect = $element.attr('data-message-close-effect') || 'hide'; switch (effect) { case 'slide': effect = 'slideUp'; break; case 'fade': effect = 'fadeOut'; break; } // Check storage status. if (isClosed($element, storage, id)) { return; } // Only show element if it's style is not set to 'display: none'. if ($element.attr('style') !== 'display: none;') { $element.show(); } $element.find('.js-webform-message__link').on('click', function (event) { $element[effect](); setClosed($element, storage, id); $element.trigger('close'); event.preventDefault(); }); }); } }; function isClosed($element, storage, id) { if (!id || !storage) { return false; } switch (storage) { case 'local': if (hasLocalStorage) { return localStorage.getItem('Drupal.webform.message.' + id) || false; } return false; case 'session': if (hasSessionStorage) { return sessionStorage.getItem('Drupal.webform.message.' + id) || false; } return false; default: return false; } } function setClosed($element, storage, id) { if (!id || !storage) { return; } switch (storage) { case 'local': if (hasLocalStorage) { localStorage.setItem('Drupal.webform.message.' + id, true); } break; case 'session': if (hasSessionStorage) { sessionStorage.setItem('Drupal.webform.message.' + id, true); } break; case 'user': case 'state': case 'custom': $.get($element.find('.js-webform-message__link').attr('href')); return true; } } })(jQuery, Drupal); ; // imported in forms twig templates of theme obelisco (function (Drupal) { Drupal.behaviors.GcabaFeedback = { attach: (context, settings) => { const showFeedbackForm = () => { feedbackFirst.style.display = "none"; feedbackNegative.style.display = "block"; removeClass(feedbackNegative, "d-none"); }; const hideFeedbackForm = () => { feedbackFirst.style.display = "block"; feedbackNegative.style.display = "none"; }; const feedbackFirst = document.getElementById("feedback-form-container"); if (feedbackFirst) { const footerInfoActionsFirst = feedbackFirst.querySelector( ".footer-info-actions" ); if (footerInfoActionsFirst) removeClass(footerInfoActionsFirst, "mb-3"); } const feedbackNegative = document.getElementById( "feedback-negative-form-container" ); if (feedbackNegative) { if (document.getElementById("already-submitted-webform-alert")) { feedbackFirst.remove(); feedbackNegative.remove(); } else { alterContainer(feedbackNegative); alterCheckboxes(); const textBox = document.querySelector( "[data-drupal-selector=edit-texto]" ); if (textBox) { createNewCounter(feedbackNegative); const footerInfoActions = feedbackNegative.querySelector( ".footer-info-actions" ); if (footerInfoActions) footerInfoActions.children[0].remove(); } if (shouldDisplayFeedbackNegative(feedbackNegative, textBox)) removeClass(feedbackNegative, "d-none"); const notUsefulButton = document.getElementById( "continueToNegativeFeedback" ); const cancelarButton = document.getElementById( "feedbackNegativeCancel" ); if (notUsefulButton) { modifyButton(notUsefulButton, showFeedbackForm); addStyle(notUsefulButton, "order", "1"); } if (cancelarButton) modifyButton(cancelarButton, hideFeedbackForm); } } }, }; })(Drupal); const alterCheckboxes = () => { let checkboxContainer = document.getElementById( "edit-en-que-aspectos-esta-pagina-no-es-util-" ); if (checkboxContainer === null) { checkboxContainer = document.querySelector( "[data-drupal-selector=edit-en-que-aspectos-esta-pagina-no-es-util-]" ); } if (checkboxContainer) { addStyle(checkboxContainer, "padding", "2rem 1rem"); checkboxContainer = checkboxContainer.children[1].children[0]; const checkboxChildren = checkboxContainer.children; for (let i = 0; i < checkboxChildren.length; i++) { removeClass(checkboxChildren[i], "form-group"); // remove class to div conflict with obelisco checkboxChildren[i].classList.add("custom-control", "custom-checkbox"); // add class to div checkboxChildren[i].children[0].classList.add("custom-control-input"); checkboxChildren[i].children[1].classList.add("custom-control-label"); if (checkboxChildren[i].children[0].value == "_other_") { checkboxChildren[i].remove(); } } } }; const alterContainer = (feedbackNegative) => { const container = feedbackNegative.querySelector(".container"); if (container) { if (!!window.chrome) { addStyle(container, "flexFlow", "column"); addStyle(container, "alignItems", "start"); } const containerButtons = container.querySelector( "[data-drupal-selector=edit-container]" ); if (containerButtons) containerButtons.classList.add("col-9"); } }; const createNewCounter = (feedbackNegative) => { const counterContainer = feedbackNegative.querySelector( "#character-counter-container" ); const textArea = feedbackNegative.querySelector( "[data-drupal-selector=edit-gracias-por-tus-comentarios]" ); const maxValue = textArea.getAttribute("maxlength"); const counter = document.createElement("span"); counter.innerText = `0/${maxValue}`; counterContainer.appendChild(counter); textArea.addEventListener("input", (event) => { const target = event.currentTarget; const currLength = target.value.length; counter.innerText = `${currLength}/400`; }); }; const shouldDisplayFeedbackNegative = (feedbackNegative, textBox) => { return ( (!document.getElementById("edit-en-que-aspectos-esta-pagina-no-es-util-") && document.querySelector( "[data-drupal-selector=edit-en-que-aspectos-esta-pagina-no-es-util-]" )) || textBox || feedbackNegative.querySelector(".webform-confirmation") ); }; const removeClass = (el, className) => el.classList ? el.classList.remove(className) : null; const addStyle = (el, property, value) => (el.style[property] = value); const modifyButton = (button, fn) => { button.type = "button"; button.onclick = fn; }; ; /** * @file * JavaScript behaviors for details element. */ (function ($, Drupal) { 'use strict'; /** * Attach handler to details with invalid inputs. * * @type {Drupal~behavior} */ Drupal.behaviors.webformDetailsInvalid = { attach: function (context) { $('details :input', context).on('invalid', function () { $(this).parents('details:not([open])').children('summary').trigger('click'); // Synd details toggle label. if (Drupal.webform && Drupal.webform.detailsToggle) { Drupal.webform.detailsToggle.setDetailsToggleLabel($(this.form)); } }); } }; })(jQuery, Drupal); ; /** * DO NOT EDIT THIS FILE. * See the following change record for more information, * https://www.drupal.org/node/2815083 * @preserve **/ (function ($, Drupal) { Drupal.behaviors.detailsAria = { attach: function attach() { $('body').once('detailsAria').on('click.detailsAria', 'summary', function (event) { var $summary = $(event.currentTarget); var open = $(event.currentTarget.parentNode).attr('open') === 'open' ? 'false' : 'true'; $summary.attr({ 'aria-expanded': open, 'aria-pressed': open }); }); } }; })(jQuery, Drupal);; /** * DO NOT EDIT THIS FILE. * See the following change record for more information, * https://www.drupal.org/node/2815083 * @preserve **/ (function ($, Modernizr, Drupal) { function CollapsibleDetails(node) { this.$node = $(node); this.$node.data('details', this); var anchor = window.location.hash && window.location.hash !== '#' ? ', ' + window.location.hash : ''; if (this.$node.find('.error' + anchor).length) { this.$node.attr('open', true); } this.setupSummary(); this.setupLegend(); } $.extend(CollapsibleDetails, { instances: [] }); $.extend(CollapsibleDetails.prototype, { setupSummary: function setupSummary() { this.$summary = $(''); this.$node.on('summaryUpdated', $.proxy(this.onSummaryUpdated, this)).trigger('summaryUpdated'); }, setupLegend: function setupLegend() { var $legend = this.$node.find('> summary'); $('').append(this.$node.attr('open') ? Drupal.t('Hide') : Drupal.t('Show')).prependTo($legend).after(document.createTextNode(' ')); $('').attr('href', '#' + this.$node.attr('id')).prepend($legend.contents()).appendTo($legend); $legend.append(this.$summary).on('click', $.proxy(this.onLegendClick, this)); }, onLegendClick: function onLegendClick(e) { this.toggle(); e.preventDefault(); }, onSummaryUpdated: function onSummaryUpdated() { var text = $.trim(this.$node.drupalGetSummary()); this.$summary.html(text ? ' (' + text + ')' : ''); }, toggle: function toggle() { var _this = this; var isOpen = !!this.$node.attr('open'); var $summaryPrefix = this.$node.find('> summary span.details-summary-prefix'); if (isOpen) { $summaryPrefix.html(Drupal.t('Show')); } else { $summaryPrefix.html(Drupal.t('Hide')); } setTimeout(function () { _this.$node.attr('open', !isOpen); }, 0); } }); Drupal.behaviors.collapse = { attach: function attach(context) { if (Modernizr.details) { return; } var $collapsibleDetails = $(context).find('details').once('collapse').addClass('collapse-processed'); if ($collapsibleDetails.length) { for (var i = 0; i < $collapsibleDetails.length; i++) { CollapsibleDetails.instances.push(new CollapsibleDetails($collapsibleDetails[i])); } } } }; var handleFragmentLinkClickOrHashChange = function handleFragmentLinkClickOrHashChange(e, $target) { $target.parents('details').not('[open]').find('> summary').trigger('click'); }; $('body').on('formFragmentLinkClickOrHashChange.details', handleFragmentLinkClickOrHashChange); Drupal.CollapsibleDetails = CollapsibleDetails; })(jQuery, Modernizr, Drupal);; /** * @file * JavaScript behaviors for checkboxes. */ (function ($, Drupal) { 'use strict'; /** * Adds check all or none checkboxes support. * * @type {Drupal~behavior} * * @see https://www.drupal.org/project/webform/issues/3068998 */ Drupal.behaviors.webformCheckboxesAllorNone = { attach: function (context) { $('[data-options-all], [data-options-none]', context) .once('webform-checkboxes-all-or-none') .each(function () { var $element = $(this); var options_all_value = $element.data('options-all'); var options_none_value = $element.data('options-none'); // Get all checkboxes. var $checkboxes = $element.find('input[type="checkbox"]'); // Get all options/checkboxes. var $options = $checkboxes .not('[value="' + options_all_value + '"]') .not('[value="' + options_none_value + '"]'); // Get options all and none checkboxes. var $options_all = $element .find(':checkbox[value="' + options_all_value + '"]'); var $options_none = $element .find(':checkbox[value="' + options_none_value + '"]'); // All of the above. if ($options_all.length) { $options_all.on('click', toggleCheckAllEventHandler); if ($options_all.prop('checked')) { toggleCheckAllEventHandler(); } } // None of the above. if ($options_none.length) { $options_none.on('click', toggleCheckNoneEventHandler); toggleCheckNoneEventHandler(); } $options.on('click', toggleCheckboxesEventHandler); toggleCheckboxesEventHandler(); /** * Toggle check all checkbox checked state. */ function toggleCheckAllEventHandler() { if ($options_all.prop('checked')) { // Uncheck options none. if ($options_none.is(':checked')) { $options_none .prop('checked', false) .trigger('change', ['webform.states']); } // Check check all unchecked options. $options.not(':checked') .prop('checked', true) .trigger('change', ['webform.states']); } else { // Check uncheck all checked options. $options.filter(':checked') .prop('checked', false) .trigger('change', ['webform.states']); } } /** * Toggle check none checkbox checked state. */ function toggleCheckNoneEventHandler() { if ($options_none.prop('checked')) { $checkboxes .not('[value="' + options_none_value + '"]') .filter(':checked') .prop('checked', false) .trigger('change', ['webform.states']); } } /** * Toggle check all checkbox checked state. */ function toggleCheckboxesEventHandler() { var isAllChecked = ($options.filter(':checked').length === $options.length); if ($options_all.length && $options_all.prop('checked') !== isAllChecked) { $options_all .prop('checked', isAllChecked) .trigger('change', ['webform.states']); } var isOneChecked = $options.is(':checked'); if ($options_none.length && isOneChecked) { $options_none .prop('checked', false) .trigger('change', ['webform.states']); } } }); } }; })(jQuery, Drupal); ; /** * @file * JavaScript behaviors for other elements. */ (function ($, Drupal) { 'use strict'; /** * Toggle other input (text) field. * * @param {boolean} show * TRUE will display the text field. FALSE with hide and clear the text field. * @param {object} $element * The input (text) field to be toggled. * @param {string} effect * Effect. */ function toggleOther(show, $element, effect) { var $input = $element.find('input'); var hideEffect = (effect === false) ? 'hide' : 'slideUp'; var showEffect = (effect === false) ? 'show' : 'slideDown'; if (show) { // Limit the other inputs width to the parent's container. // If the parent container is not visible it's width will be 0 // and ignored. var width = $element.parent().width(); if (width) { $element.width(width); } // Display the element. $element[showEffect](); // If not initializing, then focus the other element. if (effect !== false) { $input.trigger('focus'); } // Require the input. $input.prop('required', true).attr('aria-required', 'true'); // Restore the input's value. var value = $input.data('webform-value'); if (typeof value !== 'undefined') { $input.val(value); var input = $input.get(0); // Move cursor to the beginning of the other text input. // @see https://stackoverflow.com/questions/21177489/selectionstart-selectionend-on-input-type-number-no-longer-allowed-in-chrome if ($.inArray(input.type, ['text', 'search', 'url', 'tel', 'password']) !== -1) { input.setSelectionRange(0, 0); } } // Refresh CodeMirror used as other element. $element.parent().find('.CodeMirror').each(function (index, $element) { $element.CodeMirror.refresh(); }); } else { // Hide the element. $element[hideEffect](); // Save the input's value. $input.data('webform-value', $input.val()); // Empty and un-required the input. $input.val('').prop('required', false).removeAttr('aria-required'); } } /** * Attach handlers to select other elements. * * @type {Drupal~behavior} */ Drupal.behaviors.webformSelectOther = { attach: function (context) { $(context).find('.js-webform-select-other').once('webform-select-other').each(function () { var $element = $(this); var $select = $element.find('select'); var $input = $element.find('.js-webform-select-other-input'); $select.on('change', function () { var isOtherSelected = $select .find('option[value="_other_"]') .is(':selected'); toggleOther(isOtherSelected, $input); }); var isOtherSelected = $select .find('option[value="_other_"]') .is(':selected'); toggleOther(isOtherSelected, $input, false); }); } }; /** * Attach handlers to checkboxes other elements. * * @type {Drupal~behavior} */ Drupal.behaviors.webformCheckboxesOther = { attach: function (context) { $(context).find('.js-webform-checkboxes-other').once('webform-checkboxes-other').each(function () { var $element = $(this); var $checkbox = $element.find('input[value="_other_"]'); var $input = $element.find('.js-webform-checkboxes-other-input'); $checkbox.on('change', function () { toggleOther(this.checked, $input); }); toggleOther($checkbox.is(':checked'), $input, false); }); } }; /** * Attach handlers to radios other elements. * * @type {Drupal~behavior} */ Drupal.behaviors.webformRadiosOther = { attach: function (context) { $(context).find('.js-webform-radios-other').once('webform-radios-other').each(function () { var $element = $(this); var $radios = $element.find('input[type="radio"]'); var $input = $element.find('.js-webform-radios-other-input'); $radios.on('change', function () { toggleOther(($radios.filter(':checked').val() === '_other_'), $input); }); toggleOther(($radios.filter(':checked').val() === '_other_'), $input, false); }); } }; /** * Attach handlers to buttons other elements. * * @type {Drupal~behavior} */ Drupal.behaviors.webformButtonsOther = { attach: function (context) { $(context).find('.js-webform-buttons-other').once('webform-buttons-other').each(function () { var $element = $(this); var $buttons = $element.find('input[type="radio"]'); var $input = $element.find('.js-webform-buttons-other-input'); var $container = $(this).find('.js-webform-webform-buttons'); // Create set onchange handler. $container.on('change', function () { toggleOther(($(this).find(':radio:checked').val() === '_other_'), $input); }); toggleOther(($buttons.filter(':checked').val() === '_other_'), $input, false); }); } }; })(jQuery, Drupal); ; /** * @file * JavaScript behaviors for options elements. */ (function ($, Drupal) { 'use strict'; /** * Attach handlers to options buttons element. * * @type {Drupal~behavior} */ Drupal.behaviors.webformOptionsButtons = { attach: function (context) { // Place inside of