New to Telerik UI for ASP.NET CoreStart a free 30-day trial

Upload Files from Grid Popup Editor

Environment

ProductTelerik UI for ASP.NET Core Upload
Progress Telerik UI for ASP.NET Core version2024.4.1112

Description

How can I add and use the Upload component in the Popup editable Grid?

Solution

The example below shows how to integrate the Upload component into the custom template of a Popup editable Grid.

  1. Define a Popup editable Grid that uses a custom editor template.

    Razor
        @(Html.Kendo().Grid<FileViewModel>()
            .Name("grid")
            .Columns(columns =>
            {
                columns.Bound(p => p.FileId);
                columns.Bound(p => p.FileName);
                columns.Command(command => { command.Edit(); command.Destroy(); }).Width(200);
            })
            .ToolBar(toolbar => toolbar.Create())
            .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("CustomPopupEditor"))
            .Pageable()
            .Scrollable()
            .HtmlAttributes(new { style = "height:550px;" })
            .DataSource(dataSource => dataSource
                .Ajax()
                .PageSize(20)
                .Model(m =>
                {
                    m.Id(f => f.FileId);
                    m.Field(f => f.FileId).Editable(false);
                })
                .Read(read => read.Action("Read", "Grid"))
                .Update(update => update.Action("Update", "Grid"))
                .Create(create => create.Action("Create", "Grid"))
                .Destroy(destroy => destroy.Action("Destroy", "Grid"))
            )
        )
    
  2. Create the custom editor template CustomPopupEditor.cshtml in the ~/Views/Shared/EditorTemplates folder. Define the FileName property as read-only, since it will be populated dynamically based on the uploaded file in the next Step. Also, handle the Success event of the Upload control to get the name of the uploaded file.

    CustomPopupEditor.cshtml
        @model FileViewModel
    
        @Html.HiddenFor(model => model.FileId)
    
        @(Html.Kendo().TextBoxFor(m => m.FileName).Readonly(true))
    
        <br/><br/>
        
        @(Html.Kendo().Upload()
            .Name("file")
            .Multiple(false)
            .Async(a => a
                .Save("SaveFile", "Grid")
                .Remove("RemoveFile", "Grid")
                .AutoUpload(true)
            )
            .Validation(validation => validation.AllowedExtensions(new string[] { ".gif", ".jpg", ".jpeg", ".png" }))
            .Validation(validation => validation.MaxFileSize(3145728))
            .Events(ev => ev.Success("onUploadSuccess"))
        )
  3. Set up the Save and Remove Action methods of the Upload.

    C#
    public IWebHostingEnvironment WebHostEnvironment { get; set; }
    
    public GridController(IWebHostEnvironment webHostEnvironment)
    {
        WebHostEnvironment = webHostEnvironment;
    }
    
    public async Task<ActionResult> SaveFile(IEnumerable<IFormFile> files)
    {
        // The Name of the Upload component is "files".
        if (files != null)
        {
            foreach (var file in files)
            {
                var fileContent = ContentDispositionHeaderValue.Parse(file.ContentDisposition);
    
                // Some browsers send file names with full path.
                // We are only interested in the file name.
                var fileName = Path.GetFileName(fileContent.FileName.ToString().Trim('"'));
                var physicalPath = Path.Combine(WebHostEnvironment.WebRootPath, "App_Data", fileName);
    
                using (var fileStream = new FileStream(physicalPath, FileMode.Create))
                {
                    await file.CopyToAsync(fileStream);
                }
            }
        }
    
        // Return an empty string to signify success.
        return Content("");
    }
    
    public ActionResult RemoveFile(string[] fileNames)
    {
        // The parameter of the Remove action must be called "fileNames".
    
        if (fileNames != null)
        {
            foreach (var fullName in fileNames)
            {
                var fileName = Path.GetFileName(fullName);
                var physicalPath = Path.Combine(WebHostEnvironment.WebRootPath, "App_Data", fileName);
    
                // TODO: Verify user permissions.
    
                if (System.IO.File.Exists(physicalPath))
                {
                    System.IO.File.Delete(physicalPath);
                }
            }
        }
    
        // Return an empty string to signify success.
        return Content("");
    }
  4. Update the value of the FileName Model property with the name of the uploaded file in the Upload Success event handler.

    Razor
        <script>
            function onUploadSuccess(e) {
                var files = e.files;
                var grid = $("#grid").getKendoGrid(); // Get a reference to the Grid
                var fileNameTextBox = $("#FileName").data("kendoTextBox"); //Get a reference to the TextBox editor in the Popup template
                if (e.operation == "upload") {
                    var uploadedFileName = e.files[0].name; // Get the name of the successfully uploaded file.
                    fileNameTextBox.value(uploadedFileName); // Change the TextBox value based on the name of the uploaded file.
                    fileNameTextBox.trigger("change"); // It is required to trigger the 'change' event manually.
                    grid.editable.options.model.set("FileName", uploadedFileName); //Update the "FileName" Model property based on the uploaded file name.
                }
                if(e.operation == "remove") {
                    fileNameTextBox.value("");
                    fileNameTextBox.trigger("change");
                    grid.editable.options.model.set("FileName", "");
                }
            }
        </script>

More ASP.NET Core Upload Resources

See Also