Friday, 16 December 2011

NeatUpload jQuery plugin – Examples – Part 2

In my last post I covered two scenarios where we changed the texts and the elements for the actions add and upload. Well, let's continue with these changes, in this case the turn is for the link of cancel operation. It's a bit more complex than the others, that's why I've let for another post, but no so hard to do.
Scenario 3 – Changing the cancel link.

Due to the fact the cancel link has a special function and is intended for call an internal function, it’s required that the custom cancel element to call sendCancel function on its click event. This function can be accessed through plugin parameter and options object. Let’s check the code:

@{
    // get the text from wherever i.e. some i18n service in the application
    var textAdd = "Add a file to upload list";
    var textUpload = "Start Upload";
    var textCancel = "Abort Operation";
}
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.neatupload.js")" type="text/javascript"></script>
<script type="text/javascript" defer="defer">
    $(function() {
        $("#file1").neatupload({
            postDataUrl: $("input[type=hidden][id=upload-action]").val(),
            fnShowStatus: function (plugin, index, data) {
                $('span#progress-file').text(data.PercentComplete + "%");
            },
            textCancel: "@textCancel",
            selectorButtonAdd: "input[name=addfile]",
            selectorButtonUpload: "input[name=uploadfile]",
            createCancelLink: function (plugin, index) {
                var cancel = $('<div>' + plugin.options.textCancel + '</div>')
                        .click(function () {
                                                plugin.options.sendCancel(plugin, index);
                        });
                return cancel;
            }
        });
    });
</script>

@using(Html.BeginForm("UploadFile", "Home"))
{
    @Html.Hidden("upload-action", Url.Action("UploadFile"))
    <div>
        @Html.Label("newfield", "Select File: ")
        <div id="file1">
            place holder for the input -> file for upload
        </div>
        <input type="button" name="addfile" value="@textAdd" />
        <input type="button" name="uploadfile" value="@textUpload" />
    </div>
    <div>
        <span id="progress-file"></span>
    </div>
    <div>
        <input type="submit" value="save"/>
    </div>
}
Here is a new parameter introduced in the last release: createCancelLink, which corresponds to a function with 2 parameters: plugin and index.
·         plugin is a reference to the current plugin element and is used for access the functions with the current data.
·         index is the unique identifier for the current file being queued for upload.
In the example just created a “div” element with a custom text and set the click event to an anonymous function which calls to plugin.options.sendCancel(plugin, index); and that’s the key point, through plugin.options it’s possible access to functions declared as public in the plugin (as in any other jquery plugin). The current values of plugin and index are passed to sendCancel internal who is responsible for send a “cancel” message to the server and stops the internal frame (in case of upload is in progress).

Scenario 3.1 – Changing the cancel link using a more complex DOM element.
In the previous example I demonstrated how to change the element cancel, and that works will if this element is very simple (as in the example, of course), but what if we have an element previously created in the page? I suggest this code fragment for solve it.

(...)
createCancelLink: function (plugin, index) {
    var cancel = $("input[name=cancelupload]").clone();
    cancel.show().click(function () {
        plugin.options.sendCancel(plugin, index);
    });
    return cancel;
}
(...)
<input type="button" name="cancelupload" value="@textCancel" style="display: none" />

Here I have an input button named “cancelupload” hidden by default using inline style and this will be the element chosen for cancel. The first is get it via query (remember, we are using jquery so take all advantages) and make a clone, then show it and finally assign the click function for the event handler like the previous example.
Scenario 4 – Start upload immediately.
Sometimes we don’t want the user follow the two steps: add and upload, This is useful for applications where the user only upload one file at time, for example: attach a file in a webmail interface, set up a profile logo image, etc. I have a solution for that and I show you as follows:

fnAddFile: function (plugin, filename, form, index) {
    $(plugin.options.selectorButtonUpload).click();
}

I introduce you a new parameter fnAddFile, this is a function that is called when a new file is going to be added to the queue. By default this function renders a visual element where we can see the cancel element, the name of the file being queued and a placeholder for the progress element.

In this case I have overridden this default behavior and I just call the click event of upload button element using the plugin.options.selectorButtonUpload parameter previously explained, I know that could be called as a little dirty but I think is valid, if we already have defined a button and its click event with a lot of work done, why not call it and go? At least this is my concept of reuse of code.

Well, I think it’s all for today, in the next post I’ll talk the third group of scenarios for use this plugin, which include personalizing the user interface using a more cute progress bar and more use of the uploaded file in server side. I hope this information to be useful for you. The source code for this example is available here.

2 comments:

  1. Hi Abel,

    I have a problem with my project when I cancel an file that is uploading, I have an HttpException with message "Upload canceled by user".

    It does not happen in your sample project and I don't see how you handle it...

    ReplyDelete
    Replies
    1. Hi Steve, did you manage to fix it? I'm having the same problem.

      Delete