KendoUI for ASP.NET MVC duplicates rows - asp.net-mvc

KendoUI for ASP.NET MVC 2016.1.412 grid duplicating data at any update or destroy action. If you click Destroy command it call CREATE action for 10 (ten) times. So if I got 1 row after I destroy it I got 11 row of same data (different ID).
View is like this
#(Html.Kendo().Grid<CETSchoolERP.ViewModels.Administration.StudentsViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.FirstName);
columns.Bound(p => p.LastName).Width(100);
columns.Bound(p => p.BirthDate).Width(100);
columns.Command(command => { command.Edit().Text(" "); command.Destroy().Text(" "); }).Width(180);
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Pageable()
.Sortable()
.Scrollable()
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.StudentID))
.Create(create => create.Action("Students_Create", "Students"))
.Read(read => read.Action("Students_Read", "Students"))
.Update(update => update.Action("Students_Update", "Students"))
.Destroy(destroy => destroy.Action("Students_Destroy", "Students"))
)
)
Controller code
public StudentsController(ApplicationDbContext context)
{
_context = context;
}
// GET: Students
public IActionResult Index()
{
return View();
}
public IActionResult Students_Read([DataSourceRequest] DataSourceRequest request)
{
return Json(_context.Student.ToList().Select(student => new StudentsViewModel
{
FirstName = student.FirstName,
LastName = student.LastName,
BirthDate = student.BirthDate,
}).ToDataSourceResult(request));
}
[AcceptVerbs("Post")]
public ActionResult Students_Create([DataSourceRequest] DataSourceRequest request, StudentsViewModel student)
{
if (student != null && ModelState.IsValid)
{
var entity = new Student();
entity.FirstName = student.FirstName;
entity.LastName = student.LastName;
entity.BirthDate = student.BirthDate;
_context.Student.Add(entity);
_context.SaveChanges();
student.StudentID = (int)entity.StudentID;
}
return Json(new[] { student }.ToDataSourceResult(request, ModelState));
}
[AcceptVerbs("Post")]
public ActionResult Students_Update([DataSourceRequest] DataSourceRequest request, StudentsViewModel student)
{
if (student != null && ModelState.IsValid)
{
var entity = new Student();
entity.StudentID = student.StudentID;
entity.FirstName = student.FirstName;
entity.LastName = student.LastName;
entity.BirthDate = student.BirthDate;
_context.Student.Attach(entity);
_context.Entry(entity).State = EntityState.Modified;
_context.SaveChanges();
}
return Json(new[] { student }.ToDataSourceResult(request, ModelState));
}
[AcceptVerbs("Post")]
public ActionResult Students_Destroy([DataSourceRequest] DataSourceRequest request, StudentsViewModel student)
{
if (student != null)
{
var entity = new Student();
entity.StudentID = student.StudentID;
_context.Student.Attach(entity);
_context.Student.Remove(entity);
_context.SaveChanges();
}
return Json(new[] { student }.ToDataSourceResult(request, ModelState));
}
In debug mode any delete or update actions in grid only triggers Students_Create procedure 10 time. Delete or update never called.

Related

Kendo UI dropdown showing as textbox

Here is the code of the grid with the dropdown that I have inserted into a Kendo grid:
#model Portal.Web.Areas.Orders.Models.IngressoMerceViewModel
#(Html.Kendo().Grid<Portal.Web.Areas.Orders.Models.IngressoMerceGridViewModel>()
.Name("grid")
.Events(e => e.DataBound(#<text>function() {for (var i = 0; i #Html.Raw("<") this.columns.length; i++) {this.autoFitColumn(i);}}</text>))
.Columns(columns =>
{
columns.Template("<input type='checkbox' />");
columns.Bound(p => p.Posizione).Title("Posizione").Width(200);
columns.Bound(p => p.Materiale).Title("Materiale").Width(200);
columns.Bound(p => p.Description).Title("Testo breve").Width(200);
columns.Bound(p => p.WarehouseLogicStore).Editable("false").Width(200)
.ClientTemplate(Html.Kendo().DropDownList()
.Name("WHLogicValue").DataTextField("Code").DataValueField("Code").DataSource(source =>
{
source.Read(read =>
{
read.Action("WarehouseLogicTypes_Read", "IngressoMerce");
});
}).ToClientTemplate().ToString()
); ;
columns.Bound(p => p.Quantity).Title("Qta Ordine").Width(200);
columns.Bound(p => p.UnitOfMeasure).Title("UM").Width(200);
columns.Bound(p => p.ReceivedQty).Title("Qta giĆ  ricevute").Width(200);
columns.Template("<input type='text' />").Title("Qta ricevute");
columns.Bound(p => p.InProgressQtyCheck).Title("Qta da ricevere").Width(200);
columns.Bound(p => p.ExpectedDeliveryDate).Format("{0:dd/MM/yyyy}").Title("Data consegna prevista").Width(200);
columns.Bound(p => p.QualityCheckNeeded).Title("Check qualitativo richiesto").Width(220);
})
.Pageable()
.Sortable()
.Scrollable()
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
//.Read(read => read.Url("/orders/details").Type(HttpVerbs.Get))
.Read(read => read.Action("OrderDetails_Read", "IngressoMerce", Model))
)
.Deferred(!Model.IsAjax)
)
Unfortunately, the dropdown shows as textbox and the respective action in the ASP.net MVC controller is not firing. Here is the code for the action:
[AllowAnonymous]
public async Task<JsonResult> WarehouseLogicTypes_Read()
{
try
{
var types = await gateway.GetWarehouseLogicTypes();
return Json(types);
}
catch (Exception ex)
{
//logger.LogError(ex.Message);
throw ex;
}
}
you can insert dropdown inside kendo grid using EditorTemplates
Your Index view code should be like this
#(Html.Kendo().Grid<DemoApplication.Models.ProductsModel>()
.Name("CategoryGrid")
.Columns(columns =>
{
columns.Bound(p => p.category).ClientTemplate("#=category.CategoryName#");
columns.Bound(c => c.ProductName);
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Scrollable()
.Sortable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(x => x.Id);
})
.Read(read => read.Action("ListAll", "Test"))
.PageSize(10)
))
Add Editor Template(_CategoryEditor.cshtml) inside Shared/EditorTemplates folder
your _CategoryEditor code should be like this
#model DemoApplication.Models.Category
#(Html.Kendo().DropDownListFor(m => m)
.Name("category")
.DataValueField("CategoryId")
.DataTextField("CategoryName")
.BindTo((System.Collections.IEnumerable)ViewData["Category"]))
Model code
public class ProductsModel
{
public int Id { get; set; }
[UIHint("_CategoryEditor")]
public Category category { get; set; }
public string ProductName { get; set; }
}
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
}
Controller Code
public ActionResult Index()
{
ViewData["Category"] = GetCategories();
return View();
}
public List<Category> GetCategories()
{
List<Category> categories = new List<Category>();
categories.Add(new Category() { CategoryId = 1, CategoryName = "Category 1" });
categories.Add(new Category() { CategoryId = 2, CategoryName = "Category 2" });
categories.Add(new Category() { CategoryId = 3, CategoryName = "Category 3" });
return categories;
}
public ActionResult ListAll([DataSourceRequest] DataSourceRequest request)
{
List<ProductsModel> productsList = new List<ProductsModel>();
productsList.Add(new ProductsModel() { Id = 1, category = GetCategories().First(), ProductName = "Product 1" });
productsList.Add(new ProductsModel() { Id = 1, category = GetCategories().First(), ProductName = "Product 1" });
productsList.Add(new ProductsModel() { Id = 1, category = GetCategories().First(), ProductName = "Product 1" });
return Json(productsList.ToDataSourceResult(request));
}

Kendo ui MVC Grid Popup Editor Template DropDownListFor not working

I am using Kendo UI for ASP.MVC with Razor view and in Grid editing popup mode, EditorTemplate does not display value from Grid in DropDownListFor. What am I missing?
View:
#(Html.Kendo().Grid<CustomerLeadViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.CustomerName).Width(200);
columns.Bound(c => c.CustomerGroup);
columns.Bound(c => c.CustomerActivityField);
columns.Bound(c => c.AgentName);
columns.Command(command =>
{
command.Edit().Text("Edit");
command.Destroy().Text("Delete");
}).Width(250);
})
.HtmlAttributes(new { style = "height: 480px;" })
.Editable(editable => editable.Mode(GridEditMode.PopUp)).TemplateName("_CustomerEdit"))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(c => c.Id);
})
.Read(read => read.Action("Customers_Read", "CustomerLead", new { model = Model }))
.Update(update => update.Action("Customers_Update", "CustomerLead"))
.Destroy(delete => delete.Action("Customers_Destroy", "CustomerLead"))
)
)
and EditorTemplate/_CustomerEdit:
#model CustomerLeadViewModel
#Html.HiddenFor(model => model.Id)
#Html.Kendo().TextBoxFor(model => model.CustomerName)
#(
Html.Kendo().DropDownListFor(model=>model.CustomerGroupId)
.Name("CustomerGroup") //This name has to be the same as the Title on the main grid page
.DataTextField("GroupName")
.DataValueField("Id")
.DataSource(source =>
{
source.Read(read => { read.Action("GetCustomerGroups", "CustomerLead"); });
})
.OptionLabel("Select a group ...")
)
Controller:
public ActionResult Customers_Read([DataSourceRequest]DataSourceRequest request, CustomerLeadSearchViewModel model)
{
var customers = customerLeadRepository.Get(includeProperties: "CustomerSubGroup.CustomerGroup, CustomerActivityField");
if (model.CustomerName != null)
{
customers = customers.Where(c => c.CustomerName.Contains(model.CustomerName));
}
var customersViewModel = customers.Select(customer => new CustomerLeadViewModel
{
Id = customer.Id,
CustomerGroupId = customer.CustomerGroupId,
CustomerGroup = customer.CustomerSubGroup.CustomerGroup.GroupName,
CustomerName = customer.CustomerName,
CustomerActivityField = customer.CustomerActivityField.ActivityName,
AgentName = customer.AgentName,
Phone1 = customer.Phone1,
Mobile = customer.Mobile
});
return Json(customersViewModel.ToDataSourceResult(request));
}
public JsonResult GetCustomerGroups()
{
var customerGroups = customerGroupRepository.GetAll();
return Json(customerGroups.Select(c => new { Id = c.Id, GroupName = c.GroupName }), JsonRequestBehavior.AllowGet);
}
Model:
public class CustomerLeadViewModel
{
[ScaffoldColumn(false)]
public int Id { get; set; }
public string CustomerName { get; set; }
public string AgentName { get; set; }
public string Post { get; set; }
public string CustomerActivityField { get; set; }
public int CustomerGroupId { get; set; }
public string CustomerGroup { get; set; }
}
Change your _CustomerEditor template model field from
#(Html.Kendo().DropDownListFor(model=>model.CustomerGroupId)
to
#(Html.Kendo().DropDownListFor(model=>model.CustomerGroup)
Just as the comment says, "This name has to be the same as the Title on the main grid page"
The field that the DropDownListFor is binding to needs to be the same. Or, depending on your model, change them all to CustomerGroupId. Either way, they need to match.

How do I hide a Kendo Grid Column based on a value provided?

I have the following Grid:
#(Html.Kendo().Grid<Something>()
.Name("GridName")
.Columns(columns =>
{
columns.Bound(m => m.Id).Hidden()
columns.Bound(m => m.Name)
}))
I would like to hide ID depending on a value provided from the controller to the view.
How would I do this?
if (hideValue)
{
.....
??
}
Please try with the below code snippet.
Method 1: (Using viewbag)
View
#model MvcApplication1.Models.TestModel
#(Html.Kendo().Grid<Something>()
.Name("GridName")
.Columns(columns =>
{
columns.Bound(m => m.Id).Hidden(ViewBag.IsHideIDColumn);
columns.Bound(m => m.Name);
}))
Controller
public ActionResult Index()
{
TestModel test = new TestModel();
ViewBag.IsHideIDColumn = true;
return View();
}
Method 2: (Using strongly typed view)
View
#model MvcApplication1.Models.TestModel
#(Html.Kendo().Grid<Something>()
.Name("GridName")
.Columns(columns =>
{
columns.Bound(m => m.Id).Hidden(Model.IsHideIDColumn);
columns.Bound(m => m.Name);
}))
Controller
public ActionResult Index()
{
TestModel test = new TestModel();
test.IsHideIDColumn = true;
return View(test);
}
Model
public class TestModel
{
public bool IsHideIDColumn { get; set; }
}
Let me know if any concern.

How to detect Kendo Grid MVC initial binding on controller

I have a Kendo grid :
#(Html.Kendo().Grid<MyVm>().Name("grid").Columns(columns =>
...
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(p => p.Id))
.Read(read => read.Action("List", "MyController", new { id = Model.Id }).Type(HttpVerbs.Get)))
On my controller I have :
public JsonResult List([DataSourceRequest] DataSourceRequest request, int id)
{
//if (FIRST/INITIAL LOADING) ?????
...
}
How can I check on controller if its the initial loading/binding?
Thanks
You can add a Data method to your read call which will use a js function that will return a global variable that's set true onLoad and sets it false.
Then every time you read data it will send IsFirstRead parameter
.Read(read => read.Action("List", "MyController", new { id = Model.Id }).Type(HttpVerbs.Get)).Data("isFirstRead"))
function isFirstRead() {
if (firstTime) {
firstTime = false;
return true;
}
else
return false;
}
public JsonResult List([DataSourceRequest] DataSourceRequest request, int id, bool isFirstTime)
{
//if (isFirstTime) ?????
...
}
GoodLuck

How to bind the Kendo Grid in asp.net MVC 4 Razor

I have create the asp.net MVC 4 application where i am using the entity framework and class "Data" is the model.
AdventureWorksTrainingEntities _dbContext = new AdventureWorksTrainingEntities();
Data _data = new Data(); //Model
Now i want to display the data of the table to the kendo grid. In the controller, i am using the following code:
public ActionResult Index()
{
List<Movie> dataForGrid= _dbContext.Movies.ToList();
return View(dataForGrid);
}
Now i have no idea for displaying the data in Kendo Grid (i am new to kendo and MVC). I have also tried the following but not working:
#model IEnumerable<MvcApp.Models.Data>
#using Kendo.Mvc.UI
#{
ViewBag.Title = "Index";
}
<h2>Grid For Data</h2>
Html.Kendo().Grid<Order>()
.Name("Grid")
.DataSource(dataSource => dataSource // Not implemented
)
Finally got answer:
View:
#(Html.Kendo().Grid<KendoUI.Models.EmployeeViewModel>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.name).Title("Name");
columns.Bound(p => p.gender).Title("Gender");
columns.Bound(p => p.designation).Title("Designation").Width("300px");
columns.Bound(p => p.department).Title("Department").Width("300px");
})
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Navigatable()
.Pageable()
.Sortable()
.Scrollable()
.DataSource(dataSource => dataSource // Configure the grid data source
.Ajax()
.Model(model =>
{
model.Id(x => x.id);
})
.Read(read => read.Action("Employee_Read", "Home")) // Set the action method which will return the data in JSON format
)
)
Controller:
public ActionResult Employee_Read([DataSourceRequest]DataSourceRequest request)
{
IQueryable<Bhupendra_employees> Details = _dbContext.Bhupendra_employees;
DataSourceResult result = Details.ToDataSourceResult(request, p => new EmployeeViewModel
{
id = p.id,
name = p.name,
gender = p.gender,
designation = p.designation,
department = p.Bhupendra_Dept.Dept_Description
});
return Json(result, JsonRequestBehavior.AllowGet);
}
Model:
public class EmployeeViewModel
{
public Int32 id { get; set; }
public String name { get; set; }
public String gender { get; set; }
public String designation { get; set; }
public String department { get; set; }
//public DateTime dob { get; set; }
}
if your controller name is Data then you can use the following
Your Model
public ActionResult ReadDegrees([DataSourceRequest] DataSourceRequest request)
{
ViewBag.Countries = CommonController.CountryList();
ViewBag.DegreeTypes = CommonController.DegreeTypeList();
using (var _dbContext= new AdventureWorksTrainingEntities ())
{
return Json(_dbContext.Movies.ToList.ToDataSourceResult(request));
}
}
Your View
Just you need to add the following assuming that your Model has a Key called ID
Html.Kendo().Grid<Order>()
.Name("Grid")
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Model(model => model.Id(p => p.ID))
.Read(read => read.Action("ReadDegrees", "Data"))))

Resources