Kendo.Web Grid Popup Create with ComboBox - asp.net-mvc

I am using the free Kendo web controls. I have used the grid view in several places before and decided to use the popup style editing for my current project.
I have most of it working. I have three combo boxes for category, bank account and payee and when I edit an existing item, the model object passed back to my MVC action has the correct values in it. However, when I click on the create button, the three combo box values are returned as null to the controller.
Here is the CSHTML code for this view:
#using System
#using System.Linq
#{
ViewBag.Title = "Transactions";
}
#section Head
{
<link href="~/Content/kendo/kendo.common.min.css" rel="stylesheet" />
<link href="~/Content/kendo/kendo.default.min.css" rel="stylesheet" />
<script src="~/Scripts/kendo/kendo.web.min.js"> </script>
}
#section featured
{
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>#ViewBag.Title</h1>
</hgroup>
</div>
</section>
}
<div id="grid"></div>
<script>
$(function() {
$("#grid").kendoGrid({
height: 350,
toolbar: [{ name: "create", text: "Create New Transaction" }],
columns:
[
{ field: "Date", width: "100px", template: '#= kendo.toString(Date,"MM/dd/yyyy") #' },
{ field: "Amount", format: "{0:c}", width: "100px" },
{ field: "Category", width: "80px", editor: categoryDropDownEditor, template: "#=Category.Name#" },
{ field: "BankAccount", title: "Account", width: "80px", editor: bankAccountDropDownEditor, template: "#=BankAccount.Name#" },
{ field: "Payee", width: "80px", editor: payeeDropDownEditor, template: "#=Payee.Name#" },
{ command: ["edit", "destroy"], title: " ", width: "160px" }
],
editable: { mode: "popup", confirmation: "Are you sure you want to delete this transaction?" },
pageable:
{
refresh: true,
pageSizes: true
},
sortable: true,
filterable: false,
dataSource:
{
serverPaging: true,
serverFiltering: true,
serverSorting: true,
pageSize: 7,
schema:
{
data: "Data",
total: "Total",
model:
{
id: "Id",
fields:
{
Id: { editable: false, nullable: true },
Date: { type: "Date" },
Amount: { type: "number", validation: { required: true, min: 0 } },
Category: { validation: { required: true } },
BankAccount: { validation: { required: true } },
Payee: { validation: { required: true } },
Note: { validation: { required: false } }
}
}
},
batch: false,
transport:
{
create:
{
url: "#Url.Action("Create", "Transaction")",
contentType: "application/json",
type: "POST"
},
read:
{
url: "#Url.Action("Read", "Transaction")",
contentType: "application/json",
type: "POST"
},
update:
{
url: "#Url.Action("Update", "Transaction")",
contentType: "application/json",
type: "POST"
},
destroy:
{
url: "#Url.Action("Delete", "Transaction")",
contentType: "application/json",
type: "POST"
},
parameterMap: function(data)
{
return JSON.stringify(data);
}
}
}
});
function categoryDropDownEditor(container, options)
{
$('<input required data-text-field="Name" data-value-field="Id" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList(
{
autoBind: true,
dataValueFileld: "Id",
dataTextField: "Name",
dataSource:
{
type: "json",
transport: { read: "#Url.Action("GetCategories", "Transaction")" }
}
});
}
function bankAccountDropDownEditor(container, options)
{
$('<input required data-text-field="Name" data-value-field="Id" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList(
{
autoBind: true,
dataValueFileld: "Id",
dataTextField: "Name",
dataSource:
{
type: "json",
transport: { read: "#Url.Action("GetBankAccounts", "Transaction")" }
}
});
}
function payeeDropDownEditor(container, options)
{
$('<input required data-text-field="Name" data-value-field="Id" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList(
{
autoBind: true,
dataValueFileld: "Id",
dataTextField: "Name",
dataSource:
{
type: "json",
transport: { read: "#Url.Action("GetPayees", "Transaction")" }
}
});
}
});
</script>
The binding to the kendo combo box must be working, otherwise the edit would fail as well. All I can think is that the object is not created correctly. Also, it selects the first item in the combo box by default, but even so, does not bind the value.
Following is the code for my create and update actions:
[HttpPost]
public ActionResult Create(TransactionModel transactionModel)
{
var transaction = _moneyBO.CreateTransaction();
Mapper.Map(transactionModel, transaction);
_moneyBO.UpdateTransaction(transaction);
return Json(Mapper.Map<TransactionModel>(transaction));
}
public ActionResult Update(TransactionModel transactionModel)
{
var transaction = _moneyBO.Transactions.SingleOrDefault(x => x.Id == transactionModel.Id);
if (transaction == null)
return View("NotFound");
Mapper.Map(transactionModel, transaction);
_moneyBO.UpdateTransaction(transaction);
return Json(Mapper.Map<TransactionModel>(transaction));
}
I have not found a good example using the popup custom edit. The example on the Kendo site works inline, but if you change the example to popup it does not work.

I have a same problem. Write, if you solve it, please
I found, that Kendo think that "null" (default for int?) is ObservableObject (while initialization of ComboBox), thats why it can't be parsed to "number". If you edit item (not create), value id not "null" and model bindind work's fine

Not sure if it's the only issue here but in your code example it looks like the initialization of your dropdown isn't quite correct. You have written dataValueFileld which should be dataValueField
kendoDropDownList({
autoBind: true,
dataValueFileld: "Id", <-- Incorrect spelling
dataTextField: "Name",
dataSource:
{
type: "json",
transport: { read: "#Url.Action("GetPayees", "Transaction")" }
}
});

Related

DataSourceResult in asp.net core

When i was worked in Asp.net Mvc , for paging data use KendoUi.this code use in Asp.net Mvc Web api
public DataSourceResult Get(HttpRequestMessage requestMessage)
{
var request = JsonConvert.DeserializeObject<DataSourceRequest>(
requestMessage.RequestUri.ParseQueryString().GetKey(0)
);
WebApplicationDbContext db = new WebApplicationDbContext();
var list = db.Product.ToList();
return list.AsQueryable()
.ToDataSourceResult(request.Take, request.Skip, request.Sort, request.Filter);
}
And now working with Asp.net Core when i was use this code , it doesn't work.
in the error list show to me this error
'Uri' does not contain a definition for 'ParseQueryString' and no
extension method 'ParseQueryString' accepting a first argument of type
'Uri' could be found (are you missing a using directive or an assembly
reference?)
How can i use this code in Asp.net Core?
First remove the HttpRequestMessage requestMessage parameter. Then remove the requestMessage.RequestUri.ParseQueryString().GetKey(0) part and replace it with:
var rawQueryString = this.HttpContext.Request.QueryString.ToString();
// PM> Install-Package Microsoft.AspNetCore.WebUtilities
var rawQueryStringKeyValue = QueryHelpers.ParseQuery(rawQueryString).FirstOrDefault();
var dataString = Uri.UnescapeDataString(rawQueryStringKeyValue.Key); // this is your received JSON data from Kendo UI
I'm not sure why you need to deserialize the request. I normally pass request to ToDataSourceResult extension method.
For example,
public JsonResult Get([DataSourceRequest] DataSourceRequest request)
{
var db = new WebApplicationDbContext();
return db.Product.ToDataSourceResult(request);
}
Thank you VahidN
This project has helped me a lot
KendoUI.Core.Samples
Im use this code in Controller
public DataSourceResult GetProducts()
{
var dataString = this.HttpContext.GetJsonDataFromQueryString();
var request = JsonConvert.DeserializeObject<DataSourceRequest>(dataString);
var list = ProductDataSource.LatestProducts;
return list.AsQueryable()
.ToDataSourceResult(request.Take, request.Skip, request.Sort, request.Filter);
}
And use this code in chstml
#{
ViewData["Title"] = "Home Page";
}
<!--Right to left grid-->
<div class="k-rtl">
<div id="report-grid"></div>
</div>
#section Scripts
{
<script type="text/javascript">
$(function () {
var productsDataSource = new kendo.data.DataSource({
transport: {
read: {
url: "#Url.Action("GetProducts", "Sample03")",
dataType: "json",
contentType: 'application/json; charset=utf-8',
type: 'GET'
},
parameterMap: function (options) {
return kendo.stringify(options);
}
},
schema: {
data: "data",
total: "total",
model: {
fields: {
"id": { type: "number" }, //Determine the field for dynamic search
"name": { type: "string" },
"isAvailable": { type: "boolean" },
"price": { type: "number" }
}
}
},
error: function (e) {
alert(e.errorThrown);
},
pageSize: 10,
sort: { field: "id", dir: "desc" },
serverPaging: true,
serverFiltering: true,
serverSorting: true
});
$("#report-grid").kendoGrid({
dataSource: productsDataSource,
autoBind: true,
scrollable: false,
pageable: true,
sortable: true,
filterable: true,
reorderable: true,
columnMenu: true,
columns: [
{ field: "id", title: "RowNumber", width: "130px" },
{ field: "name", title: "ProductName" },
{
field: "isAvailable", title: "Available",
template: '<input type="checkbox" #= isAvailable ? checked="checked" : "" # disabled="disabled" ></input>'
},
{ field: "price", title: "Price", format: "{0:c}" }
]
});
});
</script>
}

Data is getting but not populating in kendo grid using angular js

I am able to get the data from database but not populating in gridview.
here is my code below:
<div ng-app="app" ng-controller="MyCtrl">
<div kendo-grid k-options="gridOptions" k-rebind="gridOptions" k-pageable='{ "pageSize": 2, "refresh": true, "pageSizes": true }'></div>
</div>
<script>
angular.module("app", ["kendo.directives"]).controller("MyCtrl", function ($scope, $http) {
$scope.gridOptions = {
columns: [{ field: "EmployeeKey" }, { field: "FirstName" }],
dataSource: {
//schema: {
// data: "d"
//},
type: "jsonp",
transport: {
read: function (e) {
$http({ method: 'GET', url: '/Employee/Employee_Read' }).
success(function (data, status, headers, config) {
// alert('Sucess')
//debugger;
e.success(data)
}).
error(function (data, status, headers, config) {
alert('something went wrong')
console.log(status);
});
}
},
//pageSize: 5
}
}
});
</script>
and this is the controller page where i am getting data
public ActionResult Employee_Read ([DataSourceRequest] DataSourceRequest request )
{
//IQueryable<IEmployeeRepositary> employeeRep = employeeRepositary.Employees;
return Json(employeeRepositary.Employees.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
so after running my application i am checking through debugger this line
"e.success(data)" so in mouse hove i am getting the total records fetched from database. but not populating in gridview it is still showing blank.
please help me out from here.
Because you are returning collection which wrapped with DataSourceResult method.
return Json(employeeRepositary.Employees.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
instead of just its collection
return Json(employeeRepositary.Employees, JsonRequestBehavior.AllowGet);
You need to define your data source schema, please try this schema setup
schema: {
data: "Data",
errors: "Errors",
total: "Total",
model: {
id: "Id",
fields: {
Id: { editable: false, defaultValue: 0 },
//the rest field definition
}
}
}
and you can change your transport's read to something like this
read: {
type: "POST",
url: "/Employee/Employee_Read",
dataType: "json",
contentType: "application/json"
}
your final code should be like this
$scope.gridOptions = {
columns: [{ field: "EmployeeKey" }, { field: "FirstName" }],
dataSource: {
transport: {
read: {
type: "POST",
url: "/Employee/Employee_Read",
dataType: "json",
contentType: "application/json"
},
parameterMap: function(options, operation) {
return JSON.stringify(options);
}
},
pageSize: 5,
schema: {
data: "Data",
errors: "Errors",
total: "Total",
model: {
id: "EmployeeKey",
fields: {
EmployeeKey: { editable: false, defaultValue: 0 },
FirstName: {type: "string", validation: { required: true }}
}
}
}
}
}
and your controller like this
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public ActionResult Employee_Read ([DataSourceRequest] DataSourceRequest request )
{
var employees = employeeRepositary.Employees;
return Json(employees.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}

Kendo UI Grid Update button not firing

I am developing a KendoUI Grid with Inline editable option in javascript and can't make Update button to fire click event and post the data to server side update event. Clicking on Update button won't even update the grid on client.
Hope someone can help me point out what I am doing wrong here.
This is not a duplicate to this as I have tired the jfiddle link in the answer and it is not working too.
kendo UI grid update function wont fire
<div id="grid"></div>
#section Scripts{
<script type="text/javascript">
$(function () {
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "Home/GetPupilsAsJson",
dataType: 'json'
},
update: {
url: "Home/UpdatePupils",
dataType: 'json',
type: 'POST'
}
},
pageSize: 5,
autoSync: true
});
$('#grid').kendoGrid({
dataSource: dataSource,
editable: "inline",
pageable: true,
columns: [{
field: "Id",
title: "Id",
width: 150,
hidden: true
}, {
field: "Firstname",
title: "Firstname",
width: 150
}, {
field: "Lastname",
title: "Lastname",
width: 150
}, {
field: "DateOfBirth",
title: "DateOfBirth",
width: 150
}, {
field: "Class",
title: "Class",
width: 150
}, {
field: "Year",
title: "Year",
width: 150
},
{
command: ["edit"],
width: 150
}]
});
});
</script>
}
HomeController
public ActionResult GetPupilsAsJson()
{
return Json(GetPupils(), JsonRequestBehavior.AllowGet);
}
[AcceptVerbs(HttpVerbs.Post)]
[HttpPost]
public void UpdatePupils(Pupil p)
{
//never reach here
}
I don't know why but fixed it by putting schema information.
schema: {
model: {
id: "Id",
fields: {
Firstname: { editable: true, validation: { required: true } },
Lastname: { validation: { required: true } },
DateOfBirth: { validation: { required: true } },
Class: { validation: { required: true } },
Year: { validation: { required: true } }
}
}
}
Use #Url.Action("GetPupilsAsJson", "Home")' so no need to pass base url in your update action like this BASEURL+ "Home/GetPupilsAsJson".
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: '#Url.Action("GetPupilsAsJson", "Home")',
dataType: 'json'
},
update: {
url:'#Url.Action("UpdatePupils", "Home")',
dataType: 'json',
type: 'POST'
}
},
pageSize: 5,
autoSync: true
});
use parameter map to pass model values
<script type="text/javascript">
$(function () {
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: '#Url.Action("GetPupilsAsJson", "Home")',,
dataType: 'json'
},
update: {
url: '#Url.Action("UpdatePupils", "Home")',
dataType: 'json',
type: 'POST'
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
pageSize: 5,
autoSync: true
});
Call Controller with parameterMap
public JsonResult UpdatePupils(string models)
{
return Json(..);
}
Is any of your cell text has HTML tags like < or >, remove them and click on update. The update event will fire.

Kendo UI Upload inside Grid

I am trying to implement Kendo UI Grid with an Kendo Upload inside the grid. While I am using ASP.NET MVC I am not using the Telerik MVC Wrappers. I am attempting to do this without them.
The problem that I am having is that IEnumerable HttpPostedFileBase is null when it posts back to my Action method.
JavaScript:
$(document).ready(function () {
var dsGalleryItemFile = new kendo.data.DataSource({
transport: {
read: "#Url.Content("~/Intranet/GalleryItemFile/ListFiles/")#Model.galleryItemID",
update: {
url: "#Url.Content("~/Intranet/GalleryItemFile/UpdateFile")",
type: "POST"
},
destroy: {
url: "#Url.Content("~/Intranet/GalleryItemFile/DeleteFile")",
type: "POST"
},
create: {
url: "#Url.Content("~/Intranet/GalleryItemFile/CreateFile/")#Model.galleryItemID",
type: "POST"
}
},
// determines if changes will be send to the server individually or as batch
batch: false,
schema: {
model: {
id: "fileID",
fields: {
fileID: {
editable: false,
nullable: true
},
filename: {},
fileType: { defaultValue: {fileTypeID: 1, fileType: "Web JPEG"} },
fileType: {},
width: { type: "number" },
height: { type: "number" },
}
}
}
});
$("#gvGalleryItemFile").kendoGrid({
columns: [{
field: "filename",
title: "Filename"
}, {
field: "filepath",
title: "File Upload",
editor: fileUploadEditor//,
//template: "<img src='#=filepath.filepath#' />"
}, {
field: "fileType",
title: "File Type",
editor: fileTypeDropDownEditor,
template: "#=fileType.fileType#",
}, {
field: "width",
title: "Width"
}, {
field: "height",
title: "Height"
}, {
command: ["edit", "destroy"]
}],
editable: { mode: "inline" },
toolbar: ["create"],
dataSource: dsGalleryItemFile
});
});
function fileTypeDropDownEditor(container, options) {
$('<input required data-text-field="fileType" data-value-field="fileTypeID" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataSource: {
transport: {
read: "#Url.Content("~/Intranet/FileType/ListFileTypes")"
}
}
});
}
function fileUploadEditor(container, options) {
$('<input type="file" name="fileUpload" id="fileUpload" />')
.appendTo(container)
.kendoUpload({
async: {
saveUrl: "#Url.Content("~/Intranet/GalleryItemFile/UploadFile")"
},
complete: onUploadComplete
});
}
MVC Action:
[HttpPost]
public ActionResult UploadFile(IEnumerable<HttpPostedFileBase> uploadedFiles)
{
if (uploadedFiles != null)
{
foreach (var thisFile in uploadedFiles)
{
string newFileName = Path.GetFileName(thisFile.FileName).Replace(" ", "");
var physicalPath = Path.Combine(Server.MapPath("~/Areas/Gallery/Content/GalleryImages"), newFileName);
thisFile.SaveAs(physicalPath);
}
return Content("");
}
else
{
return Content("Error");
}
}
Try to name the argument parameter in the action method signature the same way as the name attribute of the input that you turn into upload widget.
In your case
public ActionResult UploadFile(IEnumerable<HttpPostedFileBase> fileUpload)

Unable to bind JSON data to KendoUI Grid

I am facing a certain issue while trying to bind the KendoUi Grid with the Json data from the controller. Things seem fine and my Json object contains data but still grid is not showing any thing:
And I am getting this error in chrome JavaScript console:
GET http://localhost:8084/Records?take=5&skip=0&page=1&pageSize=5 500 (Internal Server Error)
In View:
<div id="grid">
</div>
<div>
<script type="text/javascript">
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: {
type: "json",
serverPaging: true,
pageSize: 5,
groupable: true,
selectable: "row",
transport: { read: { url: "Records", dataType: "json"} }
},
height: 400,
scrollable: true,
sortable: true,
filterable: true,
pageable: true,
columns: [
{ field: "No", title: "No" },
{ field: "Desc", title: "Description" },
{ field: "priority", title: "Priority" },
{ field: "decision", title: "Decision" }
],
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
}
});
});
</script>
In Controller:
public ActionResult GetRecords()
{
var obj = new User();
var jsnRslt = obj.GetResult(Session["id"].ToString());
//return Json(jsnRslt);
return Json(jsnRslt, JsonRequestBehavior.AllowGet); //Changed as suggested by Dismissile
}
In Model:
public object GetResult(string usrId)
{
…
….
….. try
{
int i = 0;
if (rcrds != null || rcrds.HasRows)
{
jsonWriter.WriteStartObject();
while (rcrds.Read())
{
for (int j = 0; j < rcrds.FieldCount; j++)
{
jsonWriter.WritePropertyName(rcrds.GetName(j));
jsonWriter.WriteValue(rcrds.GetValue(j));
}
i++;
}
jsonWriter.WriteEndObject();
}
}
catch (Exception ex) { }
return jsonWriter;
}
}
Kindly help.
You probably need this in your JSON call:
return Json(jsnRslt, JsonRequestBehavor.AllowGet);
It looks like you are doing a GET call, and by default GET is not allowed on a JSON call.
Try to use the transport attribute within dataSource, something like this:
<script type="text/javascript">
var dataSource = new kendo.data.DataSource({
batch: true,
schema: {
model: {
id: "EmployeeID",
fields: {
EmployeeID: { editable: true, validation: { required: true } },
EmployeeName: { validation: { required: true } }
}
}
},
transport: {
read: {
url: "/Home/GetData",
type: "GET"
},
update: {
url: "/Home/Update",
type: "POST",
contentType: 'application/json'
},
destroy: {
url: "/Home/Destroy",
type: "POST",
contentType: 'application/json'
},
create: {
url: "/Home/Create",
type: "POST",
contentType: 'application/json'
},
pageSize: 1,
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return kendo.stringify(options.models) ;
}
}
}
});
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: dataSource,
navigatable: true,
pageable: true,
height: 430,
sortable: true,
toolbar: ["create", "save", "cancel"],
columns: [
{ field: "EmployeeID", title: "Employee ID", width: 110 },
{ field: "EmployeeName", title: "Employee Name", width: 110 },
{ command: "destroy", title: "Delete", width: 90 }],
editable: true,
selectable: "multiple row",
groupable: true,
navigatable: true,
filterable: true
});
});
</script>
The controller:
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
var employee = new Employee().GetEmployeeList();
return View(employee);
}
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult GetData()
{
var obj = new Employee();
return Json(obj.GetEmployeeList(), JsonRequestBehavior.AllowGet);
}
[HttpPost]
public JsonResult Update(List<Employee> model)
{
var obj = new Employee();
//return View();
return Json(obj);
}
[HttpPost]
public JsonResult Create(List<Employee> model)
{
var obj = new Employee();
return Json(obj);
}
public ActionResult Destroy(Employee model)
{
return View();
}
}
Return a html view from index method to hold the grid &
I think you also need to add a datasource request in your ActionMethod Parm
public ActionResult GetResult([DatasourceRequest]request, string usrId)
return Json(jsnRslt.ToDatasourceResult(request), JsonRequestBehavior.AllowGet);
Every kendogrid needs this
Try this
transport: { read: { url: "Records", dataType: "jsonp"} }
try with jsonp instead of json.
You are returning an ActionResult, it should be a JsonResult instead.

Resources