I have a kendo grid that returns all the results except for the first column, being the date. It is showing as blank. In my viewmodel the reviewdate is of type string. In my controller I have the reviewdate converted to a string. I know that reviewdate returns MM/dd/yyyy from debug.
Controller snippet:
foreach (var item in query)
{
model.Add(new PreviousReviewViewModel()
{
ReviewId = item.ReviewId,
ReviewDate = item.NextReviewDt.ToString("MM/dd/yyyy"),
Rating = item.Rating,
SubmittedFl = item.SubmittedFl
});
}
In my view i have the grid as follows:
#(Html.Kendo().Grid<PreviousReviewViewModel>()
.Name("Grid")
//.HtmlAttributes(new { style = "width:450px;" })
.Columns(columns =>
{
columns.Template(
#<text>
#Html.ActionLink(Model.ReviewDate, "SavedFormsIndex", new { Controller = "Forms", id = Model.ReviewId })
</text>).ClientTemplate(#"").Title("Review Date");
columns.Bound(m => m.Rating).Title("Composite Rating"); //rating is the avg
columns.Bound(m => m.SubmittedFl).Title("Submitted");
})
.Pageable(p => p.Numeric(false).PreviousNext(false).Refresh(true))
.Resizable(resize => resize.Columns(true))
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(2147483647)
.Read(read => read.Action("read_PrevProjReviews", "Forms", new { id = ViewBag.ProjectId }))
)
try change your client template
.ClientTemplate(#"#=ReviewDate#
Related
I have two <section> in the Index view of my MVC application and I want to render two partial views in these sections. There is no problem rendering a Kendo grid to one Index. However, in order to render data on Kendo Grid, could I use the two methods returning Json in the controller as shown below. Could you give me an example how to achieve this?
Controller:
public ActionResult Index()
{
return View();
}
public ActionResult Issues_Read([DataSourceRequest]DataSourceRequest request)
{
IQueryable<Issue> issues = db.Issues;
DataSourceResult result = issues.ToDataSourceResult(request, c => new IssueViewModel
{
ID = c.ID,
ProjectID = c.ProjectID
});
return Json(result);
}
View:
#(Html.Kendo().Grid<IssueViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.ProjectID);
columns.Command(command => { command.Edit(); command.Destroy(); }).Width(180);
})
.ColumnMenu()
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Pageable()
.Navigatable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(p => p.ID))
.Read(read => read.Action("Issues_Read", "Issue"))
.Create(create => create.Action("Issues_Create", "Issue" ))
.Update(update => update.Action("Issues_Update", "Issue"))
.Destroy(destroy => destroy.Action("Issues_Destroy", "Issue"))
)
)
In order to use the same partial view multiple times, grid ID should be unique so passing the ID in partial view data is one possible solution. In your case
Partial view first call:
#Html.Partial("grid", new ViewDataDictionary { { "id", "grid1" }})
Partial view second call:
#Html.Partial("grid", new ViewDataDictionary { { "id", "grid2" }})
Partial view content:
#(Html.Kendo().Grid<IssueViewModel>()
.Name(#ViewData["id"].ToString())
...
I'm trying to use a Kendo grid for the first time: Here's the code for the grid:
#model IEnumerable<SustIMS.Models.ModelTest>
<div id="grid">
#(Html.Kendo().Grid(Model)
.Name("datagrid")
.Columns(columns =>
{
columns.Bound(c => c.Genre).Width(140);
columns.Bound(c => c.Title).Width(190);
columns.Bound(c => c.ReleaseDate);
columns.Bound(c => c.Price).Width(110);
})
.HtmlAttributes(new { style = "height: 90%;" })
.Scrollable()
.Sortable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("Show", "MasterData"))
)
)
</div>
This displays the grid without any data in it. I've created a test model and am trying to add data like this in the controller:
public ActionResult Show()
{
var list = new List<ModelTest>();
list.Add(new ModelTest { Title = "A Title", Price = 10.5m, ReleaseDate = DateTime.Now, ID = 1, Genre = "zz" });
list.Add(new ModelTest { Title = "B Title", Price = 11.5m, ReleaseDate = DateTime.Now, ID = 2, Genre = "zzzzzz" });
return Json(list);
}
This doesn't show any data in the grid. How can I pass data into it? And does it have to come from a model or can it be added in a custom way?
try this:
public ActionResult Show([DataSourceRequest] DataSourceRequest request)
{
var list = new List<ModelTest>();
list.Add(new ModelTest { Title = "A Title", Price = 10.5m, ReleaseDate = DateTime.Now, ID = 1, Genre = "zz" });
list.Add(new ModelTest { Title = "B Title", Price = 11.5m, ReleaseDate = DateTime.Now, ID = 2, Genre = "zzzzzz" });
return Json(list.ToDataSourceResult(request));
}
then put this in your controller:
using Kendo.Mvc.Extensions;
I have a Kendo MVC grid that contains a nullable property (short) that is bound as a foreign key and uses a dropdown list as an editor template. I am also using inline editing.
When the property value is null, the dropdown list selected value does not get set into the grid cell after the update button is clicked. This works fine if incell editing is used. I am looking for a workaround that will solve my problem. I am including a stripped down version of my code below
Everything works if the nullable value is set to a non-null value.
GRID
#(Html.Kendo().Grid<AssetViewModel>()
.Name("DealAssets")
.Columns(c =>
{
c.Bound(x => x.Name);
c.ForeignKey(x => x.AssetTypeID, (IEnumerable<SelectListItem>)ViewBag.AssetTypeList, "Value", "Text");
c.ForeignKey(x => x.SeniorityTypeID, seniorityTypeList, "Value", "Text").EditorTemplateName("GridNullableForeignKey");
c.ForeignKey(x => x.RateBaseID, rateBaseList, "Value", "Text").EditorTemplateName("GridNullableForeignKey"); ;
c.Command(m => { m.Edit(); m.Destroy(); });
})
.ToolBar(toolbar => toolbar.Create().Text("Add New Asset"))
.Editable(x => x.Mode(GridEditMode.InLine))
.DataSource(ds => ds
.Ajax()
.Model(model => model.Id(request => request.ID))
.Read(read => read.Action("ReadAssets", "Deal", new { id = Model.ID }))
.Create(create => create.Action("CreateAsset", "Deal", new { currentDealID = Model.ID }))
.Update(update => update.Action("UpdateAsset", "Deal"))
.Destroy(destroy => destroy.Action("DeleteAsset", "Deal"))
)
)
EDITOR TEMPLATE
#model short?
#{
var controlName = ViewData.TemplateInfo.GetFullHtmlFieldName("");
}
#(
Html.Kendo().DropDownListFor(m => m)
.Name(controlName)
.OptionLabel("- Please select -")
.BindTo((SelectList)ViewData[ViewData.TemplateInfo.GetFullHtmlFieldName("") + "_Data"])
)
UPDATE ACTION
public ActionResult UpdateAsset([DataSourceRequest] DataSourceRequest request, int ID)
{
var dealAsset = DataContext.DealAssets.SingleOrDefault(o => o.ID == ID);
if (dealAsset != null)
{
if (TryUpdateModel(dealAsset.Asset, new[] {"Name","AssetTypeID","SeniorityTypeID","RateBaseID" }))
{
DataContext.SaveChanges();
}
}
return Json(new[] { new AssetViewModel(dealAsset) }.ToDataSourceResult(request, ModelState), JsonRequestBehavior.AllowGet);
}
Telerik just recently added a new HTML attribute, data_value_primitive, to their selectlist that addresses the issue above. The new attribute should be added in the foreign key editor template and set to true.
Html.Kendo().DropDownListFor(m => m)
.Name(controlName)
.OptionLabel("- Please select -")
.BindTo((SelectList)ViewData[ViewData.TemplateInfo.GetFullHtmlFieldName("") + "_Data"])
**.HtmlAttributes(new { data_value_primitive = true})**
This last section is a modification to the update method to account for the grid not passing back null properties when doing the ajax call. I think this has more to do with how the TryUpdateModel method works
...
if (TryUpdateModel(dealAsset.Asset, new[] {"Name","AssetTypeID","SeniorityTypeID","RateBaseID" }))
{
// If no property passed back then set it to null
var senorityTypeID = ValueProvider.GetValue("SeniorityTypeID");
if (senorityTypeID == null)
{
dealAsset.Asset.SeniorityTypeID = null;
} else {
dealAsset.Asset.SeniorityTypeID = (short)senorityTypeID.ConvertTo(typeof(short));
}
var rateBaseID = ValueProvider.GetValue("RateBaseID");
if (rateBaseID == null)
{
dealAsset.Asset.RateBaseID = null;
} else {
dealAsset.Asset.RateBaseID = (byte)rateBaseID.ConvertTo(typeof(byte));
}
DataContext.SaveChanges();
}
'''
I'm trying to launch a Kendo grid in a Kendo popup Window but instead of the grid showing, I'm getting the json data.
This is the code from my controller:
[HttpGet]
public ActionResult Read([DataSourceRequest]DataSourceRequest request, int id)
{
var model = Service.FindOne("Cashflows", x => x.Id == id);
var cashflows = new List<flows>();
foreach (var cf in model.CashFlows)
{
var flow = new flows
{
Id = cf.Id,
AssetId = cf.Id,
MortgageValue = cf.MortgageValue,
Year = cf.Year
};
cashflows.Add(flow);
}
var result = cashflows.ToDataSourceResult(request);
return Json(result, JsonRequestBehavior.AllowGet);
}
This is what I have in my Kendo View.
#(Html.Kendo().Grid<ViewModels.Finance.flows>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.Id);
columns.Bound(p => p.AssetId);
columns.Bound(p => p.Year);
columns.Bound(p => p.MortgageValue);
})
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("Read", "Finance"))
.ServerOperation(false)
.PageSize(5)
)
.Pageable()
)
You need to update the return command to:
return Json(result.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
i have a telerik grid as follow:
Html.Telerik().Grid<MatchViewModel>().Name("Matches").Columns(cols =>
{
cols.Bound(e => e.Name);
cols.Bound(e => e.Date);
cols.Bound(e => e.GuestTeamId);
cols.Bound(e => e.HostTeamId);
cols.Bound(e => e.PostponedDate);
==> cols.Bound(e => e.RefereeId).EditorViewData(new { RefereeName = '' });
cols.Bound(e => e.StatusId);
})
in the column reffered by arrow i wanna send referee name as additional data for EditorTemplate.i inferred from the EditorViewData method name that it can help me doing this.but i can't get it working.can anyone help me with this?
thanks.
If you have a well defined Model for your page you should not ever need to use ViewBag or ViewData, they are sloppy. EditorViewData allows you to create ViewData on-the-fly to pass extra data to your EditorTemplate.
For example, say you want to have different DropDownList values in the EditorTemplate for each item in your grid, you will need to pass extra data to do this. With EditorViewData you can add additional values from your Model for exactly that purpose without having to resort to coding up any ViewBag or ViewData objects in your Controller.
The first place I used it was a People grid that allowed editing of defined Qualifications added to a Qualifications grid inside a nested TabStrip. The trick was I didn't want the DropDownList for each person to contain any of the qualifications they already had earned. Like this...
People Grid
#using Kendo.Mvc.UI
#model PeopleViewModel
#(Html.Kendo().Grid<PersonModel>()
.Name("PersonGrid")
.Columns(columns => {
columns.Bound(b => b.LastName).EditorTemplateName("_TextBox50");
columns.Bound(b => b.FirstName).EditorTemplateName("_TextBox50");
...
columns.Command(cmd => { cmd.Edit(); cmd.Destroy(); }).Width(180);
})
.ClientDetailTemplateId("personTemplate")
.ToolBar(toolbar => toolbar.Create())
.Selectable()
.Editable(editable => editable.Mode(GridEditMode.InLine))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(a => a.Id);
})
.Create(create => create.Action("CreatePerson", "People"))
.Read(read => read.Action("ReadPeople", "People"))
.Update(update => update.Action("UpdatePerson", "People"))
.Destroy(destroy => destroy.Action("DestroyPerson", "People"))
)
.Events(events => events.DataBound("dataBound"))
)
<script type="text/javascript">
function dataBound() {
this.expandRow(this.tbody.find("tr.k-master-row").first());
}
</script>
<script id="personTemplate" type="text/kendo-tmpl">
#(Html.Kendo().TabStrip()
.Name("TabStrip_#=Id#")
.Items(items =>
{
...
items.Add().Text("Edit Qualifications")
.LoadContentFrom("PersonQualifications", "People", new {personId = "#=Id#"});
...
})
.ToClientTemplate()
)
</script>
PeopleViewModel
Ignore the inheritance stuff, it is beyond this discussion. But note that I use this same Model on all the sub Views related to this top level View.
public class PeopleViewModel : PageViewModel
{
public int PersonId { get; set; }
public PersonModel Person { get; set; }
public IList<QualificationModel> AllQualifications { get; set; }
...
public PeopleViewModel(BaseViewModel baseViewModel) : base(baseViewModel)
{}
}
PersonQualifications Controller
The data providers are injected elsewhere, but note the POCO to Model flattening - just a static method that applies a List to the Model constructor.
public ActionResult PersonQualifications(int personId)
{
SetBaseContext(HttpContext);
var model = new PeopleViewModel(BaseViewModel)
{
PersonId = personId,
AllQualifications = QualificationModel.FlattenToThis(_qualificationDataProvider.Read())
};
return View(model);
}
Nested Grid (View Loaded Inside TabStrip)
#using Kendo.Mvc.UI
#model PeopleViewModel
#{
Layout = null;
}
#(Html.Kendo().Grid<PersonQualificationModel>()
.Name("QualificationEditGrid_" + Model.PersonId)
.Columns(columns =>
{
columns.ForeignKey(f => f.QualificationId, Model.AllQualifications, "Id", "Display")
===> .EditorViewData(new {personId = Model.PersonId})
.EditorTemplateName("PersonQualificationDropDownList");
columns.Command(cmd =>
{
cmd.Edit();
cmd.Destroy();
}).Width(180);
})
.ToolBar(toolbar => toolbar.Create())
.DataSource(dataSource => dataSource
.Ajax()
.Events(events => events.Error("error_handler"))
.Model(model => {
model.Id(a => a.Id);
})
.Create(create => create.Action("CreatePersonQualification", "People"))
.Read(read => read.Action("ReadPersonQualifications", "People", new {personId = Model.PersonId}))
.Destroy(destroy => destroy.Action("DestroyPersonQualification", "People"))
)
)
The EditorTemplate (Finally!)
Ignore the first ViewData reference that helps make this EditorTemplate shared. The one we are interested in is a little further down.
#using Kendo.Mvc.UI
#(Html.Kendo().DropDownList()
.Name(ViewData.TemplateInfo.GetFullHtmlFieldName(""))
.DataValueField("Id")
.DataTextField("Name")
.OptionLabel("Select...")
.DataSource(dataSource => dataSource
===> .Read(read => read.Action("ReadDdlQualifications", "People", new {personId = ViewData["personId"]}))
)
)
Controller Method (Just to be Thorough)
public JsonResult ReadDdlQualifications(int personId)
{
var qualification = _qualificationDataProvider.ReadAvailableToPerson(personId);
IList<IdNamePair> results = IdNamePair.FlattenToThis(qualification);
return Json(results, JsonRequestBehavior.AllowGet);
}
Obviously there is a lot of other stuff going on in this example (I hope I left enough code in for it to make sense), but it should get across the point of when it is needed - and it is REALLY needed.
Enjoy.
I ran into the same issue as Chad and as Trey mentioned, this cannot be done via passing information to EditorViewData. There is no way to pass the row data item, only page data.
As an alternative you can add this script to the editor template. Then you can access a field value from the grid row and pass it to the datasource call, filtering the dropdownlist based on each rows data.
<script type="text/javascript">
function getParentId() {
var row = $(event.srcElement).closest("tr");
var grid = $(event.srcElement).closest("[data-role=grid]").data("kendoGrid");
var dataItem = grid.dataItem(row);
return { EmployeeId: dataItem.EmployeeId };
}
</script>
And then add the data item to the read method on the data source.
#(Html.Kendo().DropDownList()
.Name("Product")
.DataValueField("ProductId")
.DataTextField("ProductName")
.DataSource(ds => ds
.Read(read => read.Action("ProductsRead", "Home")
.Data("getParentId")
))
)