summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/widgets/attach_document.js
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/web/static/src/js/widgets/attach_document.js
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/web/static/src/js/widgets/attach_document.js')
-rw-r--r--addons/web/static/src/js/widgets/attach_document.js139
1 files changed, 139 insertions, 0 deletions
diff --git a/addons/web/static/src/js/widgets/attach_document.js b/addons/web/static/src/js/widgets/attach_document.js
new file mode 100644
index 00000000..8ad48882
--- /dev/null
+++ b/addons/web/static/src/js/widgets/attach_document.js
@@ -0,0 +1,139 @@
+odoo.define('web.AttachDocument', function (require) {
+"use static";
+
+var core = require('web.core');
+var framework = require('web.framework');
+var widgetRegistry = require('web.widget_registry');
+var Widget = require('web.Widget');
+
+var _t = core._t;
+
+var AttachDocument = Widget.extend({
+ template: 'AttachDocument',
+ events: {
+ 'click': '_onClickAttachDocument',
+ 'change input.o_input_file': '_onFileChanged',
+ },
+ /**
+ * @constructor
+ * @param {Widget} parent
+ * @param {Object} record
+ * @param {Object} nodeInfo
+ */
+ init: function (parent, record, nodeInfo) {
+ this._super.apply(this, arguments);
+ this.res_id = record.res_id;
+ this.res_model = record.model;
+ this.state = record;
+ this.node = nodeInfo;
+ this.fileuploadID = _.uniqueId('o_fileupload');
+ },
+ /**
+ * @override
+ */
+ start: function () {
+ $(window).on(this.fileuploadID, this._onFileLoaded.bind(this));
+ return this._super.apply(this, arguments);
+ },
+ /**
+ * @override
+ */
+ destroy: function () {
+ $(window).off(this.fileuploadID);
+ this._super.apply(this, arguments);
+ },
+
+ //--------------------------------------------------------------------------
+ // private
+ //--------------------------------------------------------------------------
+
+ /**
+ * Helper function to display a warning that some fields have an invalid
+ * value. This is used when a save operation cannot be completed.
+ *
+ * @private
+ * @param {string[]} invalidFields - list of field names
+ */
+ _notifyInvalidFields: function (invalidFields) {
+ var fields = this.state.fields;
+ var warnings = invalidFields.map(function (fieldName) {
+ var fieldStr = fields[fieldName].string;
+ return _.str.sprintf('<li>%s</li>', _.escape(fieldStr));
+ });
+ warnings.unshift('<ul>');
+ warnings.push('</ul>');
+ this.do_warn(_t("Invalid fields:"), warnings.join(''));
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * Opens File Explorer dialog if all fields are valid and record is saved
+ *
+ * @private
+ * @param {Event} ev
+ */
+ _onClickAttachDocument: function (ev) {
+ if ($(ev.target).is('input.o_input_file')) {
+ return;
+ }
+ var fieldNames = this.getParent().canBeSaved(this.state.id);
+ if (fieldNames.length) {
+ return this._notifyInvalidFields(fieldNames);
+ }
+ // We want to save record on widget click and then open File Selection Explorer
+ // but due to this security restriction give warning to save record first.
+ // https://stackoverflow.com/questions/29728705/trigger-click-on-input-file-on-asynchronous-ajax-done/29873845#29873845
+ if (!this.res_id) {
+ return this.do_warn(false, _t('Please save before attaching a file'));
+ }
+ this.$('input.o_input_file').trigger('click');
+ },
+ /**
+ * Submits file
+ *
+ * @private
+ * @param {Event} ev
+ */
+ _onFileChanged: function (ev) {
+ ev.stopPropagation();
+ this.$('form.o_form_binary_form').trigger('submit');
+ framework.blockUI();
+ },
+ /**
+ * Call action given as node attribute after file submission
+ *
+ * @private
+ */
+ _onFileLoaded: function () {
+ var self = this;
+ // the first argument isn't a file but the jQuery.Event
+ var files = Array.prototype.slice.call(arguments, 1);
+ return new Promise(function (resolve) {
+ if (self.node.attrs.action) {
+ self._rpc({
+ model: self.res_model,
+ method: self.node.attrs.action,
+ args: [self.res_id],
+ kwargs: {
+ attachment_ids: _.map(files, function (file) {
+ return file.id;
+ }),
+ }
+ }).then(function () {
+ resolve();
+ });
+ } else {
+ resolve();
+ }
+ }).then(function () {
+ self.trigger_up('reload');
+ framework.unblockUI();
+ });
+ },
+
+});
+widgetRegistry.add('attach_document', AttachDocument);
+});