Fix no-use-before-define eslint rule in ES5 files

[MAILPOET-1144]
This commit is contained in:
Pavel Dohnal
2017-11-29 15:17:30 +00:00
parent 159e946093
commit dc569672a9
5 changed files with 359 additions and 359 deletions

View File

@ -41,7 +41,6 @@
"no-throw-literal": 0,
"no-extra-bind": 0,
"brace-style": 0,
"no-use-before-define": 0,
"camelcase": 0,
"padded-blocks": 0,
"strict": 0,

View File

@ -11,6 +11,27 @@ var Observable;
var WysijaHistory;
var WysijaForm;
/* LOGGING */
function info(value) {
if (WysijaForm.options.debug === false) return;
if (!(window.console && console.log)) {
(function () {
var noop = function () {};
var methods = ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'markTimeline', 'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'];
var length = methods.length;
var console = {};
window.console = {};
while (length--) {
console[methods[length]] = noop;
}
}());
}
try {
console.log('[DEBUG] ' + value);
} catch (e) {}
}
Event.cacheDelegated = {};
Object.extend(document, (function () {
var cache = Event.cacheDelegated;
@ -96,6 +117,12 @@ Observable = (function () {
return name.underscore().split('_').join(':');
}
function getWrapper(handler, klass) {
return function (event) {
return handler.call(new klass(this), event, event.memo);
};
}
function getHandlers(klass) {
var proto = klass.prototype;
var namespace = proto.namespace;
@ -106,12 +133,6 @@ Observable = (function () {
});
}
function getWrapper(handler, klass) {
return function (event) {
return handler.call(new klass(this), event, event.memo);
};
}
function onDomLoad(selector, klass) {
window.$$(selector).each(function (element) {
new klass(element).onDomLoaded();
@ -1074,25 +1095,4 @@ WysijaForm.Widget = window.Class.create(WysijaForm.Block, {
/* When dom is loaded, initialize WysijaForm */
document.observe('dom:loaded', WysijaForm.init);
/* LOGGING */
function info(value) {
if (WysijaForm.options.debug === false) return;
if (!(window.console && console.log)) {
(function () {
var noop = function () {};
var methods = ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'markTimeline', 'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'];
var length = methods.length;
var console = {};
window.console = {};
while (length--) {
console[methods[length]] = noop;
}
}());
}
try {
console.log('[DEBUG] ' + value);
} catch (e) {}
}
module.exports = WysijaForm;

View File

@ -196,13 +196,6 @@ define([
var $toggleButton = this.$('> .mailpoet_tools .mailpoet_newsletter_layer_selector');
var $overlay = jQuery('.mailpoet_layer_overlay');
var $container = this.$('> .mailpoet_container');
var enableContainerLayer = function () {
that.$el.addClass('mailpoet_container_layer_active');
$toggleButton.addClass('mailpoet_container_layer_active');
$container.addClass('mailpoet_layer_highlight');
$overlay.click(disableContainerLayer);
$overlay.show();
};
var disableContainerLayer = function () {
that.$el.removeClass('mailpoet_container_layer_active');
$toggleButton.removeClass('mailpoet_container_layer_active');
@ -210,6 +203,13 @@ define([
$overlay.hide();
$overlay.off('click');
};
var enableContainerLayer = function () {
that.$el.addClass('mailpoet_container_layer_active');
$toggleButton.addClass('mailpoet_container_layer_active');
$container.addClass('mailpoet_layer_highlight');
$overlay.click(disableContainerLayer);
$overlay.show();
};
if ($toggleButton.hasClass('mailpoet_container_layer_active')) {
disableContainerLayer();
} else {

View File

@ -31,6 +31,16 @@ define(
// render template
jQuery('#mailpoet_subscribers_export > div.inside').html(subscribers_export_template(window.exportData));
function toggleNextStepButton(condition) {
var disabled = 'button-disabled';
if (condition === 'on') {
nextStepButton.removeClass(disabled);
}
else {
nextStepButton.addClass(disabled);
}
}
// define reusable variables
segmentsContainerElement = jQuery('#export_lists');
subscriberFieldsContainerElement = jQuery('#export_columns');
@ -128,16 +138,6 @@ define(
segmentsContainerElement.val(selectedSegments).trigger('change');
});
function toggleNextStepButton(condition) {
var disabled = 'button-disabled';
if (condition === 'on') {
nextStepButton.removeClass(disabled);
}
else {
nextStepButton.addClass(disabled);
}
}
nextStepButton.click(function () {
var exportFormat;
if (jQuery(this).hasClass('button-disabled')) {

View File

@ -117,6 +117,196 @@ define(
// start step 1
showCurrentStep();
function toggleNextStepButton(element, condition) {
var disabled = 'button-disabled';
if (condition === 'on') {
element.closest('table a').removeClass(disabled);
return;
}
element.closest('table a').addClass(disabled);
}
function parseCSV(isFile) {
var processedSubscribers = [];
var parsedEmails = [];
var duplicateEmails = [];
var invalidEmails = [];
var emailColumnPosition = null;
var columnCount = null;
var isHeaderFound = false;
var advancedOptionHeader = true;
var advancedOptionDelimiter = '';
var advancedOptionNewline = '';
var advancedOptionComments = false;
// trim spaces, commas, periods,
// single/double quotes and convert to lowercase
var detectAndCleanupEmail = function (emailString) {
var test;
// decode HTML entities
var email = jQuery('<div />').html(emailString).text();
email = email
.toLowerCase()
// left/right trim spaces, punctuation (e.g., " 'email@email.com'; ")
// right trim non-printable characters (e.g., "email@email.com<6F>")
.replace(/^["';.,\s]+|[^\x20-\x7E]+$|["';.,_\s]+$/g, '')
// remove spaces (e.g., "email @ email . com")
// remove urlencoded characters
.replace(/\s+|%\d+|,+/g, '');
// detect e-mails that will be otherwise rejected by email regex
test = /<(.*?)>/.exec(email);
if (test) {
// is the email inside angle brackets (e.g., 'some@email.com <some@email.com>')?
email = test[1].trim();
}
test = /mailto:(?:\s+)?(.*)/.exec(email);
if (test) {
// is the email in 'mailto:email' format?
email = test[1].trim();
}
// test for valid characters using WP's rule (https://core.trac.wordpress.org/browser/tags/4.7.3/src/wp-includes/formatting.php#L2902)
if (!/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.\-@]+$/.test(email)) {
return false;
}
return email;
};
return {
skipEmptyLines: true,
delimiter: advancedOptionDelimiter,
newline: advancedOptionNewline,
comments: advancedOptionComments,
error: function () {
MailPoet.Notice.hide();
MailPoet.Notice.error(MailPoet.I18n.t('dataProcessingError'));
},
complete: function (CSV) {
var email;
var emailAddress;
var column;
var rowCount;
var rowData;
var rowColumnCount;
var errorNotice;
for (rowCount in CSV.data) {
rowData = CSV.data[rowCount].map(function (el) {
return el.trim();
});
rowColumnCount = rowData.length;
// set the number of row elements based on the first non-empty row
if (columnCount === null) {
columnCount = rowColumnCount;
}
// Process the row with the following assumptions:
// 1. Each row should contain the same number of elements
// 2. There should be at least 1 valid (as per HTML5 e-mail regex)
// e-mail address on each row EXCEPT when the header option is set to true
// 3. Duplicate addresses are skipped
if (rowColumnCount === columnCount) {
// determine position of email address inside an array; this is
// done once and then email regex is run just on that element for each row
if (emailColumnPosition === null) {
for (column in rowData) {
emailAddress = detectAndCleanupEmail(rowData[column]);
if (emailColumnPosition === null
&& window.emailRegex.test(emailAddress)) {
emailColumnPosition = column;
parsedEmails[emailAddress] = true; // add current e-mail to an object index
rowData[column] = emailAddress;
processedSubscribers[emailAddress] = rowData;
}
}
if (emailColumnPosition === null
&& advancedOptionHeader
&& parseInt(rowCount) === 0) {
isHeaderFound = true;
processedSubscribers[0] = rowData;
}
}
else if (rowData[emailColumnPosition] !== '') {
email = detectAndCleanupEmail(rowData[emailColumnPosition]);
if (_.has(parsedEmails, email)) {
duplicateEmails.push(email);
}
else if (!window.emailRegex.test(email)) {
invalidEmails.push(rowData[emailColumnPosition]);
}
// if we haven't yet processed this e-mail and it passed
// the regex test, then process the row
else {
parsedEmails[email] = true;
rowData[emailColumnPosition] = email;
processedSubscribers[email] = rowData;
}
}
}
}
// reindex array to avoid non-numeric indices
processedSubscribers = _.values(processedSubscribers);
// if the header options is set, there should be at least
// 2 data rows, otherwise at least 1 data row
if (processedSubscribers &&
(isHeaderFound && processedSubscribers.length >= 2) ||
(!isHeaderFound && processedSubscribers.length >= 1)
) {
// since we assume that the header line is always present, we need
// to detect the header by checking if it contains a valid e-mail address
window.importData.step1 = {
header: (!window.emailRegex.test(
processedSubscribers[0][emailColumnPosition])
) ? processedSubscribers.shift() : null,
subscribers: processedSubscribers,
subscribersCount: processedSubscribers.length,
duplicate: duplicateEmails,
invalid: invalidEmails
};
MailPoet.trackEvent('Subscribers import started', {
source: isFile ? 'file upload' : 'pasted data',
'MailPoet Free version': window.mailpoet_version
});
router.navigate('step2', { trigger: true });
}
else {
MailPoet.Modal.loading(false);
errorNotice = MailPoet.I18n.t('noValidRecords');
errorNotice = errorNotice.replace('[link]', MailPoet.I18n.t('csvKBLink'));
errorNotice = errorNotice.replace('[/link]', '</a>');
MailPoet.Notice.error(errorNotice);
}
}
};
}
function displayMailChimpLists(data) {
var listSelectElement = mailChimpListsContainerElement.find('select');
if (listSelectElement.data('select2')) {
listSelectElement.select2('data', data);
listSelectElement.trigger('change');
}
else {
listSelectElement
.select2({
data: data,
width: '20em',
templateResult: function (item) {
return item.name;
},
templateSelection: function (item) {
return item.name;
}
})
.change(function () {
if (jQuery(this).val() !== null) {
toggleNextStepButton(mailChimpProcessButtonElement, 'on');
}
else {
toggleNextStepButton(mailChimpProcessButtonElement, 'off');
}
})
.trigger('change');
}
mailChimpListsContainerElement.show();
}
/*
* Paste
*/
@ -262,195 +452,6 @@ define(
});
});
function displayMailChimpLists(data) {
var listSelectElement = mailChimpListsContainerElement.find('select');
if (listSelectElement.data('select2')) {
listSelectElement.select2('data', data);
listSelectElement.trigger('change');
}
else {
listSelectElement
.select2({
data: data,
width: '20em',
templateResult: function (item) {
return item.name;
},
templateSelection: function (item) {
return item.name;
}
})
.change(function () {
if (jQuery(this).val() !== null) {
toggleNextStepButton(mailChimpProcessButtonElement, 'on');
}
else {
toggleNextStepButton(mailChimpProcessButtonElement, 'off');
}
})
.trigger('change');
}
mailChimpListsContainerElement.show();
}
function toggleNextStepButton(element, condition) {
var disabled = 'button-disabled';
if (condition === 'on') {
element.closest('table a').removeClass(disabled);
return;
}
element.closest('table a').addClass(disabled);
}
function parseCSV(isFile) {
var processedSubscribers = [];
var parsedEmails = [];
var duplicateEmails = [];
var invalidEmails = [];
var emailColumnPosition = null;
var columnCount = null;
var isHeaderFound = false;
var advancedOptionHeader = true;
var advancedOptionDelimiter = '';
var advancedOptionNewline = '';
var advancedOptionComments = false;
// trim spaces, commas, periods,
// single/double quotes and convert to lowercase
var detectAndCleanupEmail = function (emailString) {
var test;
// decode HTML entities
var email = jQuery('<div />').html(emailString).text();
email = email
.toLowerCase()
// left/right trim spaces, punctuation (e.g., " 'email@email.com'; ")
// right trim non-printable characters (e.g., "email@email.com<6F>")
.replace(/^["';.,\s]+|[^\x20-\x7E]+$|["';.,_\s]+$/g, '')
// remove spaces (e.g., "email @ email . com")
// remove urlencoded characters
.replace(/\s+|%\d+|,+/g, '');
// detect e-mails that will be otherwise rejected by email regex
test = /<(.*?)>/.exec(email);
if (test) {
// is the email inside angle brackets (e.g., 'some@email.com <some@email.com>')?
email = test[1].trim();
}
test = /mailto:(?:\s+)?(.*)/.exec(email);
if (test) {
// is the email in 'mailto:email' format?
email = test[1].trim();
}
// test for valid characters using WP's rule (https://core.trac.wordpress.org/browser/tags/4.7.3/src/wp-includes/formatting.php#L2902)
if (!/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.\-@]+$/.test(email)) {
return false;
}
return email;
};
return {
skipEmptyLines: true,
delimiter: advancedOptionDelimiter,
newline: advancedOptionNewline,
comments: advancedOptionComments,
error: function () {
MailPoet.Notice.hide();
MailPoet.Notice.error(MailPoet.I18n.t('dataProcessingError'));
},
complete: function (CSV) {
var email;
var emailAddress;
var column;
var rowCount;
var rowData;
var rowColumnCount;
var errorNotice;
for (rowCount in CSV.data) {
rowData = CSV.data[rowCount].map(function (el) {
return el.trim();
});
rowColumnCount = rowData.length;
// set the number of row elements based on the first non-empty row
if (columnCount === null) {
columnCount = rowColumnCount;
}
// Process the row with the following assumptions:
// 1. Each row should contain the same number of elements
// 2. There should be at least 1 valid (as per HTML5 e-mail regex)
// e-mail address on each row EXCEPT when the header option is set to true
// 3. Duplicate addresses are skipped
if (rowColumnCount === columnCount) {
// determine position of email address inside an array; this is
// done once and then email regex is run just on that element for each row
if (emailColumnPosition === null) {
for (column in rowData) {
emailAddress = detectAndCleanupEmail(rowData[column]);
if (emailColumnPosition === null
&& window.emailRegex.test(emailAddress)) {
emailColumnPosition = column;
parsedEmails[emailAddress] = true; // add current e-mail to an object index
rowData[column] = emailAddress;
processedSubscribers[emailAddress] = rowData;
}
}
if (emailColumnPosition === null
&& advancedOptionHeader
&& parseInt(rowCount) === 0) {
isHeaderFound = true;
processedSubscribers[0] = rowData;
}
}
else if (rowData[emailColumnPosition] !== '') {
email = detectAndCleanupEmail(rowData[emailColumnPosition]);
if (_.has(parsedEmails, email)) {
duplicateEmails.push(email);
}
else if (!window.emailRegex.test(email)) {
invalidEmails.push(rowData[emailColumnPosition]);
}
// if we haven't yet processed this e-mail and it passed
// the regex test, then process the row
else {
parsedEmails[email] = true;
rowData[emailColumnPosition] = email;
processedSubscribers[email] = rowData;
}
}
}
}
// reindex array to avoid non-numeric indices
processedSubscribers = _.values(processedSubscribers);
// if the header options is set, there should be at least
// 2 data rows, otherwise at least 1 data row
if (processedSubscribers &&
(isHeaderFound && processedSubscribers.length >= 2) ||
(!isHeaderFound && processedSubscribers.length >= 1)
) {
// since we assume that the header line is always present, we need
// to detect the header by checking if it contains a valid e-mail address
window.importData.step1 = {
header: (!window.emailRegex.test(
processedSubscribers[0][emailColumnPosition])
) ? processedSubscribers.shift() : null,
subscribers: processedSubscribers,
subscribersCount: processedSubscribers.length,
duplicate: duplicateEmails,
invalid: invalidEmails
};
MailPoet.trackEvent('Subscribers import started', {
source: isFile ? 'file upload' : 'pasted data',
'MailPoet Free version': window.mailpoet_version
});
router.navigate('step2', { trigger: true });
}
else {
MailPoet.Modal.loading(false);
errorNotice = MailPoet.I18n.t('noValidRecords');
errorNotice = errorNotice.replace('[link]', MailPoet.I18n.t('csvKBLink'));
errorNotice = errorNotice.replace('[/link]', '</a>');
MailPoet.Notice.error(errorNotice);
}
}
};
}
});
router.on('route:step2', function () {
@ -492,6 +493,15 @@ define(
showCurrentStep();
function toggleNextStepButton(condition) {
var disabled = 'button-disabled';
if (condition === 'on') {
nextStepButton.removeClass(disabled);
return;
}
nextStepButton.addClass(disabled);
}
// hide previous statistics/import results
jQuery('#subscribers_data_parse_results:visible').html('');
jQuery('#subscribers_data_import_results:visible').hide();
@ -743,127 +753,14 @@ define(
);
}
// render template
jQuery('#subscribers_data > table').html(subscribersDataTemplate(subscribers));
// filter displayed data
jQuery('select.mailpoet_subscribers_column_data_match')
.select2({
data: window.mailpoetColumnsSelect2,
width: '15em',
templateResult: function (item) {
return item.name;
},
templateSelection: function (item) {
return item.name;
}
})
.on('select2:selecting', function (selectEvent) {
var selectElement = this;
var selectedOptionId = selectEvent.params.args.data.id;
// CREATE CUSTOM FIELD
if (selectedOptionId === 'create') {
selectEvent.preventDefault();
jQuery(selectElement).select2('close');
MailPoet.Modal.popup({
title: MailPoet.I18n.t('addNewField'),
template: jQuery('#form_template_field_form').html()
});
jQuery('#form_field_new').parsley().on('form:submit', function () {
// get data
var data = jQuery(this.$element).mailpoetSerializeObject();
// save custom field
MailPoet.Ajax.post({
api_version: window.mailpoet_api_version,
endpoint: 'customFields',
action: 'save',
data: data
}).done(function (response) {
var new_column_data = {
id: response.data.id,
name: response.data.name,
type: response.data.type,
params: response.data.params,
custom: true
};
// if this is the first custom column, create an "optgroup"
if (window.mailpoetColumnsSelect2.length === 2) {
window.mailpoetColumnsSelect2.push({
name: MailPoet.I18n.t('userColumns'),
children: []
});
}
window.mailpoetColumnsSelect2[2].children.push(new_column_data);
window.mailpoetColumns.push(new_column_data);
jQuery('select.mailpoet_subscribers_column_data_match')
.each(function () {
jQuery(this)
.html('')
.select2('destroy')
.select2({
data: window.mailpoetColumnsSelect2,
width: '15em',
templateResult: function (item) {
return item.name;
},
templateSelection: function (item) {
return item.name;
}
});
});
jQuery(selectElement).data('column-id', new_column_data.id);
jQuery(selectElement).data('validation-rule', false);
filterSubscribers();
// close popup
MailPoet.Modal.close();
}).fail(function (response) {
if (response.errors.length > 0) {
MailPoet.Notice.error(
response.errors.map(function (error) { return error.message; }),
{ positionAfter: '#field_name' }
);
}
});
return false;
});
}
// CHANGE COLUMN
else {
// check for duplicate values in all select options
jQuery('select.mailpoet_subscribers_column_data_match')
.each(function () {
var element = this;
var elementId = jQuery(element).val();
// if another column has the same value and it's not an 'ignore', prompt user
if (elementId === selectedOptionId
&& elementId !== 'ignore') {
if (confirm(MailPoet.I18n.t('selectedValueAlreadyMatched') + ' ' + MailPoet.I18n.t('confirmCorrespondingColumn'))) {
jQuery(element).data('column-id', 'ignore');
}
else {
selectEvent.preventDefault();
jQuery(selectElement).select2('close');
}
}
});
}
})
.on('select2:select', function (selectEvent) {
var selectElement = this;
var selectedOptionId = selectEvent.params.data.id;
jQuery(selectElement).data('column-id', selectedOptionId);
filterSubscribers();
});
// filter subscribers' data to detect dates, emails, etc.
function filterSubscribers() {
var subscribersClone = jQuery.extend(true, {}, subscribers);
var preventNextStep = false;
var displayedColumns;
jQuery(
'[data-id="notice_invalidEmail"], [data-id="notice_invalidDate"]')
.remove();
'[data-id="notice_invalidEmail"], [data-id="notice_invalidDate"]')
.remove();
displayedColumns = jQuery.map(
jQuery('.mailpoet_subscribers_column_data_match'), function (element, elementIndex) {
var columnId = jQuery(element).data('column-id');
@ -977,25 +874,129 @@ define(
});
// refresh table with susbcribers' data
jQuery('#subscribers_data > table > tbody')
.html(subscribersDataTemplatePartial(subscribersClone));
.html(subscribersDataTemplatePartial(subscribersClone));
if (preventNextStep) {
toggleNextStepButton('off');
}
else if (!jQuery('.mailpoet_notice.error:visible').length
&& segmentSelectElement.val()) {
&& segmentSelectElement.val()) {
toggleNextStepButton('on');
}
}
function toggleNextStepButton(condition) {
var disabled = 'button-disabled';
if (condition === 'on') {
nextStepButton.removeClass(disabled);
return;
}
nextStepButton.addClass(disabled);
}
// render template
jQuery('#subscribers_data > table').html(subscribersDataTemplate(subscribers));
// filter displayed data
jQuery('select.mailpoet_subscribers_column_data_match')
.select2({
data: window.mailpoetColumnsSelect2,
width: '15em',
templateResult: function (item) {
return item.name;
},
templateSelection: function (item) {
return item.name;
}
})
.on('select2:selecting', function (selectEvent) {
var selectElement = this;
var selectedOptionId = selectEvent.params.args.data.id;
// CREATE CUSTOM FIELD
if (selectedOptionId === 'create') {
selectEvent.preventDefault();
jQuery(selectElement).select2('close');
MailPoet.Modal.popup({
title: MailPoet.I18n.t('addNewField'),
template: jQuery('#form_template_field_form').html()
});
jQuery('#form_field_new').parsley().on('form:submit', function () {
// get data
var data = jQuery(this.$element).mailpoetSerializeObject();
// save custom field
MailPoet.Ajax.post({
api_version: window.mailpoet_api_version,
endpoint: 'customFields',
action: 'save',
data: data
}).done(function (response) {
var new_column_data = {
id: response.data.id,
name: response.data.name,
type: response.data.type,
params: response.data.params,
custom: true
};
// if this is the first custom column, create an "optgroup"
if (window.mailpoetColumnsSelect2.length === 2) {
window.mailpoetColumnsSelect2.push({
name: MailPoet.I18n.t('userColumns'),
children: []
});
}
window.mailpoetColumnsSelect2[2].children.push(new_column_data);
window.mailpoetColumns.push(new_column_data);
jQuery('select.mailpoet_subscribers_column_data_match')
.each(function () {
jQuery(this)
.html('')
.select2('destroy')
.select2({
data: window.mailpoetColumnsSelect2,
width: '15em',
templateResult: function (item) {
return item.name;
},
templateSelection: function (item) {
return item.name;
}
});
});
jQuery(selectElement).data('column-id', new_column_data.id);
jQuery(selectElement).data('validation-rule', false);
filterSubscribers();
// close popup
MailPoet.Modal.close();
}).fail(function (response) {
if (response.errors.length > 0) {
MailPoet.Notice.error(
response.errors.map(function (error) { return error.message; }),
{ positionAfter: '#field_name' }
);
}
});
return false;
});
}
// CHANGE COLUMN
else {
// check for duplicate values in all select options
jQuery('select.mailpoet_subscribers_column_data_match')
.each(function () {
var element = this;
var elementId = jQuery(element).val();
// if another column has the same value and it's not an 'ignore', prompt user
if (elementId === selectedOptionId
&& elementId !== 'ignore') {
if (confirm(MailPoet.I18n.t('selectedValueAlreadyMatched') + ' ' + MailPoet.I18n.t('confirmCorrespondingColumn'))) {
jQuery(element).data('column-id', 'ignore');
}
else {
selectEvent.preventDefault();
jQuery(selectElement).select2('close');
}
}
});
}
})
.on('select2:select', function (selectEvent) {
var selectElement = this;
var selectedOptionId = selectEvent.params.data.id;
jQuery(selectElement).data('column-id', selectedOptionId);
filterSubscribers();
});
previousStepButton.off().on('click', function () {
router.navigate('step1', { trigger: true });