From 3c5194a00b3c0525dfd84552233e9c8f85a150f4 Mon Sep 17 00:00:00 2001 From: Julien Mougenot Date: Fri, 22 Nov 2019 11:37:09 +0000 Subject: [ADD] web: Custom File Input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New component: the custom file input. Its purpose is to define a input of type file with a custom trigger (button, link, etc.). Its construction is the following: - attributes: behaviour of the actual input (route to call, multifile, allowed extensions etc.) - inner template: the trigger that will fire the upload prompt when clicked Once a file has been uploaded, the component will emit a 'uploaded' custom event containing the files. closes odoo/odoo#38423 Related: odoo/enterprise#6031 Signed-off-by: Géry Debongnie (ged) --- .../static/src/js/components/custom_file_input.js | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 addons/web/static/src/js/components/custom_file_input.js (limited to 'addons/web/static/src/js/components/custom_file_input.js') diff --git a/addons/web/static/src/js/components/custom_file_input.js b/addons/web/static/src/js/components/custom_file_input.js new file mode 100644 index 00000000000..eb9c4267cfc --- /dev/null +++ b/addons/web/static/src/js/components/custom_file_input.js @@ -0,0 +1,88 @@ +odoo.define('web.CustomFileInput', function (require) { + "use strict"; + + const { Component, hooks } = owl; + const { useRef } = hooks; + + /** + * Custom file input + * + * Component representing a customized input of type file. It takes a sub-template + * in its default t-slot and uses it as the trigger to open the file upload + * prompt. + * @extends Component + */ + class CustomFileInput extends Component { + /** + * @param {Object} [props] + * @param {string} [props.accepted_file_extensions='*'] Comma-separated + * list of authorized file extensions (default to all). + * @param {string} [props.action='/web/binary/upload'] Route called when + * a file is uploaded in the input. + * @param {string} [props.id] + * @param {string} [props.model] + * @param {string} [props.multi_upload=false] Whether the input should allow + * to upload multiple files at once. + */ + constructor() { + super(...arguments); + + this.fileInputRef = useRef('file-input'); + } + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * Upload an attachment to the given action with the given parameters: + * - ufile: list of files contained in the file input + * - csrf_token: CSRF token provided by the odoo global object + * - model: a specific model which will be given when creating the attachment + * - id: the id of the model target instance + * @private + */ + async _onFileInputChange() { + const { action, model, id } = this.props; + const params = { + csrf_token: odoo.csrf_token, + ufile: [...this.fileInputRef.el.files], + }; + if (model) { + params.model = model; + } + if (id) { + params.id = id; + } + const fileData = await this.env.services.httpRequest(action, params, 'text'); + const parsedFileData = JSON.parse(fileData); + if (parsedFileData.error) { + throw new Error(parsedFileData.error); + } + this.trigger('uploaded', { files: parsedFileData }); + } + + /** + * Redirect clicks from the trigger element to the input. + * @private + */ + _onTriggerClicked() { + this.fileInputRef.el.click(); + } + } + CustomFileInput.defaultProps = { + accepted_file_extensions: '*', + action: '/web/binary/upload', + multi_upload: false, + }; + CustomFileInput.props = { + accepted_file_extensions: { type: String, optional: 1 }, + action: { type: String, optional: 1 }, + id: { type: Number, optional: 1 }, + model: { type: String, optional: 1 }, + multi_upload: { type: Boolean, optional: 1 }, + }; + CustomFileInput.template = 'CustomFileInput'; + + return CustomFileInput; +}); -- cgit v1.2.3