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

Grid Binding to ICollection

Hello,

I have a two Grids on a View, and I'm using the List Binding method as described in the documentation here: https://ej2.syncfusion.com/aspnetmvc/documentation/grid/data-binding/. I'm wondering if it's because I'm trying to use ICollection or if something else is preventing the binding on submit. Everything works fine loading up and using the grid works well. I passed a FormCollection to test and saw nothing from the grid is even getting on the html form. 

Here is a sample of what I'm doing:
.CSHTML:
@{
var contactDropDown = new Syncfusion.EJ2.DropDowns.DropDownList
{
DataSource = Model.ContactSelectList,
Query = "new ej.data.Query()",
Fields = new Syncfusion.EJ2.DropDowns.DropDownListFieldSettings
{
Value = "Id",
Text = "ProdId"
},
AllowFiltering = true,
ActionComplete="contactActionComplete"
};
}

@(Html.EJS()
.Grid("ContactGrid")
.DataSource(Model.Contacts)
.ActionBegin("contactActionBegin")
.ActionComplete("contactActionComplete")
.EditSettings(edit => edit.AllowAdding(true).AllowDeleting(true).AllowEditing(true).Mode(EditMode.Dialog))
.Toolbar(new List<object> {"Search", "PdfExport", "ExcelExport", "Add", "Delete"})
.Columns(col =>
{
col.Field("ProdId").HeaderText("Producer ID").EditType("dropdownedit").Edit(new { @params = contactDropDown }).Add();
col.Field("FirstName").HeaderText("First Name").Add();
col.Field("LastName").HeaderText("Last Name").Add();
})
.AllowPdfExport()
.AllowExcelExport()
.ToolbarClick("toolBarHandler")
.AllowSorting()
.Render())

Model:
public class PoolViewModel
{
public int Id { get; set; }

// ... Other Fields not involved with the Grid ...

public ICollection<ContactViewModel> Contacts { get; set; }

public ICollection<ContactViewModel> ContactSelectList { get; set; }

}
The grid will show all of the items from the "Contacts" collection. The user can click the add button and a dialog pops up giving a searchable drop down list of everything from the "ContactSelectList" collection; which has all of the available contacts to choose from. Once they add it to the grid I grab the data from an ajax call and populate the required fields to the grid like so:

function contactActionBegin(args) {
addGridItem(args, "ProdId", this.columns);
}
function addGridItem(args, visibleColumn, columns) {
if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
showSingleColumn(visibleColumn, columns);
}
}
function showSingleColumn(columnName, columns) {
for (var i = 0; i < columns.length; i++) {
if (columns[i].field != columnName) {
columns[i].visible = false;
}
else {
columns[i].visible = true;
}
}
}
** After user clicks add:
function contactActionComplete(args) {
if (args.requestType === 'save') {
showAllColumns(this.columns);

$.ajax({
async: false,
type: 'GET',
url: '****Intentionally Hidden***' + args.data.ProdId,
dataType: 'json',
success: function (data) {
args.data.ProdId = data.ProdId;
args.data.FirstName = data.FirstName;
args.data.LastName = data.LastName;
}
});

refreshGrid("ContactGrid");
}
}
function showAllColumns(columns) {
for (var i = 0; i < columns.length; i++) {
columns[i].visible = true;
}
}
FYI: I did not want to make calls every time the user adds/remove items from the grid to reduce the request load. I prefer the user to make changes on the grid all at once and then submit one request. I wasn't able to figure out how to get the data from the ContactSelectList property to populate the ContactViewModel which is just a ProdId (id), first and last name. I didn't want them to edit first and last name so I hide those fields in the dialog then reshow them when they click add.

In recap, I need to find a way to bind the grid items for the form POST. A side objective would be to find a way to not make an ajax call to get the data already from the ContactSelectList if possible.

I hope this makes sense, please let me know if you have any questions. I appreciate any help or pointers.

Thanks,

3 Replies

TS Thavasianand Sankaranarayanan Syncfusion Team May 30, 2019 01:22 PM UTC

 
Hi Jake, 
 
Greetings from Syncfusion. 
 
We have validated your query with the provided information. From the provided information, we suspect that you want to handle the grid operations with remote data(ie: you want to update the data in server and return the updated data to the grid). But you have provided data to grid as Model data. You can achieve your requirement by using datamanager and adaptor. When comes with remote datasource, the data adaptor is used to send the request that the server can understand and process the server response. The adaptor can be assigned using the adaptor property of the DataManager.  
 
 
Please find the below code example and sample for your reference. 
 
[code example] 
 
@Html.EJS().Grid("grid").DataSource(dataManger => 
   { 
       dataManger.Url("/Home/UrlDatasource").BatchUrl("/Home/BatchUpdate").Adaptor("UrlAdaptor"); 
   }).Columns(col => 
{ 
    col.Field("OrderID").HeaderText("OrderID").IsPrimaryKey(true).Width("50").Add(); 
    ... 
}).AllowPaging().Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true).Mode(Syncfusion.EJ2.Grids.EditMode.Batch); }).Render() 
 
 
public ActionResult UrlDatasource(DataManagerRequest dm) 
        { 
            ICollection<OrdersDetails> ordcol = orddata.ToList(); 
 
            IEnumerable<OrdersDetails> DataSource = ordcol; 
            DataOperations operation = new DataOperations(); 
 
            if (dm.Search != null && dm.Search.Count > 0) 
            { 
                DataSource = operation.PerformSearching(DataSource, dm.Search);  //Search 
            } 
            if (dm.Sorted != null && dm.Sorted.Count > 0) //Sorting 
            { 
                DataSource = operation.PerformSorting(DataSource, dm.Sorted); 
            } 
            if (dm.Where != null && dm.Where.Count > 0) //Filtering 
            { 
                DataSource = operation.PerformFiltering(DataSource, dm.Where, dm.Where[0].Operator); 
            } 
            int count = DataSource.Cast<OrdersDetails>().Count(); 
            if (dm.Skip != 0) 
            { 
                DataSource = operation.PerformSkip(DataSource, dm.Skip);   //Paging 
            } 
            if (dm.Take != 0) 
            { 
                DataSource = operation.PerformTake(DataSource, dm.Take); 
            } 
            return dm.RequiresCounts ? Json(new { result = DataSource, count = count }) : Json(DataSource); 
        } 
 
And you have mentioned you want to send request to each editing operations(add/update/delete). If you want to perform all the operations in grid and send one request to server to update the edited records, then you can achieve your requirement by using batch mode of editing.  
 
Help Documentation:                https://ej2.syncfusion.com/aspnetcore/documentation/grid/edit/#batch  
                                             https://ej2.syncfusion.com/aspnetcore/documentation/grid/edit/#batch-url 
 
In server side, you need to handle the update operation like below. 
 
[code example] 
public ActionResult BatchUpdate(string action, CRUDModel batchmodel) 
        { 
            if (batchmodel.Changed != null) 
            { 
                for (var i = 0; i < batchmodel.Changed.Count(); i++) 
                { 
                    var ord = batchmodel.Changed[i]; 
                    OrdersDetails val = orddata.Where(or => or.OrderID == ord.OrderID).FirstOrDefault(); 
                    val.OrderID = ord.OrderID; 
                    val.EmployeeID = ord.EmployeeID; 
                    val.CustomerID = ord.CustomerID; 
                    val.Freight = ord.Freight; 
                    val.OrderDate = ord.OrderDate; 
                    val.ShipCity = ord.ShipCity; 
                    val.ShipAddress = ord.ShipAddress; 
                    val.ShippedDate = ord.ShippedDate;       //update the changed records 
                } 
            } 
 
            if (batchmodel.Deleted != null) {  
                for (var i = 0; i < batchmodel.Deleted.Count(); i++) 
                { 
                    orddata.Remove(orddata.Where(or => or.OrderID == batchmodel.Deleted[i].OrderID).FirstOrDefault());  //for delete operation 
                } 
            } 
 
            if (batchmodel.Added != null) {  
                for (var i = 0; i < batchmodel.Added.Count(); i++) 
                { 
                    orddata.Insert(0, batchmodel.Added[i]);      //for insert operation 
                } 
        } 
            var data = orddata.ToList(); 
            return Json(data); 
 
        } 
 
 
Here, we have prepared a sample in url adaptor with batch editing. In this, you can perform editing operations all the operations and send one request to server when clicking update button. Please find the sample in below link. 
 
 
Please get back to us if you need further assistance. 
 
Regards, 
Thavasianand S. 



JC Jake Charles May 30, 2019 09:34 PM UTC

Hello,

Thank you for the response. I've started to make these adjustments but running into issues with trying to update the row data in the save method. I changed it to use the save method like the example does but every time I try using the setCellValue function nothing happens. I get the correct grid instance, and I've even tried hard coding indexes just to see how it works. If I call a refresh on the grid it blows everything away. In addition I'm now not able to use the dialog because in order to do batch updates you have to use inline editing which isn't ideal in my case. The other issue with this is now I have to use this Update button so having form fields and two grids now I have to have three save buttons which is confusing.

Is there another way of doing this?


TS Thavasianand Sankaranarayanan Syncfusion Team June 3, 2019 01:36 PM UTC

Hi Jake, 
 
Query 1: Modified data is not updated in Grid dataSource. 
 
By default, if we using setCellValue method then it will modify the data in UI level and it will not be reflected in the Grid dataSource. So, if you want to update the Grid dataSource with the modified value then we suggest you to use the updateRow method of Grid.  
 
 
Query 2: I have to use this Update button so having form fields and two grids now I have to have three save buttons which is confusing. 
 
Before proceeding to your query please provide the following details for better assistance. 
 
  1. Share screen shot or video demonstration of the issue.
  2. Share the complete Grid example.
  3. Share the replication procedure to reproduce the issue.
  4. Share the stack trace details if you face any script error in console.
  5. Share the Essential Studio version details.
 
Regards, 
Thavasianand S. 


Loader.
Live Chat Icon For mobile
Up arrow icon