summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/components/custom_file_input.js
blob: 14f521a4ed630d024fbab15f51ed3a0802d588ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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 = 'web.CustomFileInput';

    return CustomFileInput;
});