I'm using a Kendo (for jQuery) Grid in an MVC Core project with Add, Edit, Delete using ajax JSON and SQL Server, but the Update, Destroy and Create actions are not called.
Here is my view:
<div id="grid" class="k-rtl applicationFontLight"></div>
<script>
$(document).ready(function () {
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "/Persons/Read",
dataType: "json"
},
update: {
url: "/Persons/Update",
dataType: "json"
},
destroy: {
url: "/Persons/Destroy",
dataType: "json"
},
create: {
url: "/Persons/Create",
dataType: "json"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
batch: true,
pageSize: 20,
schema: {
model: {
id: "id",
fields: {
Id: { editable: false, nullable: true },
firstName: {
type: "string",
validation: {
required: {
message: "Required"
}
}
},
lastName: {
type: "string",
validation: {
required: {
message: "Required"
}
}
},
birthDate: {
type: "string",
validation: {
required: {
message: "Required"
}
}
}
}
}
}
})
$("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
toolbar: [{ name: "create", text: "New" }],
columns: [
{ field: "firstName", title: "Name", width: "80px" },
{ field: "lastName", title: "Last Name", width: "120px" },
{ field: "birthDate", title: "Birth Date", width: "80px" },
{
command: [{
name: "edit",
text: {
edit: "Edit",
update: "Update",
cancel: "Cancel"
}
}
, {
name: "destroy",
text: "Delete"
}
], width: "200px"
}
],
editable: "inline"
});
});
</script>
And my Controller Code:
public class PersonsController : Controller
{
private readonly DataContext _context;
public PersonsController(DataContext context)
{
_context = context;
}
// GET: Persons
public ActionResult Index()
{
return View();
}
public ActionResult Read()
{
var persons = _context.Persons.ToList();
return Json(persons);
}
public async Task<IActionResult> Create([Bind("Id,FirstName,LastName,BirthDate")] Person person)
{
if (ModelState.IsValid)
{
_context.Add(person);
await _context.SaveChangesAsync();
return Json(person);
}
return View(person);
}
public async Task<IActionResult> Update(int id, [Bind("Id,FirstName,LastName,BirthDate")] Person person)
{
if (id != person.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(person);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!PersonExists(person.Id))
{
return NotFound();
}
else
{
throw;
}
}
return Json(person);
}
return View(person);
}
[ValidateAntiForgeryToken]
public async Task<IActionResult> Destroy(int id)
{
var person = await _context.Persons.FindAsync(id);
_context.Persons.Remove(person);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool PersonExists(int id)
{
return _context.Persons.Any(e => e.Id == id);
}
}
The other actions (besides the Read action) are not called and give me this error in the browser console:
Unexpected character encountered while parsing value: m. Path '', line 0, position 0.
or view Destroy not found...
Replace the following code:
command: [{
name: "edit",
text: {
edit: "Edit",
update: "Update",
cancel: "Cancel"
}
}
, {
name: "destroy",
text: "Delete"
}
], width: "200px"
Try the default column command, then try the toolbar create.
command: ["edit","destroy"], title: " ", width: "200px"
Related
I want to show Customer table's data of nopcommerce in admin page.
i did write a plugin for that and receive data in controller but in view i have a problem and show me error happened message.
here is my controller code:
public class UserDetailsController : BasePluginController
{
private ICustomerService _UserDetail;
public UserDetailsController(ICustomerService UserDetail)
{
_UserDetail = UserDetail;
}
public ActionResult Manage()
{
return View();
}
[HttpPost]
public ActionResult GetUsers(DataSourceRequest userDetail)
{
var details = _UserDetail.GetAllCustomers();
var gridModel = new DataSourceResult
{
Data = details,
Total = details.Count
};
return Json(gridModel);
}
}
And this is my view code:
#{
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
<script>
$(document).ready(function() {
$("#user-details").kendoGrid({
dataSource: {
type: "json",
transport: {
read: {
url: "#Html.Raw(Url.Action("GetUsers", "UserDetails"))",
type: "POST",
dataType: "json",
},
},
schema: {
data: "Data",
total: "Total",
errors: "Errors",
model: {
id: "Id",
}
},
requestEnd: function(e) {
if (e.type == "update") {
this.read();
}
},
error: function(e) {
display_kendoui_grid_error(e);
// Cancel the changes
this.cancelChanges();
},
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
pageable: {
refresh: true,
numeric: false,
previousNext: false,
info:false
},
editable: {
confirmation: true,
mode: "inline"
},
scrollable: false,
columns: [
{
field: "Email",
title: "User Name",
width: 200
},
{
command: [
{
name: "edit",
text: "#T("Admin.Common.Edit")"
}, {
name: "destroy",
text: "#T("Admin.Common.Delete")"
}
],
width: 200
}
]
});
});
</script>
<div id="user-details"></div>
can anybody help me?
Change your GetUsers method on this way:
var details = _UserDetail.GetAllCustomers();
var gridModel = new DataSourceResult
{
Data=details.Select(x=>
{
return new UserDetail()
{
Email= x.Email
};
}),
Total = details.Count(),
};
return Json(gridModel);
I am trying to create batch insert , update , delete using kendo ui grid and MVC.
Here is my code for View and Controller.
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<link href="~/Content/kendo.custom.css" rel="stylesheet" />
<link href="~/Content/kendo.common.min.css" rel="stylesheet" />
<script src="~/Scripts/kendo.all.min.js"></script>
<script src="~/Scripts/kendo.custom.js"></script>
<div>
<div id="grid"></div>
<script>
$(document).ready(function () {
$("#grid").kendoGrid({
editable: true,
pageable: true,
sortable: true,
filterable: true,
toolbar: ["create", "save", "cancel"],
columns: [
"Name",
{ command: "destroy", title: "Delete", width: "110px" }
],
dataSource: {
transport: {
create: {
url: "#Url.Action("Create", "VendorType")",
dataType: "json",
type: "POST"
},
read: {
url: "#Url.Action("Read", "VendorType")",
contentType: "application/json",
type: "POST"
}
},
serverPaging: true,
serverFiltering: true,
serverSorting: true,
pageSize: 5,
schema: {
data: "Data",
total: "Total",
model: {
id: "Id",
fields: {
Id: { editable: false, nullable: true },
Name: { validation: { required: true } }
}
}
}
}
});
});
</script>
</div>
Controller :
[HttpPost]
public ActionResult Read(int take, int skip, IEnumerable<Sort> sort, Kendo.DynamicLinq.Filter filter)
{
var result = db.VendorTypes
.OrderBy(p => p.Id)
.ToDataSourceResult(take, skip, sort, filter);
return Json(result);
}
[HttpPost]
public ActionResult Create(IEnumerable<VendorType> types)
{
var result = new List<VendorType>();
try
{
foreach (var category in types)
{
result.Add(category);
// Add the entity
db.VendorTypes.Add(category);
}
db.SaveChanges();
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
}
return Json(result);
}
Now the read operation works fine. but when i try to save the entries the list of objects in CREATE , UPDATE Or DELETE methods are always null. I can see the values being passed in the browser but in the controller they are not available. Can any one point out a mistake i am making ?
I found the solution for this. The model name which you have as parameter in controller need to be mapped using "ParameterMap" of kendo UI.
parameterMap: function (data, operation) {
if (operation != "read") {
var result = {};
for (var i = 0; i < data.models.length; i++) {
var site = data.models[i];
for (var member in site) {
result["projects[" + i + "]." + member] = site[member];
}
}
return result;
} else {
return JSON.stringify(data)
}
}
As my parameters collection is defined as "projects" my controller action method should have the same name for the argument.
i.e
public ActionResult Create(IEnumerable<Project> projects)
{
}
Hope this will help some one.
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);
}
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)
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.