Why Is `data(“kendogrid”)` Undefined? - asp.net-mvc

I'm a starter in kendo.ui, I've written this code to create kendo.ui.grid
#(Html.Kendo().Grid<BrandViewModel>(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.BrandName);
columns.Bound(p => p.BrandAbbr);
columns.Bound(p => p.SrcImage);
columns.Command(command => command.Custom("Edit").Click("editItem"));
})
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("CustomCommand_Read", "Brand"))
.Model(model => model.Id(p => p.Id))
)
)
When the user clicks the edit button in grid it will show Edit view in kendo.ui.window and the user can edit data.
#(Html.Kendo().Window().Name("Details")
.Title("Customer Details")
.Visible(false)
.Modal(true)
.Height(400)
.Draggable(true)
.Width(300)
.Events(events => events.Close("onClose"))
)
<script type="text/x-kendo-template" id="template">
<div id="details-container">
<!-- this will be the content of the popup -->
BrandName: <input type='text' value='#= BrandName #' />
</div>
</script>
<script type="text/javascript">
var detailsTemplate = kendo.template($("#template").html());
var windowObject;
$(document).ready(function () {
windowObject = $("#Details").data("kendoWindow");
});
function editItem(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
windowObject.refresh({
url: "/Brand/Edit/" + dataItem.Id
});
windowObject.center().open();
}
function onClose(e) {
var grid = $("#Grid").data("kendoGrid").dataSource.read();
}
</script>
but in onClose method $("#Grid").data("kendoGrid") is Undefined, please help me, thanks all

try Window load event
$(window).load(function () {
var grid = $("#grid").data("kendoGrid");
this work for me.

var grid = $("#Grid").data("kendoGrid"); //call grid by Name of Grid you used in razor

Related

Kendo Grid command.custom url

I am trying to get command.custom to work with a url. i have command.Custom("Tasks"); and it creates the button like it should. But i can't figure out how to get it to point to this url ../../OBClientSetupTasks/Index/#item.SetupID
I tried to make it do a .action and click through the controller and view but it returns a not supported exception
command.Custom("Tasks").Action("Index", "OBClientSetup");
I also can't seem to identify #item.SetupID . item is usually from a foreach, but in this case I don't see where a foreach would go.
EDIT:
Adding full grid
#(Html.Kendo().Grid<XXX_2_0_OBOE.OpenAccess.OBClientSetup>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(obcs => obcs.ProfileName);
columns.Bound(obcs => obcs.Default).ClientTemplate("#= Default ? 'Yes' : 'No' #");
columns.Bound(obcs => obcs.EEFinalize).ClientTemplate("#= EEFinalize ? 'Yes' : 'No' #");
columns.Bound(obcs => obcs.AllowOutsideCodes).ClientTemplate("#= EEFinalize ? 'Yes' : 'No' #");
columns.Bound(obcs => obcs.Completed).ClientTemplate("#= Completed ? 'Yes' : 'No' #");
columns.Command(command =>
{
command.Custom("Tasks").Action("Index", "OBClientSetup", new { SetupID = Model.SetupID });
command.Edit();
command.Destroy().HtmlAttributes(new { #class = "onboard-delete " });
});
})
.ToolBar(toolbar =>
{
toolbar.Template(#<text>
<div class="toolbar">
<div class="row">
<div class="col-md-3 pull-right">
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></span>
<input type="text" class="form-control" id='FieldFilter' placeholder="Search Profile Name">
</div>
</div>
</div>
</div>
</text>);
})
.HtmlAttributes(new { #class = "table-responsive" })
.Groupable()
.Pageable()
.Sortable()
.Editable(editable => editable.Mode(GridEditMode.InLine))
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("OB2_ClientProfiles", "OB"))
.PageSize(5)
.Update(update => update.Action("EditingInline_Update", "OB"))
.Destroy(update => update.Action("EditingInline_Destroy", "OB"))
.Model(model => model.Id(obcs => obcs.SetupID))
)
)
The Model
public partial class OBClientSetup
{
private int _setupID;
public virtual int SetupID
{
get
{
return this._setupID;
}
set
{
this._setupID = value;
}
}
The idea is so they can click a button and be sent to OBClientSetupTasks/Index/1 or whatever their ID is
To use the Grid's model that way you'll probably need something like this:
Create a JavaScript function to handle the click event. Here you can grab the SetupID. I don't know what you're controller's action is going, but there are a few options.
If you want to change to the Index page, do something like this:
<script>
function SetupTasks(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
window.location.href = '#Url.Action("Index", "OBClientSetup")' + "/" + dataItem.SetupID;
}
</script>
Or, execute some ajax request like this:
<script>
function SetupTasks(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
windows.location.href = '#Url.Action("Index", "OBClientSetup")',
type: "POST",
dataType: "json",
data: { SetupID: dataItem.SetupID },
success: function (data) {
// Handle return value
}
});
}
</script>
In your grid specify your command button like this:
command.Custom("Tasks").Click("SetupTasks");

Redirect when Edit a Kendo UI grid with ASP .NET MVC

I want to add a redirection to another page when I click on the "Edit" button with a Kendo UI grid with ASP .NET MVC.
Here is the base code:
#(Html.Kendo().Grid<ViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(x => x.Id);
columns.Bound(x => x.Name);
columns.Bound(x => x.Field1);
columns.Command(commands =>
{
commands.Edit();
commands.Destroy();
})
})
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(x => x.Id))
.Read(read => read.Action("Read", "Home"))
.Update(update => update.Action("Edit", "Home"))
.Destroy(destroy => destroy.Action("Destroy", "Home"))
)
)
I tried to use the HTML attributes but it doesn't work:
commands.Edit().HtmlAttributes(new { #class = "edit" });
Then, I tried to add a custom edit (via commands.Custom(...) but unfortunately it is just for .Server() data binding.
I can do it with a client template but I really would like to use the default button proposed by Kendo UI:
columns.Template(#<text></text>)
.ClientTemplate(
"<a href='" + Url.Action("Edit", "Home") + "/#=Id#'>Edit</a>");
Do you have any other idea?
Thanks in advance.
You should be able to use custom commands, even with an Ajax datasource. I just tested this locally with the following code to make sure it will still work.
Code from view:
<script type="text/javascript">
function redirectTest(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
alert(dataItem.Name);
}
</script>
#(Html.Kendo().Grid<ViewModel>()
.Name("testing")
.Columns(columns =>
{
columns.Bound(x => x.Id);
columns.Bound(x => x.Name);
columns.Command(command => command.Custom("Edit").Click("redirectTest"));
})
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("ReadAction", "ControllerName"))
)
)
Source: Custom command demo
If you want to redirect to another page with accepts a parameter then use this method.
#(Html.Kendo().Grid<AGridViewModel>()
.Name("Grid")
.Columns(columns => {
columns.Bound(p => p.Id)
columns.Bound(p => p.Name);
columns.Command(command => command.Custom("View Details").Click("showDetails"));
})
<script type="text/javascript">
function showDetails(e) {
e.preventDefault();
var d = this.dataItem($(e.currentTarget).closest("tr"));
//alert("Selected item ID is:" + d.Id);
window.location.href = "#Url.Action("action", "controller")?id=" + d.Id;
}
</script>
You could add a custom ClientTemplate on the Name column, instead, and remove your columns.Command button altogether, where they simply click the name to edit it, and you pass in your object's ID to the new page like this:
columns.Bound(x => x.Name).ClientTemplate("<a href=/SomeViewFolder/Index?id=${id} target=_blank>${Name}</a>");

Post the Kendo Grid Data on Form Submit

I want to Post the data from a Kendo Grid to the server, and save it to a database.
For this I have used form like so:
#using (Html.BeginForm("MainDocumentSave","Document"))
{
<div class="row-fluid">
<div class="span10">
#(Html.Kendo().Grid<Invoice.Models.ViewModels.SegmentViewModel>()
.Name("Segment")
.TableHtmlAttributes(new { style = "height:20px; " })
.Columns(columns =>
{
columns.Bound(p => p.AirlineShortName).EditorTemplateName("AirlineEditor").Title("Airline").ClientTemplate("#=AirlineName#").Width(5);
columns.Bound(p => p.DepartureDate).Width(9);
columns.Bound(p => p.Arrives).EditorTemplateName("ArrivalLocation").Title("Arrival").ClientTemplate("#=Arrives#").Width(5);
columns.Bound(p => p.ArrivalDate).Width(7);
columns.Bound(p => p.FlightNumber).Width(8);
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Navigatable()
.Sortable()
.Scrollable(scr => scr.Height(200))
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.AirlineName))
.Create("Editing_Create", "Grid")
.Read("Segment_Read", "Document")
.Update("Editing_Update", "Grid")
.Destroy("Editing_Destroy", "Grid")
)
)
</div>
</div>
<button type="submit" class="btn btn-primary"> Save Segments</button>
}
But after submitting, the data inside the Kendo Grid is not Posted. How can I Post Kendo Grid Data to the Server?
The Grid is not a form element and it cannot be simply posted to the server. You can take advantage of the templates that the Grid provide and create hidden elements based on the different row models which to be submitted to the server.
The same approach is used in this code library which demonstrates exactly what you are searching for.
The grid data isn't in form elements. The form elements appear only when a cell is being edited, then it is removed. You can't post the data to the server by using a form submit button.
The proper way to to this would be by adding the 'save' command button that the grid provides itself:
#(Html.Kendo().Grid<Invoice.Models.ViewModels.SegmentViewModel>()
.Name("Segment")
.ToolBar(toolbar => {
toolbar.Save(); // add save button to grid toolbar
})
// ... rest of options ...
Or by calling saveChanges() on the Grid widget:
<button type="button" id="save">Save Segments</button>
$("#save").on("click", function () {
$("#Segment").data("kendoGrid").saveChanges();
});
Suppose I have three kendo grids and two textboxs in my page. Now I want to post all data along with data of three grid. I did this by below style.
#model DAL.ViewModel.ProfileViewModel
#{
ViewBag.Title = "Profile";
Layout = "~/Views/Shared/_LayoutAfterLogin.cshtml";
}
<h2>Profile</h2>
<div>
<h4>ApplicationUser</h4>
<hr />
<dl class="dl-horizontal"></dl>
<form id="frmProfile">
<div>
<label>Email<span class="mandatory"></span></label>
#Html.Kendo().TextBoxFor(model => model.Email)
</div>
<div>
<label>UserName<span class="mandatory"></span></label>
#Html.Kendo().TextBoxFor(model => model.UserName)
</div>
</form>
#(Html.Kendo().Grid<DAL.ViewModel.PhoneViewModel>()
.Name("PhoneGrid")
.Columns(columns =>
{
columns.Bound(p => p.PhoneID).Groupable(false);
columns.Bound(p => p.PhoneType).Width(160);
columns.Bound(p => p.PhoneNumber).Width(120);
columns.Bound(p => p.IsPrimary).Width(120);
columns.Command(command => command.Destroy()).Width(90);
})
.ToolBar(toolBar =>
{
toolBar.Create();
// toolBar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable()
.Sortable()
.Scrollable()
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
.Events(events => events.Error("error_handler"))
.Model(model =>
{
model.Id(p => p.PhoneID);
model.Field(p => p.PhoneID).Editable(false);
})
.PageSize(20)
.Read(read => read.Action("PhoneList", "Account"))
.Create(create => create.Action("AddPhone", "Account"))
.Update(update => update.Action("EditPhone", "Account"))
.Destroy(destroy => destroy.Action("DeletePhone", "Account"))
)
)
</div>
<p>
<button type="button" id="btnSave">Save</button>
#Html.ActionLink("Edit", "Edit", new { /* id = Model.PrimaryKey */ }) |
#Html.ActionLink("Back to List", "Index")
</p>
//jquery
$("#btnSave").on("click", function () {
sendData();
});
function sendData() {
var grid = $("#PhoneGrid").data("kendoGrid"),
parameterMap = grid.dataSource.transport.parameterMap;
//get the new and the updated records
var currentData = grid.dataSource.data();
var updatedRecords = [];
var newRecords = [];
for (var i = 0; i < currentData.length; i++) {
if (currentData[i].isNew()) {
//this record is new
newRecords.push(currentData[i].toJSON());
} else if (currentData[i].dirty) {
updatedRecords.push(currentData[i].toJSON());
}
}
//this records are deleted
var deletedRecords = [];
for (var i = 0; i < grid.dataSource._destroyed.length; i++) {
deletedRecords.push(grid.dataSource._destroyed[i].toJSON());
}
var serializedData = $("#frmProfile").serializeObject();
var data = {};
$.extend(data, parameterMap({ updated: updatedRecords }), parameterMap({ deleted: deletedRecords }), parameterMap({ new: newRecords }));
var finaldata = {};
$.extend(finaldata, parameterMap({ phone: data }), parameterMap({ email: data }), parameterMap({ address: data }), parameterMap({ pagedata: serializedData }));
$.ajax({
url: '#Url.Action("UpdateCreateDelete1", "Account")',
data: JSON.stringify(finaldata),
type: "POST",
contentType: 'application/json',
dataType: 'json',
error: function (e) {
alert('error');
//Handle the server errors using the approach from the previous example
},
success: function () {
grid.dataSource._destroyed = [];
//refresh the grid - optional
// grid.dataSource.read();
}
})
}
jQuery.fn.serializeObject = function () {
var arrayData, objectData;
arrayData = this.serializeArray();
objectData = {};
$.each(arrayData, function () {
var value;
if (this.value != null) {
value = this.value;
} else {
value = '';
}
if (objectData[this.name] != null) {
if (!objectData[this.name].push) {
objectData[this.name] = [objectData[this.name]];
}
objectData[this.name].push(value);
} else {
objectData[this.name] = value;
}
});
return objectData;
};
//action method
public ActionResult UpdateCreateDelete1(
[Bind(Prefix = "phone.updated")]List<PhoneViewModel> updatedPhone,
[Bind(Prefix = "phone.new")]List<PhoneViewModel> newPhone,
[Bind(Prefix = "phone.deleted")]List<PhoneViewModel> deletedPhone,
[Bind(Prefix = "email")]List<PhoneViewModel> emaillist,
[Bind(Prefix = "address")]List<PhoneViewModel> addresslist,
[Bind(Prefix = "pagedata")] ProfileViewModel pagedata
)
{
}

how to create custom kendo.ui.Window for edit in kendo.ui.grid

I'm starter in kendo.Ui , i write this code for create grid
#(Html.Kendo().Grid<BrandViewModel>(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.BrandName);
columns.Bound(p => p.BrandAbbr);
columns.Bound(p => p.SrcImage);
columns.Command(command => command.Custom("Edit").Click("editItem"));
})
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("CustomCommand_Read", "Brand"))
.Model(model => model.Id(p => p.Id))
)
)
i want when user click in Edit button open Edit view in kendo window i write this code
#(Html.Kendo().Window().Name("Details")
.Title("Customer Details")
.Visible(false)
.Modal(true)
.Draggable(true)
.Width(300)
)
<script type="text/x-kendo-template" id="template">
<div id="details-container"> <!-- this will be the content of the popup -->
BrandName: <input type='text' value='#= BrandName #' />
</div>
</script>
and java script code:
<script type="text/javascript">
var detailsTemplate = kendo.template($("#template").html());
function editItem(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
$("#Details").data("kendoWindow").refresh({
url: "/Brand/Edit/" + dataItem.Id
});
$("#Details").data("kendoWindow").open();
}
</script>
this code work fine For the first time I click on a button,But when I click a second time.I encountered the following error
0x800a138f - JavaScript runtime error: Unable to get property 'refresh' of undefined or null reference
please help me, thanks all
I remember I had a similar issue with this control. Now it works for me with the following Javascript code :
<script type="text/javascript">
var detailsTemplate = kendo.template($("#template").html());
var windowObject;
$(document).ready(function () {
windowObject = $("#Details").data("kendoWindow");
});
function editItem(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
windowObject.refresh({
url: "/Brand/Edit/" + dataItem.Id
});
windowObject.open();
}
</script>
Hope it helps !
The problem is that, by default, the window will be destroyed (removed from the DOM) on closure. I would suggest removing the "undefined" condition i added in the example below and, instead, dont create the "Details" div in the first place.
<script type="text/javascript">
var detailsTemplate = kendo.template($("#template").html());
function editItem(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
if($("#Details") == undefined)
$("body").append("<div id=\"Details\"></div>
$("#Details").data("kendoWindow").refresh({
url: "/Brand/Edit/" + dataItem.Id
});
$("#Details").data("kendoWindow").open();
}
</script>

how to get key row selected in kendo ui grid

i write this code for create Grid with kendo Ui in asp.net mvc
#(Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.Id).Groupable(false).Visible(false);
columns.Bound(p => p.BrandName);
columns.Bound(p => p.BrandAbbr);
columns.Bound(p => p.SrcImage);
columns.Command(command => command.Custom("ViewDetails").Click("showDetails"));
})
.ToolBar(toolbar =>
{
toolbar.Custom().Action("Create","Users").Text("add");
}
)
.Groupable()
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.HtmlAttributes(new {style = "height:500px;"})
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Multiple)
.Type(GridSelectionType.Row))
.DataSource(dataSource => dataSource
.Server()
.Model(model => model.Id(item => item.Id))
))
i want when user click on ViewDetails alert BrandId value Column, please help me.thanks all
You just need to add javascript function.
<script type="text/javascript">
function showDetails(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
alert(dataItem.Id); //considering Id = BrandId
}
</script>
Here is the demo of Kendo Grid Custom Command
also I used this successfully :
<script type="text/javascript">
function showDetails(e)
{
e.preventDefaults();
var grid = $("#Grid").data("kendoGrid");
var selectedItem = grid.dataItem(grid.select());
//you can get the value of any column after that
alert("Brand Id is : " + selectedItem.Id);
alert("Brand Name is: " + selectedItem.BrandName);
}
</script>

Resources