in

Dot Net Mafia

Group site for developer blogs dealing with (usually) .NET, SharePoint, Office 365, Mobile Development, and other Microsoft products, as well as some discussion of general programming related concepts.

Not Necessarily Dot Net

Real World Dojo part Four: User Feedback

So now we have a simple form that uses AJAX to upload a file and submits some metadata for the server to associate with that file.

It doesn't really give any useful feedback, though.  No real end-user's going to read the console, I'm not actually doing anything with the file upload progress, and using an alert to show that the metadata uploaded is incredibly lame.

Easy part first.  The response from the XHR. Add a div for feedback:

     <div id="metadataFeedback"></div>

And let's make the response handler do something vaguely interesting:

                        if(typeof data == "error"){
                            alert("Error!");
                            console.log(args);
                        }else{
                            dojo.fadeOut({node: box, duration:0}).play();
                            box.innerHTML = data;
                            dojo.fadeIn({node: box, duration:5000, delay:500}).play();
                        }

(I did warn you that it was only vaguely interesting).

The point to doing the fadeOut first is to avoid animation flicker while the DOM is being updated.

Feedback about the file upload is a tad bit more involved.

Add some divs for tracking upload progress:

    <div id="uploadProgress"></div>
    <div id="uploadResult"></div>

So far, I've limited these articles to using events assigned in the markup.  Now we have to scrape the surface of Dojo's rich event system.  The nutshell version is that, in an addOnLoad method (or whenever else seems appropriate) you connect various named events to whatever function you want to fire when that event happens.

For  starters, let's inform the user that we realize they've selected a file:

            dojo.connect(uploader, "onChange", function(data){
                dojo.forEach(data, function(d){
                    if(selectMultipleFiles){
                        dojo.byId("fileToUpload").innerHTML += "File to upload: " +
                            d.name+" " + Math.ceil(d.size*.001)+"kb \n";
                    }else{
                        dojo.byId("fileToUpload").innerHTML = "File to upload: " + d.name
                            + " " + Math.ceil(d.size*.001)+"kb \n";
                    }
                });
            });

Letting the user know that the upload is complete should be this simple:

             dojo.connect(uploader, "onComplete", function(data){
                console.log("Upload complete");
                console.dir(data);
                dojo.forEach(data, function(d){
                    dojo.byId("uploadProgress").innerHTML = d.name;

                    // FIXME: Actually, want to display the uploaded picture
                    dojo.byId("uploadResult").innerHTML = "Finished: " + d;
                    console.dir(d);
                });
            });

For whatever reason, that event isn't firing.  That forces me to shoehorn things in the progress event:

            dojo.connect(uploader, "onProgress", function(data){
                dojo.byId("uploadProgress").innerHTML = "";
                // Think the forEach is for handling multiple files
                dojo.forEach(data, function(d){
                    var progress = "(" + d.percent + "%) " + d.name;
                    dojo.byId("uploadProgress").innerHTML += progress;

                    var movie = uploader.flashMovie;

                    // Kludge because onComplete isn&#8217;t getting called:
                    if(d.percent == 100){
                        // Do another AJAX postback to get the URL to the image

                        dojo.xhrGet({
                            url: "/beta/test/get_url?id=some_guid",
                            handleAs: "text",
                            handle: function(data, args){
                                var box = dojo.byId("metadataFeedback");

                                if(typeof data == "error"){
                                    // Unfortunately, w/ web2py, we never actually get here
                                    alert("Error!");
                                    console.log(args);
                                }else{
                                    console.log("URL: " + data);
                                    var result = dojo.byId("uploadResult");
                                    result.innerHTML = '<img src="' + data + '" />'
                                }
                            }
                        });
                    }
                });
            });

Obviously, your server should be handling the file upload and be able to return a URL to the newly added picture.

Have I mentioned before that Dojo's file-handling abilities seem to leave a bit to be desired?

 

Comments

No Comments

Leave a Comment

(required)  
(optional)
(required)  
Add
2015 dotnetmafia.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems