Skip to main content

Optimizely

Optimizely CMS – Customize your Bulk Upload Confirmation

When you upload a media file to a specific location, if the file is already existed, you will be noticed by a warning:

Replacedialog1

You can either choose “Skip this File” to ignore the replacement, or hit “Replace File” to replace the old existing file.

The issue

Assuming that you have to replace 2 existing images, but due to wrong naming in one of the images, after you upload them, instead of showing 2 replacements, now it shows that you are trying to add 1 new file and replace 1 existing file.

Replacedialog2

Now you realized that maybe it was your mistake, you want to cancel the bulk upload, but at this point, there is NO GOING BACK! You have to select 1) Upload both of the files and accept the replacements OR 2) Skip the existing files and continue uploading the remaining new file.

To undo the mistake, you have to delete/revert each of the file you have uploaded to that folder. It’s going to be painful if the folder is already large, or the number of files in your bulk upload is not just 2 but dozens.

The solution

It could be nice if we can have another button to cancel the upload so we can have a second chance to carefully review the changes. This is exactly what we did:

Newreplacedialog

 

Taking a look at the MultipleFileUploadConfirmation component (the dialog displaying replacement warning), you can see it only have 2 options, skip or replace:

return [
    {
        name: "skipFiles",
        label: single ? resources.single.buttons.skip : resources.multiple.buttons.skip,
        title: null,
        action: function () {
            when(dialog.hide(), function () {
                return dialog.onAction(false);
            });
        }
    },
    {
        name: "replaceFiles",
        label: single ? resources.single.buttons.replace : resources.multiple.buttons.replace,
        settings: { "class": "Salt" },
        title: null,
        action: function () {
            when(dialog.hide(), function () {
                return dialog.onAction(true);
            });
        }
    }
];

We are going to extends the dialog, add another cancel button to scrap out the bulk upload.

Implementation steps

Setup a module initializer

First step is adding a module initializer. This will allows you to intercept to the UI events and create your own configures/customizations. Define your module initializer by following the Official Optimizely Developer Documentation

Create your own Upload Confirmation Dialog which extends the original one

We are creating a Custom Upload Confirmation Dialog based on the original dialog. But we will override the _getActions method (to add a cancel button) and the showConfirmation method (to handle when users select an action). Here is the example code:

define("poc/Widget/CustomMultipleFileUploadConfirmation", [
    // dojo
    "dojo/_base/array",
    "dojo/_base/declare",
    "dojo/_base/lang",

    "dojo/dom-class",

    "dojo/aspect",
    "dojo/Deferred",
    "dojo/when",
    // epi
    "epi/string",

    "epi/shell/widget/dialog/Dialog",

    "epi-cms/widget/ReadOnlyContentList",
    "epi-cms/widget/MultipleFileUploadConfirmation",
    // resources
    "epi/i18n!epi/cms/nls/episerver.cms.widget.uploadmultiplefiles.replaceconfirmdialog"
],

    function (
        // dojo
        array,
        declare,
        lang,

        domClass,

        aspect,
        Deferred,
        when,
        // epi
        epiString,

        Dialog,

        ReadOnlyContentList,
        MultipleFileUploadConfirmation,
        // resources
        resources
    ) {

        return declare([MultipleFileUploadConfirmation], {
            // summary:
            //      Confirmation dialog for multiple file upload widget
            // tags:
            //      internal

            showConfirmation: function (/*Array*/existingContents, /*Array*/uploadingFiles, /*Array*/newFiles) {
                // summary:
                //      Show confirmation dialog to replace/skip the existing contents when uploading file(s) by multiple file upload widget.
                // existingContents: [Array]
                //      Filtered existing content(s) on the server
                // uploadingFiles: [Array]
                //      The uploading file(s) given from multiple file upload widget
                // newFiles: [Array]
                //      Filtered new file(s) that are not existing on the server
                // returns: [dojo.Deferred]
                //      An instance of Array for filtered file list to upload to server.
                //      This list can be the whole original selected file(s) or just the new file(s) that not existed on the server.
                // tags:
                //      public

                var deferred = new Deferred(),
                    dialog = this._getDialog(existingContents.length),
                    content = this._getContentList();

                dialog.set("content", content);
                dialog.set("onAction", function (result) {
                    /*deferred.resolve(result ? uploadingFiles : newFiles);*/
                    switch (result) {
                        case 0:
                            // cancel
                            deferred.resolve([]);
                            break;
                        case 1:
                            // skip existing files
                            deferred.resolve(newFiles);
                            break;
                        case 2:
                            // replace
                            deferred.resolve(uploadingFiles);
                            break;
                        default:
                            deferred.resolve([]);
                            break;
                    }
                });

                when(dialog.show(), function () {
                    content.grid.renderArray(existingContents);
                });

                return deferred;
            },

            // =======================================================================
            // Private functions

            _getActions: function (/*epi/shell/widget/dialog/Dialog*/dialog, /*Boolean*/single) {
                // summary:
                //      Overridden from Dialog base to assemble the action collection
                // dialog: [epi/shell/widget/dialog/Dialog]
                //      Confirmation dialog
                // single: [Boolean]
                //      Indicates that we must show text for single item or multiple items
                // returns:
                //      A collection of action definitions that can be added to the action pane.
                // tags:
                //      private

                return [
                    {
                        name: "cancel",
                        label: "Cancel",
                        title: null,
                        action: function () {
                            when(dialog.hide(), function () {
                                return dialog.onAction(0);
                            });
                        }
                    },
                    {
                        name: "skipFiles",
                        label: single ? resources.single.buttons.skip : resources.multiple.buttons.skip,
                        title: null,
                        action: function () {
                            when(dialog.hide(), function () {
                                return dialog.onAction(1);
                            });
                        }
                    },
                    {
                        name: "replaceFiles",
                        label: single ? resources.single.buttons.replace : resources.multiple.buttons.replace,
                        settings: { "class": "Salt" },
                        title: null,
                        action: function () {
                            when(dialog.hide(), function () {
                                return dialog.onAction(2);
                            });
                        }
                    }
                ];
            }

        });

    });

 

Replace the old dialog with your custom dialog above, using moduleInitializer

define([
    "dojo",
    "dojo/_base/declare",
    "epi/_Module",
    "epi-cms/widget/MultipleFileUpload",
    "poc/Widget/CustomMultipleFileUploadConfirmation"
], function (dojo,
    declare,
    _Module,
    MultipleFileUpload,
    CustomMultipleFileUploadConfirmation
) {
    return declare("poc.moduleInitializer", [_Module], {
        initialize: function () {
            this.inherited(arguments);

            // Do any custom module initialization here

            // Extend postCreate method for MultipleFileUpload
            var originalMultipleFileUpload = MultipleFileUpload.prototype.postCreate;
            MultipleFileUpload.prototype.postCreate = function () {
                // call the original function
                originalMultipleFileUpload.apply(this, arguments);

                this._confirmationDialog = new CustomMultipleFileUploadConfirmation();
            }
        }
    });
});

 

That’s it! Now you have a cancel button for your Bulk Upload Confirmation Dialog. With this methodology you can even extend your custom dialog further to fit a variety of requirements. Happy coding!

Thoughts on “Optimizely CMS – Customize your Bulk Upload Confirmation”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Tung Tran

Tung is an Optimizely Certified Content Cloud Developer with experience working with .NET technologies. Strong engineering professional skilled in developing both Windows and Web Applications. In his free time, he enjoys watching, playing soccer, and spending time with his small family.

More from this Author

Follow Us