[ADD] survey_extra_fields : file question type
Some checks failed
pre-commit / pre-commit (pull_request) Failing after 1m39s

This commit is contained in:
2026-02-17 12:27:22 +01:00
parent e1c2be8939
commit 0d4a91f1b7
14 changed files with 626 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
odoo.define("survey_extra_fields.survey_form", function (require) {
"use strict";
var core = require("web.core");
var _t = core._t;
var survey_form = require("survey.form");
survey_form.include({
_readFileAsDataURL: function (file) {
return new Promise(function (resolve, reject) {
var reader = new FileReader();
reader.onload = function (e) {
resolve(e.target.result);
};
reader.onerror = function () {
reject(reader.error);
};
reader.readAsDataURL(file);
});
},
_submitForm: function (options) {
var self = this;
var $fileInputs = this.$('input[data-question-type="file"]');
var hasFiles = false;
$fileInputs.each(function () {
if (this.files && this.files.length > 0) {
hasFiles = true;
return false;
}
});
if (!hasFiles || this.options.isStartScreen) {
return this._super(options);
}
// Async flow: read files then submit
var params = {};
if (options.previousPageId) {
params.previous_page_id = options.previousPageId;
}
var $form = this.$("form");
var formData = new FormData($form[0]);
if (!options.skipValidation) {
if (!this._validateForm($form, formData)) {
return;
}
}
this._prepareSubmitValues(formData, params);
// Read all selected files as base64
var filePromises = [];
$fileInputs.each(function () {
if (this.files && this.files.length > 0) {
var file = this.files[0];
var name = this.name;
filePromises.push(
self._readFileAsDataURL(file).then(function (dataURL) {
params[name] = JSON.stringify({
data: dataURL.split(",")[1],
name: file.name,
});
})
);
}
});
this.preventEnterSubmit = true;
if (this.options.sessionInProgress) {
this.fadeInOutDelay = 400;
this.readonly = true;
}
Promise.all(filePromises).then(function () {
var submitPromise = self._rpc({
route: _.str.sprintf(
"%s/%s/%s",
"/survey/submit",
self.options.surveyToken,
self.options.answerToken
),
params: params,
});
self._nextScreen(submitPromise, options);
});
},
_validateForm: function ($form, formData) {
var result = this._super.apply(this, arguments);
var errors = {};
var inactiveQuestionIds = this.options.sessionInProgress
? []
: this._getInactiveConditionalQuestionIds();
$form.find('input[data-question-type="file"]').each(function () {
var $questionWrapper = $(this).closest(".js_question-wrapper");
var questionId = $questionWrapper.attr("id");
if (inactiveQuestionIds.includes(parseInt(questionId))) {
return;
}
var questionRequired = $questionWrapper.data("required");
var constrErrorMsg =
$questionWrapper.data("constrErrorMsg") ||
_t("This question requires an answer.");
if (questionRequired && !(this.files && this.files.length > 0)) {
errors[questionId] = constrErrorMsg;
}
});
if (_.keys(errors).length > 0) {
this._showErrors(errors);
return false;
}
return result;
},
});
});