forms: execute javascript behaviour enhancements on added block rows (#52066)

This commit is contained in:
Frédéric Péters 2021-03-15 21:17:01 +01:00
parent 4e205acbe1
commit e0f4755d3c
1 changed files with 171 additions and 161 deletions

View File

@ -153,6 +153,7 @@ $(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.
@ -161,75 +162,181 @@ $(function() {
var well_known_domains = WCS_WELL_KNOWN_DOMAINS;
var known_domains = WCS_VALID_KNOWN_DOMAINS;
}
$('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) {
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"><span class="message"></span><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('span').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();
}
return;
}
});
$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);
});
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;
/* 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;
}
}
if (highest_ratio > 0.80 && highest_ratio < 1) {
if ($domain_hint_div === undefined) {
$domain_hint_div = $('<div class="field-live-hint"><span class="message"></span><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;
});
$(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; }
}
};
if (!required) {
options.placeholder = '...';
options.allowClear = true;
}
$domain_hint_div.find('span').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();
}
});
$('.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);
});
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: 10};
},
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 text = $(elem).find(':selected').first().text();
$input_display_value.val(text);
});
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());
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_js_behaviours($('form[data-live-url]'));
// Form with error
const first_widget_with_error = document.querySelector('.widget-with-error');
if (first_widget_with_error) {
@ -395,104 +502,6 @@ $(function() {
$(this).closest('div.widget').removeClass('widget-prefilled');
});
/* searchable select */
$('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 */
$('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; }
}
};
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: 10};
},
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 text = $(elem).find(':selected').first().text();
$input_display_value.val(text);
});
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());
select2.val($(elem).data('value')).trigger('change');
$(elem).select2('data', {id: $(elem).data('value'), text: $(elem).data('initial-display-value')});
}
});
/* Make table widgets responsive */
$('.TableWidget, .SingleSelectTableWidget, .TableListRowsWidget').each(function (i, elem) {
const table = elem.querySelector('table');
new Responsive_table_widget(table);
});
function disable_single_block_remove_button() {
$('.BlockSubWidget button.remove-button').each(function(i, elem) {
@ -532,6 +541,7 @@ $(function() {
success: function(result, text_status, jqXHR) {
result = $(result);
$block.replaceWith(result.find('[data-field-id="' + block_id + '"]'));
add_js_behaviours($('[data-field-id="' + block_id + '"]'));
}
});
});