For some reason i can get second tab (Product Details) to bind record in the grids although the GetAllProductList return records. Please advise, thank you
index.cshtml
HOME/Index.cshtml
#(Html.Kendo().TabStrip()
.Name("tabstrip")
.Items(items =>
{
items.Add().Text("Search")
.LoadContentFrom("Index", "ProductDetails")
.Selected(true);
items.Add().Text("Product Details")
.LoadContentFrom("_ProductData", "ProductDetails")
})
)
ProductDetails/Index.cshtml
#(Html.Kendo().Grid()
.Name("BookGrid")
.HtmlAttributes(new { #Style = "align:center; font-size:10px; width:950px" })
.Columns(columns =>
{
columns.Bound(p => p.BookId).Width(95);
columns.Bound(p => p.Name).Width(120);
})
.ToolBar(toolbar => toolbar.Create())
.Sortable()
//.Pageable()
.Pageable(paging => paging
.Input(false)
.Numeric(true)
.PreviousNext(true)
.PageSizes(new int[] { 5, 10, 25, 50 })
.Refresh(false)
)
.Selectable()
.Scrollable()
.ColumnMenu(c => c.Columns(false))
.DataSource(dataSource => dataSource
.Ajax()//bind with Ajax instead server bind
.PageSize(10)
.ServerOperation(true)
.Model(model =>
{
model.Id(p => p.BookId);
})
.Sort(sort => sort
.Add(x => x.Name).Descending())
.Read(read => read.Action("GetBookData", "ProductDetails").Type(HttpVerbs.Get))
)
)
ProductDetails/_ProductData.chtml (Partial page)
#(Html.Kendo().Grid<HH.PrductModel>()
.Name("ProductGrid")
.HtmlAttributes(new { #Style = "align:center; font-size:10px; width:950px" })
.Columns(columns =>
{
columns.Bound(p => p.ProductId).Width(95);
columns.Bound(p => p.Name).Width(120);
})
.ToolBar(toolbar => toolbar.Create())
.Sortable()
//.Pageable()
.Pageable(paging => paging
.Input(false)
.Numeric(true)
.PreviousNext(true)
.PageSizes(new int[] { 5, 10, 25, 50 })
.Refresh(false)
)
.Selectable()
.Scrollable()
.ColumnMenu(c => c.Columns(false))
.DataSource(dataSource => dataSource
.Ajax()//bind with Ajax instead server bind
.PageSize(10)
.ServerOperation(true)
.Model(model =>
{
model.Id(p => p.ProductId);
})
.Sort(sort => sort
.Add(x => x.Name).Descending())
.Read(read => read.Action("GetProductData", "ProductDetails").Type(HttpVerbs.Get))
)
)
**ProductDetailscontroller**
public ActionResult Index()
{
return View();
}
///Display for tab 1
public ActionResult GetBookData ([DataSourceRequest] DataSourceRequest request)
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
return Json(GetAllBookList().ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
private static IEnumerable<BookModel> GetAllBookList()
{
using (var dc = new HHEntities())
{
var result = (from a in dc.Books
select new BookModel
{
BookId= a.BookId,
Name= a.Name
});
return result.Distinct().ToList();
}
}
///Display for tab 2
public ActionResult GetProductData([DataSourceRequest] DataSourceRequest request)
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
return Json(GetAllProductList().ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
The following will return records but for some reason it would bind to grid in Product details tab
/// <summary>
/// </summary>
/// <returns></returns>
private static IEnumerable<ProductModel> GetAllProductList()
{
using (var dc = new HHEntities())
{
var result = (from a in dc.Products
select new ProductModel
{
ProductId= a.ProductId,
Name= a.Name,
Description= a.Description,
ExpiryDate= a.ExpiryDate
});
return result.Distinct().ToList();
}
}
public ActionResult __ProductData()
{ return PartialView();}
I suspect the problem is that both grids are rendered with the same HTML id attribute (which is set via the Name() method). You need to give your grids unique names. For example you can put some index in ViewData in the action methods which render the partial view that contains the grid. Then use that index in the partial view itself to make the grid name unique:
#(Html.Kendo().Grid<HH.PrductModel>()
.Name("Product" + ViewData["index"])
Related
i have implemented a kendo grid as shown below , paging works without any issues but sort not work. Could you please help
CSHTML
<div class="panel">
<div id="CsHistory" class="row">
<div class="col-lg-12 col-md-12 col-sm-12" style="float:none; margin-left:auto; margin-right:auto; margin-top: 10px; margin-bottom: 10px;">
#using PC.Cmgr.Claims.Domain.Models;
#using PC.Cmgr.Claims.Domain.Common;
#using PC.Cmgr.Models;
#using System.Linq;
#(Html.Kendo().Grid<CsAuditTrailViewModel>
()
.HtmlAttributes(new { style = "width:auto; height:auto; text-center;margin-right: 30px;margin-left: 30px; " })
.Name("AllCsHistory")
.Columns(columns =>
{
columns.Bound(o => o.CsAuditTrailId).Title("CsAuditTrailId");
})
.ToolBar(toolBar =>
{
})
.Resizable(resize => resize.Columns(false))
.Reorderable(reorder => reorder.Columns(true))
.Sortable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(true)
.Model(model =>
{
model.Id(o => o.CsAuditTrailId);
})
.Read(read => read.Action("GetCHistoryByClaimId", "Claims", new { ClaimId = Model.Claim.ClaimId }))
.Events(events => { events.Sync("sync_handler"); }
)
)
)
</div>
</div>
Controller
public async Task<ActionResult> GetCsHistoryByClaimId([DataSourceRequest] DataSourceRequest request, Guid ClaimId)
{
var CsHistory = await _CsHistoryProxy.GetCsHistoryByClaimId(ClaimId);
var rawData = new ConcurrentBag<CsAuditTrailViewModel>();
var gridData = new List<CsAuditTrailViewModel>();
Parallel.ForEach(CsHistory, (x) =>
{
rawData.Add(
new CsAuditTrailViewModel
{
CsAuditTrailId = x.CsAuditTrailId,
NewData = x.NewData,
OldData = x.OldData,
UpdateDate = x.UpdateDate,
UserId = x.UserId
});
});
ViewData["total"] = rawData.Count();
// Apply paging
if (request.Page > 0)
{
gridData = rawData.Skip((request.Page - 1) * request.PageSize).ToList();
}
gridData = gridData.Take(request.PageSize).ToList();
var result = new DataSourceResult()
{
Data = gridData,
Total = (int)ViewData["total"]
};
return Json(result);
}
You wil have to customize it for your solution.
The sort-fields are in your DataSourceRequest, you can process them in your controller. See this example:
if (request.Sorts.Any())
{
foreach (SortDescriptor sortDescriptor in request.Sorts)
{
if (sortDescriptor.SortDirection == ListSortDirection.Ascending)
{
switch (sortDescriptor.Member)
{
case "OrderID":
orders= orders.OrderBy(order => order.OrderID);
break;
case "ShipAddress":
orders= orders.OrderBy(order => order.ShipAddress);
break;
}
}
else
{
switch (sortDescriptor.Member)
{
case "OrderID":
orders= orders.OrderByDescending(order => order.OrderID);
break;
case "ShipAddress":
orders= orders.OrderByDescending(order => order.ShipAddress);
break;
}
}
}
}
You will have to do the sorting before the paging...
Taken from : http://docs.telerik.com/kendo-ui/aspnet-mvc/helpers/grid/custom-binding
From Telerik FAQs,
For ajax binding scenarios the ToDataSourceResult extension method must be used to perform the data processing
So, you have to do it this way,
var result = new DataSourceResult()
{
Data = gridData.ToDataSourceResult(request).Data,
Total = (int)ViewData["total"]
};
I have a kendo grid like this.
#(Html.Kendo().Grid(Model.GridView.DataSource)
.Name("grid").Columns(columns => columns.LoadSettings(Model.GridView.ColumnSettings))
.Editable(editable => editable.Mode(GridEditMode.InLine))
.ToolBar(toolbar => toolbar.Create().Text("Add User"))
.DataSource(dataSource => dataSource
.Ajax().ServerOperation(true)
.Model(model =>
{
model.Id(p => p.Id);
model.Field(p => p.Id).Editable(false);
})
.Read(read => read.Action("OnGridRead", "Manage"))
)
)
And I'm using Kendo GridColumnSettings to define the columns in my model which is a GridView(Model) here like below.
public class GridView
{
public List<GridColumnSettings> ColumnSettings
{
get
{
var items = new List<GridColumnSettings>
{
new GridCommandColumnSettings
{
Commands =
{
new GridEditActionCommand()
},
Width = "70px"
},
new GridColumnSettings
{
Member = "Id",
Hidden = true
},
new GridColumnSettings
{
Member = "FirstName"
},
new GridColumnSettings
{
Member = "LastName"
},
new GridColumnSettings
{
Member = "UserName"
},
new GridColumnSettings
{
Member = "Password",
ClientTemplate = "***",
}
};
return items;
}
}
}
And here I need to disable Username field only in inline edit mode of the grid.
Currently there is no property available in GridColumnSettings class as editable. How can I disable the username field in edit mode of the grid using GridColumnSettings class.
Please try with the below code snippet. I have disabled the StudentID field in below demo.
#(Html.Kendo().Grid<MvcApplication1.Models.Student>()
.Name("Grid")
//.Columns(columns =>
// {
// columns.Bound(c => c.StudentID);
// columns.Bound(c => c.StudentName);
// })
.Columns(cols => cols.LoadSettings(ViewBag.cols))
.Scrollable()
.Groupable()
.Sortable()
.Editable(editable => editable.Mode(GridEditMode.InLine)).ToolBar(toolbar => toolbar.Create())
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.Events(events => events.Edit("onEdit"))
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("Grid_Read", "Home"))
.Update(update => update.Action("EditingInline_Update", "Grid"))
.Create(update => update.Action("EditingInline_Create", "Grid"))
.Model(model =>
{
model.Id(p => p.StudentID);
model.Field(p => p.StudentID).Editable(true);
})
)
)
Method 1:-
<script>
function onEdit(e) {
if (e.model.isNew() == false) {
$(e.container).find("input[name='StudentID']").attr('disabled', 'disabled');
}
}
</script>
Method 2:-
<script>
function onEdit(e) {
if (e.model.isNew() == false) {
$(e.container).find("input[name='StudentID']").parent().html($(e.container).find("input[name='StudentID']").val()).removeAttr('data-container-for');
}
}
</script>
Let me know if any concern.
Please try below solution to disable the username field in edit mode of the grid.
.Model(model =>
{
model.Id(p => p.Id);
model.Field(p => p.Id).Editable(false);
model.Field(p => p.UserName).Editable(false);
})
I am trying to bind the kendo grid , i am getting data till controller.Controller returns data, but cannot see those data in grid. Anything wrong with the following code?
<div class="panel">
<div id="chstry" class="row">
<div class="col-lg-12 col-md-12 col-sm-12" style="float:none; margin-left:auto; margin-right:auto; margin-top: 10px; margin-bottom: 10px;">
#using Pnc.cmgr.Claims.Domain.Models;
#using Pnc.cmgr.Claims.Domain.Common;
#using Pnc.cmgr.Models;
#using System.Linq;
#(Html.Kendo().Grid<CaseAuditTrailViewModel>()
.HtmlAttributes(new { style = "width:auto; height:auto; text-center;margin-right: 30px;margin-left: 30px; " })
.Name("Allchstry")
.Columns(columns =>
{
columns.Bound(o => o.CaseAuditTrailId).Title("CaseAuditTrailId").Locked(true);
columns.Bound(o => o.TableName).Title("TableName");
columns.Bound(o => o.UserId).Title("UserId");
columns.Bound(o => o.Actions).Title("Actions");
columns.Bound(o => o.OldData).Title("OldData");
columns.Bound(o => o.NewData).Title("NewData");
columns.Bound(o => o.TableIdValue).Title("TableIdValue");
})
.ToolBar(toolBar =>
{
})
.Resizable(resize => resize.Columns(false))
.Reorderable(reorder => reorder.Columns(true))
.Sortable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(true)
.Model(model =>
{
model.Id(o => o.CaseAuditTrailId);
})
.Read(read => read.Action("GetchstryByClaimId", "Claims", new { ClaimId = Model.Claim.ClaimId }))
.Events(events => { events.Sync("sync_handler"); }
)
)
.Events(events => events
.DataBound("onDataBound")
)
)
<script>
function sync_handler(e) {
this.read();
}
</script>
</div>
</div>
Following is the controller code and i am getting return data :
public async Task<ActionResult> GetchstryByClaimId([DataSourceRequest] DataSourceRequest request, Guid ClaimId)
{
var chstry = await _chstryProxy.GetchstryByClaimId(ClaimId);
var gridData = new List<CaseAuditTrailViewModel>();
Parallel.ForEach(chstry, (x) =>
{
gridData.Add(
new CaseAuditTrailViewModel
{
CaseAuditTrailId = x.CaseAuditTrailId,
Actions = x.Actions,
NewData = x.NewData,
OldData = x.OldData,
TableIdValue = x.TableIdValue,
TableName = x.TableName,
UpdateDate = x.UpdateDate,
UserId = x.UserId
});
});
var result = new DataSourceResult()
{
Data = gridData,
Total = gridData.Count()
};
//return new JsonResult { Data = result };
return Json(result);
}
Also, please let me know anything wrong the above approach of pulling data, view model binding is no where in the scene, do we have better approach to bind to process data faster?
i have kendo mvc grid in my page and i bind it dynamically but the size of each column is not good and i have to give the static size of all, but my columns are dynamic and in design time i don't have size of each column, how can i make a dynamic size for grid columns after read method?
this is how i create kendo grid in my view
#(Html.NFSGrid<dynamic>("PortfolioGrid")
.Name("PortfolioGrid")
.EnableCustomBinding(true)
.Selectable()
.BindTo(Model)
.DataSource(dataSource => dataSource
.Ajax()
.Model(m =>
{
foreach (var Allcoulms in (List<HtmlHelperGridBuilder.GridCol>)ViewData["ViewDataGridfildes"])
{
if (Allcoulms.ColumnName == "Id")
{
m.Id(Allcoulms.ColumnName);
}
else
{
m.Field(Allcoulms.ColumnName, Type.GetType("System.String")).Editable(true);
}
}
})
.ServerOperation(true)
.Read(read => read.Action("Read", "Portfolio").Data("portFolioNameSpace.additionalInfo")
)
)
.HtmlAttributes(new { style = "width:2000;" })
.Columns(columns =>
{
columns.Template(p => { }).ClientTemplate("<input name='selectedIds' type='checkbox' value=\"#=Id#\" class='check_row' onchange='portFolioNameSpace.changeChk(event,this.checked,this);'/>")
.HeaderTemplate("<input type='checkbox' class='selectAll' onclick='portFolioNameSpace.ToggleChkBox(this.checked);'/>")
.HeaderHtmlAttributes(new { style = "text-align:center;" })
.Width(30);
columns.Template(#<text></text>).Title(T("روند").ToString()).Width(30).ClientTemplate("<a onclick='portFolioNameSpace.onclickFlowFPortfolio(event)'><i class='iconmain-showall'></i></a>");
foreach (var Allcoulms in (List<HtmlHelperGridBuilder.GridCol>)ViewData["ViewDataGridfildes"])
{
if (Allcoulms.ColumnName == "Id")
{
columns.Bound(Allcoulms.ColumnName).Visible(false);
}
else if (Allcoulms.ColumnName == "Subject")
{
columns.Bound(Allcoulms.ColumnName).Width(700).Title(T(Allcoulms.ColumnTitle).ToString()).HtmlAttributes(new { style = "text-align:center;" });
}
else if (Allcoulms.ColumnName == "Comment")
{
columns.Bound(Allcoulms.ColumnName).Width(200).Title(T(Allcoulms.ColumnTitle).ToString()).HtmlAttributes(new { style = "text-align:center;" }).ClientTemplate("<input type=\"text\" id=\"#=Id#\" value=\"#=Comment#\"/>");
}
else if (Allcoulms.ColumnName == "notViewdRows")
{
}
else
{
columns.Bound(Allcoulms.ColumnName).Width(200).Title(T(Allcoulms.ColumnTitle).ToString()).HtmlAttributes(new { style = "text-align:center;" });
}
}
//.HtmlAttributes(new { #style = "display:none" });
})
.Sortable(sortable => sortable
.AllowUnsort(true)
.SortMode(GridSortMode.MultipleColumn))
.Pageable(pager => pager.Enabled(true))
.Scrollable()
.Filterable()
.Resizable(resize => resize.Columns((true)))
.Reorderable(reorder => reorder.Columns(true))
.Events(e => e
.DataBound("gridDataBound")
)
)
Have you tried this:
.Columns(columns =>
{
columns.LoadSettings((IEnumerable<GridColumnSettings>)ViewData["Columns"]);
})
?
You can pass 'width' via GridColumnSettings object.
I would like to update the parent grid when the child grid record is updated, is that possible? If so could anyone provide any advice on it?
Firstly I'm not sure which event would be best to use on the child grid. I want the child grid's CRUD action to fire, then load the contents of the parent again, preferably by Ajax.
Below is my grid as is:
#{
ViewBag.Title = "Bills: Parent/Child";
}
<h2>Bills Index</h2>
#(Html.Kendo().Grid<BillParent>()
.Name("BillParentsGrid")
.Columns(columns =>
{
columns.Bound(h => h.Category);
columns.Bound(h => h.Description);
columns.Bound(h => h.Amount);
columns.Command(command =>
{
command.Edit();
}).Width(95);
})
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(h => h.BillId);
model.Field(h => h.BillId).Editable(false);
})
.Events(events => events.Error("error_handler"))
.Read(read => read.Action("BillParents_Read", "Bill"))
.Update(update => update.Action("BillParent_Update", "Bill"))
)
.Events(events => events.DataBound("dataBound"))
.ClientDetailTemplateId("BillChildren")
)
<script id="BillChildren" type="text/kendo-tmpl">
#(Html.Kendo().Grid<BillChild>()
.Name("BillChildren_#=BillId#")
.Columns(columns =>
{
columns.Bound(d => d.BillId).Width(50);
columns.Bound(d => d.Description).Width(150);
columns.Bound(d => d.Amount).Width(80);
columns.Command(command =>
{
command.Edit();
command.Destroy();
}).Width(55);
})
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(d => d.BillId);
model.Field(d => d.BillId).Editable(false);
})
.Events(events => events.Error("error_handler"))
.Read(read => read.Action("BillChildren_Read", "Bill", new { id = "#=BillId#" }))
.Update(update => update.Action("BillChild_Update", "Bill"))
.Create(create => create.Action("BillChild_Create", "Bill", new { id = "#=BillId#" }))
.Destroy(destroy => destroy.Action("BillChild_Destroy", "Bill")))
.ToolBar(tools => tools.Create())
.ToClientTemplate()
)
</script>
Many thanks.
I cracked it in the end.
The Event needs to be on the dataSource, using the Sync event, not on the grid itself.
Short version
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(d => d.BillId);
model.Field(d => d.BillId).Editable(false);
})
.Events(events =>
{
events.Error("error_handler");
events.Sync("resyncParentGrid");
})
<script>
function resyncParentGrid(e) {
var parentData = $('#BillParentsGrid').data("kendoGrid");
parentData.dataSource.read();
}
</script>
Full Version
#(Html.Kendo().Grid<BillParent>()
.Name("BillParentsGrid")
.Columns(columns =>
{
columns.Bound(h => h.Category).Width(50);
columns.Bound(h => h.Description);
columns.Bound(h => h.Amount).Width(80);
columns.Command(command =>
{
command.Edit();
})
.Title("Commands").Width(150);
})
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(h => h.BillId);
model.Field(h => h.BillId).Editable(false);
})
.Events(events => events.Error("error_handler"))
.Read(read => read.Action("BillParents_Read", "Bill"))
.Update(update => update.Action("BillParent_Update", "Bill"))
)
.Events(events => events.DataBound("dataBound"))
.ClientDetailTemplateId("BillChildren")
)
<script id="BillChildren" type="text/kendo-tmpl">
#(Html.Kendo().Grid<BillChild>()
.Name("BillChildren_#=BillId#")
.Columns(columns =>
{
columns.Bound(d => d.BillId).Width(50);
columns.Bound(d => d.Description).Width(150);
columns.Bound(d => d.Amount).Width(80);
columns.Command(command =>
{
command.Edit();
command.Destroy();
})
.Title("Commands").Width(150);
})
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(d => d.BillId);
model.Field(d => d.BillId).Editable(false);
})
.Events(events =>
{
events.Error("error_handler");
**events.Sync("resyncParentGrid");**
})
.Read(read => read.Action("BillChildren_Read", "Bill", new { id = "#=BillId#" }))
.Update(update => update.Action("BillChild_Update", "Bill"))
.Create(create => create.Action("BillChild_Create", "Bill", new { id = "#=BillId#" }))
.Destroy(destroy => destroy.Action("BillChild_Destroy", "Bill"))
)
.ToolBar(tools => tools.Create())
.ToClientTemplate()
)
</script>
<script>
function dataBound() {
this.expandRow(this.tbody.find("tr.k-master-row").first());
}
function resyncParentGrid(e) {
var parentData = $('#BillParentsGrid').data("kendoGrid");
parentData.dataSource.read();
}
</script>