Implementing Remove Buttons for jQuery-File-Upload

2019-07-05 13:19发布

I may be approaching this with an entirely wrong idea so let me explain my situation first.

What I'm trying to achieve using jQuery-File-Upload is to allow the user to select files they choose to upload. They will be allowed to select multiple files. For now it doesn't matter what type but they'll mainly be uploading images. The selected files will appear in a list with a "remove" button to the right of the filename for each file. As pictured below.

Basic setup of jQuery-File-Upload

How can I implement a means of allowing the user to remove the file they've selected from the list of files that are awaiting upload?

Once the user feels comfortable with their selection of files they will click the 'Start Upload' button which will begin uploading the files contained in the list and trigger the progress bar pictured above.

I've tried some troubleshooting myself including logging out events that happen when the button is clicked but can't manage to remove it from the list of files selected for upload. I know there is a drop callback but I'm not sure if that's what I should be using.

Below is my code.

$(function () {
    $('#fileupload').fileupload({
        dataType: 'json',
        url: '../php/',
        add: function (e, data) {
            //$.each(data.files, function(index, file) {
                data.context = $('<li class=\"list-group-item\">')
                    //.html(file.name+"<button type=\"button\" id=\"drop\" class=\"btn btn-danger btn-xs pull-right\"><span class=\"glyphicon glyphicon-remove\"></span></button>")
                    // see https://stackoverflow.com/questions/26234279/blueimp-jquery-upload-multiple-files-doesnt-work for the reason for the line below
                    .html(data.files[0].name+"<button type=\"button\" id=\"drop\" class=\"btn btn-danger btn-xs pull-right\"><span class=\"glyphicon glyphicon-trash\"></span></button>")
                    .appendTo(".list-group");
                /*$('.btn-danger').on('click', function() {
                    console.log('Drop '+file.name+' \n');
                });*/
            //});
            $('.btn-danger').on('click', function(e, data) {
                //console.log("Removing all objects...\n");
                //data.context.remove(data.files[0].name);
                //data.context.remove(data.files[0]);
                e.preventDefault();
                /*var filename = $(this).parent().text();
                console.log("Filename: "+filename);
                data.context.remove(data.files.filename);
                console.log("Clicked the drop button");*/
                try { // here I try thinking that I can call the drop() callback but I'm still trying to wrap my head around how this all works.
                    drop(e, data);
                } catch(error) {
                    console.log("The error was: "+error);
                }
            });


        },
        submit: function (e, data) {
            $('#start-upload').on('click', function() {
                //$('#start-upload').addClass('#disabledInput');
                console.log("This is the start upload button!");
            });
        },
        done: function (e, data) {
            /*$.each(data.result.files, function (index, file) {
                $('<p/>').text(file.name).appendTo('.files').find('#panel-body');
            });*/
        },
        progressall: function (e, data) {
            var progress = parseInt(data.loaded / data.total * 100, 10);
            $('#progress .bar').css(
                'width',
                progress + '%'
            );
        },
        drop: function (e, data) {
            $.each(data.files, function (index, file) {
                //$('.btn-danger').on('click', function() {
                    console.log('Dropped file: '+ file.name +'\n');
                //});
            });
        }
    }).on('.fileuploadsubmit', 'click', function(e, data) {
        console.log("Submit button pressed.");
        //data.formData = data.context.find(':input').seralizeArray();
    });
});

Lastly, should all of this be placed inside my $(document).ready?

I do realize that this may be a re-post of this post but that's two questions in one where here I figured I subdivide it into smaller problems.

2条回答
叼着烟拽天下
2楼-- · 2019-07-05 13:32

According to the Documentation for the plugin there should be a .destroy method, but the docs are pretty fuzzy about how to initialize it, or if its to destroy a file from the array, or just destroy the whole form. There should be a way, at-least in theory there should be.

As for the second part, yes. Your code should be in a jQuery initializer such as $(document).ready or the more popular $(function() {});

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-07-05 13:44

Abort from upload by click event

First I need to tell you, that I've built something similar to you. After reaching that point I asked myself the same questions and ended up here. Unfortunatly I had to help myself and solved it.

Your basic problem is that you are using a method signature for the click event (function(e, data)) that will overwrite the signature of the containing add method (function(e, data)). So while you've been trying to remove the data context you were actually altering the data of the click event. So just leave the variables (or either rename them) in the click event, because in your example you don't need them.

After doing that you end up trying to cleanly "destroy" uploads. I figured out, it's clean to first abort them and disable any later submit.

Here is a working code example that should fit your needs and has some self-explanatory comments:

add: function (e, data) {

// Append data context to collection.
data.context = $('<li class="list-group-item">'+data.files[0].name+'<button class="btn btn-danger btn-xs pull-right"><i class="glyphicon glyphicon-trash"></i></button>')
    .appendTo('.list-group');

// Search in the children of the data context for the button
// and register the click event.
data.context.children('button')
    .click(function () {
        // This button will be disabled.
        $(this).addClass('disabled');
        // Abort the data upload if it's running.
        data.abort();
        // Overwrite the plugin's default submit function.
        data.submit = function () { return false; };
        // Optional: Remove the data context (thus from collection).
        //data.context.remove();
        })
    ;

},

Additional hint: Don't use double quotation marks for JavaScript, because you need to escape them within the HTML-markup.

How to load the JavaScript

This question is far more complex than you expect. It's a never-ending discussion of conformity/clean HTML-markup versus page loading. When choosing one direction you end up in another choice between onload-events and jQuery. You should open another question or try to find a related one. While doing that I agree with putting your scripts in a clean anonymous function, which is automatically loaded after the document being ready: $(function() { /*yourcontent*/ });.

查看更多
登录 后发表回答