We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

Uploader Inside Grid Cell

Hi.

Is there a way to render a file uploader control inside a datagrid when adding or editing records?
if it is possible, can you help me with a code example (controller side) to manage the file submition?

Thx =)

7 Replies

BS Balaji Sekar Syncfusion Team August 19, 2019 11:48 AM UTC

Hi Javier, 

Greetings from the Syncfusion support, 

As per your requirement we have created a sample for your reference. In the below sample , we have upload files using our uploader controller and stored uploaded file and other data in the server side(with the help of custom adaptor). While perform editing we have fetch the uploaded file(previously while adding) and you can able to edit the details and update the data in server side. 

Please refer the below code example and sample for more information. 

<div> 
    <ejs-grid id="Grid" load="load" actionComplete="complete" allowPaging="true" toolbar="@(new List<string>() { "Add", "Edit", "Cancel", "Update" })"> 
        <e-data-manager url="/Home/UrlDatasource" insertUrl="/Home/Save" updateUrl="/Home/Update" adaptor="UrlAdaptor"></e-data-manager> 
        <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Dialog"></e-grid-editSettings> 
        <e-grid-columns> 
            <e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" width="150"></e-grid-column> 
            <e-grid-column field="CustomerID" headerText="CustomerID" width="150"></e-grid-column> 
            <e-grid-column field="file" headerText="File" type="string" valueAccessor="@("fileName")" edit="@(new {create="fileCreate", read="fileRead", destroy="fileDestroy", write="fileWrite"  })" width="120"></e-grid-column> 
        </e-grid-columns> 
    </ejs-grid> 
</div> 
<script> 
    var file; 
    function fileName(field, data, column) { 
        //show only the file name in grid columns 
        return (data[field]) ? data[field].name : data[field] 
    } 
 
    function complete(args) { 
        if (args.requestType === 'add') { 
            args.form.setAttribute('enctype', 'multipart/form-data'); 
            args.form.setAttribute('encoding', 'multipart/form-data'); 
        } 
    } 
    function fileCreate() { 
        elem = document.createElement('input'); 
        return elem; 
    } 
    function fileRead(args) { 
        return (file) ? file : uploadObj.filesData; 
    } 
    function fileDestroy() { 
        uploadObj.destroy(); 
    } 
    function fileWrite(args) { 
        if (args.requestType === 'beginEdit') { 
            file = args.rowData.file; 
        } 
        uploadObj = new ej.inputs.Uploader({ 
            //while editing we have loaded the previous file 
            files: (args.requestType === 'beginEdit') ? [args.rowData.file] : [''] 
        }); 
        uploadObj.appendTo(elem) 
    } 
 
    window.customAdaptor = new ej.data.UrlAdaptor(); 
    function load() { 
        this.dataSource.adaptor = customAdaptor; 
    } 
    customAdaptor = ej.base.extend(customAdaptor, { 
 
        processResponse: function (data, ds, query, xhr, request, changes) { 
            request.data = JSON.stringify(data); 
            return ej.data.UrlAdaptor.prototype.processResponse.call(this, data, ds, query, xhr, request, changes) 
        }, 
        insert: function (dm, data, tableName) { 
            var fd = new FormData(); 
            // create new form data and append the data that we want to stored in server side 
            for (var prop of data.file) { 
                fd.append('UploadFiles', prop.rawFile); 
            } 
            fd.append('OrderID', data.OrderID); 
            fd.append('CustomerID', data.CustomerID); 
            return { 
                url: dm.dataSource.insertUrl || dm.dataSource.crudUrl || dm.dataSource.url, 
                type: "POST", 
                data: fd, 
                contentType: null 
            } 
        }, 
    }); 
 
</script> 

[AcceptVerbs("Post")] 
        // Upload method for chunk-upload and normal upload 
        public IActionResult Save(int OrderID, string CustomerID, IList<IFormFile> chunkFile, IList<IFormFile> UploadFiles) 
        { 
            long size = 0; 
            try 
            { 
                foreach (var file in UploadFiles) 
                { 
                    var filename = ContentDispositionHeaderValue 
                                    .Parse(file.ContentDisposition) 
                                    .FileName 
                                    .Trim('"'); 
                    var folders = filename.Split('/'); 
                    var uploaderFilePath = hostingEnv.WebRootPath; 
                    // for Directory upload 
                    if (folders.Length > 1) 
                    { 
                        for (var i = 0; i < folders.Length - 1; i++) 
                        { 
                            var newFolder = uploaderFilePath + $@"\{folders[i]}"; 
                            Directory.CreateDirectory(newFolder); 
                            uploaderFilePath = newFolder; 
                            filename = folders[i + 1]; 
                        } 
                    } 
                    size += file.Length; 
                    // insert data and uploaded files in server  
                    OrdersDetails.GetAllRecords().Insert(0, new OrdersDetails(){ OrderID=OrderID, CustomerID= CustomerID, file = new OrdersDetails.File(){ name=filename, onlinePath= uploaderFilePath + $@"\{filename}", size =size, type='.'+filename.Split('.')[1] } }); 
                    filename = uploaderFilePath + $@"\{filename}"; 
                    if (!System.IO.File.Exists(filename)) 
                    { 
                        using (FileStream fs = System.IO.File.Create(filename)) 
                        { 
                            file.CopyTo(fs); 
                            fs.Flush(); 
                        } 
                    . . . . . 
           } 
            return Content(""); 
        } 


Please get back to us, if you need further assistance. 

Regards, 
Balaji Sekar. 



JA Javier A Aguilera August 20, 2019 09:27 PM UTC

Imanaged to make the insert part work, but it was not possible for the update part. The record key field are empty when editing.



Controller:
 public async Task<IActionResult> DocumentacionEspecificaSiniestroGrid_CRUD(int DocumentacionID, int DetalleSiniestroID, int documentoID, bool Enviado, IList<IFormFile> UploadFiles)
        {
            //NO UPDATE FUNCTION HERE AS "DocumentacionID" HAS NO VALUE ON UPDATE FUNCTION
            var archivo = "";          
            var filename = ContentDispositionHeaderValue
                            .Parse(UploadFiles.FirstOrDefault().ContentDisposition)
                            .FileName
                            .Trim('"');
            var fileToSave = Guid.NewGuid().ToString() + Path.GetExtension(filename);
            archivo = fileToSave;
            filename = hostingEnv.WebRootPath + @"\DocumentosSiniestrosAutos\" + $@"\{fileToSave}";
            if (!System.IO.File.Exists(filename))
            {
                using (var fileStream = new FileStream(filename, FileMode.Create))
                {
                    await UploadFiles.FirstOrDefault().CopyToAsync(fileStream);
                }
            }
            var nuevo = new DocumentacionSiniestroAuto
            {
                DetalleSiniestroID = DetalleSiniestroID,
                documentoID = documentoID,
                Enviado = Enviado,
                NombreArchivo = archivo
            };
            _context.DocumentacionSiniestroAuto.Add(nuevo);
            _context.SaveChanges();
            return Json(nuevo);            
        }



VIEW:

@model int

<script>
    var file;
    function fileName(field, data, column) {
        return (data[field]) ? data[field].name : data[field]
    }
    function complete(args) {
        if (args.requestType === 'add') {
            args.form.setAttribute('enctype', 'multipart/form-data');
            args.form.setAttribute('encoding', 'multipart/form-data');
        }
    }

    function fileCreate() {
        elem = document.createElement('input');
        return elem;
    }  

    function fileRead(args) {
        return (file) ? file : uploadObj.filesData;
    }

    function fileDestroy() {
        uploadObj.destroy();
    }

    function fileWrite(args) {
       
        if (args.requestType === 'beginEdit') {
            file = args.rowData.NombreArchivo;
        }
        uploadObj = new ej.inputs.Uploader({
            files: (args.requestType === 'beginEdit') ? [args.rowData.file] : [''],
            autoUpload: true
        });
        uploadObj.appendTo(elem)
    }

    window.customAdaptor = new ej.data.UrlAdaptor();
    function load() {
        this.dataSource.adaptor = customAdaptor;
    }
    customAdaptor = ej.base.extend(customAdaptor, {

        processResponse: function (data, ds, query, xhr, request, changes) {
            request.data = JSON.stringify(data);
            //alert(data.DocumentacionID);
            return ej.data.UrlAdaptor.prototype.processResponse.call(this, data, ds, query, xhr, request, changes)
        },
        insert: function (dm, data) {
            var fd = new FormData();
            for (var prop of data.NombreArchivo) {
                fd.append('UploadFiles', prop.rawFile);
            }
            fd.append('DocumentacionID', data.DocumentacionID);
            fd.append('DetalleSiniestroID', @Model);
            fd.append('documentoID', data.documentoID);
            fd.append('Enviado', data.Enviado);
            //data.File = fd;
            return {
                url: dm.dataSource.insertUrl || dm.dataSource.updateUrl || dm.dataSource.url,
                type: "POST",
                data: fd,
                contentType: null
            }
        }, 
       
    });

</script>

<div>
    <ejs-grid id="DocumentacionEspecificaSiniestroGrid" allowPaging="true" load="load" actionComplete="complete" toolbar="@(new List<string>() { "Add", "Edit", "Cancel", "Update" })">
        <e-data-manager url="/Sistema/Siniestros/DocumentacionEspecificaSiniestroGrid_Read/?id=@Model" insertUrl="/Sistema/Siniestros/DocumentacionEspecificaSiniestroGrid_Crud" updateUrl="/Sistema/Siniestros/DocumentacionEspecificaSiniestroGrid_Crud"  adaptor="UrlAdaptor"></e-data-manager>
        <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal"></e-grid-editSettings>
        <e-grid-columns>
            <e-grid-column field="DocumentacionID" headerText="ID" isPrimaryKey="true" visible="true"></e-grid-column>
            <e-grid-column field="DetalleSiniestroID" visible="false" allowEditing="false" defaultValue="@Model"></e-grid-column>
            <e-grid-column field="documentoID" headerText="Tipo Documento" foreignKeyField="documentacionID" foreignKeyValue="nombreCategoria" dataSource="@ViewBag.TiposDocumento" ></e-grid-column>
            <e-grid-column field="Enviado" headerText="Enviado" visible="true" displayAsCheckBox="true" editType="booleanedit"></e-grid-column>
            <e-grid-column field="NombreArchivo" headerText="Documento" type="string" valueAccessor="@("fileName")" edit="@(new {create="fileCreate", read="fileRead", destroy="fileDestroy", write="fileWrite"  })"></e-grid-column>
        </e-grid-columns>
    </ejs-grid>
</div>

<ejs-scripts></ejs-scripts>





BS Balaji Sekar Syncfusion Team August 21, 2019 09:51 AM UTC

Hi Javier, 
  
Before proceeding further, we confirm that whether you have reported issue like updating the Grid row return the empty value while inserting a row. If we misunderstood your requirement, please share more details(video demonstration of an issue and the exact scenario of the issue) to us it will help to validate further. 
  
Regards, 
Balaji Sekar. 



JA Javier A Aguilera August 22, 2019 07:23 PM UTC

Yes, thats correct, following the example I can insert new records with the image from the uploader....but I cant proceed with the update (the parameters in the controller arrive at 0 value and the value for the uploader also doesnt arrive with value).

Can you help me out with that part please?




SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team August 23, 2019 09:06 AM UTC

Hi Javier,  

Thanks for your update.  

We suspect that some of the fields were not type build correctly on submitting the form to the server-end.  So we suggest to ensure the ModelState using the following highlighted code example.  

        public IActionResult Update(int DocumentacionID, int DetalleSiniestroID, int documentoID, bool Enviado,[FromBody]CRUDModel<Orders> value) 
        { 
            if (!ModelState.IsValid) 
            { 
                // collect exception message from ModelState 
            } 
       .. .  
           . . 
 
        } 

Check whether the ModelState condition is passing. If it is not valid, please collect the exception details that shown in the ModelState variable and share that to us. 


Regards,  
Seeni Sakthi Kumar S. 



JA Javier A Aguilera August 23, 2019 05:23 PM UTC

Good morning,

I implemented the code you mentioned above and I think I'm almost there, right now I can read every value from the grid when Im editing an existing row EXCEPT for the value of the uploader (problaby I'm still doing something wrong)

I implemented also the part for validate the model state, but it has a valid state, I'm attaching an image of this


//////////////////////////////////MY VIEW//////////////////////////////////
@model HammurabiSistema.Models.DocumentacionSiniestroAuto

<script>
    var file;
    function fileName(field, data, column) {
        return (data[field]) ? data[field].name : data[field]
    }
    function complete(args) {
        if (args.requestType === 'beginEdit' || args.requestType === 'add') {
            args.form.setAttribute('enctype', 'multipart/form-data');
            args.form.setAttribute('encoding', 'multipart/form-data');
        }
    }

    function fileCreate() {
        elem = document.createElement('input');
        return elem;
    }  

    function fileRead(args) {
        return (file) ? file : uploadObj.filesData;
    }

    function fileDestroy() {
        uploadObj.destroy();
    }

    function fileWrite(args) {
       
        if (args.requestType === 'beginEdit') {
            file = args.rowData.NombreArchivo;
        }
        uploadObj = new ej.inputs.Uploader({
            files: (args.requestType === 'beginEdit') ? [args.rowData.file] : [''],
            autoUpload: true
        });
        uploadObj.appendTo(elem)
    }

    window.customAdaptor = new ej.data.UrlAdaptor();
    function load() {
        this.dataSource.adaptor = customAdaptor;
    }
    customAdaptor = ej.base.extend(customAdaptor, {

        processResponse: function (data, ds, query, xhr, request, changes) {
            request.data = JSON.stringify(data);
            //alert(data.DocumentacionID);
            return ej.data.UrlAdaptor.prototype.processResponse.call(this, data, ds, query, xhr, request, changes)
        },
        insert: function (dm, data) {
            var fd = new FormData();
            for (var prop of data.NombreArchivo) {
                fd.append('UploadFiles', prop.rawFile);
            }
            fd.append('DocumentacionID', data.DocumentacionID);
            fd.append('DetalleSiniestroID', @Model.DetalleSiniestroID);
            fd.append('documentoID', data.documentoID);
            fd.append('Enviado', data.Enviado);
            //data.File = fd;
            return {
                url: dm.dataSource.insertUrl || dm.dataSource.updateUrl || dm.dataSource.url,
                type: "POST",
                data: fd,
                contentType: null
            }
        },
    });

</script>

<div>
    <ejs-grid id="DocumentacionEspecificaSiniestroGrid" allowPaging="true" load="load" actionComplete="complete" toolbar="@(new List<string>() { "Add", "Edit", "Cancel", "Update" })">
        <e-data-manager url="/Sistema/Siniestros/DocumentacionEspecificaSiniestroGrid_Read/?id=@Model.DocumentacionID" insertUrl="/Sistema/Siniestros/DocumentacionEspecificaSiniestroGrid_Crud" updateUrl="/Sistema/Siniestros/DocumentacionEspecificaSiniestroGrid_Crud"  adaptor="UrlAdaptor"></e-data-manager>
        <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal"></e-grid-editSettings>
        <e-grid-columns>
            <e-grid-column field="DocumentacionID" headerText="ID" isPrimaryKey="true" visible="true"></e-grid-column>
            <e-grid-column field="DetalleSiniestroID" visible="false" allowEditing="false" defaultValue="@Model.DetalleSiniestroID"></e-grid-column>
            <e-grid-column field="documentoID" headerText="Tipo Documento" foreignKeyField="documentacionID" foreignKeyValue="nombreCategoria" dataSource="@ViewBag.TiposDocumento" ></e-grid-column>
            <e-grid-column field="Enviado" headerText="Enviado" visible="true" displayAsCheckBox="true" editType="booleanedit"></e-grid-column>
            <e-grid-column field="NombreArchivo" headerText="Documento" type="string" valueAccessor="@("fileName")" edit="@(new {create="fileCreate", read="fileRead", destroy="fileDestroy", write="fileWrite"  })"></e-grid-column>
        </e-grid-columns>
    </ejs-grid>
</div>

<ejs-scripts></ejs-scripts>


//////////////////////////////////MY CONTROLLER (code is under comment since I'm just testing for the values to reach this point)//////////////////////////////////

[AcceptVerbs("Post")]
        public IActionResult DocumentacionEspecificaSiniestroGrid_Crud(int DocumentacionID, int DetalleSiniestroID, int documentoID, bool Enviado, [FromBody]CRUDModel<DocumentacionSiniestroAuto> value)
        {
            if (!ModelState.IsValid)
            {
                // collect exception message from ModelState 
            }

            //NO UPDATE FUNCTION HERE AS "DocumentacionID" HAS NO VALUE ON UPDATE FUNCTION
            //var archivo = ""; //UploadFiles
            //var filename = ContentDispositionHeaderValue
            //                .Parse(UploadFiles.FirstOrDefault().ContentDisposition)
            //                .FileName
            //                .Trim('"');
            //var fileToSave = Guid.NewGuid().ToString() + Path.GetExtension(filename);
            //archivo = fileToSave;
            //filename = hostingEnv.WebRootPath + @"\DocumentosSiniestrosAutos\" + $@"\{fileToSave}";
            //if (!System.IO.File.Exists(filename))
            //{
            //    using (var fileStream = new FileStream(filename, FileMode.Create))
            //    {
            //        await UploadFiles.FirstOrDefault().CopyToAsync(fileStream);
            //    }
            //}
            var nuevo = new DocumentacionSiniestroAuto
            {
                DetalleSiniestroID = DetalleSiniestroID,
                documentoID = documentoID,
                Enviado = Enviado,
                NombreArchivo = "" //archivo
            };
            _context.DocumentacionSiniestroAuto.Add(nuevo);
            _context.SaveChanges();


            //var nuevo = new DocumentacionSiniestroAuto
            //{
            //    DetalleSiniestroID = 0,
            //    documentoID = 0,
            //    Enviado = false,
            //    NombreArchivo = ""
            //};
            return Json(nuevo);            
        }






Attachment: modelstate_139c40.rar


DR Dhivya Rajendran Syncfusion Team August 27, 2019 01:09 PM UTC

Hi Javier, 

Thanks for sharing the details. 

We have validated the provided code example and in your code example, you are handling the uploaded files(formData) for insert operation only you need to handle the same for update operation too.  

We suggest you to override the default adaptor and customize the update method to achieve your requirement. 

<script> 
    var file; 
    function fileName(field, data, column) { 
        return (data[field]) ? data[field].name : data[field] 
    } 
    function complete(args) { 
        if (args.requestType === 'add' || args.requestType=='beginEdit') { 
            args.form.setAttribute('enctype', 'multipart/form-data'); 
            args.form.setAttribute('encoding', 'multipart/form-data'); 
        } 
    } 
    function fileRead(args) { 
        return uploadObj.filesData; 
    } 
     
    function fileWrite(args) { 
        if (args.requestType === 'beginEdit') { 
            file = args.rowData.file; 
        } 
        uploadObj = new ej.inputs.Uploader({ 
            files: (args.requestType === 'beginEdit') ? [args.rowData.file] : [''], 
            autoUpload: true 
        }); 
        uploadObj.appendTo(elem) 
    } 
 
    window.customAdaptor = new ej.data.UrlAdaptor(); 
    function load() { 
        this.dataSource.adaptor = customAdaptor; 
    } 
    customAdaptor = ej.base.extend(customAdaptor, { 
 
        processResponse: function (data, ds, query, xhr, request, changes) { 
            request.data = JSON.stringify(data); 
            return ej.data.UrlAdaptor.prototype.processResponse.call(this, data, ds, query, xhr, request, changes) 
        }, 
        . . . . . 
       update: function (dm, keyField, data, tableName) { 
            var fd = new FormData(); 
            for (var prop of data.file) { 
                fd.append('UploadFiles', prop.rawFile); 
            }  // you can customize and send parameter based on your requirement 
            fd.append('OrderID', data.OrderID); 
            fd.append('CustomerID', data.CustomerID); 
            return { 
                url: dm.dataSource.updateUrl || dm.dataSource.crudUrl || dm.dataSource.url, 
                type: "POST", 
                action: 'update', 
                data: fd, 
                keyColumn: keyField, 
                key: data[keyField], 
                contentType: null 
            } 
        }, 
    }); 
 
</script> 

Regards, 
R.Dhivya 


Loader.
Live Chat Icon For mobile
Up arrow icon