Custom Fields Not Included in Payload – File Uploader Customization (Frappe v15 Stable)

Dear Frappe Community,

I am working on customizing the default file uploader in Frappe v15 (Stable) to meet specific business requirements. I have successfully overridden the file uploader dialog using a custom JavaScript script, adding two new fields (file_type and description). However, these additional fields are not being included in the payload when the file is uploaded.

Image

Code i used for this modification.

frappe.require("file_uploader.bundle.js", () => {
        frappe.provide("frappe.ui");

        class CustomFileUploader extends frappe.ui.FileUploader {
            constructor(opts) {
                super(opts);
                console.log("Custom File Uploader Loaded!");
                this.add_custom_fields();
            }

            add_custom_fields() {
                let me = this;

                frappe.after_ajax(() => {
                    if (!me.dialog || !me.dialog.$wrapper) return;

                    // Prevent duplicate fields
                    if (me.dialog.$wrapper.find(".custom-file-fields").length) return;

                    let $container = $('<div class="custom-file-fields"></div>').appendTo(me.dialog.body);

                    let file_type_field = `
                        <div class="frappe-control">
                            <label class="control-label">File Type</label>
                            <select class="form-control file-type">
                                <option value="Image">Image</option>
                                <option value="Document">Document</option>
                                <option value="Video">Video</option>
                                <option value="Other">Other</option>
                            </select>
                        </div>`;

                    let description_field = `
                        <div class="frappe-control">
                            <label class="control-label">Description</label>
                            <input type="text" class="form-control file-description">
                        </div>`;

                    $container.append(file_type_field);
                    $container.append(description_field);

                    console.log("Custom fields added to file uploader!");
                });
            }

            upload_files() {
                let me = this;

                // Ensure the dialog is initialized
                if (!me.dialog || !me.dialog.$wrapper) {
                    console.error("Dialog not found!");
                    return;
                }

                // Capture values from the custom fields
                let file_type = me.dialog.$wrapper.find(".file-type").val();
                let description = me.dialog.$wrapper.find(".file-description").val();

                // Modify the request payload before sending
                me.upload_attachments = async function (files) {
                    let form_data = new FormData();
                    files.forEach(file => {
                        form_data.append("file", file);
                    });

                    form_data.append("is_private", me.is_private);
                    form_data.append("folder", me.folder);
                    form_data.append("doctype", me.doctype);
                    form_data.append("docname", me.docname);

                    // Add custom fields
                    form_data.append("file_type", file_type);
                    form_data.append("description", description);

                    console.log("Final FormData Payload:", [...form_data.entries()]);

                    return frappe.upload(form_data, me);
                };

                // Call the original upload function
                super.upload_files();
            }
        }

        // Override the existing FileUploader
        frappe.ui.FileUploader = CustomFileUploader;
        console.log("Custom FileUploader has been initialized!");
    });
1 Like