By default it looks like Telerik Grid for MVC3 submits only the rows marked as "dirty" to my controller. I need to be able to submit all rows on a Telerik Grid to my controller. In other words I think I need to mark all rows as changed so the grid will send all rows to my controller.
I am using Ajax data binding as in:
.DataBinding(dataBinding => dataBinding
.Ajax()
.Select("GetData", "ModuleAccess", new { roleId = #ViewBag.RoleId, appId = #ViewBag.AppId })
.Update("SaveBatchEditing", "ModuleAccess")
#(Html.Telerik().Grid<BarcodeListModel>()
.Name("orders-grid")
.ClientEvents(events => events.OnDataBinding("onDataBinding"))
.DataKeys(keys =>
{
keys.Add(x => x.Id);
})
.ToolBar(commands =>
{
commands.SubmitChanges();
})
.DataBinding(dataBinding =>
dataBinding.Ajax()
.Select("BulkEditSelect", "ProductVariant")
.Update("BulkEditSaveBarcode", "ProductVariant")
.Delete("DeleteBarcode", "ProductVariant")
)
.Columns(columns =>
{
columns.Bound(x => x.Id).ReadOnly();
columns.Bound(x => x.SKU);
columns.Bound(x => x.barcode);
//columns.Bound(x => x.Id)
// .Template(x => Html.ActionLink(T("Admin.Common.View").Text, "DeleteBarcode", new { id = x.Id }))
// .ClientTemplate("" + "Delete" + "")
// .Width(50)
// .Centered()
// .HeaderTemplate("DeleteBarcode")
// .Filterable(false)
// .Title("Delete");
columns.Command(commands => commands.Delete()).Width(180);
})
.Pageable(settings => settings.PageSize(gridPageSize).Position(GridPagerPosition.Both))
.DataBinding(dataBinding => dataBinding.Ajax().Select("BarcodeList", "ProductVariant", Model))
.Editable(editing => editing.Mode(GridEditMode.InCell))
.EnableCustomBinding(true)
)
use like this code
I found the answer:
function ModuleAccessGridHasChanges() {
var grid = $("#ModuleAccessGrid").data("tGrid");
if (grid != null) {
var additionalValues = grid.data;
if (!$.telerik.trigger(grid.element, 'submitChanges', { values: additionalValues })) {
grid.sendValues($.extend({}, additionalValues), 'updateUrl', 'submitChanges');
}
}
}
Fiddler shows all the data for the grid coming accross:
Related
Inside the editor template of one of my Grids, A, I have another grid, B. I want to set read and update actions of this Grid based on the current Id in the A.
I've tried using Razor code inside the editor template like this:
// details grid: B
.Read("action", "controller", new { #Model.Id })
But Id was always null, probably because Razor is server-side.
So I've tried to set the Grid inside the main page, in the Edit event of the main Grid.
function EditHandler(e) {
if (e.model.isNew())
return;
var detailGrid = e.container.find("#details").data('kendoGrid');
detailGrid.dataSource.options.transport.read.url = "#Url.Action("", "")".concat('/', e.model.Id);
detailGrid.dataSource.options.transport.update.url = "#Url.Action("", "")".concat("/", e.model.Name);
}
This doesn't work neither. The definition of the Grid in the editor template will overwrite these properties.
This is the main Grid:
#(Html.Kendo().Grid<A>()
.Name("A")
.Columns(columns =>
{
columns.Bound(x => x.Id).Hidden();
columns.Bound(x => x.Name).HtmlAttributes(new { #style = "text-align: left" });
....
columns.Command(command =>
{
command.Edit(); command.Destroy();
});
})
.....
.Selectable()
.Navigatable()
.DataSource(ds => ds
.Ajax()
.Model(model =>
{
model.Id(x => x.Name);
})
.Read("", "")
.Update("", "")
.Destroy("", "")
.Create("", "")
)
.Events(e => e.Edit("EditHandler").Save("SaveHandler"))
)
Inside the editor template of this class, a.cshtml, I have another Grid that I want its Edit and Read Actions include the Id of the Grid A.
#(Html.Kendo().Grid<B>()
.Name("B")
.Columns(columns =>
{
columns.Bound(.....
})
.....
.Editable(edit => edit.Mode(GridEditMode.InCell))
.Selectable()
.Navigatable()
.DataSource(ds => ds
.Ajax()
.PageSize(5)
.Model(model =>
{
model.Id(x => x.Id);
})
.Read("", "")
.Update("", "")
).ToClientTemplate()
)
UPDATE
function EditHandler(e) {
if (e.model.isNew())
return;
var detailGrid = e.container.find("#details").data('kendoGrid');
detailGrid.dataSource.read({ Id: e.model.Id });
detailGrid.dataSource.update({ Name: e.model.Name });
}
As Dion noted, it needs 2 changes:
In the child Grid, B, set the auto bind to false: .AutoBind(false)
Set the ID with read method, not manually as I've been trying.
To overcome this case, I will trigger Grid-B's read manually inside Grid-A's edit event. Follow this setup:
Grid-B Config:
.AutoBind(false)
.DataSource(ds => ds.Ajax()
.Read("action", "controller")
.Update(url => url.Action("update", "controller").Data(paramData)))
Modify Grid-A edit function:
function EditHandler(e) {
var gridB = $("#gridB").getKendoGrid(),
model = e.model;
gridB.dataSource.read({Id: model.Id});
}
// get Id for update
function paramData() {
return { Id : $("#Id").val(); };
}
Hope this help.
Note: Unlike read, update will be triggered after popup shown then Id field will be already have its value. Therefor you can use Url.Action(...).Data() for this case.
I have Kendo Grid with delete command. When I click delete and then click "save change" on the left top of grid, real data is not sent to server. data has key/create date/other fields. I used Odata service. In debug mode, key = 0 and create date = 1/1/0001. Anyone got a clue what is happening here?
#(Html.Kendo().Grid<OData.proxySvc.table1>()
.Name("MyGrid")
.Columns(columns =>
{
columns.Bound(f => f.key).Visible(false);
columns.Bound(f => f.UserName).Title("Name");
columns.Command(command => {
command.Destroy();
}).Title("Action").Width(90);
})
.ToolBar(toolbar =>
{
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Sortable()
.Scrollable(s => s.Height("100px"))
.Filterable()
.DataSource(ds => ds
.Ajax()
.Batch(true)
.ServerOperation(false)
.Model(model => model.Id(p => p.key))
.Destroy("Delete","Home")
))
in control file, there is action:
// no [Httppost] attributes. if [HttpPost] attributes exist, no event fire
public ActionResult Delete([DataSourceRequest]DataSourceRequest request,
[Bind(Prefix = "models")]IEnumerable<table1> tbl1)
{
var context = CreateOdataServiceContext();
foreach (var t1 in tbl1)
{
var x = context.table1.Where(r => r.key == t1.key).FirstOrDefault();
if (x!=null)
{
context.DeleteObject(x);
context.SaveChanges();
}
}
}
I am using Ajax binding and so I am assuming that if I want the total to update after the user edits a change, I need the ClientFooterTemplate as opposed to just the FooterTemplate which works.
Here is my grid which works with FooterTemplate:
#{
GridEditMode mode = (GridEditMode)ViewData["mode"];
GridButtonType type = (GridButtonType)ViewData["type"];
GridInsertRowPosition insertRowPosition = (GridInsertRowPosition)ViewData["insertRowPosition"];
Html.Telerik().Grid<RedFile.Models.QuickQuoteItemView>("items")
.Name("QuoteItems")
.DataKeys(k => k.Add(o => o.Id))
.ToolBar(commands => commands.Insert().ButtonType(type).ImageHtmlAttributes(new { style = "margin-left:0" }))
.Columns(c =>
{
c.Bound(o => o.Id).ReadOnly().Hidden();
c.Bound(o => o.ItemID);
c.Bound(o => o.Description);
c.Bound(o => o.ItemQty);
c.Bound(o => o.ItemPrice).Format("{0:c}");
c.Bound(o => o.LineTotal)
.Width(100)
.Aggregate(ag => ag.Sum())
.FooterTemplate(result => (result.Sum == null ? "0.00" : result.Sum.Format("{0:c}")))
.Format("{0:c}");
c.Command(s =>
{
s.Edit();
s.Delete();
});
})
.Editable(editing => editing.Mode(mode).InsertRowPosition(insertRowPosition))
.DataBinding(b => b.Ajax()
.Select("GridSelect", "QuickQuote")
.Insert("GridInsert", "QuickQuote", new { qqid = Model.Id })
.Update("GridUpdate", "QuickQuote", new { qqid = Model.Id })
.Delete("GridDelete", "QuickQuote", new { qqid = Model.Id })
)
.Footer(true)
.Render();
}
If I change the footer template to something like this: (I have tried multiple variations with the same result)
.ClientFooterTemplate("<#= $.telerik.formatString('{0:c}', Sum) #>")
The total simply disappears.
All I want is a total that updates after the user changes something. Any idea what I'm doing wrong?
Thanks
columns.Bound(p => p.ItemPrice)
.FooterTemplate(
#<text>
Total:#string.Format("{0:c}", Model.ItemPrice)
</text>
)
.Width(100)
.Format("{0:c}");
Refer to Teleriks MVC grid Documentation
I have a Telerik Grid on a MVC3 project with Razor layout engine with the popUp edit mode working fine. Here is the grid code:
#(Html.Telerik().Grid(Model)
.Name("grid-moedas")
.DataKeys(keys => keys.Add(m => m.ID))
.Columns(columns =>
{
columns.Bound(m => m.Nome);
columns.Bound(m => m.Simbolo);
columns.Bound(m => m.ExtensoNoSingular);
columns.Bound(m => m.ExtensoNoPlural);
columns.Command(commands =>
{
commands.Edit();
});
})
.DataBinding(dataBinding =>
{
dataBinding.Ajax().Select("AjaxGrid", "Moeda");
dataBinding.Ajax().Update("AjaxEdit", "Moeda");
})
.Sortable()
.Editable(editing => editing.Mode(GridEditMode.PopUp))
.Pageable(paging =>
paging.Style(GridPagerStyles.NextPreviousAndInput)
)
.Footer(true)
.ClientEvents(events => events
.OnRowSelect("onRowSelect")
)
.Selectable()
)
I wanna two things:
Hide the buttons generated for each row on the grid
Call the edit command on the OnRowSelect event, so the editing popUp form will be called in response to the user click on a row.
function onRowSelect(e) {
//how to call edit command for e.row???
return false;
}
You can try this:
<script>
function onRowSelect(e) {
var grid = $(this).data("tGrid");
grid.editRow($(e.row));
}
</script>
I can't easily try this (I don't have the Telerik controls), but is this of any use:
<script type="text/javascript">
function OnRowClick(sender, args) {
var masterTable = sender.get_masterTableView();
masterTable.fireCommand("Edit", args.get_itemIndexHierarchical())
}
</script>
Taken from here: http://www.telerik.com/community/forums/aspnet-ajax/grid/grid-edit-on-row-select.aspx#1405657
I am using free Telerik.Web.Mvc grid and following this example: http://demos.telerik.com/aspnet-mvc/grid/hierarchyajax
My Issue:
I am populating the grid with search results after user input some data and submit with a search button
In the DetailView() method I reference my 'SearchQuote_QuotesForHierarchyAjax' method, which is in defined in my Controller when DetailView executes data should be fetched, but this controller action does not execute for me.
If i load the grid first time page loads it execute. but not when the grid is loaded in a search button click
The Code in my project:
My SearchQuote.aspx View looks like this
<%= Html.Telerik().Grid(Model.QuoteSummaryList)
.Name("SearchQuoteGrid")
.Columns(columns =>
{
columns.Bound(q => q.QuoteId).Title("Quote #").Width(50);
columns.Bound(q => q.AxiomId).Title("Axiom Id").Width(180);
})
.ClientEvents(events => events.OnRowDataBound("quotes_onRowDataBound"))
.DetailView(details => details.ClientTemplate(
Html.Telerik().Grid(Model.QuoteSubSummaryList)
.Name("Quotes_<#= QuoteId #>")
.Columns(columns =>
{
columns.Bound(o => o.PositionCode).Width(101);
columns.Bound(o => o.Group).Width(140);
})
.DataBinding(dataBinding => dataBinding.Ajax()
.Select("SearchQuote_QuotesForHierarchyAjax", "SearchQuote", new
{quoteid ="<#= QuoteId #>"}))
.Pageable()
.Sortable()
.Filterable()
.ToHtmlString()
))
.DataBinding(dataBinding => dataBinding.Ajax()
.Select("SearchQuote_Select", "SearchQuote"))
.Sortable()
.Pageable(p => p.PageSize(3))
%>
<script type="text/javascript">
function expandFirstRow(grid, row) {
if (grid.$rows().index(row) == 0) {
grid.expandRow(row);
}
}
function quotes_onRowDataBound(e) {
var grid = $(this).data('tGrid');
expandFirstRow(grid, e.row);
}
</script>
And SearchQuoteController has this code.
[AcceptVerbs(HttpVerbs.Post)]
[GridAction]
public ActionResult SearchQuote_QuotesForHierarchyAjax(int quoteid)
{
List<QuoteLineSummaryDM> sublist = new List<QuoteLineSummaryDM>();
QuoteLineSummaryDM a = new QuoteLineSummaryDM();
a.PositionCode = "50";
a.Group = "1";
sublist.Add(a);
QuoteLineSummaryDM b = new QuoteLineSummaryDM();
b.PositionCode = "40";
b.Group = "2";
sublist.Add(b);
var qrows = (from r in sublist
select r).AsQueryable();
return View(new GridModel(qrows));
}
What am I missing? My version is even simpler than the demo. Any ideas?
Thanks.
I found another grid that does what I want to do. It's called jqGrid