If you hadn’t guessed by my last two posts, I’ve been using Telerik’s Kendo UI controls for a project I’m working on. Today we’re going to talk about the Kendo UI Upload control, which I have been using in asynchronous mode. As I’ve stated plenty of times before, I’m not a huge fan of 3rd party controls, but the Upload control is pretty nice. That said, there is a nagging issue with the control.
The project I am working on has a form that users use as an editor for a “forum” of sorts. They can enter messages and add attachments. They are also free to edit their entries, and make changes to the attachments (add or remove them). Well, that’s where the Kendo UI Upload control falls short. There isn’t a “built-in” way to add an existing list of files and let users remove them using the default Upload interface. You could always write your own UI for displaying the existing files, but that’s a bunch of extra work. Shouldn’t you just be able to use the existing interface and not have to come up with something different? That was my goal. You can hack things fairly easily so that you get a list of the files, but the built-in “Remove” button doesn’t work. That’s what we will discuss in this post. We’ll get the list generated AND have the “Remove” button work as expected (where it calls your Remove URL and actually removes the item from the list).
ASIDE: Before we go any further: I’m not saying “Go out and buy Kendo UI” with this post; there’s no incentive in endorsing the product. Of course if Telerik wants to provide me with a free license, you know, that would be cool ;) Again, I’m not a huge fan of 3rd party tools. I happen to be using them for a client and I encountered this specific issue, and I’m not the only one. The purpose of this post (like the majority of the posts on this blog) is to help others keep their sanity.
There have been numerous inquiries around the web regarding this nagging issue, at StackOverflow, the Telerik MVC Controls Forum (the precursor to Kendo UI), and the Kendo UI Forums. Despite this, there are no real solutions on the web, though that MVC Controls Forum post gets you close.
In case you aren’t familiar with asynchronous Upload control, it’s a very simple design.
![Kendo UI Upload Control]
ulportion is generated once you upload a file.
Keep this structure in mind as we move through the process as this is what we’ll be building manually. For the examples, I’ll make references to ASP.NET MVC, but this approach isn’t .NET specific. You can use Kendo UI with just about any framework.
The MVC View
The initial setup for the Upload control is a piece of cake. In my project I’m using [Kendo’s MVVM] approach to set up the Upload control (this is inside a form partial, named _Form.cshtml). We’ll simply add a
file input and set some
data-* attributes to support the setup.
I like the MVVM approach for set up because I’m able to initialize multiple Kendo UI controls by simply calling
kendo.init with the parent object (in my case it’s a
In order to get the existing files list, I mimic the list (the
ul) found in the snagged HTML snippet from earlier. There is one main difference, my list is hidden. It is hidden because the file list has to be appended to Kendo’s generated parent element for the Upload control,
div.k-upload. That element can be found in the snippet that is generated, which I listed out earlier in the post. In addition, we’ll need to hook up some
data to each of the
lis after the Upload control is initialized, but that’s getting ahead of ourselves. With that in mind, let’s look at the rest of the code in _Form.cshtml:
ASIDE: I don’t want the list to generate if there isn’t any attachments on my model, hence the
Fairly straight-forward, right? Just loop through and add an
li that looks like the one that Kendo would create after you upload a file.
We’re on our way, but let’s take a minute to discuss something with that last bit of code that is pretty easy to overlook. It initially tripped me up when I was working on this solution, so I want to make sure you don’t do the same thing.
When I was trying to get this approach to work, I ran into various issues. One thing preventing the Remove button from being wired up properly had to do with me not including that first
span within the
It didn’t seem like that would be necessary. It just puts a little checkbox next to the file name in the list. But it is important. Without that, the Remove button won’t make a request to the server. All that would happen is the
li will be removed from the list.
How exactly did I figure out what was happening? A bit of digging in the Kendo UI Upload source revealed the required
span. In the
onRemove function, you’ll find the following code:
removeUploadedFilemethod is the one that makes an AJAX call out to the server.
It makes perfect sense because if the file wasn’t uploaded correctly (as indicated by that
span with the two classes
.k-success), we wouldn’t need to call out to the server to delete anything.
Now that you are aware of the key elements in the HTML, let’s finish this solution up.
_fn. The CoffeeScript
doloop yields this to generate a closure. It’s probably not something you would have written out, but that closure keeps everything isolated inside the loop. You can read more about this on [Justin Reidy’s blog].
First, the CoffeeScript:
The code should be fairly self-explanatory, but let’s quickly review what’s happening. First we check if our
existing-files element was generated (remember, I’m only outputting the block if there are existing attachments). From there, we loop through the
k.file elements (the
lis) and wire up the required
ASIDE: I’m not sure why it takes an array of “filenames.” Each
lishould represent one file, but alas, that is what it needs.
The Kendo UI Upload control uses the
data when posting to the
If you were to inspect what is generated by Kendo after you do an upload, you’ll see that it stores a bunch of information about the file, e.g. size, name, etc. in the
data attribute. For our purposes, all we need to include is a way for us to distinguish each file on the server. Whatever you need to do that should be set to the
name property of the object inside the
fileNames array. In my case, I’m using GUID instead of the file name.
So there you have it. It is possible to add a pre-populated list of uploaded files. It’s just two steps, the first is to create the list items, making sure to include the
fileNames for the
data of each
li. It’s actually not too difficult when you know what it entails.
https://images.visoftinc.com/2013-02-25/fig01.png : http://docs.kendoui.com/documentation/getting-started/framework/mvvm/overview : http://js2coffee.org : http://rzrsharp.net/2011/06/27/what-does-coffeescripts-do-do.html : http://www.dyn-web.com/tutorials/obj_lit.php