This is a migrated thread and some comments may be shown as answers.

Batch mode - Not working?

15 Answers 793 Views
Upload
This is a migrated thread and some comments may be shown as answers.
IS SAM
Top achievements
Rank 1
IS SAM asked on 10 Oct 2014, 02:47 AM
Hi All,

I've got the simplest upload control with batch mode enabled.

View is;
            @(Html.Kendo().Upload().Name("uploadFiles").Async(a => a.Save("Upload", "Home").AutoUpload(false).Batch(true)))

Controller is;
        public JsonResult Upload(IEnumerable<HttpPostedFileBase> uploadFiles)
        { 
                  return new JsonResult();
        }

Hoping to see a single call to the action which handles the upload with multiple files. Instead, once I hit upload, I see a separate request for each file that was selected. I must be doing something wrong but finding it hard to figure out what, since the setup is so simple.

Running it in IIS Express, however I've tried with IIS8 and that didn't work either.

Telerik Version: 2014.2.1008
Browser : Chrome 37.0.2062.124

Thanks a lot.
Chris R

15 Answers, 1 is accepted

Sort by
0
IS SAM
Top achievements
Rank 1
answered on 10 Oct 2014, 02:53 AM
Here's the project zipped up. I've kept the NuGet package folder and Kendo.Mvc.dll out to keep the size within limits.
0
Dimiter Madjarov
Telerik team
answered on 10 Oct 2014, 08:00 AM
Hello Chris,


This behavior is expected. The batch mode applies to multiple files, which are selected at the same time i.e. a single list item and a single input are created for them. Files selected one after the other, as in the current case will be uploaded in separate requests.

Let me know if this information helps or I could assist further.

Regards,
Dimiter Madjarov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
IS SAM
Top achievements
Rank 1
answered on 13 Oct 2014, 02:02 AM
Hi Dimiter,

Thanks  a lot for the response. Whilst fully understanding the way the control behaves as of now, may I pick your brains a bit more. 

As you can see in the attached image, I want the user to upload multiple files with each having its own copy of meta data (A start & end date in this instance). It's essential that the files and their meta data reach the server in 1 request for the file processing and validations. Do you see me achieving this anyway in async mode without going for a form submit?

btw I'm open for hacking the kendo js if we want to go that far. 




0
Dimiter Madjarov
Telerik team
answered on 13 Oct 2014, 07:23 AM
Hi Deborah,


You could use the following approach to attach the metadata. Each file have unique uid property which is set as data-uid attribute to the list item. You could use them to access the associated date pickers.
E.g.
.Events(e => e.Upload("onUpload"))
asdf
function onUpload(e) {
    var uid = e.files[0].uid;
    var listItem = this.wrapper.find(".k-file[data-uid='" + uid + "']");
 
    //use listItem to access the date pickers and attach metadata
}

Regards,
Dimiter Madjarov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
IS SAM
Top achievements
Rank 1
answered on 14 Oct 2014, 12:08 AM
Hi Dimiter,

Thank you for your continuous help. I may have misguided the conversation by mentioning meta data - as I have no problem attaching it to the request. The problem is forcing the control to send multiple files (which were added as separate list items) in 1 request in async mode. 

As you correctly pointed out this is not available by default through configuration. What I'm after now, is to get this working by either modifying kendo code or any other 'javascripty' way. Any guidance is much appreciated.

Regards,
IM
0
Accepted
Dimiter Madjarov
Telerik team
answered on 14 Oct 2014, 08:52 AM
Hi Deborah,


At the moment this is not possible with the Kendo UI Upload widget, but you could post it as a suggestion in our Feedback portal. Regarding the custom modifications of the Kendo UI source code, such are not supported, so I could not provide technical assistance in that matter.

Regards,
Dimiter Madjarov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
IS SAM
Top achievements
Rank 1
answered on 11 Nov 2014, 02:33 AM
I have posted the request in the portal - http://kendoui-feedback.telerik.com/forums/127393-telerik-kendo-ui-feedback/suggestions/6562500-enable-batch-upload-of-multiple-list-items-in-kend
0
Dimiter Madjarov
Telerik team
answered on 12 Nov 2014, 09:10 AM
Hello Deborah,


Thank you for posting the suggestion. If it's popular among the community and needed from other users too, we will consider to implement it in future versions of Kendo UI.

Regards,
Dimiter Madjarov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
David Yardy
Top achievements
Rank 1
answered on 26 Feb 2015, 11:24 PM
So, are we saying that using async that each file has to hit the server for each file uploaded? (so 3 files, 3 requests to server?) - Our issue is i need to associate all 3 documents to same parent record.  How best can we associate 3 uploaded documents to the same parent Id? 

is it possible if using non-ajax? (say with form post) > is this the best only alternative?
0
T. Tsonev
Telerik team
answered on 02 Mar 2015, 05:46 PM
Hello,

I'll update this thread for community reference, as we've already addressed the issue in a support ticket.

The recommended approach to associate the individual uploads is to transmit the originating entity ID as metadata. Files can be stored in a temporary location until the create/update operation is complete.

Regards,
T. Tsonev
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
David PettyJohn
Top achievements
Rank 1
answered on 02 Feb 2017, 05:35 PM
I also would like a way to asynchronously send multiple files in batch with only one request as opposed to multiple.  Any update?
0
Dimiter Madjarov
Telerik team
answered on 03 Feb 2017, 08:19 AM

Hello David,

Does the built in async.batch option suits the current requirements? It will allow uploading all files selected at once in a single request.

Regards,
Dimiter Madjarov
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
David PettyJohn
Top achievements
Rank 1
answered on 07 Feb 2017, 09:24 PM

It worked fine if you either only selected one file or if you selected multiple files at once upon clicking the "Select Files" button, however, if you selected one file, then clicked "Selected Files" button again to pick a different file or files, the behavior was that the action wired up to Save gets called more than once as David Yardy mentioned.  Here's how I made it work for my use case.  What I wanted was to be able to have the uploader control as part of another form where the user was entering other data as well as optionally attaching files.  I made use of ASP MVC Application cache to save the documents temporarily that then can be grabbed out of memory by a subsequent server request to save all of the form data including the attachments if there were any.

@using System.Web.UI.HtmlControls
@model MvcTemplate.UploadTestVm
@{
 ViewBag.Title = "Index";
}
<script language="javascript">
function getViewModelFromFormData() {
//Return Anonymous Javascript object with same properties as your
//view model object with values from the form controls
var returnObj = {
    Name: $('#txtName').val()
    };
return returnObj;
    }
function saveData() {
var ctrlKendoUploader = $('#updFiles').data('kendoUpload');
var filesUploaded = ctrlKendoUploader.getFiles();
if (filesUploaded.length > 0) {
//this will cause the upload control queue up event to post the files using the specified save action on the upload control
    ctrlKendoUploader.upload();
    } else {
//If the user did not attached files then just get the other form data and call method to post form
var vmObj = getViewModelFromFormData();
    submitForm(vmObj);
    }
    }
function submitForm(formDataVm) {
//Ajax call to post for the form data
var url = '@Url.Action("SaveFormData", "Upload", new { fileUploaderId = ViewBag.FileUploaderId })';
    $.ajax(
    {
    url: url,
    type: "POST",
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify(formDataVm),
    success: function (data) {
var ctrlKendoUploader = $('#updFiles').data('kendoUpload');
if (data.succesInd === true) {
    alert('Success!');
    } else {
    ctrlKendoUploader.clearAllFiles();
    alert('Failure!');
    }
    }
    });
    }
function onUploadComplete(e) {
//On upload complete then get a JSON object
//representing your View Model and call method to post via AJAX
var vmObj = getViewModelFromFormData();
    submitForm(vmObj);
    }
function onUploadSelect(e) {
    setTimeout(function () {
//hide the 'Upload' and 'Cancel' buttons
    $(".k-clear-selected").hide();
    $(".k-upload-selected").hide();
    }, 10);
    }
function onUploadError(e) {
debugger;
if (e.operation == 'upload') {
    alert('error');
//do some other error handling
    }
    }
</script>
<h2>Upload Test Page</h2>
<div class="row">
    @(Html.Kendo().Upload()
    .Name( "updFiles" )
    .Multiple( true )
    .Async( pA => pA
    .AutoUpload( false )
    .Batch( true )
.Save( "ProcessFiles", "Upload" , new {fileUploaderId = ViewBag.FileUploaderId })
    )
    .ShowFileList( true )
    .Events( pE => pE
    .Select( "onUploadSelect" )
    .Complete( "onUploadComplete" )
    .Error("onUploadError")
    )
    )
</div>
<div class="row">
<div class="form-group">
<label class="control-label" for="txtName">Name:</label>
@Html.TextBoxFor(m => m.Name, new { id="txtName", @class = "form-control input-sm", placeholder = "Enter a name" })
</div>
</div>
<div class="row">
<button class="btn btn-primary" onclick="saveData();">Save</button>
</div>
 

Controller Code

public ActionResult Index()
        {
            var uploadVm = new UploadTestVm {Name=""};
            ViewBag.FileUploaderId = Guid.NewGuid();
            return View( uploadVm );
        }
 
        public ActionResult ProcessFiles( IEnumerable<HttpPostedFileBase> updFiles, string fileUploaderId)
        {
 
            List<HttpPostedFileBase> fileUploads = new List<HttpPostedFileBase>();
            //Use lock to make the collection thread-safe
            lock(fileUploads)
            {
                if (HttpContext.Application[fileUploaderId] == null)
                {
                    HttpContext.Application[fileUploaderId] = fileUploads;
                }
                else
                {
                    fileUploads = (List<HttpPostedFileBase>)HttpContext.Application[fileUploaderId];
                }
                fileUploads.AddRange(updFiles);
            }
            return Json( new {successInd = true, numDocsAttached = updFiles.Count()/*documentList.Count*/} );
        }
 
        public ActionResult SaveFormData(UploadTestVm uploadTest, string fileUploaderId)
        {
            var success = true;
            var returnMsg = "";
            try
            {
                var fileList = HttpContext.Application[fileUploaderId] as List<HttpPostedFileBase>;
                //Call your code to save both the form data and the files
 
            }
            catch ( Exception ex )
            {
                success = false;
                returnMsg = ex.Message;
            }
            finally
            {
                HttpContext.Application.Remove(fileUploaderId);
            }
            return Json( new {succesInd = success, msg = returnMsg } );
        }

 

The one caveat being that you have to configure in web.config the <httpRuntime> tag under <system.web> to allow for attachments larger than 80 K in one request.

<httpRuntime maxRequestLength="20480" requestLengthDiskThreshold="4096"  />
0
Dimiter Madjarov
Telerik team
answered on 09 Feb 2017, 08:47 AM

Hello David,

Thank you for sharing the approach with the community. Indeed files selected by clicking the "Select files" button a second time will be uploaded in another request. This behavior is by design.

Regards,
Dimiter Madjarov
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Chris
Top achievements
Rank 1
answered on 03 Sep 2019, 10:23 PM

Batch mode complete solution is here:  https://www.telerik.com/forums/how-to-set-initial-files-from-model-when-using-upload-tag-helper#KWe1kZJ-aEig9eoe1Q7_lA

 

Tags
Upload
Asked by
IS SAM
Top achievements
Rank 1
Answers by
IS SAM
Top achievements
Rank 1
Dimiter Madjarov
Telerik team
David Yardy
Top achievements
Rank 1
T. Tsonev
Telerik team
David PettyJohn
Top achievements
Rank 1
Chris
Top achievements
Rank 1
Share this question
or