Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to populate Kendo Upload with previously uploaded files

Tags:

kendo-ui

I'm using the Kendo UI File Upload for MVC and it works great. On my edit page, I want to show the files that were previously uploaded from the Create page. For visual consistency, I would like to re-use the upload widget on my edit page so the user can use the "remove" functionality, or add additional files if they choose. Does the upload widget support this?

Thanks!

like image 435
Buster Avatar asked Dec 17 '12 19:12

Buster


4 Answers

So, I realize this is question pretty old, but I recently figured out how to do this reliably. While the other answer on here will certainly display the files, it doesn't really wire it up to any of the events (specifically the "remove" event). Also, rather than manually setting all of this up, I figured I'd much rather have Kendo do all of the real dirty work.

Note, this only applies if your file upload is not set to autosync. If you use the auto upload feature, you can find examples in the Kendo documentation here: http://docs.kendoui.com/api/web/upload#configuration-files

So anyway, let's assume we have a file input that we've made into a Kendo Upload:

<input id="files" name="files" type="file" multiple="multiple" />
$(document).ready(function () { 
    var $upload = $("#files");
    var allowMultiple = Boolean($upload.attr("multiple"));

    $upload.kendoUpload({
        multiple: allowMultiple,
        showFileList: true,
        autoUpload: false        
    });
}

Then, we just need to get the information about the files to our jQuery. I like to jam it into JSON strings in hidden fields, but you can do it however you want.

Here's an example using the Mvc HtmlHelpers and Newtonsoft's JSON.NET (I don't use Razor, but you should get the general idea):

if (Model.Attachments.Count > 0)
{
    var files = Model.Attachments.Select(x => new { name = x.FileName, extension = x.FileExtension, size = x.Size });
    var filesJson = JsonConvert.SerializeObject(files);
    Html.Render(Html.Hidden("existing-files", filesJson));
}

Note, the format there is incredibly important. We're tying to match the structure of the JavaScript object that Kendo is expecting:

{
    relatedInput : sourceInput,
    fileNames: [{ // <-- this is the collection we just built above            
        name: "example.txt",
        extenstion: ".txt",            
        size: 1234
    }]
}

So, then all that's left to do is put it all together. Basically, we're going to recreate the onSelect function from Kendo's internal syncUploadModule:

$(document).ready(function () {
    // setup the kendo upload
    var $upload = $("#files");
    var allowMultiple = Boolean($upload.attr("multiple"));

    var upload = $upload.kendoUpload({
        multiple: allowMultiple,
        showFileList: true,
        autoUpload: false        
    }).getKendoUpload();

    // initialize the files
    if (upload) {
        var filesJson = $("[name$='existing-files']").val();
        if (filesJson) {                
            var files = JSON.parse(filesJson);

            var name = $.map(files, function (item) {
                return item.name;
            }).join(", ");

            var sourceInput = upload._module.element.find("input[type='file']").last();
            upload._addInput(sourceInput.clone().val(""));
            var file = upload._enqueueFile(name, {
                relatedInput : sourceInput,
                fileNames : files
            });
            upload._fileAction(file, "remove");
        }
    }
});

And that's pretty much it!

like image 83
valverij Avatar answered Dec 10 '22 16:12

valverij


I came up with a way to do this.

Basically, you need HTML that mimics what the Upload control generates, and you use a bit of JavaScript to hook each item up. I initially render the HTML as hidden, then after you initialize the Kendo Upload control, you append the HTML list to the parent container that Kendo creates.

This is my MVC view:

@if (Model.Attachments != null && Model.Attachments.Count > 0)
{
  <ul id="existing-files" class="k-upload-files k-reset" style="display: none;">
    @foreach (var file in Model.Attachments)
    {
      <li class="k-file" data-att-id="@file.Id">
        <span class="k-icon k-success">uploaded</span>
        <span class="k-filename" title="@file.Name">@file.Name</span>
        <button type="button" class="k-button k-button-icontext k-upload-action">
          <span class="k-icon k-delete"></span>
          Remove
        </button>
      </li>
    }
  </ul>
}

and here is the JavaScript (note, it was generated from CoffeeScript):

var $fileList, $files, item, _fn, _i, _len;
$fileList = $("#existing-files");
if ($fileList.length > 0) {
  $(".k-upload").append($fileList);
  $files = $(".k-file");
  _fn = function(item) {
    var $item, fileId, filenames;
    $item = $(item);
    fileId = $item.data("att-id");
    filenames = [
      {
        name: fileId
      }
    ];
    return $item.data("fileNames", filenames);
  };
  for (_i = 0, _len = $files.length; _i < _len; _i++) {
    item = $files[_i];
    _fn(item);
  }
  $fileList.show();
}

You can find the full write up on my blog where I go into depth on the topic. I hope this helps you!

like image 40
dwhite Avatar answered Dec 10 '22 17:12

dwhite


Some additional searches gave me the answer I wasn't looking for - According to this and this, Telerik does not support pre-populating an upload widget with previously uploaded documents.

like image 39
Buster Avatar answered Dec 10 '22 17:12

Buster


It has been added in the options since this question has been asked.

Check out http://docs.telerik.com/kendo-ui/api/web/upload#configuration-files

It only works in async mode.

like image 44
Nabab Avatar answered Dec 10 '22 16:12

Nabab