Batch mode - Not working?

15 posts, 1 answers
  1. IS SAM
    IS SAM avatar
    5 posts
    Member since:
    Oct 2014

    Posted 09 Oct 2014 Link to this post

    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

  2. IS SAM
    IS SAM avatar
    5 posts
    Member since:
    Oct 2014

    Posted 09 Oct 2014 in reply to IS SAM Link to this post

    Here's the project zipped up. I've kept the NuGet package folder and Kendo.Mvc.dll out to keep the size within limits.
  3. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2205 posts

    Posted 10 Oct 2014 Link to this post

    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.

     
  4. IS SAM
    IS SAM avatar
    5 posts
    Member since:
    Oct 2014

    Posted 12 Oct 2014 in reply to Dimiter Madjarov Link to this post

    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. 




  5. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2205 posts

    Posted 13 Oct 2014 Link to this post

    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.

     
  6. IS SAM
    IS SAM avatar
    5 posts
    Member since:
    Oct 2014

    Posted 13 Oct 2014 in reply to Dimiter Madjarov Link to this post

    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
  7. Answer
    Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2205 posts

    Posted 14 Oct 2014 Link to this post

    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.

     
  8. IS SAM
    IS SAM avatar
    5 posts
    Member since:
    Oct 2014

    Posted 10 Nov 2014 in reply to Dimiter Madjarov Link to this post

    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
  9. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2205 posts

    Posted 12 Nov 2014 Link to this post

    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.

     
  10. David Yardy
    David Yardy avatar
    22 posts
    Member since:
    Aug 2007

    Posted 26 Feb 2015 in reply to Dimiter Madjarov Link to this post

    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?
  11. T. Tsonev
    Admin
    T. Tsonev avatar
    2779 posts

    Posted 02 Mar 2015 Link to this post

    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.

     
  12. David PettyJohn
    David PettyJohn avatar
    2 posts
    Member since:
    May 2008

    Posted 02 Feb in reply to David Yardy Link to this post

    I also would like a way to asynchronously send multiple files in batch with only one request as opposed to multiple.  Any update?
  13. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2205 posts

    Posted 03 Feb Link to this post

    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.
  14. David PettyJohn
    David PettyJohn avatar
    2 posts
    Member since:
    May 2008

    Posted 07 Feb in reply to Dimiter Madjarov Link to this post

    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"  />
  15. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2205 posts

    Posted 09 Feb Link to this post

    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.
Back to Top