Telerik Grid MVC not displaying data on read - telerik

So I've got a grid that I believe is all set up correctly. I've confirmed that the data is coming through, and I've even checked that the AJAX call returns a success with the "ToDataSourceResult" JSON data.
​
Unfortunately, the only problem is that the data doesn't display. This seems to only be an issue on read, as update, create and delete all work. Just can't retrieve the list of all items afterwards.
​
My controller action looks like this:
public IActionResult Blog_Read([DataSourceRequest] DataSourceRequest request)
{
var blogs = _blogService.GetPosts().Select(post => new BlogPostModel
{
Id = post.Id,
Title = post.Title,
Author = post.Author,
ShortDescription = post.ShortDescription,
Contents = post.Contents,
LastSaved = post.LastSaved,
Published = post.Published,
PublishedOn = post.PublishedOn
});
var result = blogs.ToDataSourceResult(request);
return Json(result);
}
​
And my Grid View looks like this:
#(Html.Kendo().Grid<BlogPostModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.Title);
columns.Bound(p => p.Author).Width(120);
columns.Bound(p => p.LastSaved).Width(120);
columns.Bound(p => p.Published).Width(120);
columns.Command(command => { command.Edit(); command.Destroy(); }).Width(250);
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Pageable()
.Sortable()
.Scrollable()
.HtmlAttributes(new { style= "height:600px;"})
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.Id))
.Create(update => update.Action("Blog_Create", "BlogAdmin"))
.Read(read => read.Action("Blog_Read", "BlogAdmin"))
.Update(update => update.Action("Blog_Update", "BlogAdmin"))
.Destroy(update => update.Action("Blog_Delete", "BlogAdmin"))
)
.Deferred()
)
​
The correct JSON is returned, no javascript errors in the console, so I'm a little confused as to what this could be. Any help would be greatly appreciated.

I solved this by adding
services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
to my Startup.cs ConfigureServices method.

Related

WEB API Kedo Grid with Grouping

I am new at using Kendo .
I have searched all over but could not see any hint on using group on kendo grid , with server/client side grouping.
#(Html.Kendo().Grid<TemperatureRecord>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(temperatureRecord => temperatureRecord.RecordId).Width(100);
columns.Bound(temperatureRecord => temperatureRecord.MemberIdentity).Width(150);
columns.Bound(temperatureRecord => temperatureRecord.Location);
columns.Bound(temperatureRecord => temperatureRecord.TemperatureCelcius).Width(200);
columns.Bound(temperatureRecord => temperatureRecord.Remark).Width(300);
})
.Groupable(g => g.Enabled(false))
.ToolBar(toolbar =>
{
toolbar.Save();
})
.Editable(editable => editable.Mode(Kendo.Mvc.UI.GridEditMode.InCell))
.DataSource(dataSource => dataSource
.WebApi()
.Batch(true) // Enable batch updates
.Group(groups => groups.Add(temperatureRecord => temperatureRecord.MemberIdentity))
.Model(model =>
{
model.Id(temperatureRecord => temperatureRecord.RecordId);
})
.Read(read => read.Url(Url.HttpRouteUrl("DefaultApi", new { controller = "TemperatureRecord" })))
.Update(update => update.Url(Url.HttpRouteUrl("DefaultApi", new { controller = "TemperatureRecord" })))
)
)
The code which I have do not show any error on screen but it hangs.
Same thing happens when I manually group the grid on browser.. It hangs.
After a number of tries , I discovered that Model needs to be added on the field which you want to group.
Changed the code to following and it worked
#(Html.Kendo().Grid<IHiS.Noss.Web.Models.TemperatureRecord>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(temperatureRecord => temperatureRecord.RecordId).Width(100).Hidden(true);
columns.Bound(temperatureRecord => temperatureRecord.MemberIdentity).Width(150).Groupable(true).Hidden(true);
columns.Bound(temperatureRecord => temperatureRecord.Location).Width(100);
columns.Bound(temperatureRecord => temperatureRecord.TemperatureCelcius).Width(200);
columns.Bound(temperatureRecord => temperatureRecord.Remark).Width(300);
})
.Groupable(g => g.Enabled(false))
.ToolBar(toolbar =>
{
toolbar.Save(); // The "save" command saves the changed data items
})
.Editable(editable => editable.Mode(Kendo.Mvc.UI.GridEditMode.InCell)) // Use in-cell editing mode
.DataSource(dataSource => dataSource
.WebApi()
.ServerOperation(false)
.Batch(true) // Enable batch updates
.Group(groups => groups.Add(temperatureRecord => temperatureRecord.MemberIdentity))
.Model(model =>
{
model.Id(temperatureRecord => temperatureRecord.RecordId); // Specify the property which is the unique identifier of the model
model.Field(temperatureRecord => temperatureRecord.MemberIdentity);
})
.Read(read => read.Url(Url.HttpRouteUrl("DefaultApi", new { controller = "TemperatureRecord" })).Data("getdate"))
.Update(update => update.Url(Url.HttpRouteUrl("DefaultApi", new { controller = "TemperatureRecord" })))
)
)

Kendo grid in edit mode doesn't fire push event

My grid is build like this:
#(Html.Kendo().Grid<MyProject.Models.DataObjects.MyObject>()
.Name("my-object-grid")
.Columns(columns =>
{
columns.Bound(p => p.ID).Hidden();
columns.Bound(p => p.Name).Width(300);
columns.Command(command =>
{
command.Edit().Text("Modify")
.UpdateText("Save")
.CancelText("Cancel")
.HtmlAttributes(new { style = "width:90px;height:30px;font-size:12px;" });
command.Destroy().Text("Delete").HtmlAttributes(new { style = "width:90px;height:30px;font-size:12px;" });
}).Width(220);
})
.ToolBar(toolbar => toolbar.Create().Text("Add").HtmlAttributes(new { style = "width:120px;height:30px;float:left;" }))
.Editable(editable => editable.Mode(GridEditMode.PopUp)
.Window(win => win.Title("MyObject")).TemplateName("MyObject"))
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Model(model =>
{
model.Id(p => p.ID);
})
.Create(update => update.Action("MyObject_Create", "MyObject"))
.Read(read => read.Action("MyObject_Read", "MyObject"))
.Update(update => update.Action("MyObject_Update", "MyObject"))
.Destroy(update => update.Action("MyObject_Delete", "MyObject"))
.Events(evt => evt.Push("myObjectGridDataSource_push").Error("myObjectGridDataSource_error"))
)
)
And the foolwingo javacript handlers are defined after:
<script type="text/javascript">
function myObjectGridDataSource_push(e) {
alert(e.type);
}
function myObjectGridDataSource_error(e) {
alert(e.status);
}
</script>
The javascript generated by the helper seems to be ok, but the event handlers are never fired when I add/edit/remove some item of the grid. But the requests to the controller are working fine.
Could be this related to the edit mode of the grid (using popup)?
I can't find what I am doing wrong...
Push is invoked during dataSource transport initialization which sets up push notifications. The data source will call this function only once and provide callbacks which will handle push notifications (data pushed from the server).
Push event Detailed information
If you can tell what exactly you are trying to achieve then I can be of a bit more help. Also if you want to catch the event before the record id being udpated or inserted or deleted then push won't do it. You will need to implement the sync event of the grid.

MVC: get uploaded filename back in grid column

I have an MVC razor form with a Kendo grid. The grid has an asynch image uploader.
#(Html.Kendo().Grid<CraftStore.Models.Catalog>()
.Name("CatalogGrid")
.Columns(columns =>
{
columns.Bound(p => p.CatalogName).Filterable(true).Width(240);
columns.Bound(p => p.CatalogDescription).Filterable(true).Width(340);
columns.Bound(p => p.ModelNumber).Filterable(true).Width(110);
columns.Bound(p => p.SerialNumber).Filterable(true).Width(110);
columns.Bound(p => p.InventoryCount).Filterable(true).Width(110);
columns.Bound(p => p.WebPrice).Title("Price").Format("{0:C}").EditorTemplateName("Currency").Width(110);
columns.Bound(p => p.ImagePath).ClientTemplate("<img height='80' src='" + Url.Content("~/Content/Images/catalog/Products/") + "#=data.ImagePath#' title='#=data.ImagePath#' alt='#=data.CatalogName#' />").EditorTemplateName("Image").Title("Picture").Width(300);
columns.Command(command => command.Destroy()).Width(110);
})
.ToolBar(toolbar =>
{
toolbar.Create();
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Filterable(filterable => filterable
.Extra(false)
.Operators(operators => operators
.ForString(str => str.Clear()
.Contains("Contains")
.StartsWith("Starts with")
.IsEqualTo("Is equal to")
.IsNotEqualTo("Is not equal to"))
.ForNumber(num => num.Clear()
.IsEqualTo("Is equal to")
.IsNotEqualTo("Is not equal to")
.IsGreaterThan("Greater than")
.IsLessThan("Greater than"))
))
.Navigatable()
.Selectable(selectable => selectable.Type(GridSelectionType.Row))
.Scrollable(scrollable =>
{
scrollable.Virtual(true);
scrollable.Height(400);
})
.Events(events =>
{
events.Change("change");
})
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.PageSize(20)
.Model(model =>
{
model.Id(p => p.Id);
}
)
.Events(events =>
{
events.Error("error_handler");
})
.Create("CatalogEditing_Create", "WebCatalog")
.Read("CatalogEditing_Read", "WebCatalog")
.Update("CatalogEditing_Update", "WebCatalog")
.Destroy("CatalogEditing_Destroy", "WebCatalog")
)
)
All work fine! - the image has a tooltip of the filename...
The upload and remove work great...
I have an edit template for image (image.cshtml in Views/Shared/EditorTemplates)
The template is:
#model string
<div style="width:100%">
<div class="section">
#Html.TextBoxFor(model => model, new {#class="k-textbox result-box" })
#(Html.Kendo().Upload()
.Name("files")
.Events(events=>events.Success("OnUploadSuccess"))
.Multiple(false)
.Async(a => a
.Save("Save", "Upload")
.Remove("Remove", "Upload")
.AutoUpload(true)
)
)
</div>
</div>
The OnUploadSuccess js function (which is defined on the razor view) has the success function
<script type="text/javascript">
//file upload scripts
function getFileInfo(e) {
return $.map(e.files, function (file) {
var info = file.name;
// File size is not available in all browsers
if (file.size > 0) {
info += " (" + Math.ceil(file.size / 1024) + " KB)";
}
return info;
}).join(", ");
}
function OnUploadSuccess(e) {
$(".result-box").value = getFileInfo(e);
Model = getFileInfo(e);
}
all works fine - the variable 'Model' does get the correct filename.
Now...
How do I get that filename value returned by getFileInfo(e) to be the current value for the grid column???
I thought 'Model' would work, but it does not.
Model = getFileInfo(e);
//since this is in a template, I thought it would bind 'Model' to the column
Then, you can see above, in OnUploadSuccess, I also thought it could be done by using jQuery :
$(".result-box").value = getFileInfo(e);
The jQuery does find and set the value, but the row's member named ImagePath never gets the resulting value.
Neither work, and I'm not sure how to get the returned filename to be the column value.
Any help appreciated.
UPDATE:
Well, I've updated the OnUpdateSuccess js function:
var fn = getFileName(e);
$("#ImagePath").val(fn)
And this now updates the field - but this is not saving when you tab out of the field or immediately hit save. In either care, the old value is restored.
How do I get it to stay? I imagine this is where the MVVM binding will help?
After working with the amazing support from Telerik, I was right - it's a binding issue because the MVVM doesn't know about my change. To get it to know about my change I need to add a line after the script change above:
$("#ImagePath").trigger("change");
Now, it works perfectly!

How to open kendo window on click

please go through the code below. In below grid, I've a column with hyperlink. I want to open a kendo window when i click on the particular link. How can i achieve this. Currently it is navigating to some other page.
#model IEnumerable<WeBOC.Support.Entities.ImportUnit>
#{
ViewBag.Title = "Import Units";
}
<h2>Import Units</h2>
#(Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.UnitNbr).Width(150).ClientTemplate(#Html.ActionLink("#=UnitNbr#", "UnitInspector", new { id = "#=UnitId#" }).ToHtmlString()).Title("Unit No.");
columns.Bound(p => p.VIRNbr).Width(150).Title("VIR No.");
columns.Bound(p => p.BLNbr).Width(150).Title("BL No.");
columns.Bound(p => p.IGMStatus).Width(80).Title("IGM Status");
columns.Bound(p => p.LineCode).Width(80).Title("Line Code");
columns.Bound(p => p.Arrived).Format("{0:dd/MM/yyyy HH:mm}").Width(150).Title("Arrived");
})
.Groupable()
.Pageable()
.Sortable()
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.ServerOperation(false)
)
)
How to create hyperlinks, how to invoke javascript functions and how to pass parameters is all covered in this section of the documentation.
Why don't you change your client template to a simple html-element such as an a-element and assing a javascript function to this element which opens your window?
...
columns.Bound(p => p.UnitNbr).Width(150).ClientTemplate("<a id="myId>Unit No.</a>);
...
and then use jquery:
$("#myId").click(function() {
$("#kendoWindow").data("kendoWindow").open();
});
Adjust your template so the links have a css class:
columns.Bound(p => p.UnitNbr).Width(150).ClientTemplate(#Html.ActionLink("#=UnitNbr#", "UnitInspector", new { id = "#=UnitId#" }, new { #class="someclass" }).ToHtmlString()).Title("Unit No.");
Then use jQuery:
$(document).on("click", ".someclass", function (e) {
e.preventDefault();
var address = $(this).attr("href");
$("<div/>").kendoWindow({
content: address
}).data("kendoWindow").open();
});

Kendo UI Grid batch delete

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();
}
}
}

Resources