Telerik/ Kendo MVC Grid, Load grid on demand, not on page load - model-view-controller

i found a couple examples on how to do this, and none of them are working for me.
Here is my Telerik MVC grid:
#(Html.Kendo().Grid<PlayerStatsViewModel>()
.Name("PlayerStats")
.Columns(columns =>
{
columns.Bound(o => o.PlayerId);
columns.Bound(o => o.FirstName);
})
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(p => p.PlayerId))
.Read(read => read.Action("PlayerStats_Read_Bound", "Contest").Data("getPlayerId"))
).AutoBind(false)
)
Open modal with my grid
I set autobind(false) which prevents page load. After a user clicks a link i open a modal with my grid, and need to pass in a parameter.
// open modal
$(document).on("click", "#openStatsModal", function () {
playerId = $(this).data('id'); // get parameter from click
loadPlayerStats();
});
function getPlayerId() {
return {
playerId: playerId
}
}
Make ajax call?
My click method works and i get my player id. Then i try and make my grid call.
function loadPlayerStats() {
var grid = $("#PlayerStats").data("playerStats");
alert(grid); // returns undefined
//grid.ajaxRequest(); this didnt work either
grid.dataSource.read(); // Cannot read property 'dataSource' of undefined
}
Action method
Never gets called unless i turn off autobind
public ActionResult PlayerStats_Read_Bound([DataSourceRequest]DataSourceRequest request, int playerId)
{
// some code
return Json(result)
}

Just try:
var grid = $("#PlayerStats").data("kendoGrid");
and then:
grid.dataSource.read();

Related

Model Empty in Popup Editor template for Kendo MVC Grid Create, No default value

I have a Kendo MVC hierarchy grid. My example is simplified for readability.
#(Html.Kendo().Grid<LeagueViewModel>(Model.Leagues)
.Name("grid_#=LeagueTypeId#")
.Columns(columns => { })
.ToolBar(toolbar =>
{
toolbar.Create().Text("Add New League(Window)");
})
.Editable(editable => editable.Mode(GridEditMode.PopUp)
.TemplateName("LeagueEdit")
.Window(w =>
{
w.Position(p => p.Top(200)); // position not working, need to center more vertically
w.Width(800);
}
)
)
.Events(e => e.Edit("leagueEdit"))
.DataSource(dataSource => dataSource
.Server()
.Model(model =>
{
model.Id(p => p.LeagueID);
model.Field(l => l.strSportId).DefaultValue("#=SportId#"); // set default value with parent grid data
model.Field(l => l.strLeagueTypeId).DefaultValue("#=LeagueTypeId#"); // set default value with parent grid data
}
)
.Read(read => read.Action("Bound_League_Read", "Configuration", new { _leagueTypeId = "#=LeagueTypeId#" }))
.Create(create => create.Action("League_Create", "Configuration"))
)
)
Here is my javascript event handler. When observing the e.model object from the handler after the create button is clicked i have the default values i set earlier with in the grid with DefaultValue("#=ParentProperty#").
function leagueEdit(e) {
// setting these with default value on model,
// had to have string variants to pass over because template expression syntax
e.model.SportId = parseInt(e.model.strSportId);
e.model.LeagueTypeId = parseInt(e.model.strLeagueTypeId);
}
LeagueEdit.cshtml
When my popup template opens, the model has no data. How do i get data into the model? I have elements in the popup editor that need the values from the parent grids.
<p>sport: #Model.SportId</p> <!-- value does not carry over -->
<p>leaguetype: #Model.LeagueTypeId</p> <!-- value does not carry over -->
In your Edit event try to find the control in popup using its Id and set the value. For example in the below code am finding a datepicker inside my popup and setting its value to the model property.
function LeagueEditEdit(e) {
var val1 = e.container.find("input[name=CallDate]").data("kendoDatePicker");
val1.value($('#CallDate').attr('value'));
e.model.CallDate = val1._value;
}

Disabling edit on Telerick MVC Grid

I have a MVC Kendo UI Grid as follows
#(Html.Kendo().Grid<SomeViewModel>()
.Name("someGrid")
.ToolBar(toolbar =>
{
toolbar.Create().Text("Add Entry");
toolbar.Save();
})
.Columns(columns =>
{
columns.Bound(p => p.Name).ClientTemplate(#"<input type='radio' name='SomeradioName'> #= Name # </input>");
columns.Bound(p => p.DateCreated).Format("{0:dddd dd MMMM yyyy}");
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Events(e => e.DataBound("onDataBound"))
.Events(e => e.Edit("onDataEdit"))
.Selectable(selectable => selectable.Enabled(true).Mode(GridSelectionMode.Single).Type(GridSelectionType.Row))
.Scrollable()
.Filterable()
.HtmlAttributes(new {style = "height:200px;"})
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(false)
.Batch(false)
.Events(events => events.Error("onError"))
.Model(model =>
{
model.Id(s => s.Id);
model.Field(s => s.Name).Editable(true);
model.Field(s => s.DateCreated).Editable(false);
})
.Read(read => read.Action(...))
.Create(create => create.Action(...))
.Update(create => create.Action(...))))
I want to disable In cell editing for already added entries.
So, couple of things I tried
Approach# 1:
<script>
function onDataEdit(e) {
if (!e.model.isNew()) {
var grid = this;
grid.closeCell();
}
}
</script>
Apparently this breaks the radio button selection event (.change event) which is wired up in OnDataBound.closeCell screws it up and change event no longer gets fired up
Approach# 2:
In OnDataEdit event do
$("#Name").attr("readonly", true);
This is also fine but again Change event is no longer fired on radio button click until the Cancel changes command is clicked.
Approach# 3
There seems to be another way of doing it by disabling enable as given in this link here: http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#events-edit
if (!e.model.isNew()) {
// Disable the editor of the "id" column when editing data items
var numeric = e.container.find("input[name=id]").data("kendoNumericTextBox");
numeric.enable(false);
}
How do I do something similar in my case ? Couldn't get data resolved.
Any other ways ?
Update
Approach# 4
e.container.find("input[name=Name]").each(function () { $(this).attr("disabled", "disabled") });
var grid = this;
grid.cancelChanges();
This does not break the change event. However, the experience is not that great. If adding new record, if the user presses any other row the changes are canceled. They have to add new record and either hit Save or click anywhere except grid rows
You can make the columns readonly on edit, using Approach 3
function edit(e) {
if (e.model.isNew() == false) {
$('[name="Name"]').attr("readonly", true);
}
}
Also, your template doesnt have an id=Name, hence I doubt below will work for you. Instead find by name attribute as above
$("#Name").attr("readonly", true);
Refer this link for more information
I have chosen approach 4 which I updated. IF anyone has any better ideas feel free to share.

How do I prevent the cancel event from changing my grid row color?

I search for data and then bind to my grid. In the grid's databound event, I change the row background color according to the cell's value. This works OK. But when I click the Edit button in the grid and then click the Cancel button, the grid no longer has the background color set. I tried to call the databound event in the Cancel event, but it does not work. How do I prevent the Cancel Event from changing my grid color?
grid
#(Html.Kendo().Grid(Model)
.Name("mygrid")
.Events(e=>e.DataBound("dataBound"))
.Columns(columns =>
{
columns.Bound(p =>p.StudentName).Title("StudentName");
columns.Command(command =>
{
command.Edit().UpdateText("Edit");
command.Destroy().Text("Delete");
}).Width(160);
})
.Editable(editable => editable.Mode(GridEditMode.PopUp)
.TemplateName("SudentEditor")
.Window(configurator=>configurator.Width(500)
.Title("EditStudent")))
.Scrollable()
.Events(events=>events.Cancel("onCancel"))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Model(model =>
{
model.Id(p => p.Id);
})
.Read(read => read.Action("GetStudentForGrid", "Student"))
.Create(create=>create.Action("CreateSudent","Equipment"))
.Update(update => update.Action("UpdateStudent", "Student"))
.Destroy(destory=>destory.Action("DestroyStudent","Student"))
.Events(events => events.Error("error_handler"))
))
databound event
//change grid color
function dataBound(e) {
$("#mygrid tbody tr").each(function(i) {
$(this).find("td:lt(9)").css("backgroundColor", '#000000');
});
}
cancel event
//I try to call preventDefault event and close the PopUp window
//,but the background is still grey
function onCancel(e) {
//e.preventDefault();
//e.container.parent().css("display", "none");
// e.sender.clearSelection();
dataBound();
}
Just refresh the grid in the cancel event. It will fire the onDataBound event again. I had the same issue and resolved it like this:
function onCancel(e) {
$("#GridName").data("kendoGrid").refresh();
}
//change grid color
function dataBound(e) {
$("#mygrid tbody tr").each(function(i) {
$(this).find("td:lt(9)").css("backgroundColor", '#000000');
});
}
You can use grid.cancelRow() in the cancel enent,and then refresh the grid.
If you don't want to refresh the grid but run code after the event has finished instead, you can use a setTimeout() in the cancel event.
function onGridCancel(e){
setTimeout(function() {
colorMyRowsBeutifully();
}, 0);
}
See this answer from Telerik:
https://www.telerik.com/forums/grid-cancel-event
I also ran into this problem and the solutions from above didn't work for me.
But I found another solution that did the trick, to use the Edit event of the Grid to attach event handler to the Deactivate event of the Window.
Grid events:
.Events(e => {
e.DataBound("onDataBound");
e.Edit("onEdit");
})
Grid event handlers:
function onDataBound(e) {
//Conditional formatting on DataBound
formatGridRows();
}
function onEdit(e) {
//Bind deactivate event to the Popup window
e.container.data("kendoWindow").bind("deactivate", function () {
formatGridRows();
})
}
function formatGridRows() {
$("#Grid tbody tr").each(function () {
grid = $("#Grid").data("kendoGrid");
dataItem = grid.dataItem($(this));
//Conditionally format the current row
if (dataItem.Discontinued) {
$(this).find(":nth-child(3):first").css("background", "red");
}
})
}
Here's the source:
http://www.telerik.com/forums/cancel-popup-clears-grid-background-color

Invoking Page Refresh from Kendo Grid Update

I am using a Kendo-grid with inline editing Let's call this Grid3. The Grid is displaying a list of items from a referenced property of the page's view model. When an item on the grid has been saved, I would like to invoke a complete page refresh (or a refresh two other grids, Grid1 and Grid2 on the page). The reason is that when an items has been updated in the grid, values displayed in other grids are affected.
Any ideas?
Call datasource.read() at those grids you want to refresh.
$("#grid3").kendoGrid({
dataSource : dataSource,
save: function(e) {
grid1.dataSource.read();
grid2.dataSource.read();
}
}
Alternatively place the grid.datasource.read() call into your datasource complete.
var dataSource = new kendo.data.DataSource({
transport: {
update: {
complete: function (jqXhr, textStatus) {
grid1.dataSource.read();
grid2.dataSource.read();
}
}
}
});
This can be accomplished using the RequestEnd event.
The Kendo Grid declaration would have something like:
.DataSource(datasource => datasource
.Ajax()
.Model(model => model.Id(fi => fi.Id))
.Read(read => read.Action("Buildings_ReadForecast", "Plan", new {buildingId = Model.BuildingID}))
.Events(events => events.Error("error_handler"))
.Events(events => events.RequestEnd("OnRequestEnd_Grid"))
Then create the javascript method like:
function OnRequestEnd_Grid(e) {
if (e.type === "update") {
var forecastgrid = $('#ForecastGrid').data('kendoGrid');
var planGrid = $('#PlanGrid').data('kendoGrid');
planGrid.dataSource.read();
forecastgrid.dataSource.read();
}
}
That's it!

Kendo UI Grid: Method "removeRow" deletes all events of the grid

I have a Kendo UI Grid and added mouse events to the grid by jQuery (e.g. click). This is working without any problem. But by deleting a row in the grid, all events of the grid are also deleted. What am I doing wrong?
This is my code to delete a row:
var rowToDelete = $(this).closest("tr");
var grid = $("#gridId").data("kendoGrid");
grid.removeRow(rowToDelete);
I added a button to each row of the grid, added a click event to these buttons which deletes the corresponding row. After the row is deleted, the click events of all other buttons are removed. The same with the mouse-over events of a grid column.
Thanks for your help!
Please try with the below code snippet.
VIEW
<script>
function gridDataBound(e) {
var grid = $("#Grid").data("kendoGrid");
grid.tbody.find(">tr").click(function () {
$("#divTest").html('Row Index Clicked :' + $(this).index());
});
}
function DeleteRow(obj) {
var rowToDelete = $(obj).parent().parent()
var grid = $("#Grid").data("kendoGrid");
grid.removeRow(rowToDelete);
}
</script>
#(Html.Kendo().Grid<MvcApplication1.Models.TestModels>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.ID);
columns.Bound(p => p.Name);
columns.Template(#<text></text>).ClientTemplate("<input type='button' class='k-button' value='Delete' onclick='DeleteRow(this);' />");
})
.Pageable()
.Sortable()
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("Grid_Read", "Home"))
)
.Events(e => e.DataBound("gridDataBound"))
)
<div id="divTest"></div>
CONTROLLER
public ActionResult Grid_Read([DataSourceRequest] DataSourceRequest request)
{
List<TestModels> models = new List<TestModels>();
for (int i = 0; i < 5; i++)
{
TestModels t1 = new TestModels();
t1.ID = i;
t1.Name = "Name" + i;
models.Add(t1);
}
return Json(models.ToDataSourceResult(request));
}
MODEL
public class TestModels
{
[Display(Name = "ID")]
public int ID { get; set; }
[Display(Name = "Name")]
public string Name { get; set; }
}
Let me know if any concern.
You are not posting all the code so I have to guess...
What is happening is that you set an event handler associated to the elements just after the initialization and therefore for some particular HTML elements but there are circumstances under which Kendo UI grid gets regenerated (basically the system removes the table and generates a new one).
If you want to set an event handler not for the current table content but for any future one, you might use jQuery on event but using three arguments where the second is the selector (in previous version of jQuery this was achieved with live function but now is deprecated, so if your jQuery version supports it better use on).
What you have to do is:
$("#grid").on("click", ".my-selector", function(e) {
var rowToDelete = $(this).closest("tr");
var grid = $("#gridId").data("kendoGrid");
grid.removeRow(rowToDelete);
});
Where my-selector is a CSS class attribute that you probably already set for identifying the remove button.

Resources