I have the following markup.
#(Html.Telerik().Grid(Model)
.Name("Grid")
.DataKeys(keys => keys.Add(key => key.Id))
.Columns(columns =>
{
columns.Bound(c => c.FullNameWithEmail).ClientTemplate("<#= FullNameWithEmail #>").Title("Name and Email").Width(230);
columns.Bound(c => c.Notes);
})
.ClientEvents(events => events.OnRowDataBound("grid_onRowDataBound"))
.DetailView(checkInAppGridDetails => checkInAppGridDetails.ClientTemplate("<# if (RelatedCount > 0) { #>" +
Html.Telerik().Grid<ViewModel>()
.Name("GridDetails_<#= Id #>")
.Footer(false)
.Columns(columns =>
{
columns.Bound(c => c.FullNameWithEmail).ClientTemplate("<#= FullNameWithEmail #>").Title("Name and Email").Width(225);
columns.Bound(c => c.Notes);
columns.Bound(c => c.Actions).ClientTemplate("<#= Actions #>").Width(150);
})
.ClientEvents(events => events.OnRowDataBound("GridDetails_onRowDataBound"))
.DataBinding(dataBinding => dataBinding.Ajax()
.Select("GetRelated", "Controller", new
{
id = #ViewBag.EventKey,
ticketId = "<#= Id #>"
}))
.ToHtmlString() +
"<# } #>"
))
)
What i have here is that i am binding the main grid with Ajax call, and once rows got bound the details view gets bound with the DataBinding ajax call.
I already have in the Model a collection for the related records i wanted to show in the DetailView, i don't want the extra call to the server.
here is an example of the ViewModel
public class ViewModel
{
public string FirstProperty {get; set;}
.
.
.
public IEnumurable<ViewModel> RelatedRecords { get; set; }
}
Any idea how to bind the whole Grid with the DetailView with only single Ajax request?
Just used telerik support example to fix this, and it worked very well.Telerik Post
Related
I'm having trouble with an AJAX POST. I'm defining where I want the AJAX call to be posted, but it's posting elsewhere. Please help.
I'm using an MVC Telerik Grid. It probalby doesn't matter if you aren't familiar with it. I'm following the example at http://demos.telerik.com/aspnet-mvc/razor/grid/editingbatch
From that example, Important pieces to this Grid puzzle include:
.Editable(editing => editing.Mode(GridEditMode.InCell))
Also from that example, defining the url for the AJAX call:
.DataBinding(dataBinding => dataBinding.Ajax()
.Select("_SelectContactsBatchEditing", "Ajax", new {FirstName = #ViewData["FirstName"], LastName = #ViewData["LastName"]})
.Update("_SaveContactsBatchEditing", "Ajax", new {FirstName = #ViewData["FirstName"], LastName = #ViewData["LastName"]})
)
For both Select() and Update() methods, the first parameter is the Action and the second parameter is the Controller. I have a third optional parameter which contains the other data to send back in the post.
My grid is Master/Detail. I've taken out the Detail portion and I'm still having the issue. I've giving you my entire grid. For now please let's focus on the Master portion.
#(Html.Telerik().Grid<ContactView>()
.Name("ContactsGrid")
.Columns(columns =>
{
columns.Bound<int>(c => c.Id).Width(65).ReadOnly();
columns.Bound<string>(c => c.FirstName).Width(100);
columns.Bound<string>(c => c.LastName).Width(100);
columns.Bound<string>(c => c.Phone).Width(120);
columns.Bound<string>(c => c.Street).Width(200);
columns.Bound<string>(c => c.City).Width(100);
columns.Bound<string>(c => c.Province).Width(50).Title("Prov");
columns.Bound<string>(c => c.PostalCode).Width(80).Title("PC");
columns.Bound<string>(c => c.Email).Width(100);
columns.Bound<bool>(c => c.OkToContact).Width(40).Title("Ok")
.ClientTemplate("<input type='checkbox' disabled='disabled' name='OkToContact' <#=OkToContact? checked='checked' : '' #> />");
columns.Command(commands =>
{
commands.Delete();
}).Width(100);
})
.DetailView(details => details.ClientTemplate(
Html.Telerik().Grid<DonationView>()
.Name("Donations_<#= Id #>")
.Resizable(resizing => resizing.Columns(true))
.Editable(editing => editing.Mode(GridEditMode.InCell).DefaultDataItem(new DonationView(){Description = "Internal Cause"}))
.DataKeys(d => d.Add<int>(a => a.Id).RouteKey("Id"))
.Columns(columns =>
{
columns.Bound(o => o.Id).Width(65).ReadOnly();
columns.Bound(o => o.Description).Width(400);
columns.Bound(o => o.Amount).Width(80);
columns.Bound(o => o.Date).Format("{0:d}");
})
/*.ClientEvents(events => events.OnRowDataBound("cause_onRowDataBound"))*/
.DataBinding(dataBinding => dataBinding.Ajax()
.Select("_SelectDonationsHierarchyBatchEditing", "Ajax", new { ContactID = "<#= Id #>" })
.Update("_SaveDonationsHierarchyBatchEditing", "Ajax", new {ContactID = "<#= Id #>"})
)
.Sortable()
.ToolBar(commands => {
commands.Insert();
commands.SubmitChanges();
})
/*.Filterable()*/
.ToHtmlString()
))
.DataBinding(dataBinding => dataBinding.Ajax()
.Select("_SelectContactsBatchEditing", "Ajax", new {FirstName = #ViewData["FirstName"], LastName = #ViewData["LastName"]})
.Update("_SaveContactsBatchEditing", "Ajax", new {FirstName = #ViewData["FirstName"], LastName = #ViewData["LastName"]})
)
.Resizable(resizing => resizing.Columns(true))
//.Pageable(paging => paging.PageSize(25))
.Editable(editing => editing.Mode(GridEditMode.InCell))
.DataKeys(d => d.Add<int>(a => a.Id).RouteKey("Id"))
.Scrollable(scrolling => scrolling.Height(500))
.ToolBar(commands => {
commands.Insert();
commands.SubmitChanges();
})
//.HtmlAttributes(new { style = "width: 1200px" } )
.Sortable()
)
My Select() method calls correctly, however my Update() method does not. It simply posts to the same page the grid resides on. I had this working but didn't bother to check in (stupid), and broke it a few days later. No amount of Ctrl+Z has helped me.
Here is the action in my Ajax Controller. Details removed since they don't matter. The method just isn't getting called.
[GridAction]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult _SaveContactsBatchEditing([Bind(Prefix = "inserted")]IEnumerable<ContactView> insertedContacts,
[Bind(Prefix = "updated")]IEnumerable<ContactView> updatedContacts,
[Bind(Prefix = "deleted")]IEnumerable<ContactView> deletedContacts, string FirstName, string LastName)
{
ISession session = SessionManager.OpenSession();
ContactProvider cp = new ContactProvider(session);
if (insertedContacts != null)
{
//stuff
}
if (updatedContacts != null)
{
//stuff
}
if (deletedContacts != null)
{
//stuff
}
IList<ContactView> Contacts = new List<ContactView>();
ContactViewProvider Provider = new ContactViewProvider(SessionManager.OpenSession());
Contacts = Provider.GetContactsByName(FirstName, LastName);
//return View(new GridModel(Contacts));
return new LargeJsonResult
{
MaxJsonLength = int.MaxValue,
JsonRequestBehavior = System.Web.Mvc.JsonRequestBehavior.AllowGet,
Data = new GridModel<ContactView>
{
Data = Contacts
}
};
}
When I click the Save button in my grid's toolbar, I can use firebug to see the Select() method makes the proper AJAX call but the Update() method doesn't: (See http://i.stack.imgur.com/GPCS6.png)
In this image the first post url corresponds with the values passed into my Select() method. The second post url does not correspond with my Update() method.
What's going on here? Thanks in advance
So it turns out there is nothing wrong with what I did. The MVC project somehow became messed up.
I created a throwaway project to try to reproduced the issue but I couldn't - the throwaway was working. So I deleted the MVC project in my solution and copied the pieces into the new project one by one and sure enough, it works. I have no idea how it became discombopulated in the first place but at least the issue is rectified. For anyone having the same issue, I suggest you try this!
I try to create a Ajax-support Paging Nested Grid in Telerik MVC Extension. I have rendered the Nested Grid in browse, can expand row Genre to show the related Albums filtered by GenreId, but when i use Ajax for this nested Grid, it don't work in grid paging. I have upload my project and post some code about my View and Controller.
When i don't use ajax, the gird can work properly but it cannot expand correctly when browse is reloaded, how can i maintain the state of row which had expanded?
I'm gratiful for any help.
My Project:
http://share.vnn.vn/dl.php/11718146
My View:
#{
ViewBag.Title = "Home Page";
Layout = #"~\Views\Shared\_Layout.cshtml";
}
#( Html.Telerik().Grid<MvcMusicCodeFirsr.Models.Genre>(#Model)
.Name("personGrid")
.DataKeys(keys => keys.Add(k => k.GenreId))
.DataBinding(d => d.Ajax().Update( "_Update", "Home" )
)
// .Editable(editing => editing.Mode(GridEditMode.PopUp))
.Columns(c =>
{
c.Bound(m => m.Name).Width(150);
c.Bound(m => m.Description).Width(150);
//c.Bound(m => m.Birthdate);
c.Command(commands =>
{
commands.Edit();
}).Width(80);
})
.DetailView(detailView =>
detailView.Template(
#<text>
#(Html.Telerik().Grid<MvcMusicCodeFirsr.Models.Album>(item.Albums)
.Name("Albums_" + item.GenreId)
.DataBinding(d => d.Ajax())
.Columns(columns =>
{
columns.Bound(o => o.Title).Width(101);
columns.Bound(o => o.Price).Width(140);
})
.Pageable()
.Sortable()
.Filterable()
)
</text>
)
.ClientTemplate(
Html.Telerik().Grid<MvcMusicCodeFirsr.Models.Album>()
.Name("Albums_<#=GenreId#>")
.DataBinding(d => d.Ajax())
.Footer(false)
.ClientEvents(events => events.OnDataBinding("detailGrid_dataBinding"))
.ToHtmlString()
))
.Sortable()
.Pageable()
)
)
<script type="text/javascript">
function detailGrid_dataBinding(e) {
var grid = $(this).data("tGrid"),
masterRow = $(this).closest("tr.t-detail-row").prev(),
dataItem = $("#Grid").data("tGrid").dataItem(masterRow);
grid.dataBind(dataItem.Albums);
e.preventDefault();
}
</script>
My Controller:
MusicStoreEntities db = new MusicStoreEntities();
public ActionResult Index()
{
return View(db.Genres.ToList());
}
[GridAction]
public ActionResult _Select()
{
return View(new GridModel ( db.Genres.ToList()));
}
[GridAction]
public ActionResult _Update()
{
return View(new GridModel { Data = db.Genres.ToList() });
}
Here is an example showing ajax pading for the nested grid: http://demos.telerik.com/aspnet-mvc/grid/hierarchyajax
I have a Telerik grid query. The grid with delete action is working fine in FF and Crome. But in IE showing error 500. I put up break point at the starting point of action method. But its not reaching the action at all. Please tell me what's wrong with this query.
Query
#(Html.Telerik().Grid<Vibrant.Areas.ItemControl.Models.ViewModel>()
.Name("Temp").ClientEvents(e => e.OnLoad("SetFilterPosition").OnDataBinding("Grid_onDataBinding").OnRowDataBound("RowBound").OnDataBound("onDataBound"))
.DataKeys(d => { d.Add(a => a.Itemid).RouteKey("Id"); d.Add(a => a.CurrItemNo).RouteKey("ItemNo"); d.Add(a => a.CurrStatus).RouteKey("Status"); d.Add(a => a.CurrLocation).RouteKey("Location"); d.Add(a => a.CurrStart).RouteKey("Start"); d.Add(a => a.CurrEnd).RouteKey("End"); d.Add(a => a.Option).RouteKey("Option"); })
.ToolBar(commands => commands.Position(GridToolBarPosition.Bottom)
.Custom().ButtonType(GridButtonType.Text)
.HtmlAttributes(new { id = "export" })
.Text("Export to Excel")
.Action("ExportExcel", "WeedItem", new { page = 1, orderBy = "~", filter = "~" }))
.Columns(columns =>
{
columns.Bound(o => o.INo).Title("Item No");
columns.Bound(o => o.BTags).Title("Title");
columns.Bound(o => o.Sid).Title("Status");
//columns.Bound(o => o.Option).Title("Record Status");
columns.Command(commands =>
{
commands.Delete();
}).Width(80).Title("Action");
})
.Pageable(paging =>
paging.PageSize(10)
.Style(GridPagerStyles.NextPreviousAndDropDown | GridPagerStyles.Numeric)
.Position(GridPagerPosition.Bottom)
)
.DataBinding(dataBinding => dataBinding
.Ajax().Select("post", "WeedItem").Delete("DeleteTempData", "WeedItem"))
.Sortable()
.Filterable()
.Groupable()
)
Controller
[GridAction]
public ActionResult DeleteTempData(int Id)
{
var model = ......
...... ;
return View(new GridModel(model));
}
Thanks
The view is returned at the end of your action method. If you cannot hit a debug point at the start of action method, then the problem is not in your view (or grid). 500 is an internal server error, I'd double check the URL you're trying to navigate to and custom errors off in your web.config.
<configuration>
<system.web>
<customErrors mode="Off"/>
...
</system.web>
...
</configuration>
I compared the codes with Telerik sample , everything is the same except the model. But I can't see the records in Grid.
// Controller
public ActionResult Index()
{
return View();
}
[GridAction]
public ActionResult _Index()
{
return View(new GridModel<AuctionViewModel>
{
Data = GetData()
}
);
}
// If I replace 'Index' Action codes with '_Index' , the server binding works fine and shows the records but when I try to run AjaxBinding , It doesn't works (never runs _Index codes)
// View
#model List<TestMVC3_Telerik.Models.AuctionViewModel>
#{
Html.Telerik().Grid((List<TestMVC3_Telerik.Models.AuctionViewModel>)ViewData["MyAuctions"])
.Name("Grid")
.Columns(columns =>
{
columns.Bound(o => o.AuctionID).Title("ID").Width(100);
columns.Bound(o => o.AuctionName).Title("Name");
})
.DataBinding(dataBinding => dataBinding.Ajax().Select("_Index", "Grid"))
.Pageable(paging => paging.PageSize(5))
.Sortable()
.Scrollable()
.Groupable()
.Filterable();
}
.DataBinding(dataBinding => dataBinding.Ajax().Select("_Index", "Grid"))
Change "Grid" to what you are calling the page from
.DataBinding(dataBinding => dataBinding.Ajax().Select("_Index", "Home"))
Once I did that it loaded for me.
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