Webform module and config export
This commit is contained in:
parent
3e6a5cbed2
commit
0e15467384
1040 changed files with 117682 additions and 0 deletions
41
web/modules/contrib/webform/js/jquery.common_ancestor.js
Normal file
41
web/modules/contrib/webform/js/jquery.common_ancestor.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* @file
|
||||
* Jquery plugin to find common ancestor.
|
||||
*
|
||||
* @see http://stackoverflow.com/questions/3217147/jquery-first-parent-containing-all-children
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
|
||||
'use strict';
|
||||
|
||||
jQuery.fn.commonAncestor = function() {
|
||||
var parents = [];
|
||||
var minlen = Infinity;
|
||||
|
||||
$(this).each(function() {
|
||||
var curparents = $(this).parents();
|
||||
parents.push(curparents);
|
||||
minlen = Math.min(minlen, curparents.length);
|
||||
});
|
||||
|
||||
for (var i in parents) {
|
||||
parents[i] = parents[i].slice(parents[i].length - minlen);
|
||||
}
|
||||
|
||||
// Iterate until equality is found
|
||||
for (var i = 0; i < parents[0].length; i++) {
|
||||
var equal = true;
|
||||
for (var j in parents) {
|
||||
if (parents[j][i] != parents[0][i]) {
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (equal) return $(parents[0][i]);
|
||||
}
|
||||
return $([]);
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
61
web/modules/contrib/webform/js/webform.admin.js
Normal file
61
web/modules/contrib/webform/js/webform.admin.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for admin pages.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Filter webform autocomplete handler.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformFilterAutocomplete = {
|
||||
attach: function (context) {
|
||||
$('.webform-filter-form input.form-autocomplete', context).once('webform-autocomplete')
|
||||
.each(function () {
|
||||
// If input value is an autocomplete match, reset the input to its
|
||||
// default value.
|
||||
if (/\(([^)]+)\)$/.test(this.value)) {
|
||||
this.value = this.defaultValue;
|
||||
}
|
||||
|
||||
// From: http://stackoverflow.com/questions/5366068/jquery-ui-autocomplete-submit-onclick-result
|
||||
$(this).bind('autocompleteselect', function (event, ui) {
|
||||
if (ui.item) {
|
||||
$(this).val(ui.item.value);
|
||||
this.form.submit();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Allow table rows to be hyperlinked.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformTableRowHref = {
|
||||
attach: function (context) {
|
||||
// Only attach the click event handler to the entire table and determine
|
||||
// which row triggers the event.
|
||||
$('.webform-results__table', context).once('webform-results-table').click(function (event) {
|
||||
if (event.target.tagName == 'A' || event.target.tagName == 'BUTTON') {
|
||||
return true;
|
||||
}
|
||||
|
||||
var $tr = $(event.target).parents('tr[data-webform-href]');
|
||||
if (!$tr.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
window.location = $tr.attr('data-webform-href');
|
||||
return false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
41
web/modules/contrib/webform/js/webform.ajax.js
Normal file
41
web/modules/contrib/webform/js/webform.ajax.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for AJAX.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* 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.webformScrollTop
|
||||
*/
|
||||
Drupal.AjaxCommands.prototype.webformScrollTop = function (ajax, response) {
|
||||
// Scroll to the top of the view. This will allow users
|
||||
// to browse newly loaded content after e.g. clicking a pager
|
||||
// link.
|
||||
var offset = $(response.selector).offset();
|
||||
// We can't guarantee that the scrollable object should be
|
||||
// the body, as the view could be embedded in something
|
||||
// more complex such as a modal popup. Recurse up the DOM
|
||||
// and scroll the first element that has a non-zero top.
|
||||
var scrollTarget = response.selector;
|
||||
while ($(scrollTarget).scrollTop() === 0 && $(scrollTarget).parent()) {
|
||||
scrollTarget = $(scrollTarget).parent();
|
||||
}
|
||||
// Only scroll upward.
|
||||
if (offset.top - 10 < $(scrollTarget).scrollTop()) {
|
||||
$(scrollTarget).animate({scrollTop: (offset.top - 10)}, 500);
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
8
web/modules/contrib/webform/js/webform.assets.js
Normal file
8
web/modules/contrib/webform/js/webform.assets.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* @file
|
||||
* This an empty placeholder file that is replaced with custom JavaScript.
|
||||
*
|
||||
* @see webform_js_alter()
|
||||
* @see _webform_asset_alter()
|
||||
* @see \Drupal\webform\WebformSubmissionForm::form
|
||||
*/
|
44
web/modules/contrib/webform/js/webform.block.js
Normal file
44
web/modules/contrib/webform/js/webform.block.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* @file
|
||||
* Webform block behaviors.
|
||||
*/
|
||||
|
||||
(function ($, window, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Provide the summary information for the block settings vertical tabs.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches the behavior for the block settings summaries.
|
||||
*/
|
||||
Drupal.behaviors.webformBlockSettingsSummary = {
|
||||
attach: function () {
|
||||
// The drupalSetSummary method required for this behavior is not available
|
||||
// on the Blocks administration page, so we need to make sure this
|
||||
// behavior is processed only if drupalSetSummary is defined.
|
||||
if (typeof $.fn.drupalSetSummary === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a summary for selected in the provided context.
|
||||
*
|
||||
* @param {HTMLDocument|HTMLElement} context
|
||||
* A context where one would find selected to summarize.
|
||||
*
|
||||
* @return {string}
|
||||
* A string with the summary.
|
||||
*/
|
||||
function selectSummary(context) {
|
||||
return $(context).find("#edit-visibility-webform-webforms option:selected").map(function(){ return this.text }).get().join(", ") || Drupal.t('Not restricted');
|
||||
}
|
||||
|
||||
$('[data-drupal-selector="edit-visibility-webform"]').drupalSetSummary(selectSummary);
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, window, Drupal);
|
19
web/modules/contrib/webform/js/webform.dialog.js
Normal file
19
web/modules/contrib/webform/js/webform.dialog.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors to fix dialogs.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
// @see http://stackoverflow.com/questions/20533487/how-to-ensure-that-ckeditor-has-focus-when-displayed-inside-of-jquery-ui-dialog
|
||||
var _allowInteraction = $.ui.dialog.prototype._allowInteraction;
|
||||
$.ui.dialog.prototype._allowInteraction = function (event) {
|
||||
if ($(event.target).closest('.cke_dialog').length) {
|
||||
return true;
|
||||
}
|
||||
return _allowInteraction.apply(this, arguments);
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
35
web/modules/contrib/webform/js/webform.element.buttons.js
Normal file
35
web/modules/contrib/webform/js/webform.element.buttons.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for jQuery UI buttons element integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Create jQuery UI buttons element.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformButtons = {
|
||||
attach: function (context) {
|
||||
$(context).find('.js-webform-buttons [type="radio"]').commonAncestor().once('webform-buttons').each(function () {
|
||||
var $input = $(this);
|
||||
// Remove all div and classes around radios and labels.
|
||||
$input.html($input.find('input[type="radio"], label').removeClass());
|
||||
// Create buttonset.
|
||||
$input.buttonset();
|
||||
// Disable buttonset.
|
||||
$input.buttonset('option', 'disabled', $input.find('input[type="radio"]:disabled').length);
|
||||
|
||||
// Turn buttonset off/on when the input is disabled/enabled.
|
||||
// @see webform.states.js
|
||||
$input.on('webform:disabled', function () {
|
||||
$input.buttonset('option', 'disabled', $input.find('input[type="radio"]:disabled').length);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
103
web/modules/contrib/webform/js/webform.element.codemirror.js
Normal file
103
web/modules/contrib/webform/js/webform.element.codemirror.js
Normal file
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for CodeMirror integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Initialize CodeMirror editor.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformCodeMirror = {
|
||||
attach: function (context) {
|
||||
|
||||
// Webform CodeMirror editor.
|
||||
$(context).find('textarea.js-webform-codemirror').once('webform-codemirror').each(function () {
|
||||
var $input = $(this);
|
||||
|
||||
// Open all closed details, so that editor height is correctly calculated.
|
||||
var $details = $(this).parents('details:not([open])');
|
||||
$details.attr('open', 'open');
|
||||
|
||||
// #59 HTML5 required attribute breaks hack for webform submission.
|
||||
// https://github.com/marijnh/CodeMirror-old/issues/59
|
||||
$(this).removeAttr('required');
|
||||
|
||||
var editor = CodeMirror.fromTextArea(this, {
|
||||
mode: $(this).attr('data-webform-codemirror-mode'),
|
||||
lineNumbers: true,
|
||||
viewportMargin: Infinity,
|
||||
readOnly: $(this).prop('readonly') ? true : false,
|
||||
// Setting for using spaces instead of tabs - https://github.com/codemirror/CodeMirror/issues/988
|
||||
extraKeys: {
|
||||
Tab: function (cm) {
|
||||
var spaces = Array(cm.getOption('indentUnit') + 1).join(' ');
|
||||
cm.replaceSelection(spaces, 'end', '+element');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Now, close details.
|
||||
$details.removeAttr('open');
|
||||
|
||||
// Issue #2764443: CodeMirror is not setting submitted value when
|
||||
// rendered within a webform UI dialog.
|
||||
editor.on('blur', function (event) {
|
||||
editor.save();
|
||||
});
|
||||
|
||||
// Update CodeMirror when the textarea's value has changed.
|
||||
// @see webform.states.js
|
||||
$input.on('change', function () {
|
||||
editor.getDoc().setValue($input.val());
|
||||
});
|
||||
|
||||
// Set CodeMirror to be readonly when the textarea is disabled.
|
||||
// @see webform.states.js
|
||||
$input.on('webform:disabled', function () {
|
||||
editor.setOption("readOnly", $input.is(':disabled'));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Webform CodeMirror syntax coloring.
|
||||
$(context).find('.js-webform-codemirror-runmode').once('webform-codemirror-runmode').each(function () {
|
||||
// Mode Runner - http://codemirror.net/demo/runmode.html
|
||||
CodeMirror.runMode($(this).addClass('cm-s-default').html(), $(this).attr('data-webform-codemirror-mode'), this);
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// Workaround: When a dialog opens we need to reference all CodeMirror
|
||||
// editors to make sure they are properly initialized and sized.
|
||||
$(window).on('dialog:aftercreate', function (dialog, $element, settings) {
|
||||
// Delay refreshing CodeMirror for 10 millisecond while the dialog is
|
||||
// still being rendered.
|
||||
// @see http://stackoverflow.com/questions/8349571/codemirror-editor-is-not-loading-content-until-clicked
|
||||
setTimeout(function () {
|
||||
$('.CodeMirror').each(function (index, $element) {
|
||||
var $details = $(this).parents('details:not([open])');
|
||||
$details.attr('open', 'open');
|
||||
$element.CodeMirror.refresh();
|
||||
// Now, close details.
|
||||
$details.removeAttr('open');
|
||||
});
|
||||
}, 10);
|
||||
});
|
||||
|
||||
// On state:visible refresh CodeMirror elements.
|
||||
$(document).on('state:visible', function (event) {
|
||||
var $element = $(event.target);
|
||||
if ($element.hasClass('js-webform-codemirror')) {
|
||||
$element.parent().find('.CodeMirror').each(function (index, $element) {
|
||||
$element.CodeMirror.refresh();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery, Drupal);
|
46
web/modules/contrib/webform/js/webform.element.color.js
Normal file
46
web/modules/contrib/webform/js/webform.element.color.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for color element integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Enhance HTML5 color element.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformColor = {
|
||||
attach: function (context) {
|
||||
$(context).find('.form-color:not(.form-color-output)').once('webform-color').each(function () {
|
||||
var $element = $(this);
|
||||
// Handle browser that don't support the HTML5 color input.
|
||||
if (Modernizr.inputtypes.color === false) {
|
||||
// Remove swatch sizes.
|
||||
$element.removeClass('form-color-small')
|
||||
.removeClass('form-color-medium')
|
||||
.removeClass('form-color-large');
|
||||
}
|
||||
else {
|
||||
// Display color input's output to the end user.
|
||||
var $output = $('<input class="form-color-output ' + $element.attr('class') + ' js-webform-element-mask" data-inputmask-mask="\\#######" />').inputmask();
|
||||
$output[0].value = $element[0].value;
|
||||
$element
|
||||
.after($output)
|
||||
.css({float: 'left'});
|
||||
|
||||
// Sync $element and $output.
|
||||
$element.on('input', function () {
|
||||
$output[0].value = $element[0].value;
|
||||
});
|
||||
$output.on('input', function () {
|
||||
$element[0].value = $output[0].value;
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
38
web/modules/contrib/webform/js/webform.element.counter.js
Normal file
38
web/modules/contrib/webform/js/webform.element.counter.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for jQuery Word and Counter Counter integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Initialize text field and textarea word and character counter.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformCounter = {
|
||||
attach: function (context) {
|
||||
$(context).find('.js-webform-counter').once('webform-counter').each(function () {
|
||||
var options = {
|
||||
goal: $(this).attr('data-counter-limit'),
|
||||
msg: $(this).attr('data-counter-message')
|
||||
};
|
||||
// Only word type can be defined, otherwise the counter defaults to
|
||||
// character counting.
|
||||
if ($(this).attr('data-counter-type') == 'word') {
|
||||
options.type = 'word';
|
||||
}
|
||||
|
||||
// Set the target to a div that is appended to end of the input's parent container.
|
||||
options.target = $('<div></div>');
|
||||
$(this).parent().append(options.target);
|
||||
|
||||
$(this).counter(options);
|
||||
})
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
69
web/modules/contrib/webform/js/webform.element.date.js
Normal file
69
web/modules/contrib/webform/js/webform.element.date.js
Normal file
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* @file
|
||||
* Override polyfill for HTML5 date input and provide support for custom date formats.
|
||||
*/
|
||||
|
||||
(function ($, Modernizr, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Attach datepicker fallback on date elements.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches the behavior. Accepts in `settings.date` an object listing
|
||||
* elements to process, keyed by the HTML ID of the form element containing
|
||||
* the human-readable value. Each element is an datepicker settings object.
|
||||
* @prop {Drupal~behaviorDetach} detach
|
||||
* Detach the behavior destroying datepickers on effected elements.
|
||||
*/
|
||||
Drupal.behaviors.date = {
|
||||
attach: function (context, settings) {
|
||||
var $context = $(context);
|
||||
// Skip if date are supported by the browser.
|
||||
if (Modernizr.inputtypes.date === true) {
|
||||
return;
|
||||
}
|
||||
$context.find('input[data-drupal-date-format]').once('datePicker').each(function () {
|
||||
var $input = $(this);
|
||||
var datepickerSettings = {};
|
||||
var dateFormat = $input.data('drupalDateFormat');
|
||||
// The date format is saved in PHP style, we need to convert to jQuery
|
||||
// datepicker.
|
||||
// @see http://stackoverflow.com/questions/16702398/convert-a-php-date-format-to-a-jqueryui-datepicker-date-format
|
||||
datepickerSettings.dateFormat = dateFormat
|
||||
// Year.
|
||||
.replace('Y', 'yy')
|
||||
// Month.
|
||||
.replace('F', 'MM')
|
||||
.replace('m', 'mm')
|
||||
.replace('n', 'm')
|
||||
// Date.
|
||||
.replace('d', 'dd');
|
||||
|
||||
// Add min and max date if set on the input.
|
||||
if ($input.attr('min')) {
|
||||
datepickerSettings.minDate = $.datepicker.formatDate(datepickerSettings.dateFormat, $.datepicker.parseDate('yy-mm-dd', $input.attr('min')));
|
||||
}
|
||||
if ($input.attr('max')) {
|
||||
datepickerSettings.maxDate = $.datepicker.formatDate(datepickerSettings.dateFormat, $.datepicker.parseDate('yy-mm-dd', $input.attr('max')));
|
||||
}
|
||||
|
||||
// Format default value.
|
||||
if ($input.val()) {
|
||||
$input.val($.datepicker.formatDate(datepickerSettings.dateFormat, $.datepicker.parseDate('yy-mm-dd', $input.val())));
|
||||
}
|
||||
|
||||
$input.datepicker(datepickerSettings);
|
||||
});
|
||||
},
|
||||
detach: function (context, settings, trigger) {
|
||||
if (trigger === 'unload') {
|
||||
$(context).find('input[data-drupal-date-format]').findOnce('datePicker').datepicker('destroy');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Modernizr, Drupal);
|
102
web/modules/contrib/webform/js/webform.element.details.save.js
Normal file
102
web/modules/contrib/webform/js/webform.element.details.save.js
Normal file
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for details element.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Attach handler to save details open/close state.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformDetailsSave = {
|
||||
attach: function (context) {
|
||||
if (!window.localStorage) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Summary click event handler.
|
||||
$('details > summary', context).once('webform-details-summary-save').click(function () {
|
||||
var $details = $(this).parent();
|
||||
|
||||
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 $details
|
||||
* A details element.
|
||||
*
|
||||
* @returns string
|
||||
* The name used to store the state of details element.
|
||||
*/
|
||||
Drupal.webformDetailsSaveGetName = function ($details) {
|
||||
if (!window.localStorage) {
|
||||
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. (ie 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);
|
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for details element.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* 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 $details = $form.find('details');
|
||||
|
||||
// Toggle is only useful when there are two or more details elements.
|
||||
if ($details.length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add toggle state link to first details element.
|
||||
$details.first().before($('<button type="button" class="link webform-details-toggle-state"></button>')
|
||||
.attr('title', Drupal.t('Toggle details widget state.'))
|
||||
.on('click', function (e) {
|
||||
var open;
|
||||
if (isFormDetailsOpen($form)) {
|
||||
$form.find('details').removeAttr('open');
|
||||
open = 0;
|
||||
}
|
||||
else {
|
||||
$form.find('details').attr('open', 'open');
|
||||
open = 1;
|
||||
}
|
||||
setDetailsToggleLabel($form);
|
||||
|
||||
// Set the saved states for all the details elements.
|
||||
// @see webform.element.details.save.js
|
||||
if (Drupal.webformDetailsSaveGetName) {
|
||||
$form.find('details').each(function () {
|
||||
var name = Drupal.webformDetailsSaveGetName($(this));
|
||||
if (name) {
|
||||
localStorage.setItem(name, open);
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
.wrap('<div class="webform-details-toggle-state-wrapper"></div>')
|
||||
.parent()
|
||||
);
|
||||
|
||||
setDetailsToggleLabel($form);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine if a webform's details are all opened.
|
||||
*
|
||||
* @param $form
|
||||
* A webform.
|
||||
*
|
||||
* @returns {boolean}
|
||||
* TRUE if a webform's details are all opened.
|
||||
*/
|
||||
function isFormDetailsOpen($form) {
|
||||
return ($form.find('details[open]').length == $form.find('details').length)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a webform's details toggle state widget label.
|
||||
*
|
||||
* @param $form
|
||||
* A webform.
|
||||
*/
|
||||
function setDetailsToggleLabel($form) {
|
||||
var label = (isFormDetailsOpen($form)) ? Drupal.t('Collapse all') : Drupal.t('Expand all');
|
||||
$form.find('.webform-details-toggle-state').html(label);
|
||||
}
|
||||
|
||||
})(jQuery, Drupal);
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for HTML editor integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal, drupalSettings) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Initialize HTML Editor.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformHtmlEditor = {
|
||||
attach: function (context) {
|
||||
$(context).find('.js-form-type-webform-html-editor textarea').once('webform-html-editor').each(function () {
|
||||
var allowedContent = drupalSettings['webform']['html_editor']['allowedContent'];
|
||||
var $textarea = $(this);
|
||||
CKEDITOR.replace(this.id, {
|
||||
// Turn off external config and styles.
|
||||
customConfig: '',
|
||||
stylesSet: false,
|
||||
contentsCss: [],
|
||||
allowedContent: allowedContent,
|
||||
// Use <br> tags instead of <p> tags.
|
||||
enterMode: CKEDITOR.ENTER_BR,
|
||||
shiftEnterMode: CKEDITOR.ENTER_BR,
|
||||
// Set height, hide the status bar, and remove plugins.
|
||||
height: '100px',
|
||||
resize_enabled: false,
|
||||
removePlugins: 'elementspath,magicline',
|
||||
// Toolbar settings.
|
||||
format_tags: 'p;h2;h3;h4;h5;h6',
|
||||
toolbar: [
|
||||
{ name: 'styles', items: ['Format', 'Font', 'FontSize' ] },
|
||||
{ name: 'basicstyles', items: [ 'Bold', 'Italic', 'Subscript', 'Superscript' ] },
|
||||
{ name: 'insert', items: [ 'SpecialChar' ] },
|
||||
{ name: 'colors', items: [ 'TextColor', 'BGColor' ] },
|
||||
{ name: 'paragraph', items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote'] },
|
||||
{ name: 'links', items: [ 'Link', 'Unlink'] },
|
||||
{ name: 'tools', items: [ 'Source', '-', 'Maximize' ] }
|
||||
]
|
||||
}).on('change', function (evt) {
|
||||
// Save data onchange since AJAX dialogs don't execute webform.onsubmit.
|
||||
$textarea.val(evt.editor.getData().trim());
|
||||
});
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal, drupalSettings);
|
21
web/modules/contrib/webform/js/webform.element.inputmask.js
Normal file
21
web/modules/contrib/webform/js/webform.element.inputmask.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for jquery.inputmask integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Initialize input masks.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformElementMask = {
|
||||
attach: function (context) {
|
||||
$(context).find('input.js-webform-element-mask').once('webform-element-mask').inputmask();
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
53
web/modules/contrib/webform/js/webform.element.location.js
Normal file
53
web/modules/contrib/webform/js/webform.element.location.js
Normal file
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for Geocomplete location integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal, drupalSettings) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Initialize location Geocompletion.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformLocation = {
|
||||
attach: function (context) {
|
||||
$(context).find('div.js-webform-location').once('webform-location').each(function () {
|
||||
var $element = $(this);
|
||||
var $geocomplete = $element.find('.webform-location-geocomplete').geocomplete({
|
||||
details: $element,
|
||||
detailsAttribute: 'data-webform-location-attribute',
|
||||
types: ['geocode']
|
||||
});
|
||||
|
||||
$geocomplete.on('input', function () {
|
||||
// Reset attributes on input.
|
||||
$element.find('[data-webform-location-attribute]').val('');
|
||||
}).on('blur', function () {
|
||||
// Make sure to get attributes on blur.
|
||||
if ($element.find('[data-webform-location-attribute="location"]').val() == '') {
|
||||
var value = $geocomplete.val();
|
||||
if (value) {
|
||||
$geocomplete.geocomplete('find', value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// If there is default value look up location's attributes, else see if
|
||||
// the default value should be set to the browser's current geolocation.
|
||||
var value = $geocomplete.val();
|
||||
if (value) {
|
||||
$geocomplete.geocomplete('find', value);
|
||||
}
|
||||
else if (navigator.geolocation && $geocomplete.attr('data-webform-location-geolocation')) {
|
||||
navigator.geolocation.getCurrentPosition(function (position) {
|
||||
$geocomplete.geocomplete('find', position.coords.latitude + ', ' + position.coords.longitude);
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal, drupalSettings);
|
92
web/modules/contrib/webform/js/webform.element.message.js
Normal file
92
web/modules/contrib/webform/js/webform.element.message.js
Normal file
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for message element integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
$element.show().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 (window.localStorage) {
|
||||
return localStorage.getItem('Drupal.webform.message.' + id) || false;
|
||||
}
|
||||
return false;
|
||||
|
||||
case 'session':
|
||||
if (window.sessionStorage) {
|
||||
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 (window.localStorage) {
|
||||
localStorage.setItem('Drupal.webform.message.' + id, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'session':
|
||||
if (window.sessionStorage) {
|
||||
sessionStorage.setItem('Drupal.webform.message.' + id, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'user':
|
||||
case 'state':
|
||||
$.get($element.find('.js-webform-message__link').attr('href'));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
})(jQuery, Drupal);
|
26
web/modules/contrib/webform/js/webform.element.multiple.js
Normal file
26
web/modules/contrib/webform/js/webform.element.multiple.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for message element integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Move show weight to after the table.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformMultiple = {
|
||||
attach: function (context, settings) {
|
||||
for (var base in settings.tableDrag) {
|
||||
var $tableDrag = $(context).find('#' + base);
|
||||
var $toggleWeight = $tableDrag.parent().find('.tabledrag-toggle-weight');
|
||||
$toggleWeight.addClass('webform-multiple-tabledrag-toggle-weight');
|
||||
$tableDrag.after($toggleWeight);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
157
web/modules/contrib/webform/js/webform.element.other.js
Normal file
157
web/modules/contrib/webform/js/webform.element.other.js
Normal file
|
@ -0,0 +1,157 @@
|
|||
/**
|
||||
* @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.
|
||||
*/
|
||||
function toggleOther(show, $element) {
|
||||
var $input = $element.find('input');
|
||||
if (show) {
|
||||
// Limit the other inputs width to the parent's container.
|
||||
$element.width($element.parent().width());
|
||||
// Display the element.
|
||||
$element.slideDown();
|
||||
// Focus and require the input.
|
||||
$input.focus().prop('required', true);
|
||||
// Restore the input's value.
|
||||
var value = $input.data('webform-value');
|
||||
if (value !== undefined) {
|
||||
$input.val(value);
|
||||
$input.get(0).setSelectionRange(0, 0);
|
||||
}
|
||||
// Refresh CodeMirror used as other element.
|
||||
$element.parent().find('.CodeMirror').each(function (index, $element) {
|
||||
$element.CodeMirror.refresh();
|
||||
});
|
||||
}
|
||||
else {
|
||||
$element.slideUp();
|
||||
// Save the input's value.
|
||||
$input.data('webform-value', $input.val());
|
||||
// Empty and un-required the input.
|
||||
$input.val('').prop('required', false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 $otherOption = $element.find('option[value="_other_"]');
|
||||
var $input = $element.find('.js-webform-select-other-input');
|
||||
|
||||
if ($otherOption.is(':selected')) {
|
||||
$input.show().find('input').prop('required', true);
|
||||
}
|
||||
|
||||
$select.on('change', function () {
|
||||
toggleOther($otherOption.is(':selected'), $input);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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');
|
||||
|
||||
if ($checkbox.is(':checked')) {
|
||||
$input.show().find('input').prop('required', true);
|
||||
}
|
||||
|
||||
$checkbox.on('change', function () {
|
||||
toggleOther(this.checked, $input);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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');
|
||||
|
||||
if ($radios.filter(':checked').val() === '_other_') {
|
||||
$input.show().find('input').prop('required', true);
|
||||
}
|
||||
|
||||
$radios.on('change', function () {
|
||||
toggleOther(($radios.filter(':checked').val() === '_other_'), $input);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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');
|
||||
|
||||
if ($buttons.filter(':checked').val() === '_other_') {
|
||||
$input.show().find('input').prop('required', true);
|
||||
}
|
||||
|
||||
// Note: Initializing buttonset here so that we can set the onchange
|
||||
// event handler.
|
||||
// @see Drupal.behaviors.webformButtons
|
||||
var $container = $(this).find('.form-radios');
|
||||
// Remove all div and classes around radios and labels.
|
||||
$container.html($container.find('input[type="radio"], label').removeClass());
|
||||
// Create buttonset and set onchange handler.
|
||||
$container.buttonset().change(function () {
|
||||
toggleOther(($(this).find(':radio:checked').val() === '_other_'), $input);
|
||||
});
|
||||
// Disable buttonset.
|
||||
$container.buttonset('option', 'disabled', $container.find('input[type="radio"]:disabled').length);
|
||||
// Turn buttonset off/on when the input is disabled/enabled.
|
||||
// @see webform.states.js
|
||||
$container.on('webform:disabled', function () {
|
||||
$container.buttonset('option', 'disabled', $container.find('input[type="radio"]:disabled').length);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
58
web/modules/contrib/webform/js/webform.element.radios.js
Normal file
58
web/modules/contrib/webform/js/webform.element.radios.js
Normal file
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for radio buttons.
|
||||
*
|
||||
* Fix #states and #required for radios buttons.
|
||||
*
|
||||
* @see Issue #2856795: If radio buttons are required but not filled form is nevertheless submitted.
|
||||
* @see Issue #2856315: Conditional Logic - Requiring Radios in a Fieldset.
|
||||
* @see Issue #2731991: Setting required on radios marks all options required.
|
||||
* @see css/webform.form.css
|
||||
* @see /core/misc/states.js
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Attach handler to add .js-webform-radios-fieldset to radios wrapper fieldset.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformRadios = {
|
||||
attach: function (context) {
|
||||
$('.js-webform-radios', context).closest('fieldset.form-composite').addClass('js-webform-radios-fieldset');
|
||||
}
|
||||
};
|
||||
|
||||
// Make absolutely sure the below event handlers are triggered after
|
||||
// the /core/misc/states.js event handlers by attaching them after DOM load.
|
||||
$(function () {
|
||||
Drupal.behaviors.webformRadios.attach($(document));
|
||||
|
||||
function setRequired($target, required) {
|
||||
if (!$target.hasClass('js-webform-radios-fieldset')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (required) {
|
||||
$target.find('input[type="radio"]').attr({'required': 'required', 'aria-required': 'aria-required'})
|
||||
$target.find('legend span').addClass('js-form-required form-required');
|
||||
}
|
||||
else {
|
||||
$target.find('input[type="radio"]').removeAttr('required aria-required');
|
||||
$target.find('legend span').removeClass('js-form-required form-required');
|
||||
}
|
||||
}
|
||||
|
||||
setRequired($('.form-composite[required="required"]'), true);
|
||||
|
||||
$(document).on('state:required', function (e) {
|
||||
if (e.trigger) {
|
||||
setRequired($(e.target), e.value);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
})(jQuery, Drupal);
|
62
web/modules/contrib/webform/js/webform.element.range.js
Normal file
62
web/modules/contrib/webform/js/webform.element.range.js
Normal file
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for range element integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Enhance HTML5 range element.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformRange = {
|
||||
attach: function (context) {
|
||||
$(context).find('.form-range[data-range-output]').once('webform-range').each(function () {
|
||||
var $element = $(this);
|
||||
// Handle browser that don't support the HTML5 range input.
|
||||
if (Modernizr.inputtypes.range === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
var prefix = $element.attr('data-range-output-prefix');
|
||||
var suffix = $element.attr('data-range-output-suffix');
|
||||
|
||||
// Display range input's output to the end user.
|
||||
var html = '';
|
||||
html += '<div class="form-range-output-container">';
|
||||
html += (prefix ? '<span class="field-prefix">' + prefix + '</span>' : '');
|
||||
html += '<input type="number" min="' + $element.attr('min') + '" max="' + $element.attr('max') + '" step="' + $element.attr('step') + '" class="form-range-output form-number" />';
|
||||
html += (suffix ? '<span class="field-suffix">' + suffix + '</span>' : '');
|
||||
html += '</div>';
|
||||
|
||||
var height = parseInt($element.outerHeight()) || 24;
|
||||
var $outputContainer = $(html);
|
||||
|
||||
// Set the container element's line height which will vertically
|
||||
// align the range widget and the output.
|
||||
$outputContainer.find('input, span').css({
|
||||
height: height + 'px',
|
||||
lineHeight: height + 'px'
|
||||
});
|
||||
|
||||
var $output = $outputContainer.find('input');
|
||||
$output[0].value = $element[0].value;
|
||||
$element
|
||||
.after($outputContainer)
|
||||
.css({float: 'left'});
|
||||
|
||||
// Sync $element and $output.
|
||||
$element.on('input', function () {
|
||||
$output[0].value = $element[0].value;
|
||||
});
|
||||
$output.on('input', function () {
|
||||
$element[0].value = $output[0].value;
|
||||
});
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
39
web/modules/contrib/webform/js/webform.element.rating.js
Normal file
39
web/modules/contrib/webform/js/webform.element.rating.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for RateIt integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Initialize rating element using RateIt.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformRating = {
|
||||
attach: function (context) {
|
||||
$(context)
|
||||
.find('[data-rateit-backingfld]')
|
||||
.once('webform-rating')
|
||||
.each(function () {
|
||||
var $rateit = $(this);
|
||||
var $input = $($rateit.attr('data-rateit-backingfld'));
|
||||
|
||||
// Update the RateIt widget when the input's value has changed.
|
||||
// @see webform.states.js
|
||||
$input.on('change', function () {
|
||||
$rateit.rateit('value', $input.val());
|
||||
});
|
||||
|
||||
// Set RateIt widget to be readonly when the input is disabled.
|
||||
// @see webform.states.js
|
||||
$input.on('webform:disabled', function () {
|
||||
$rateit.rateit('readonly', $input.is(':disabled'));
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
39
web/modules/contrib/webform/js/webform.element.roles.js
Normal file
39
web/modules/contrib/webform/js/webform.element.roles.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for roles element integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Enhance roles element.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformRoles = {
|
||||
attach: function (context) {
|
||||
$(context).find('.js-webform-roles-role[value="authenticated"]').once('webform-roles').each(function () {
|
||||
var $authenticated = $(this);
|
||||
var $checkboxes = $authenticated.parents('.form-checkboxes').find('.js-webform-roles-role').filter(function () {
|
||||
return ($(this).val() != 'anonymous' && $(this).val() != 'authenticated');
|
||||
});
|
||||
|
||||
$authenticated.on('click', function () {
|
||||
if ($authenticated.is(':checked')) {
|
||||
$checkboxes.prop('checked', true).attr('disabled', true);
|
||||
}
|
||||
else {
|
||||
$checkboxes.prop('checked', false).removeAttr('disabled');
|
||||
}
|
||||
});
|
||||
|
||||
if ($authenticated.is(':checked')) {
|
||||
$checkboxes.prop('checked', true).attr('disabled', true);
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
26
web/modules/contrib/webform/js/webform.element.select2.js
Normal file
26
web/modules/contrib/webform/js/webform.element.select2.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for Select2 integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Initialize Select2 support.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformSelect2 = {
|
||||
attach: function (context) {
|
||||
$(context)
|
||||
.find('select.js-webform-select2, .js-webform-select2 select')
|
||||
.once('webform-select2')
|
||||
// http://stackoverflow.com/questions/14313001/select2-not-calculating-resolved-width-correctly-if-select-is-hidden
|
||||
.css('width', '100%')
|
||||
.select2();
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
83
web/modules/contrib/webform/js/webform.element.signature.js
Normal file
83
web/modules/contrib/webform/js/webform.element.signature.js
Normal file
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for signature pad integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Initialize signature element.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformSignature = {
|
||||
attach: function (context) {
|
||||
$(context).find('input.js-webform-signature').once('webform-signature').each(function () {
|
||||
var $input = $(this);
|
||||
var value = $input.val();
|
||||
var $wrapper = $input.parent();
|
||||
var $canvas = $wrapper.find('canvas');
|
||||
var $button = $wrapper.find('input[type="submit"]');
|
||||
var canvas = $canvas[0];
|
||||
|
||||
// Set height.
|
||||
$canvas.attr('width', $wrapper.width());
|
||||
$canvas.attr('height', $wrapper.width() / 3);
|
||||
$(window).resize(function () {
|
||||
$canvas.attr('width', $wrapper.width());
|
||||
$canvas.attr('height', $wrapper.width() / 3);
|
||||
|
||||
// Resizing clears the canvas so we need to reset the signature pad.
|
||||
signaturePad.clear();
|
||||
var value = $input.val();
|
||||
if (value) {
|
||||
signaturePad.fromDataURL(value);
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize signature canvas.
|
||||
var signaturePad = new SignaturePad(canvas, {
|
||||
'onEnd': function () {
|
||||
$input.val(signaturePad.toDataURL());
|
||||
}
|
||||
});
|
||||
|
||||
// Set value.
|
||||
if (value) {
|
||||
signaturePad.fromDataURL(value);
|
||||
}
|
||||
|
||||
// Set reset handler.
|
||||
$button.on('click', function () {
|
||||
signaturePad.clear();
|
||||
$input.val();
|
||||
this.blur();
|
||||
return false;
|
||||
});
|
||||
|
||||
// Input onchange clears signature pad if value is empty.
|
||||
// @see webform.states.js
|
||||
$input.on('change', function () {
|
||||
if (!$input.val()) {
|
||||
signaturePad.clear();
|
||||
}
|
||||
});
|
||||
|
||||
// Turn signature pad off/on when the input is disabled/enabled.
|
||||
// @see webform.states.js
|
||||
$input.on('webform:disabled', function () {
|
||||
if ($input.is(':disabled')) {
|
||||
signaturePad.off();
|
||||
}
|
||||
else {
|
||||
signaturePad.on();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
50
web/modules/contrib/webform/js/webform.element.telephone.js
Normal file
50
web/modules/contrib/webform/js/webform.element.telephone.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for Telephone element.
|
||||
*/
|
||||
|
||||
(function ($, Drupal, drupalSettings) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Initialize Telephone international element.
|
||||
* @see http://intl-tel-input.com/node_modules/intl-tel-input/examples/gen/is-valid-number.html
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformTelephoneInternational = {
|
||||
attach: function (context) {
|
||||
$(context).find('input.js-webform-telephone-international').once('webform-telephone-international').each(function () {
|
||||
var $telephone = $(this);
|
||||
|
||||
// Add error message container.
|
||||
var $error = $('<div class="form-item--error-message">' + Drupal.t('Invalid phone number') + '</div>').hide();
|
||||
$telephone.closest('.form-item').append($error);
|
||||
|
||||
// @todo: Figure out how to lazy load utilsScript (build/js/utils.js).
|
||||
// @see https://github.com/jackocnr/intl-tel-input#utilities-script
|
||||
$telephone.intlTelInput({
|
||||
'nationalMode': false
|
||||
});
|
||||
|
||||
var reset = function() {
|
||||
$telephone.removeClass('error');
|
||||
$error.hide();
|
||||
};
|
||||
|
||||
$telephone.blur(function() {
|
||||
reset();
|
||||
if ($.trim($telephone.val())) {
|
||||
if (!$telephone.intlTelInput('isValidNumber')) {
|
||||
$telephone.addClass('error');
|
||||
$error.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$telephone.on('keyup change', reset);
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal, drupalSettings);
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for Text format integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Enhance text format element.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformTextFormat = {
|
||||
attach: function (context) {
|
||||
$(context).find('.js-text-format-wrapper textarea').once('webform-text-format').each(function () {
|
||||
var $textarea = $(this);
|
||||
if (!window.CKEDITOR) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the CKEDITOR when the textarea's value has changed.
|
||||
// @see webform.states.js
|
||||
$textarea.on('change', function () {
|
||||
if (CKEDITOR.instances[$textarea.attr('id')]) {
|
||||
var editor = CKEDITOR.instances[$textarea.attr('id')];
|
||||
editor.setData($textarea.val());
|
||||
}
|
||||
});
|
||||
|
||||
// Set CKEDITOR to be readonly when the textarea is disabled.
|
||||
// @see webform.states.js
|
||||
$textarea.on('webform:disabled', function () {
|
||||
if (CKEDITOR.instances[$textarea.attr('id')]) {
|
||||
var editor = CKEDITOR.instances[$textarea.attr('id')];
|
||||
editor.setReadOnly($textarea.is(':disabled'));
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
57
web/modules/contrib/webform/js/webform.element.time.js
Normal file
57
web/modules/contrib/webform/js/webform.element.time.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for time integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Attach timepicker fallback on time elements.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches the behavior to time elements.
|
||||
*/
|
||||
Drupal.behaviors.webformTime = {
|
||||
attach: function (context, settings) {
|
||||
var $context = $(context);
|
||||
// Skip if time inputs are supported by the browser.
|
||||
if (Modernizr.inputtypes.time === true) {
|
||||
return;
|
||||
}
|
||||
$context.find('input[type="time"]').once('timePicker').each(function () {
|
||||
var $input = $(this);
|
||||
|
||||
var options = {};
|
||||
if ($input.data('webformTimeFormat')) {
|
||||
options.timeFormat = $input.data('webformTimeFormat');
|
||||
}
|
||||
if ($input.attr('min')) {
|
||||
options.minTime = $input.attr('min');
|
||||
}
|
||||
if ($input.attr('max')) {
|
||||
options.maxTime = $input.attr('max');
|
||||
}
|
||||
|
||||
// HTML5 time element steps is in seconds but for the timepicker
|
||||
// fallback it needs to be in minutes.
|
||||
// Note: The 'datetime' element uses the #date_increment which defaults
|
||||
// to 1 (second).
|
||||
// @see \Drupal\Core\Datetime\Element\Datetime::processDatetime
|
||||
// Only use step if it is greater than 60 seconds.
|
||||
if ($input.attr('step') && ($input.attr('step') > 60)) {
|
||||
options.step = Math.round($input.attr('step') / 60);
|
||||
}
|
||||
else {
|
||||
options.step = 1;
|
||||
}
|
||||
|
||||
$input.timepicker(options);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
})(jQuery, Drupal);
|
56
web/modules/contrib/webform/js/webform.element.toggle.js
Normal file
56
web/modules/contrib/webform/js/webform.element.toggle.js
Normal file
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for toggle integration.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Initialize toggle element using Toggles.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformToggle = {
|
||||
attach: function (context) {
|
||||
$(context).find('.js-webform-toggle').once('webform-toggle').each(function () {
|
||||
var $toggle = $(this);
|
||||
var $wrapper = $toggle.parent();
|
||||
var $checkbox = $wrapper.find('input[type="checkbox"]');
|
||||
var $label = $wrapper.find('label');
|
||||
|
||||
$toggle.toggles({
|
||||
checkbox: $checkbox,
|
||||
on: $checkbox.is(':checked'),
|
||||
clicker: $label,
|
||||
text: {
|
||||
on: $toggle.attr('data-toggle-text-on') || '',
|
||||
off: $toggle.attr('data-toggle-text-off') || ''
|
||||
}
|
||||
});
|
||||
|
||||
// If checkbox is disabled then add the .disabled class to the toggle.
|
||||
if ($checkbox.attr('disabled') || $checkbox.attr('readonly')) {
|
||||
$toggle.addClass('disabled');
|
||||
}
|
||||
|
||||
// Add .clearfix to the wrapper.
|
||||
$wrapper.addClass('clearfix')
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Track the disabling of a toggle's checkbox using states.
|
||||
$(document).on('state:disabled', function (event) {
|
||||
$('.js-webform-toggle').each(function () {
|
||||
var $toggle = $(this);
|
||||
var $wrapper = $toggle.parent();
|
||||
var $checkbox = $wrapper.find('input[type="checkbox"]');
|
||||
var isDisabled = ($checkbox.attr('disabled') || $checkbox.attr('readonly'));
|
||||
(isDisabled) ? $toggle.addClass('disabled') : $toggle.removeClass('disabled');
|
||||
});
|
||||
});
|
||||
|
||||
})(jQuery, Drupal);
|
10
web/modules/contrib/webform/js/webform.form.disable_back.js
Normal file
10
web/modules/contrib/webform/js/webform.form.disable_back.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript to disable back button.
|
||||
*/
|
||||
|
||||
// From: http://stackoverflow.com/questions/17962130/restrict-user-to-refresh-and-back-forward-in-any-browser
|
||||
history.pushState({ page: 1 }, "Title 1", "#no-back");
|
||||
window.onhashchange = function (event) {
|
||||
window.location.hash = "no-back";
|
||||
};
|
141
web/modules/contrib/webform/js/webform.form.js
Normal file
141
web/modules/contrib/webform/js/webform.form.js
Normal file
|
@ -0,0 +1,141 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for webforms.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Autofocus first input.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches the behavior for the webform autofocusing.
|
||||
*/
|
||||
Drupal.behaviors.webformAutofocus = {
|
||||
attach: function (context) {
|
||||
$(context).find('.webform-submission-form.js-webform-autofocus :input:visible:enabled:first').focus();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Prevent webform autosubmit on wizard pages.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches the behavior for disabling webform autosubmit.
|
||||
*/
|
||||
Drupal.behaviors.webformDisableAutoSubmit = {
|
||||
attach: function (context) {
|
||||
// @see http://stackoverflow.com/questions/11235622/jquery-disable-form-submit-on-enter
|
||||
$(context).find('.webform-submission-form.js-webform-disable-autosubmit input').once('webform-disable-autosubmit').on('keyup keypress', function (e) {
|
||||
var keyCode = e.keyCode || e.which;
|
||||
if (keyCode === 13) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Skip client-side validation when submit button is pressed.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches the behavior for the skipping client-side validation.
|
||||
*/
|
||||
Drupal.behaviors.webformSubmitNoValidate = {
|
||||
attach: function (context) {
|
||||
$(context).find('input:submit.js-webform-novalidate').once('webform-novalidate').on('click', function () {
|
||||
$(this.form).attr('novalidate', 'novalidate');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable validate when save draft submit button is clicked.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches the behavior for the webform draft submit button.
|
||||
*/
|
||||
Drupal.behaviors.webformDraft = {
|
||||
attach: function (context) {
|
||||
$(context).find('#edit-draft').once('webform-draft').on('click', function () {
|
||||
$(this.form).attr('novalidate', 'novalidate');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Filters the webform element list by a text input search string.
|
||||
*
|
||||
* The text input will have the selector `input.webform-form-filter-text`.
|
||||
*
|
||||
* The target element to do searching in will be in the selector
|
||||
* `input.webform-form-filter-text[data-element]`
|
||||
*
|
||||
* The text source where the text should be found will have the selector
|
||||
* `.webform-form-filter-text-source`
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches the behavior for the webform element filtering.
|
||||
*/
|
||||
Drupal.behaviors.webformFilterByText = {
|
||||
attach: function (context, settings) {
|
||||
var $input = $('input.webform-form-filter-text').once('webform-form-filter-text');
|
||||
var $table = $($input.attr('data-element'));
|
||||
var $filter_rows;
|
||||
|
||||
/**
|
||||
* Filters the webform element list.
|
||||
*
|
||||
* @param {jQuery.Event} e
|
||||
* The jQuery event for the keyup event that triggered the filter.
|
||||
*/
|
||||
function filterElementList(e) {
|
||||
var query = $(e.target).val().toLowerCase();
|
||||
|
||||
/**
|
||||
* Shows or hides the webform element entry based on the query.
|
||||
*
|
||||
* @param {number} index
|
||||
* The index in the loop, as provided by `jQuery.each`
|
||||
* @param {HTMLElement} label
|
||||
* The label of the webform.
|
||||
*/
|
||||
function toggleEntry(index, label) {
|
||||
var $label = $(label);
|
||||
var $row = $label.parent().parent();
|
||||
var textMatch = $label.text().toLowerCase().indexOf(query) !== -1;
|
||||
$row.toggle(textMatch);
|
||||
}
|
||||
|
||||
// Filter if the length of the query is at least 2 characters.
|
||||
if (query.length >= 2) {
|
||||
$filter_rows.each(toggleEntry);
|
||||
}
|
||||
else {
|
||||
$filter_rows.each(function (index) {
|
||||
$(this).parent().parent().show();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ($table.length) {
|
||||
$filter_rows = $table.find('div.webform-form-filter-text-source');
|
||||
$input.on('keyup', filterElementList);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
53
web/modules/contrib/webform/js/webform.form.submit_once.js
Normal file
53
web/modules/contrib/webform/js/webform.form.submit_once.js
Normal file
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for preventing duplicate webform submissions.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Submit once.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches the behavior for preventing duplicate webform submissions.
|
||||
*/
|
||||
Drupal.behaviors.webformSubmitOnce = {
|
||||
attach: function (context) {
|
||||
$('.js-webform-submit-once', context).each(function () {
|
||||
var $form = $(this);
|
||||
$form.removeAttr('webform-submitted');
|
||||
$form.find('#edit-actions input[type="submit"]').removeAttr('webform-clicked');
|
||||
|
||||
// Track which submit button was clicked.
|
||||
// @see http://stackoverflow.com/questions/5721724/jquery-how-to-get-which-button-was-clicked-upon-form-submission
|
||||
$form.find('#edit-actions input[type="submit"]').click(function () {
|
||||
$form.find('#edit-actions input[type="submit"]').removeAttr('webform-clicked');
|
||||
$(this).attr('webform-clicked', 'true');
|
||||
});
|
||||
|
||||
$(this).submit(function () {
|
||||
// Track webform submitted.
|
||||
if ($form.attr('webform-submitted')) {
|
||||
return false;
|
||||
}
|
||||
$form.attr('webform-submitted', 'true');
|
||||
|
||||
// Visually disable all submit buttons.
|
||||
// Submit buttons can't disabled because their op(eration) must to be posted back to the server.
|
||||
$form.find('#edit-actions input[type="submit"]').addClass('is-disabled');
|
||||
|
||||
// Set the throbber progress indicator.
|
||||
// @see Drupal.Ajax.prototype.setProgressIndicatorThrobber
|
||||
var $clickedButton = $form.find('#edit-actions input[type=submit][webform-clicked=true]');
|
||||
var $progress = $('<div class="ajax-progress ajax-progress-throbber"><div class="throbber"> </div></div>');
|
||||
$clickedButton.after($progress);
|
||||
});
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
75
web/modules/contrib/webform/js/webform.form.unsaved.js
Normal file
75
web/modules/contrib/webform/js/webform.form.unsaved.js
Normal file
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for unsaved webforms.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var unsaved = false;
|
||||
|
||||
/**
|
||||
* Unsaved changes.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches the behavior for unsaved changes.
|
||||
*/
|
||||
Drupal.behaviors.webformUnsaved = {
|
||||
attach: function (context) {
|
||||
// Look for the 'data-webform-unsaved' attribute which indicates that the
|
||||
// multi-step webform has unsaved data.
|
||||
// @see \Drupal\webform\WebformSubmissionForm::buildForm
|
||||
if ($('.js-webform-unsaved[data-webform-unsaved]').length) {
|
||||
unsaved = true;
|
||||
}
|
||||
else {
|
||||
$('.js-webform-unsaved :input:not(input[type=\'submit\'])', context).once('webform-unsaved').on('change keypress', function () {
|
||||
unsaved = true;
|
||||
});
|
||||
}
|
||||
|
||||
$('.js-webform-unsaved button, .js-webform-unsaved input[type=\'submit\']', context).once('webform-unsaved').on('click', function () {
|
||||
unsaved = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$(window).on('beforeunload', function () {
|
||||
if (unsaved) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
/*!
|
||||
* An experimental shim to partially emulate onBeforeUnload on iOS.
|
||||
* Part of https://github.com/codedance/jquery.AreYouSure/
|
||||
*
|
||||
* Copyright (c) 2012-2014, Chris Dance and PaperCut Software http://www.papercut.com/
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* Author: chris.dance@papercut.com
|
||||
* Date: 19th May 2014
|
||||
*/
|
||||
$(function () {
|
||||
if (!navigator.userAgent.toLowerCase().match(/iphone|ipad|ipod|opera/)) {
|
||||
return;
|
||||
}
|
||||
$('a').bind('click', function (evt) {
|
||||
var href = $(evt.target).closest('a').attr('href');
|
||||
if (href !== undefined && !(href.match(/^#/) || href.trim() == '')) {
|
||||
if ($(window).triggerHandler('beforeunload')) {
|
||||
if (!confirm(Drupal.t('Changes you made may not be saved.') + '\n\n' + Drupal.t('Press OK to leave this page or Cancel to stay.'))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
window.location.href = href;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
})(jQuery, Drupal);
|
60
web/modules/contrib/webform/js/webform.help.js
Normal file
60
web/modules/contrib/webform/js/webform.help.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for help.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Handles help accordion.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches the behavior for help accordion.
|
||||
*/
|
||||
Drupal.behaviors.webformHelpAccordion = {
|
||||
attach: function (context) {
|
||||
var $widget = $(context).find('.webform-help-accordion');
|
||||
$widget.once('webform-help-accordion').accordion({
|
||||
collapsible: true,
|
||||
heightStyle: "content"
|
||||
});
|
||||
|
||||
var $container = $('h3' + location.hash, $widget);
|
||||
if ($container.length) {
|
||||
var active = $widget.find($widget.accordion('option', 'header')).index($container);
|
||||
$widget.accordion('option', 'active', active);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles disabling help dialog for mobile devices.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches the behavior for disabling help dialog for mobile devices.
|
||||
*/
|
||||
Drupal.behaviors.webformHelpDialog = {
|
||||
attach: function (context) {
|
||||
$(context).find('.button-webform-play').once('webform-help-dialog').on('click', function (event) {
|
||||
if ($(window).width() < 768) {
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
}).each(function () {
|
||||
// Must make sure that this click event handler is execute first and
|
||||
// before the AJAX dialog handler.
|
||||
// @see http://stackoverflow.com/questions/2360655/jquery-event-handlers-always-execute-in-order-they-were-bound-any-way-around-t
|
||||
var handlers = $._data(this, 'events')['click'];
|
||||
var handler = handlers.pop();
|
||||
// Move it at the beginning.
|
||||
handlers.splice(0, 0, handler);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
172
web/modules/contrib/webform/js/webform.states.js
Normal file
172
web/modules/contrib/webform/js/webform.states.js
Normal file
|
@ -0,0 +1,172 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for custom webform #states.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
// Make absolutely sure the below event handlers are triggered after
|
||||
// the /core/misc/states.js event handlers by attaching them after DOM load.
|
||||
$(function () {
|
||||
var $document = $(document);
|
||||
$document.on('state:visible', function (e) {
|
||||
if (!e.trigger) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!e.value) {
|
||||
// @see https://www.sitepoint.com/jquery-function-clear-form-data/
|
||||
$(':input', e.target).andSelf().each(function () {
|
||||
var $input = $(this);
|
||||
backupValueAndRequired(this);
|
||||
clearValueAndRequired(this);
|
||||
triggerEventHandlers(this);
|
||||
});
|
||||
}
|
||||
else {
|
||||
$(':input', e.target).andSelf().each(function () {
|
||||
restoreValueAndRequired(this);
|
||||
triggerEventHandlers(this);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$document.on('state:disabled', function (e) {
|
||||
if (e.trigger) {
|
||||
$(e.target).trigger('webform:disabled')
|
||||
.find('select, input, textarea').trigger('webform:disabled');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Trigger an input's event handlers.
|
||||
*
|
||||
* @param input
|
||||
* An input.
|
||||
*/
|
||||
function triggerEventHandlers(input) {
|
||||
var $input = $(input);
|
||||
var type = input.type;
|
||||
var tag = input.tagName.toLowerCase(); // Normalize case.
|
||||
if (type == 'checkbox' || type == 'radio') {
|
||||
$input
|
||||
.trigger('change')
|
||||
.trigger('blur');
|
||||
}
|
||||
else if (tag == 'select') {
|
||||
$input
|
||||
.trigger('change')
|
||||
.trigger('blur');
|
||||
}
|
||||
else if (type != 'submit' && type != 'button') {
|
||||
$input
|
||||
.trigger('input')
|
||||
.trigger('change')
|
||||
.trigger('keydown')
|
||||
.trigger('keyup')
|
||||
.trigger('blur');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Backup an input's current value and required attribute
|
||||
*
|
||||
* @param 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.data('webform-require', true);
|
||||
}
|
||||
|
||||
// Backup 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 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) {
|
||||
$input.find("option[value='" + option_value + "']").prop("selected", true);
|
||||
});
|
||||
}
|
||||
else if (type != 'submit' && type != 'button') {
|
||||
input.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore required.
|
||||
if ($input.data('webform-required')) {
|
||||
$input.prop('required', TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear an input's value and required attributes.
|
||||
*
|
||||
* @param input
|
||||
* An input.
|
||||
*/
|
||||
function clearValueAndRequired(input) {
|
||||
var $input = $(input);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
})(jQuery, Drupal);
|
46
web/modules/contrib/webform/js/webform.tooltip.js
Normal file
46
web/modules/contrib/webform/js/webform.tooltip.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* @file
|
||||
* Javascript behaviors for jQuery UI tooltip integration.
|
||||
*
|
||||
* Please Note:
|
||||
* jQuery UI's tooltip implementation is not very responsive or adaptive.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2207383
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Initialize jQuery UI tooltip element support.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformTooltipElement = {
|
||||
attach: function (context) {
|
||||
$(context).find('.js-webform-tooltip-element').once('webform-tooltip-element').each(function () {
|
||||
var $element = $(this);
|
||||
var $description = $element.children('.description.visually-hidden');
|
||||
$element.tooltip({
|
||||
items: ':input',
|
||||
content: $description.html()
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize jQuery UI tooltip link support.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*/
|
||||
Drupal.behaviors.webformTooltipLink = {
|
||||
attach: function (context) {
|
||||
$(context).find('a.js-webform-tooltip-link').once('webform-tooltip-link').each(function () {
|
||||
$(this).tooltip();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
Reference in a new issue