I'm having an issue with Telerik's Kendo UI Pie Chart in MVC. I can't find any decent code examples on their site. The one demo I've found only shows half of the code, so I tried guessing at how to get it working. I'm getting an error, and no matter what I've tried to eliminate the error, nothing seems to work. It's having an issue with the series.Pie section where you actually bind the data. I copied the code that was in their example, and used the lambda expression just like they did. model => model.Percentage and model => model.StatusName to work with my view model. But it errors out on the very first lambda, with this error message:
CS1660: Cannot convert lambda expression to type 'string' because it is not a delegate type
Here is the relevant code:
ViewModel / View:
public class StatusPercentageViewModel
{
public string StatusName { get; set; }
public int Count { get; set; }
public double Percentage { get; set; }
}
#model IEnumerable<StatusPercentageViewModel>
#(Html.Kendo().Chart(Model)
.Name("StatusBreakdown")
.Legend(legend => legend
.Position(ChartLegendPosition.Bottom)
)
.Series(series =>
{
series.Pie(
model => model.Percentage,
model => model.StatusName,
null,
null
);
})
.Tooltip(tooltip => tooltip.
Template("${ category } - ${ value }%").Visible(true)
)
)
You probably need to specify the model if you want to define your series like that. See this example
For example:
#(Html.Kendo().Chart<StatusPercentageViewModel>()
.Name("StatusBreakdown")
.Legend(legend => legend.Position(ChartLegendPosition.Bottom))
.DataSource(ds => ds.Read(read => read.Action("GetStatus", "Status")))
.Series(series =>
{
series.Pie(
model => model.Percentage,
model => model.StatusName
);
})
.Tooltip(tooltip => tooltip.Template("${ category } - ${ value }%").Visible(true))
)
Another way (more similar to what you have now) to do it would be:
#model IEnumerable<StatusPercentageViewModel>
#(Html.Kendo().Chart()
.Name("StatusBreakdown")
.Legend(legend => legend.Position(ChartLegendPosition.Bottom))
.Series(series => series.Pie(Model))
.Tooltip(tooltip => tooltip.Template("${ category } - ${ value }%").Visible(true))
)
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'm trying to display a Kendo dataviz piechart with the following information.
I'm passing 'results' back from my controller to my view.
My view contains the piechart:
#(Html.Kendo().Chart<PropertyViewModel>()
.Name("chart")
.Title("Properties")
.Legend(legend => legend
.Position(ChartLegendPosition.Top)
)
.DataSource(ds => ds.Read(read => read.Action("GetPropertiesChart", "Home")))
.Series(series => {
series.Pie(model => model.Address.State, model => model.Address.State.Count().ToString());
})
.Tooltip(tooltip => tooltip
.Visible(true)
.Format("{0:N0}")
)
)
I get nothing but a blank area on my page where the piechart should be.
Controller code:
public ActionResult GetPropChart()
{
var allProps = PService.GetAll();
var props = allProps.Cast<PropViewModel>().ToList();
var results = props
.GroupBy(item => item.Address.State)
.Select(g => new
{
State = g.Key,
Count = g.Select(l => l.Address.State).Count()
});
return Json(results);
}
The model you return is as follows:
.Select(g => new
{
State = g.Key,
Count = g.Select(l => l.Address.State).Count()
}
However your series definition are different (there is no Adress property)
series.Pie(model => model.Address.State)
Also binding to methods (such as model.Address.State.Count().ToString()) is Not supported - created regular property which holds the value instead.
In my editor for insert telerik show only common textbox (not integer,decimal etc).
this is my view:
#(Html.Telerik().Grid <GamePlayer2>(Model).Name("za11").DataKeys(keys => keys.Add(c => c.Id))
.ToolBar(commands => commands.Insert()
.ButtonType(GridButtonType.ImageAndText))
.DataBinding(dataBinding => dataBinding.Server()
.Insert("PlayerAdd", "Player", new { })
.Update("PlayerUpdate", "Player", new { })
.Delete("PlayerDelete", "Player", new { })
)
.Columns(columns =>
{
columns.Bound(b => b.Name);
columns.Bound(b => b.Price);
columns.Command(commands =>
{
commands.Edit();
commands.Delete();
}).Width(200);
})
.Editable(editing => editing.Mode(GridEditMode.PopUp)))
model:
public class GamePlayer2
{
public int Id { get; set; }
public string Name { get; set; }
[DataType(DataType.Currency)]
public decimal Price{ get; set; }
}
Scripts are registered on _Layout. Where is a problem? Why currency(integer,date etc) textbox won't display for fields?
Make sure you have added the EditorTemplates under the Shared/EditorTemplates folder. Basically they are automatically added if you have used the wizard to create your project. If not create a demo project and copy-paste them from there.
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
I'm building an ASP.NET MVC3 app. I have 2 views;
List item contains a grid
details view consists of a drop down list (combobox)
I have a requirement to alert the user at the details view when they try to select item was previously selected in the list view. In other words, the grid should contain unique items
What is the best way to implement a server-side business logic validation?
Model:
public class AllocatedResource
{
public virtual Project Project { get; set; }
public virtual DateTime StartDate { get; set; }
public virtual DateTime EndDate { get; set; }
}
List View:
#(Html.Telerik().Grid(Model.AllocatedResources)
.Name("gridAllocatedProject")
.DataKeys(keys =>{keys.Add(p => p.Id);})
.Columns(columns =>
{
columns.Bound(p => p.Id).Visible(false);
columns.Bound(p => p.Project.Name);
columns.Bound(p => p.Project.ProjectManager).Title("Project Manager");
columns.Bound(p => p.StartDate).Width(80).Format("{0:d}");
columns.Bound(p => p.EndDate).Width(80).Format("{0:d}");
})
Details View:
#Html.Label("Project: ")
#(Html.Telerik().ComboBox().Name("Project")
.BindTo(new SelectList(Model.AllProjects, "Id", "Name"))
.Value(Model.AllocatedResource.Project.Id.ToString()))
#Html.Label("Start Date: ")
#(Html.Telerik().DatePicker().Name("StartDate")
.Value(Model.AllocatedResource.StartDate))
#Html.Label("End Date: ")
#(Html.Telerik().DatePicker().Name("EndDate")
.Value(Model.AllocatedResource.EndDate))