[IMP] website_slides: apply linting on track proposal JS files

This commit does not change anything, it simply applies linting on the track
proposal JS files to match our current guidelines.

This is done as preliminary work since we are going to change the way track
proposals are submitted (from POST request to ajax POST).

Task-2618734
This commit is contained in:
Aurélien Warnon
2021-08-09 12:14:42 +00:00
parent 8f18ab41b4
commit beb6c47876
2 changed files with 221 additions and 223 deletions
@@ -7,161 +7,160 @@ var publicWidget = require('web.public.widget');
var _t = core._t;
publicWidget.registry.websiteEventTrackProposalForm = publicWidget.Widget.extend({
selector: '.o_website_event_track_proposal_form',
events: {
'click .o_wetrack_add_contact_information_checkbox': '_onAdvancedContactToggle',
'input input[name="partner_name"]': '_onPartnerNameInput',
'click .o_wetrack_proposal_submit_button': '_onProposalFormSubmit',
},
selector: '.o_website_event_track_proposal_form',
events: {
'click .o_wetrack_add_contact_information_checkbox': '_onAdvancedContactToggle',
'input input[name="partner_name"]': '_onPartnerNameInput',
'click .o_wetrack_proposal_submit_button': '_onProposalFormSubmit',
},
/**
* @override
*/
init: function () {
this._super(...arguments);
this.useAdvancedContact = false;
},
/**
* @override
*/
init: function () {
this._super(...arguments);
this.useAdvancedContact = false;
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* Evaluate and return validity of form input fields:
* - 1) error 'invalidFormInputs' : Invalid ones are marked as is-invalid and o_wetrack_input_error.
* - 2) error 'noContactMean' : Contact mean fields are marked as is-invalid and contact
* section as o_wetrack_no_contact_mean_error if none of them is filled.
*
* @private
* @returns {Boolean} - True if no error remain, false otherwise
*/
_isFormValid: function () {
var formErrors = [];
/**
* Evaluate and return validity of form input fields:
* - 1) error 'invalidFormInputs' : Invalid ones are marked as is-invalid and o_wetrack_input_error.
* - 2) error 'noContactMean' : Contact mean fields are marked as is-invalid and contact
* section as o_wetrack_no_contact_mean_error if none of them is filled.
*
* @private
* @returns {Boolean} - True if no error remain, false otherwise
*/
_isFormValid: function () {
var formErrors = [];
// 1) Valid Form Inputs
this.$('.form-group').each(function (index, field) {
var $field = $(field);
// Validate current input, if not select2 field.
var inputs = $field.find('.form-control').not('.o_wetrack_select2_tags');
var invalidInputs = inputs.toArray().filter(function (input) {
return !input.checkValidity();
});
// 1) Valid Form Inputs
this.$('.form-group').each(function (index, field) {
var $field = $(field);
// Validate current input, if not select2 field.
var inputs = $field.find('.form-control').not('.o_wetrack_select2_tags');
var invalidInputs = inputs.toArray().filter(function (input) {
return !input.checkValidity();
$field.find('.form-control').removeClass('o_wetrack_input_error is-invalid');
if (invalidInputs.length) {
$field.find('.form-control').addClass('o_wetrack_input_error is-invalid');
formErrors.push('invalidFormInputs');
}
});
$field.find('.form-control').removeClass('o_wetrack_input_error is-invalid');
if (invalidInputs.length) {
$field.find('.form-control').addClass('o_wetrack_input_error is-invalid');
formErrors.push('invalidFormInputs');
}
});
// 2) Advanced Contact Must Have a Contact Mean
if (this.useAdvancedContact) {
var hasContactMean = this.$('.o_wetrack_contact_phone_input').val() ||
this.$('.o_wetrack_contact_email_input').val();
if (!hasContactMean) {
this.$('.o_wetrack_contact_information').addClass('o_wetrack_no_contact_mean_error');
this.$('.o_wetrack_contact_mean').addClass('is-invalid');
formErrors.push('noContactMean');
// 2) Advanced Contact Must Have a Contact Mean
if (this.useAdvancedContact) {
var hasContactMean = this.$('.o_wetrack_contact_phone_input').val() ||
this.$('.o_wetrack_contact_email_input').val();
if (!hasContactMean) {
this.$('.o_wetrack_contact_information').addClass('o_wetrack_no_contact_mean_error');
this.$('.o_wetrack_contact_mean').addClass('is-invalid');
formErrors.push('noContactMean');
} else {
this.$('.o_wetrack_contact_information').removeClass('o_wetrack_no_contact_mean_error');
this.$('.o_wetrack_contact_mean:not(".o_wetrack_input_error")').removeClass('is-invalid');
}
}
// Form Validity and Error Display
this._updateErrorDisplay(formErrors);
return formErrors.length === 0;
},
/**
* If there are still errors in form, display the error section and
* compose the error message accordingly.
*
* @private
* @param {Array} errors - Names of errors still present in form.
*/
_updateErrorDisplay: function (errors) {
this.$('.o_wetrack_proposal_error_section').toggleClass('d-none', !errors.length);
var errorMessage = '';
var $errorElement = this.$('.o_wetrack_proposal_error_message');
if (errors.includes('invalidFormInputs')) { errorMessage += _t(' Please fill out the form correctly.'); }
if (errors.includes('noContactMean')) { errorMessage += _t(' Please enter either a contact email address or a contact phone number.'); }
$errorElement.text(errorMessage).change();
},
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* Display / Hide Additional Contact Information section when toggling
* the checkbox on the form o_wetrack_add_contact_information_checkbox.
* Also empty the email to prevent hidden email format error.
*
* @private
* @param {Event} ev
*/
_onAdvancedContactToggle: function (ev) {
this.useAdvancedContact = !this.useAdvancedContact;
var $contactName = this.$(".o_wetrack_contact_name_input")[0];
var $advancedInformation = this.$('.o_wetrack_contact_information');
if (this.useAdvancedContact) {
$advancedInformation.removeClass('d-none');
$contactName.setAttribute("required", "True");
} else {
this.$('.o_wetrack_contact_information').removeClass('o_wetrack_no_contact_mean_error');
this.$('.o_wetrack_contact_mean:not(".o_wetrack_input_error")').removeClass('is-invalid');
this.$('.o_wetrack_contact_email_input').val('').change();
$advancedInformation.addClass('d-none');
$contactName.removeAttribute("required");
}
}
},
// Form Validity and Error Display
this._updateErrorDisplay(formErrors);
return formErrors.length === 0;
},
/**
* Propagates the new input on speaker name to contact name, as long as the latter
* is the start of partner name. Otherwise, do not modify existing contact name.
*
* @private
* @param {Event} ev
*/
_onPartnerNameInput: function (ev) {
var partnerNameText = $(ev.currentTarget).val();
var contactNameText = this.$(".o_wetrack_contact_name_input").val();
if (partnerNameText.startsWith(contactNameText)) {
this.$(".o_wetrack_contact_name_input").val(partnerNameText).change();
}
},
/**
* If there are still errors in form, display the error section and
* compose the error message accordingly.
*
* @private
* @param {Array} errors - Names of errors still present in form.
*/
_updateErrorDisplay: function(errors) {
/**
* Submits the form if no errors are present in the form after validation.
*
* @private
* @param {Event} ev
*/
_onProposalFormSubmit: function (ev) {
ev.preventDefault();
ev.stopPropagation();
this.$('.o_wetrack_proposal_error_section').toggleClass('d-none', !errors.length);
// Prevent further clicking
this.$target.find('.o_wetrack_proposal_submit_button')
.addClass('disabled')
.attr('disabled', 'disabled');
var errorMessage = '';
var $errorElement = this.$('.o_wetrack_proposal_error_message');
// Submission of the form if no errors remain
if (this._isFormValid()) {
this.$el.submit();
this.$target[0].reset();
}
if (errors.includes('invalidFormInputs')) { errorMessage += _t(' Please fill out the form correctly.'); }
if (errors.includes('noContactMean')) { errorMessage += _t(' Please enter either a contact email address or a contact phone number.'); }
$errorElement.text(errorMessage).change();
},
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* Display / Hide Additional Contact Information section when toggling
* the checkbox on the form o_wetrack_add_contact_information_checkbox.
* Also empty the email to prevent hidden email format error.
*
* @private
* @param {Event} ev
*/
_onAdvancedContactToggle: function(ev) {
this.useAdvancedContact = !this.useAdvancedContact;
var $contactName = this.$(".o_wetrack_contact_name_input")[0];
var $advancedInformation = this.$('.o_wetrack_contact_information');
if (this.useAdvancedContact) {
$advancedInformation.removeClass('d-none');
$contactName.setAttribute("required", "True");
} else {
this.$('.o_wetrack_contact_email_input').val('').change();
$advancedInformation.addClass('d-none');
$contactName.removeAttribute("required");
}
},
/**
* Propagates the new input on speaker name to contact name, as long as the latter
* is the start of partner name. Otherwise, do not modify existing contact name.
*
* @private
* @param {Event} ev
*/
_onPartnerNameInput: function(ev) {
var partnerNameText = $(ev.currentTarget).val();
var contactNameText = this.$(".o_wetrack_contact_name_input").val();
if (partnerNameText.startsWith(contactNameText)) {
this.$(".o_wetrack_contact_name_input").val(partnerNameText).change();
}
},
/**
* Submits the form if no errors are present in the form after validation.
*
* @private
* @param {Event} ev
*/
_onProposalFormSubmit: function(ev) {
ev.preventDefault();
ev.stopPropagation();
// Prevent further clicking
this.$target.find('.o_wetrack_proposal_submit_button')
.addClass('disabled')
.attr('disabled', 'disabled');
// Submission of the form if no errors remain
if (this._isFormValid()) {
this.$el.submit();
this.$target[0].reset();
}
// Restore button
this.$target.find('.o_wetrack_proposal_submit_button')
.removeAttr('disabled')
.removeClass('disabled');
},
// Restore button
this.$target.find('.o_wetrack_proposal_submit_button')
.removeAttr('disabled')
.removeClass('disabled');
},
});
return publicWidget.registry.websiteEventTrackProposalForm;
@@ -7,93 +7,92 @@ var publicWidget = require('web.public.widget');
var _t = core._t;
publicWidget.registry.websiteEventTrackProposalFormTags = publicWidget.Widget.extend({
selector: '.o_website_event_track_proposal_form_tags',
selector: '.o_website_event_track_proposal_form_tags',
start: function () {
var self = this;
return this._super.apply(this, arguments).then(function () {
self._bindSelect2Dropdown();
});
},
start: function () {
var self = this;
return this._super.apply(this, arguments).then(function () {
self._bindSelect2Dropdown();
});
},
/**
* Handler for select2 on tags added to the proposal track form.
*
* @private
*/
_bindSelect2Dropdown: function () {
var self = this;
this.$('.o_wetrack_select2_tags').select2(this._select2Wrapper(_t('Select categories'),
function () {
return self._rpc({
route: "/event/track_tag/search_read",
params: {
fields: ['name', 'category_id'],
domain: [],
}
});
})
);
},
/**
* Wrapper for select2. Load data from server once and store it.
* Tags are sorted in alphabetical order and have format "tag.category.name : tag.name"
* Or "tag.name" if tag does not belong to any category.
*
* @private
* @param {String} tag - Placeholder for element.
* @param {Function} fetchFNC - Fetch data from remote location. Should return a Promise.
* Resolved data should be array of objects with id and name. eg. [{'id': id, 'name': 'text'}, ...]
* @param {String} nameKey - (optional) the name key of the returned record
* ('name' if not provided)
* @returns {Object} select2 wrapper object
*/
_select2Wrapper: function (tag, fetchFNC, nameKey) {
nameKey = nameKey || 'name';
var values = {
placeholder: tag,
allowClear: true,
formatNoMatches: _t('No results found'),
selection_data: false,
fetch_rpc_fnc: fetchFNC,
multiple: 'multiple',
sorter: data => data.sort((a, b) => a.text.localeCompare(b.text)),
// category_id structure : [id, tag category name]
fill_data: function (query, data) {
var that = this,
tags = {results: []};
_.each(data, function (obj) {
// select tags matching either category or tag name
if (that.matcher(query.term, obj[nameKey]) || that.matcher(query.term, obj.category_id[1])) {
if (obj.category_id[1]) {
tags.results.push({id: obj.id, text: obj.category_id[1] + " : " + obj[nameKey]});
} else {
tags.results.push({id: obj.id, text: obj[nameKey]});
/**
* Handler for select2 on tags added to the proposal track form.
*
* @private
*/
_bindSelect2Dropdown: function () {
var self = this;
this.$('.o_wetrack_select2_tags').select2(this._select2Wrapper(_t('Select categories'),
function () {
return self._rpc({
route: "/event/track_tag/search_read",
params: {
fields: ['name', 'category_id'],
domain: [],
}
}
});
query.callback(tags);
},
query: function (query) {
var that = this;
// fetch data only once and store it
if (!this.selection_data) {
this.fetch_rpc_fnc().then(function (data) {
that.fill_data(query, data);
that.selection_data = data;
});
} else {
this.fill_data(query, this.selection_data);
})
);
},
/**
* Wrapper for select2. Load data from server once and store it.
* Tags are sorted in alphabetical order and have format "tag.category.name : tag.name"
* Or "tag.name" if tag does not belong to any category.
*
* @private
* @param {String} tag - Placeholder for element.
* @param {Function} fetchFNC - Fetch data from remote location. Should return a Promise.
* Resolved data should be array of objects with id and name. eg. [{'id': id, 'name': 'text'}, ...]
* @param {String} nameKey - (optional) the name key of the returned record
* ('name' if not provided)
* @returns {Object} select2 wrapper object
*/
_select2Wrapper: function (tag, fetchFNC, nameKey) {
nameKey = nameKey || 'name';
var values = {
placeholder: tag,
allowClear: true,
formatNoMatches: _t('No results found'),
selection_data: false,
fetch_rpc_fnc: fetchFNC,
multiple: 'multiple',
sorter: data => data.sort((a, b) => a.text.localeCompare(b.text)),
// category_id structure : [id, tag category name]
fill_data: function (query, data) {
var that = this,
tags = {results: []};
_.each(data, function (obj) {
// select tags matching either category or tag name
if (that.matcher(query.term, obj[nameKey]) || that.matcher(query.term, obj.category_id[1])) {
if (obj.category_id[1]) {
tags.results.push({id: obj.id, text: obj.category_id[1] + " : " + obj[nameKey]});
} else {
tags.results.push({id: obj.id, text: obj[nameKey]});
}
}
});
query.callback(tags);
},
query: function (query) {
var that = this;
// fetch data only once and store it
if (!this.selection_data) {
this.fetch_rpc_fnc().then(function (data) {
that.fill_data(query, data);
that.selection_data = data;
});
} else {
this.fill_data(query, this.selection_data);
}
}
}
};
return values;
},
};
return values;
},
});
return publicWidget.registry.websiteEventTrackProposalFormTags;