Aotik
Aotik

Reputation: 161

How to delete files with external delete button - Blueimp FileUploader UI

I'm trying to make a confirmation modal for when deleting a file.

This is the original button in the form & table for File uploads: https://i.sstatic.net/S8eBJ.png

This is the confirmation I'm popping up when the above delete button is clicked: https://i.sstatic.net/KKXZQ.png

This is how the original delete button is populated in the template script:

{% if (file.deleteUrl) { %}
                 <li role="presentation"><a role="menuitem" tabindex="-1" href="#" class="d-info " data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}" ><span class="fa fa-trash"></span> Delete</a></li>
{% } %}

This is the jQuery I have transferring data from the original button to the modal button:

 $(document).on('click','.d-info', function(e) { 
       $(".cl-modal").fadeIn();
       $("#confirm-delete").attr('data-url', $(this).attr('data-url'));
        $("#confirm-delete").attr('data-type', $(this).attr('data-type'));
         $("#confirm-delete").attr('data-xhr-fields', $(this).attr('data-xhr-fields'));
       });

All the data is passed on to the button along with the 'delete' class from what I can see when I inspect it.

I get no response when clicking on it, nothing happens at all. I tried going through the original FileUpload JS files however I can't seem to find any more info on it.

Any help would be greatly appreciated and let me know if any more info is needed. Thanks.

Upvotes: 0

Views: 2114

Answers (2)

Vinzz
Vinzz

Reputation: 62

I've made a Widget extension for blueimp jQuery fileUpload https://github.com/VinzzB/jQuery-File-Upload

You can easily show modal delete messages when deleting one or more files. A demo is included in the 'Bootstrap_demo' folder.

Custom.fileupload.js:

$.widget( "blueimp.fileupload", $.blueimp.fileupload, {
    options: {
        autoLoad: true,
        delButtons: "button.delete",
        delAllButtons: "button.selDelete",
        renderTemplate: function(r) { } ,
        confirmDeletion: function(e,data) { e.doDelete(); } //delete immediately if confirmDeletion is not set by user.
    },
    _unid: 0, //private counter for files.
    _create: function() {
        var me = this;
        this._hookDeleteAllButton();
        this._hookCheckboxToggleAll();
        this._super();
        $(this.options.delAllButtons,this.element).prop("disabled", true);  
        $(".toggleAll").prop('checked',false).change();

        $(this.element).bind('fileuploadadded', function() { me._checkBarButtons();})
            .bind("fileuploaddestroyed", function() { me._checkBarButtons(); })
            .bind("fileuploadfinished", function() { me._checkBarButtons();})
            .bind("fileuploadprocessalways", function() { me._checkBarButtons();});
        //alert('ee')       
        if (this.options.autoLoad)
            this._loadFiles();
        this._checkBarButtons();
    },  

    //OVERRIDDEN METHOD!
    _renderTemplate: function (func, files) {
        console.log(files);
        if (!func) {
            return $();
        }        
        //RENDER TEMPLATE
        var result = $(func({
            unid: this._unid,
            files: files,
            formatFileSize: this._formatFileSize,
            options: this.options
        }));
        //add unique ids to global counter
        this._unid += files.length;
        //RENDER STYLES (juery-UI / Bootstrap styles by user function)
        this._hookCheckboxRows(result);
        //Custom styling by user...
        this.options.renderTemplate(result);
        //if (result instanceof $) { return result; }        
        return $(this.options.templatesContainer).html(result).children();
    },

    //OVERRIDDEN METHOD!
    //Handles deletion per file. (triggers confirmation if not confirmed yet)
    _deleteHandler: function (e) {
        e.preventDefault();        
        var button = $(e.currentTarget);        
        //fire trigger for user confirmation (if not confirmed yet)
        if (!button.data('delete')) {
            var row = button.closest("." + this.options.downloadTemplateId);
            this._triggerConfirmDelete(e, [row], button);
            return false;
        }
        //removing document!
        button.removeData("delete"); //remove confirmed flag (=reset when delete fails)
        this._trigger('destroy', e, $.extend({
            context: button.closest("." + this.options.downloadTemplateId),
            type: 'DELETE'
        }, button.data()));
    },

    _loadFiles: function() {
        var me = this, $me = $(this);
        $me.addClass('fileupload-processing');
        $.ajax({
            // Uncomment the following to send cross-domain cookies:
            //xhrFields: {withCredentials: true},
            url: me.options.url,
            dataType: 'json',
            context: me.element
        }).always(function () {
            $me.removeClass('fileupload-processing');
        }).done(function (result) {
            me.options.done.call(this, $.Event('done'), {result: result});
        });        
    },

    _triggerConfirmDelete: function(e, rows, buttons) {     
        var files = [];
        //create a list with selected files
        buttons.each(function(i) {
            files[files.length] = $(this).data();
        });

        e.doDelete = function() { buttons.data("delete", "confirmed").trigger('click'); }   
        this._trigger('confirmDeletion', e,{ files: files, rows: rows } );
    },

    _hookDeleteAllButton : function() {
        var me = this;
        //Hook click on button: delete all selected
        $(this.options.delAllButtons, this.element).on('click',function(e) {

            e.preventDefault();
            var selRows = $("input.toggle[type=checkbox]:checked", me.element).closest("." + me.options.downloadTemplateId);        
            var delBtns = $(me.options.delButtons, selRows);
            if (delBtns.length) {

                //trigger confirmation message
                me._triggerConfirmDelete(e, selRows, delBtns )  
            }
        });
    },

    _hookCheckboxToggleAll: function() {
        var me = this;
        //(un-)select all checkboxes when selectAll box is changed
        $('input.toggleAll[type=checkbox]', this.element).on('click', function() {          
            //-> DO NOT USE preventDefault here, this would break the select all button!
            var val = $(this).prop("checked");
            $("input.toggle[type=checkbox]", $("tbody",me.element)).not(":disabled").prop("checked",val).change();
        })
    },

    _hookCheckboxRows: function(tm) {
        var me = this;
        $("input.toggle[type=checkbox]",tm).on('change', function() {
            var btns = $("input.toggle[type=checkbox]",$("tbody",me.element)).not(":disabled"); //get all non disabled buttons
            var selBtns = $("input.toggle[type=checkbox]:checked",$("tbody",me.element)).not(":disabled"); //get all checked buttons that are not disabled.
            $(".toggleAll",me.element).prop("checked", selBtns.length == btns.length).change() //equals checks? 
            $(me.options.delAllButtons,me.element).prop("disabled", !selBtns.length); //enable or disable 'delete all' button       
        });     
    },

    _checkBarButtons: function() {      
        var allRows = $('.' + this.options.downloadTemplateId + ', .' + this.options.uploadTemplateId, this.element);
        var upRows = $('.' + this.options.uploadTemplateId,  this.element);
        var downRows = $('.' + this.options.downloadTemplateId,  this.element);
        var starts = $("button.start:enabled", upRows);
        var cancels = $("button.cancel:enabled", allRows);
        var selected = $("input.toggle[type=checkbox]:checked:not(:disabled)",downRows);
        $(".toggleAll",this.element)
            .prop("disabled",!downRows.length)
            .prop("checked", downRows.length != 0 && selected.length == downRows.length)
            .change();
        $(".fileupload-buttonbar button.start", this.element).prop('disabled',!starts.length);
        $(".fileupload-buttonbar button.cancel", this.element).prop('disabled',!cancels.length);
        $(this.options.delAllButtons, this.element).prop("disabled", !selected.length);
    }

});

Call it like this:

$('#fileupload').fileupload({ 
    autoLoad: true,
    renderTemplate: function(r) {       
        //you can customize the rendered template here.
        //arg r holds the currently rendered template
    },      
    confirmDeletion: function(e,data) {         
        //see bootstrap demo for full example (with modal dialog)
        var doDel = confirm('delete ' + data.files.length + ' files?','Continue?');
        if (doDel) { e.doDelete(); } //perform delete 
    }
});    

Upvotes: 1

Aotik
Aotik

Reputation: 161

Done for whoever is looking for the same request:

  destroy: function (e, data) {
            if (e.isDefaultPrevented()) {
                return false;
            }
            var that = $(this).data('blueimp-fileupload') ||
                    $(this).data('fileupload'),
                removeNode = function () {
                    that._transition(data.context).done(
                        function () {
                            $(this).remove();
                            that._trigger('destroyed', e, data);
                        }
                    );
                };
            if (data.url) {
                data.dataType = data.dataType || that.options.dataType;

           $(".cl-modal").fadeIn();

                    $('#confirm-delete').click( function () {
                   $.ajax(data).done(removeNode).fail(function () {
                        that._trigger('destroyfailed', e, data);
                    });
                });

            } else {
                $(".cl-modal").fadeIn();

                $('#confirm-delete').click( function () {
               $.ajax(data).done(removeNode).fail(function () {
                    that._trigger('destroyfailed', e, data);
                });
                });
               }
        }

Upvotes: 0

Related Questions