757 lines
29 KiB
JavaScript
757 lines
29 KiB
JavaScript
String.prototype.similarity = function(string) {
|
|
// adapted from https://github.com/jordanthomas/jaro-winkler (licensed as MIT)
|
|
var s1 = this, s2 = string;
|
|
var m = 0;
|
|
var i;
|
|
var j;
|
|
|
|
// Exit early if either are empty.
|
|
if (s1.length === 0 || s2.length === 0) {
|
|
return 0;
|
|
}
|
|
|
|
// Convert to upper
|
|
s1 = s1.toUpperCase();
|
|
s2 = s2.toUpperCase();
|
|
|
|
// Exit early if they're an exact match.
|
|
if (s1 === s2) {
|
|
return 1;
|
|
}
|
|
|
|
var range = (Math.floor(Math.max(s1.length, s2.length) / 2)) - 1;
|
|
var s1Matches = new Array(s1.length);
|
|
var s2Matches = new Array(s2.length);
|
|
|
|
for (i = 0; i < s1.length; i++) {
|
|
var low = (i >= range) ? i - range : 0;
|
|
var high = (i + range <= (s2.length - 1)) ? (i + range) : (s2.length - 1);
|
|
|
|
for (j = low; j <= high; j++) {
|
|
if (s1Matches[i] !== true && s2Matches[j] !== true && s1[i] === s2[j]) {
|
|
++m;
|
|
s1Matches[i] = s2Matches[j] = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Exit early if no matches were found.
|
|
if (m === 0) {
|
|
return 0;
|
|
}
|
|
|
|
// Count the transpositions.
|
|
var k = 0;
|
|
var numTrans = 0;
|
|
|
|
for (i = 0; i < s1.length; i++) {
|
|
if (s1Matches[i] === true) {
|
|
for (j = k; j < s2.length; j++) {
|
|
if (s2Matches[j] === true) {
|
|
k = j + 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (s1[i] !== s2[j]) {
|
|
++numTrans;
|
|
}
|
|
}
|
|
}
|
|
|
|
var weight = (m / s1.length + m / s2.length + (m - (numTrans / 2)) / m) / 3;
|
|
var l = 0;
|
|
var p = 0.1;
|
|
|
|
if (weight > 0.7) {
|
|
while (s1[l] === s2[l] && l < 4) {
|
|
++l;
|
|
}
|
|
|
|
weight = weight + l * p * (1 - weight);
|
|
}
|
|
|
|
return weight;
|
|
}
|
|
|
|
/* Make table widget responsive
|
|
* new Responsive_table_widget(table)
|
|
*/
|
|
const Responsive_table_widget = function (table) {
|
|
'use strict';
|
|
this.table = table;
|
|
this.col_headers = table.querySelectorAll('thead th');
|
|
this.col_headers_text = [];
|
|
this.body_rows = table.querySelectorAll('tbody tr');
|
|
this.parent = table.parentElement;
|
|
this.init();
|
|
};
|
|
Responsive_table_widget.prototype.storeHeaders = function () {
|
|
'use strict';
|
|
let _self = this;
|
|
$(this.col_headers).each(function (i, header) {
|
|
_self.col_headers_text.push(header.innerText);
|
|
});
|
|
$(this.body_rows).each(function (i, tr) {
|
|
$(tr.querySelectorAll('td')).each(function (i, td) {
|
|
td.dataset.colHeader = _self.col_headers_text[i];
|
|
});
|
|
});
|
|
};
|
|
Responsive_table_widget.prototype.fit = function () {
|
|
'use strict';
|
|
if (this.parent.clientWidth < this.table.clientWidth) {
|
|
this.table.style.width = "100%";
|
|
} else if (! $(this.parent).parent().is('[class*=" grid-"]')) {
|
|
this.table.style.width = "auto";
|
|
}
|
|
};
|
|
Responsive_table_widget.prototype.init = function () {
|
|
'use strict';
|
|
let _self = this;
|
|
this.table.classList.add('responsive-tableWidget');
|
|
this.storeHeaders();
|
|
this.fit();
|
|
// debounce resize event
|
|
let callback;
|
|
window.addEventListener("resize", function () {
|
|
clearTimeout(callback);
|
|
callback = setTimeout( function () {
|
|
_self.fit.call(_self)
|
|
}, 200);
|
|
});
|
|
};
|
|
|
|
$(function() {
|
|
$('.section.foldable > h2 [role=button]').each(function() {
|
|
$(this).attr('tabindex', '0');
|
|
});
|
|
$('.section.foldable > h2 [role=button]').on('keydown', function(ev) {
|
|
if (ev.keyCode == 13 || ev.keyCode == 32) { // enter || space
|
|
$(this).trigger('click');
|
|
return false;
|
|
}
|
|
});
|
|
$('.section.foldable > h2').off('click').click(function() {
|
|
var folded = $(this).parent().hasClass('folded');
|
|
var $button = $(this).find('[role=button]').first();
|
|
if ($button.length) {
|
|
$button[0].setAttribute('aria-expanded', `${folded}`);
|
|
}
|
|
$(this).parent().toggleClass('folded');
|
|
$(this).parent().find('.qommon-map').trigger('qommon:invalidate');
|
|
});
|
|
|
|
var autosave_timeout_id = null;
|
|
var autosave_is_running = false;
|
|
var autosave_button_to_click_on_complete = null;
|
|
|
|
if ($('form[data-has-draft]:not([data-autosave=false])').length == 1) {
|
|
var last_auto_save = $('form[data-has-draft]').serialize();
|
|
var error_counter = 0;
|
|
function autosave() {
|
|
var $form = $('form[data-has-draft]');
|
|
if ($form.hasClass('disabled-during-submit')) return;
|
|
var new_auto_save = $form.serialize();
|
|
if (last_auto_save == new_auto_save) {
|
|
install_autosave();
|
|
return;
|
|
}
|
|
autosave_is_running = true;
|
|
$.ajax({
|
|
type: 'POST',
|
|
url: window.location.pathname + 'autosave',
|
|
data: new_auto_save,
|
|
success: function(json) {
|
|
if (json.result == 'success') {
|
|
error_counter = -1;
|
|
last_auto_save = new_auto_save;
|
|
}
|
|
},
|
|
complete: function() {
|
|
error_counter++;
|
|
if (error_counter > 5) {
|
|
// stop trying to autosave unless there are new changes
|
|
last_auto_save = new_auto_save;
|
|
}
|
|
autosave_is_running = false;
|
|
if (autosave_timeout_id !== null) {
|
|
install_autosave();
|
|
}
|
|
if (autosave_button_to_click_on_complete !== null) {
|
|
autosave_button_to_click_on_complete.click();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function install_autosave() {
|
|
// debounce
|
|
window.clearTimeout(autosave_timeout_id);
|
|
autosave_timeout_id = window.setTimeout(autosave, 5000);
|
|
}
|
|
|
|
$(document).on('mouseover scroll keydown', function() {
|
|
if (autosave_timeout_id !== null && ! autosave_is_running) {
|
|
install_autosave();
|
|
}
|
|
});
|
|
|
|
$(window).on('pagehide', function () {
|
|
if (autosave_timeout_id !== null && ! $('body').hasClass('autosaving')) {
|
|
window.clearTimeout(autosave_timeout_id);
|
|
autosave_timeout_id = null;
|
|
autosave();
|
|
}
|
|
});
|
|
|
|
$(document).on('visibilitychange', function () {
|
|
if (document.visibilityState == 'hidden' && autosave_timeout_id !== null && ! $('body').hasClass('autosaving')) {
|
|
window.clearTimeout(autosave_timeout_id);
|
|
autosave_timeout_id = null;
|
|
autosave();
|
|
}
|
|
});
|
|
|
|
install_autosave();
|
|
|
|
$('#tracking-code a').on('click', autosave);
|
|
$(document).on('wcs:set-last-auto-save', function() {
|
|
last_auto_save = $('form[data-has-draft]').serialize();
|
|
});
|
|
}
|
|
|
|
// common domains we want to offer suggestions for.
|
|
var well_known_domains = Array();
|
|
// existing domains we know but don't want to use in suggestion engine.
|
|
var known_domains = Array();
|
|
if (typeof WCS_WELL_KNOWN_DOMAINS !== 'undefined') {
|
|
var well_known_domains = WCS_WELL_KNOWN_DOMAINS;
|
|
var known_domains = WCS_VALID_KNOWN_DOMAINS;
|
|
}
|
|
|
|
function add_js_behaviours($base) {
|
|
$base.find('input[type=email]').on('change wcs:change', function() {
|
|
var $email_input = $(this);
|
|
var val = $email_input.val();
|
|
var val_domain = val.split('@')[1];
|
|
var $domain_hint_div = this.domain_hint_div;
|
|
var highest_ratio = 0;
|
|
var suggestion = null;
|
|
|
|
if (typeof val_domain === 'undefined' || known_domains.indexOf(val_domain) > -1) {
|
|
// domain not yet typed in, or known domain, don't suggest anything.
|
|
if ($domain_hint_div) {
|
|
$domain_hint_div.hide();
|
|
}
|
|
return;
|
|
}
|
|
|
|
for (var i=0; i < well_known_domains.length; i++) {
|
|
var domain = well_known_domains[i];
|
|
var ratio = val_domain.similarity(domain);
|
|
if (ratio > highest_ratio) {
|
|
highest_ratio = ratio;
|
|
suggestion = domain;
|
|
}
|
|
}
|
|
if (highest_ratio > 0.80 && highest_ratio < 1) {
|
|
if ($domain_hint_div === undefined) {
|
|
$domain_hint_div = $('<div class="field-live-hint"><p class="message"></p><button type="button" class="action"></button><button type="button" class="close"><span class="sr-only"></span></button></div>');
|
|
this.domain_hint_div = $domain_hint_div;
|
|
$(this).after($domain_hint_div);
|
|
$domain_hint_div.find('button.action').on('click', function() {
|
|
$email_input.val($email_input.val().replace(/@.*/, '@' + $(this).data('suggestion')));
|
|
$email_input.trigger('wcs:change');
|
|
$domain_hint_div.hide();
|
|
return false;
|
|
});
|
|
$domain_hint_div.find('button.close').on('click', function() {
|
|
$domain_hint_div.hide();
|
|
return false;
|
|
});
|
|
}
|
|
$domain_hint_div.find('p').text(WCS_I18N.email_domain_suggest + ' @' + suggestion + ' ?');
|
|
$domain_hint_div.find('button.action').text(WCS_I18N.email_domain_fix);
|
|
$domain_hint_div.find('button.action').data('suggestion', suggestion);
|
|
$domain_hint_div.find('button.close span.sr-only').text(WCS_I18N.close);
|
|
$domain_hint_div.show();
|
|
} else if ($domain_hint_div) {
|
|
$domain_hint_div.hide();
|
|
}
|
|
});
|
|
$base.find('.date-pick').each(function() {
|
|
if (this.type == "date" || this.type == "time") {
|
|
return; // prefer native date/time widgets
|
|
}
|
|
var $date_input = $(this);
|
|
$date_input.attr('type', 'text');
|
|
if ($date_input.data('formatted-value')) {
|
|
$date_input.val($date_input.data('formatted-value'));
|
|
}
|
|
var options = Object();
|
|
options.autoclose = true;
|
|
options.weekStart = 1;
|
|
options.format = $date_input.data('date-format');
|
|
options.minView = $date_input.data('min-view');
|
|
options.maxView = $date_input.data('max-view');
|
|
options.startView = $date_input.data('start-view');
|
|
if ($date_input.data('start-date')) options.startDate = $date_input.data('start-date');
|
|
if ($date_input.data('end-date')) options.endDate = $date_input.data('end-date');
|
|
$date_input.datetimepicker(options);
|
|
});
|
|
|
|
/* searchable select */
|
|
$base.find('select[data-autocomplete]').each(function(i, elem) {
|
|
var required = $(elem).data('required');
|
|
var options = {
|
|
language: {
|
|
errorLoading: function() { return WCS_I18N.s2_errorloading; },
|
|
noResults: function () { return WCS_I18N.s2_nomatches; },
|
|
inputTooShort: function (input, min) { return WCS_I18N.s2_tooshort; },
|
|
loadingMore: function () { return WCS_I18N.s2_loadmore; },
|
|
searching: function () { return WCS_I18N.s2_searching; }
|
|
}
|
|
};
|
|
options.placeholder = $(elem).find('[data-hint]').data('hint');
|
|
if (!required) {
|
|
if (!options.placeholder) options.placeholder = '...';
|
|
options.allowClear = true;
|
|
}
|
|
$(elem).select2(options);
|
|
});
|
|
|
|
/* searchable select using a data source */
|
|
$base.find('select[data-select2-url]').each(function(i, elem) {
|
|
var required = $(elem).data('required');
|
|
// create an additional hidden field to hold the label of the selected
|
|
// option, it is necessary as the server may not have any knowledge of
|
|
// possible options.
|
|
var $input_display_value = $('<input>', {
|
|
type: 'hidden',
|
|
name: $(elem).attr('name') + '_display',
|
|
value: $(elem).data('initial-display-value')
|
|
});
|
|
$input_display_value.insertAfter($(elem));
|
|
var options = {
|
|
minimumInputLength: 1,
|
|
formatResult: function(result) { return result.text; },
|
|
language: {
|
|
errorLoading: function() { return WCS_I18N.s2_errorloading; },
|
|
noResults: function () { return WCS_I18N.s2_nomatches; },
|
|
inputTooShort: function (input, min) { return WCS_I18N.s2_tooshort; },
|
|
loadingMore: function () { return WCS_I18N.s2_loadmore; },
|
|
searching: function () { return WCS_I18N.s2_searching; }
|
|
},
|
|
templateSelection: function(data, container) {
|
|
if (data.edit_related_url) {
|
|
$(data.element).attr('data-edit-related-url', data.edit_related_url);
|
|
}
|
|
return data.text;
|
|
}
|
|
};
|
|
if (!required) {
|
|
options.placeholder = '...';
|
|
options.allowClear = true;
|
|
}
|
|
var url = $(elem).data('select2-url');
|
|
if (url.indexOf('/api/autocomplete/') == 0) { // local proxying
|
|
var data_type = 'json';
|
|
} else {
|
|
var data_type = 'jsonp';
|
|
}
|
|
options.ajax = {
|
|
delay: 250,
|
|
dataType: data_type,
|
|
data: function(params) {
|
|
return {q: params.term, page_limit: 50};
|
|
},
|
|
processResults: function (data, params) {
|
|
return {results: data.data};
|
|
},
|
|
url: function() {
|
|
var url = $(elem).data('select2-url');
|
|
url = url.replace(/\[var_.+?\]/g, function(match, g1, g2) {
|
|
// compatibility: if there are [var_...] references in the URL
|
|
// replace them by looking for other select fields on the same
|
|
// page.
|
|
var related_select = $('#' + match.slice(1, -1));
|
|
var value_container_id = $(related_select).data('valuecontainerid');
|
|
return $('#' + value_container_id).val() || '';
|
|
});
|
|
return url;
|
|
}
|
|
};
|
|
var select2 = $(elem).select2(options);
|
|
$(elem).on('change', function() {
|
|
// update _display hidden field with selected text
|
|
var $selected = $(elem).find(':selected').first();
|
|
var text = $selected.text();
|
|
$input_display_value.val(text);
|
|
// update edit-related button href
|
|
$(elem).siblings('.edit-related').attr('href', '').hide();
|
|
if ($selected.attr('data-edit-related-url')) {
|
|
$(elem).siblings('.edit-related').attr('href', $selected.attr('data-edit-related-url') + '?_popup=1').show();
|
|
}
|
|
});
|
|
if ($input_display_value.val()) {
|
|
// if the _display hidden field was created with an initial value take it
|
|
// and create a matching <option> in the real <select> widget, and use it
|
|
// to set select2 initial state.
|
|
var option = $('<option></option>', {value: $(elem).data('value')});
|
|
option.appendTo($(elem));
|
|
option.text($input_display_value.val());
|
|
if ($(elem).data('initial-edit-related-url')) {
|
|
option.attr('data-edit-related-url', $(elem).data('initial-edit-related-url'));
|
|
}
|
|
select2.val($(elem).data('value')).trigger('change');
|
|
$(elem).select2('data', {id: $(elem).data('value'), text: $(elem).data('initial-display-value')});
|
|
}
|
|
});
|
|
|
|
/* Make table widgets responsive */
|
|
$base.find('.TableWidget, .SingleSelectTableWidget, .TableListRowsWidget').each(function (i, elem) {
|
|
const table = elem.querySelector('table');
|
|
new Responsive_table_widget(table);
|
|
});
|
|
|
|
/* Add class to reset error style on change */
|
|
$base.find('.widget-with-error').each(function(i, elem) {
|
|
$(elem).find('input, select, textarea').on('change', function() {
|
|
$(this).parents('.widget-with-error').addClass('widget-reset-error');
|
|
});
|
|
});
|
|
}
|
|
|
|
add_js_behaviours($('form[data-live-url], form[data-backoffice-preview]'));
|
|
|
|
// Form with error
|
|
const errornotice = document.querySelector('form:not([data-backoffice-preview]) .errornotice');
|
|
if (errornotice) {
|
|
document.body.classList.add('form-with-error');
|
|
errornotice.setAttribute('tabindex', '-1');
|
|
errornotice.focus();
|
|
}
|
|
|
|
$(window).bind('pageshow', function(event) {
|
|
$('form').removeClass('disabled-during-submit');
|
|
});
|
|
$('form button').on('click', function(event) {
|
|
if ($(this).hasClass('download')) {
|
|
$(this).parents('form').addClass('download-button-clicked');
|
|
} else {
|
|
$(this).parents('form').removeClass('download-button-clicked');
|
|
}
|
|
return true;
|
|
});
|
|
$('form .buttons.submit button').on('click', function (event) {
|
|
if (autosave_is_running) {
|
|
autosave_button_to_click_on_complete = event.target;
|
|
/* prevent more autosave */
|
|
autosave_timeout_id = null;
|
|
event.preventDefault();
|
|
}
|
|
});
|
|
$('form').on('submit', function(event) {
|
|
var $form = $(this);
|
|
/* prevent more autosave */
|
|
if (autosave_timeout_id !== null) {
|
|
window.clearTimeout(autosave_timeout_id);
|
|
autosave_timeout_id = null;
|
|
}
|
|
$form.addClass('disabled-during-submit');
|
|
if ($form.hasClass('download-button-clicked')) {
|
|
/* form cannot be disabled for download buttons as the user will stay on
|
|
* the same page; enable it back after a few seconds. */
|
|
setTimeout(function() { $form.removeClass('disabled-during-submit'); }, 3000);
|
|
}
|
|
if ($form[0].wait_for_changes) {
|
|
var waited = 0;
|
|
var $button = $(event.originalEvent.submitter);
|
|
if (! $button.is('button')) {
|
|
$button = $('form .buttons .submit-button button');
|
|
}
|
|
var wait_id = setInterval(function() {
|
|
waited += 1;
|
|
if (! $form[0].wait_for_changes) {
|
|
clearInterval(wait_id);
|
|
$button.click();
|
|
return;
|
|
} else if (waited > 5) {
|
|
$form[0].wait_for_changes = false;
|
|
}
|
|
}, 200);
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
var live_evaluation = null;
|
|
if ($('div[data-live-source]').length || $('.submit-user-selection').length) {
|
|
$('form[data-live-url]').on('wcs:change', function(ev, data) {
|
|
if (live_evaluation) {
|
|
live_evaluation.abort();
|
|
}
|
|
var new_data = $(this).serialize();
|
|
if (data && data.modified_field) {
|
|
new_data += '&modified_field_id=' + data.modified_field;
|
|
if (data.modified_block) new_data += '&modified_block_id=' + data.modified_block;
|
|
if (data.modified_block_row) new_data += '&modified_block_row=' + data.modified_block_row;
|
|
}
|
|
$('.widget-prefilled').each(function(idx, elem) {
|
|
new_data += '&prefilled_' + $(elem).data('field-id') + '=true';
|
|
});
|
|
var live_url = $(this).data('live-url');
|
|
live_evaluation = $.ajax({
|
|
type: 'POST',
|
|
url: live_url,
|
|
dataType: 'json',
|
|
data: new_data,
|
|
headers: {'accept': 'application/json'},
|
|
success: function(json) {
|
|
if (json.result === "error") {
|
|
console.log('error in /live request: ' + json.reason);
|
|
return;
|
|
}
|
|
$.each(json.result, function(key, value) {
|
|
if (value.block_id && value.block_row) {
|
|
var $widget = $('[data-field-id="' + value.block_id + '"] [data-block-row="' + value.block_row + '"] [data-field-id="' + value.field_id + '"]');
|
|
} else if (value.block_id) {
|
|
var $widget = $('[data-field-id="' + value.block_id + '"] [data-field-id="' + value.field_id + '"]');
|
|
} else {
|
|
var $widget = $('[data-field-id="' + key + '"]');
|
|
}
|
|
if (value.visible) {
|
|
var was_visible = $widget.is(':visible');
|
|
$widget.css('display', '');
|
|
if ($widget.hasClass('MapWidget') && !was_visible) {
|
|
$widget.find('.qommon-map').trigger('qommon:invalidate');
|
|
}
|
|
} else {
|
|
$widget.hide();
|
|
}
|
|
if (value.items && $widget.is('.RadiobuttonsWidget')) {
|
|
var current_value = $widget.find('input:checked').val();
|
|
var $hint = $widget.find('.hint').detach();
|
|
var input_name = $widget.data('widget-name');
|
|
var $content = $widget.find('.content');
|
|
var length_first_items = 0;
|
|
$content.empty();
|
|
for (var i=0; i<value.items.length; i++) {
|
|
var $label = $('<label></label>');
|
|
var $input = $('<input>', {type: 'radio', value: value.items[i].id, name: input_name});
|
|
if (value.items[i].id == current_value) {
|
|
$input.attr('checked', 'checked');
|
|
}
|
|
if (value.items[i].disabled) {
|
|
$input.prop('disabled', true);
|
|
$label.addClass('disabled');
|
|
}
|
|
var $span = $('<span></span>', {text: value.items[i].text});
|
|
$input.appendTo($label);
|
|
$span.appendTo($label);
|
|
$label.appendTo($content);
|
|
if (i < 3) {
|
|
length_first_items += value.items[i].text.length;
|
|
}
|
|
}
|
|
if (value.items.length <= 3 && length_first_items < 40) {
|
|
$widget.addClass('widget-inline-radio');
|
|
} else {
|
|
$widget.removeClass('widget-inline-radio');
|
|
}
|
|
$hint.appendTo($content);
|
|
} else if (value.items && $widget.is('.CheckboxesWidget')) {
|
|
var widget_name = $widget.data('widget-name');
|
|
var $ul = $widget.find('ul');
|
|
var current_value = $ul.find('input[type=checkbox]'
|
|
).filter(function() {return this.checked}
|
|
).map(function() {return this.name;}
|
|
).toArray();
|
|
var base_for_name = $ul.data('base-for-name');
|
|
var input_name = $widget.data('widget-name');
|
|
$ul.empty();
|
|
for (var i=0; i<value.items.length; i++) {
|
|
var $li = $('<li>');
|
|
var $label = $('<label>', {'for': base_for_name + i});
|
|
var $input = $('<input>', {
|
|
type: 'checkbox', 'id': base_for_name + i,
|
|
value: 'yes', name: widget_name + '$element' + value.items[i].id});
|
|
if (current_value.indexOf(widget_name + '$element' + value.items[i].id) != -1) {
|
|
$input.attr('checked', 'checked');
|
|
}
|
|
if (value.items[i].disabled) {
|
|
$input.prop('disabled', true);
|
|
$li.addClass('disabled');
|
|
}
|
|
var $span = $('<span>', {text: value.items[i].text});
|
|
$input.appendTo($label);
|
|
$span.appendTo($label);
|
|
$label.appendTo($li);
|
|
$li.appendTo($ul);
|
|
}
|
|
} else if (value.items) {
|
|
// replace <select> contents
|
|
var $select = $widget.find('select');
|
|
var current_value = $select.val();
|
|
var hint = $widget.find('option[data-hint]').data('hint');
|
|
$select.empty();
|
|
if (hint) {
|
|
var $option = $('<option></option>', {value: '', text: hint});
|
|
$option.attr('data-hint', hint);
|
|
$option.appendTo($select);
|
|
}
|
|
for (var i=0; i<value.items.length; i++) {
|
|
var $option = $('<option></option>', {value: value.items[i].id, text: value.items[i].text});
|
|
if ((Array.isArray(current_value) && current_value.indexOf(value.items[i].id.toString()) != -1) ||
|
|
value.items[i].id == current_value) {
|
|
$option.attr('selected', 'selected');
|
|
value.items[i].selected = true;
|
|
}
|
|
if (value.items[i].disabled) {
|
|
$option.prop('disabled', true);
|
|
}
|
|
$option.appendTo($select);
|
|
}
|
|
$select.trigger('wcs:options-change', {items: value.items});
|
|
}
|
|
if (typeof value.content !== 'undefined') {
|
|
$widget.each(function(idx, widget) {
|
|
if ($widget.hasClass('comment-field')) {
|
|
// replace comment content
|
|
$widget.html(value.content);
|
|
} else {
|
|
if ($(widget).is('.widget-prefilled') || $(widget).is('.widget-readonly') || data.modified_field == 'user') {
|
|
// replace text input value
|
|
$(widget).find('input[type=text], input[type=tel], input[type=numeric], input[type=email], input[type=date], textarea').val(value.content);
|
|
if ($(widget).is('.DateWidget')) {
|
|
// Set both hidden input for real value, and text input for
|
|
// formatted date. This will also set the old date picker
|
|
// to the formatted value, which is expected.
|
|
$(widget).find('input[type=hidden]').val(value.content);
|
|
$(widget).find('input[type=text]').val(value.text_content);
|
|
}
|
|
if ($widget.hasClass('CheckboxWidget')) {
|
|
// replace checkbox input value
|
|
$widget.find('input[type=checkbox]').prop('checked', value.content);
|
|
}
|
|
// replace select value
|
|
$(widget).find('select').val(value.content);
|
|
if ($.type(value.content) == 'string' && value.content.indexOf('"') == -1) {
|
|
// replace radio value
|
|
$(widget).find('input[type=radio]').prop('checked', false);
|
|
$(widget).find('input[type=radio][value="'+value.content+'"]').prop('checked', true);
|
|
}
|
|
if (data.modified_field == 'user' && value.locked) {
|
|
$(widget).addClass('widget-readonly');
|
|
$(widget).find('input').attr('readonly', 'readonly');
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
if (value.source_url) {
|
|
// json change of URL
|
|
$widget.find('[data-select2-url]').data('select2-url', value.source_url);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
if ($('div[data-live-source]').length) {
|
|
$('form').on('change input paste wcs:change',
|
|
'div[data-live-source] input:not([type=file]), div[data-live-source] select, div[data-live-source] textarea',
|
|
function(ev) {
|
|
var params = {};
|
|
params.modified_field = $(this).closest('[data-field-id]').data('field-id');
|
|
if ($(this).parents('.BlockWidget').length) {
|
|
params.modified_block = $(this).closest('.BlockWidget').data('field-id');
|
|
params.modified_block_row = $(this).closest('.BlockSubWidget').data('block-row');
|
|
}
|
|
$(this).parents('form').trigger('wcs:change', params);
|
|
});
|
|
}
|
|
$('form div[data-live-source]').parents('form').trigger('wcs:change', {modified_field: 'init'});
|
|
$('div.widget-prefilled').on('change input paste', function(ev) {
|
|
$(this).removeClass('widget-prefilled');
|
|
});
|
|
$('div.widget-prefilled input[type=radio], div.widget-prefilled input[type=checkbox]').on('change', function(ev) {
|
|
$(this).closest('div.widget').removeClass('widget-prefilled');
|
|
});
|
|
|
|
|
|
function disable_single_block_remove_button() {
|
|
$('.BlockSubWidget button.remove-button').each(function(i, elem) {
|
|
if ($(this).parents('.BlockWidget').find('.BlockSubWidget').length == 1) {
|
|
$(this).prop('disabled', true);
|
|
}
|
|
});
|
|
}
|
|
|
|
if ($('.BlockWidget').length) {
|
|
disable_single_block_remove_button();
|
|
$('form').on('click', '.BlockSubWidget button.remove-button', function() {
|
|
if ($(this).parents('.BlockWidget').find('.BlockSubWidget').length > 1) {
|
|
const $add_button = $(this).parents('.BlockWidget').find('.list-add');
|
|
/* rename attributes in following blocks */
|
|
const $subwidget = $(this).parents('.BlockSubWidget').first();
|
|
const name_parts = $subwidget.data('widget-name').match(/(.*)(\d+)$/);
|
|
const prefix = name_parts[1];
|
|
const idx = parseInt(name_parts[2]);
|
|
function replace_prefix(elem, prefix1, prefix2) {
|
|
$.each(elem.attributes, function() {
|
|
if (this.specified) {
|
|
this.value = this.value.replace(prefix1, prefix2);
|
|
}
|
|
});
|
|
}
|
|
$subwidget.nextAll('.BlockSubWidget').each(function(i, elem) {
|
|
const prefix1 = prefix + (idx + i + 1);
|
|
const prefix2 = prefix + (idx + i);
|
|
replace_prefix(elem, prefix1, prefix2);
|
|
$(elem).find('*').each(function(i, elem_child) { replace_prefix(elem_child, prefix1, prefix2); });
|
|
});
|
|
/* then remove row */
|
|
$subwidget.remove();
|
|
disable_single_block_remove_button();
|
|
/* display button then give it focus */
|
|
$add_button.show().find('button').focus();
|
|
}
|
|
return false;
|
|
});
|
|
|
|
$('form').on('click', 'div.BlockWidget .list-add button', function(ev) {
|
|
ev.preventDefault();
|
|
const $block = $(this).parents('.BlockWidget');
|
|
const block_id = $block.data('field-id');
|
|
const $button = $(this);
|
|
const $form = $(this).parents('form');
|
|
var form_data = $form.serialize();
|
|
form_data += '&' + $button.attr('name') + '=' + $button.val();
|
|
$.ajax({
|
|
type: 'POST',
|
|
url: $form.attr('action') || window.location.pathname,
|
|
data: form_data,
|
|
headers: {'x-wcs-ajax-action': 'block-add-row'},
|
|
success: function(result, text_status, jqXHR) {
|
|
const $new_block = $(result).find('[data-field-id="' + block_id + '"]');
|
|
$block.replaceWith($new_block);
|
|
const $new_blockrow = $new_block.find('.BlockSubWidget').last();
|
|
add_js_behaviours($('[data-field-id="' + block_id + '"]'));
|
|
$('form').trigger('wcs:block-row-added');
|
|
$(document).trigger('wcs:maps-init');
|
|
if ($new_block.find('[data-live-source]')) {
|
|
$('form div[data-live-source]').parents('form').trigger('wcs:change', {modified_field: 'init'});
|
|
}
|
|
$new_blockrow[0].setAttribute('tabindex', '-1');
|
|
$new_blockrow[0].focus();
|
|
if ($new_blockrow.position().top < window.scrollY) {
|
|
$new_blockrow[0].scrollIntoView({behavior: "instant", block: "center", inline: "nearest"});
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
});
|