MVC Kendo Grid Search - kendo-ui

I am trying to add a search function to this Kendo grid in the MVC view cshtml file. In my ActionResult I am returning the model that is being used to fill the Grid. The data and search box are displayed in the grid but it will not filter the Grid when I enter text into the search box. I would like to do it on the client side so I set the ServerOperation to false
View
#(Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(x => x.Name).Title("Name");
})
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.ServerOperation(false)
)
)
Controller
public ActionResult Index()
{
List<PeopleListsViewModel> result = new List<PeopleListsViewModel>();
try
{
var PeopleInfo = GetPeople();
if (PeopleInfo != null)
{
result = PeopleInfo ;
}
}
catch (Exception e)
{
}
return View(TemplateName, result);
}

Related

how to add unique username in kendo ui and show alert or message after this insert duplicate username

I want to use kendo ui for manage the users in asp.net mvc and i need that kendo ui don't create duplicate username and display the error message that "the user name is duplicate"
this is my action for create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddNewCountry([DataSourceRequest]DataSourceRequest request, CountryViewModel c,int countryId)
{
if (c != null && ModelState.IsValid)
{
countryService.Create(c);
}
return Json(new[] { c }.ToDataSourceResult(request, ModelState));
}
Thanks in advance for your help
I sent you a solution in your other post (see here). But here is how you handle SERVER side errors using the kendo CLIENT grid. Some of these steps could be changed. For example, you could popup an alert instead of displaying the error on the editor template.
1) Add a model state error to your action:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddNewCountry([DataSourceRequest]DataSourceRequest request, CountryViewModel c,int countryId)
{
if (countryService.UserExists(c.UserName) // You need to code this
{
ModelState.AddModelError("UserName", "User name already exists.");
}
if (c != null && ModelState.IsValid)
{
countryService.Create(c);
}
return Json(new[] { c }.ToDataSourceResult(request, ModelState));
}
Handle the error event on your DataSource:
#(Html.Kendo().Grid<OrderDetailViewModel>()
.Name("orderDetailsGrid")
/* Not relevant grid setup code... */
.DataSource(dataSource => dataSource
.Ajax()
.Read(builder => builder.Url("/api/CustomerOrderDetails/GetOrderDetails/" + Model.OrderId).Type(HttpVerbs.Get))
.Create(builder => builder.Url("/api/CustomerOrderDetails/CreateOrderDetail/" + Model.OrderId).Type(HttpVerbs.Put))
.Update(builder => builder.Url("/api/CustomerOrderDetails/UpdateOrderDetail").Type(HttpVerbs.Post))
.Destroy(builder => builder.Url("/api/CustomerOrderDetails/DeleteOrderDetail").Type(HttpVerbs.Delete))
.Model(model => {
model.Id(x => x.OrderDetailId);
model.Field(m => m.OrderDetailId).DefaultValue(0);
})
.Events(events => events.Error("OrderDetails_Error"))
))
3) Add a placeholder for the errors to your editor template:
<ul class="errors"></ul>
4) Setup a kendo template to process the errors:
<script type="text/x-kendo-template" id="orderDetailsValidationMessageTemplate">
# if (messages.length) { #
<li>#=field#
<ul>
# for (var i = 0; i < messages.length; ++i) { #
<li>#= messages[i] #</li>
# } #
</ul>
</li>
# } #
</script>
Write the js error handler that will look at the server errors returned and format them into a template that can be displayed on the editor page:
OrderDetails_Error = function(args) {
if (args.errors) {
var grid = $("#orderDetailsGrid").data("kendoGrid");
var validationTemplate = kendo.template($("#orderDetailsValidationMessageTemplate").html());
grid.one("dataBinding", function(e) {
e.preventDefault();
$.each(args.errors, function(propertyName) {
// take the template and insert it into the placeholder
var renderedTemplate = validationTemplate({ field: propertyName, messages: this.errors });
grid.editable.element.find(".errors").append(renderedTemplate);
});
});
}
};

e.slice is not a function error in ASP.NET MVC with Kendo UI

I am working on asp.net MVC with Kendo UI grid.
I am getting the information from a method and give it to the grid. and I have in toolbar a datepicker so when I pick a new date the code will go to the method refilter the LINQ then I received a new list.
I wrote this code:
public ActionResult Grid_ReadLogAdminList([DataSourceRequest] DataSourceRequest request,[Bind(Prefix = "id")] string date)
{
//both the date and result is correct always
var jsonResult = Json(result, JsonRequestBehavior.AllowGet);
jsonResult.MaxJsonLength = int.MaxValue;
return jsonResult;
}
and here is the javascript when I change the datepicker:
function filterDate()
{
$("#LogAdminGrid").kendoGrid({
dataSource: {
transport: {
read: {
url: '/LogAdmin/Grid_ReadLogAdminList/',
type: 'get',
dataType: 'json',
data: {
id: kendo.toString($("#datepicker").data("kendoDatePicker").value(), "dd.MM.yyyy")
}
}
}
}
});
}
everything is correct and I can access the method correctly. but after the return of the method after the filter I receive and error:
kendo.all.js:6599 Uncaught TypeError: e.slice is not a function
I don't know why and how to solve it. please if you can help me with it?
As you are use the kendo ui MVC grid so i would suggest that go with below method.
View
#(Html.Kendo().Grid<WebApplication2.Models.Product>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(product => product.ProductID);
columns.Bound(product => product.ProductName);
})
.Pageable()
.Sortable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(x => x.ProductID);
})
.Read(read => read.Action("Grid_Read", "Home").Data("gridParam"))
)
)
<input id="txtID" type="text" value="1" />
<input type="button" value="filterGrid" onclick="filterGrid();" />
<script>
function gridParam() {
return {
ID: $("#txtID").val()
}
}
function filterGrid() {
$("#grid").data("kendoGrid").dataSource.read();
$("#grid").data("kendoGrid").refresh();
}
</script>
Controller
public ActionResult Grid_Read([DataSourceRequest]DataSourceRequest request, int? ID)
{
List<Product> lst = new List<Product>();
lst.Add(new Product() { ProductID = 1, ProductName = "aaa" });
lst.Add(new Product() { ProductID = 2, ProductName = "bbb" });
lst.Add(new Product() { ProductID = 3, ProductName = "ccc" });
if (ID.HasValue)
lst = lst.Where(i => i.ProductID == ID.GetValueOrDefault()).ToList();
return Json(lst.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
Modal
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
}
The root cause of the error "e.slice is not a function" is that instead of binding array to the kendo grid we binding object. (because we can apply slice method array only)

Get PK of Selected Row Kendo Grid From Toolbar Button

I have a Selectable Kendo Grid with a Custom Toolbar Button.
How can I get the selected row PK when button is Clicked?
I tried many tips but no one was working because I have a Server DataSource.
<%: Html.Kendo().Grid<Web.Models.Model>()
.Name("Grid")
.BindTo((IEnumerable<Web.Models.Model>)ViewBag.List)
.Columns(columns =>
{
columns.Bound(p => p.PK).Title("PK");
columns.Bound(p => p.STATUS).Title("Status");
columns.Bound(p => p.NOTES).Title("Notes");
})
.ToolBar(toolbar =>
{
toolbar.Custom();
toolbar.Template("<a class='k-button k-button-icontext' onClick='EditItem();' ></span>Edit Item</a>");
})
.DataSource(dataSource => dataSource
.Server()
.Model(Model => Model.Id(p => p.PK))
)
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Multiple))
%>
function EditItem(e) {
???
};
Please try with the below code snippet.
<script>
function EditItem() {
var grid = $("#Grid").data("kendoGrid");
var rows = grid.select();
rows.each(function (index, row) {
var selectedItem = grid.dataItem(row);
alert(selectedItem.PK);
});
}
</script>
Let me know if any concern.
hi you can use plain jquery for that as an another option
var rowID = $("#Grid .k-state-selected").find("td:eq(0)")[0].innerText
alert(rowID)
This one works!
function EditItem(e) {
var selectedRows = $("#Grid").find(".k-state-selected");
for (var i = 0; i < selectedRows.length; i++) {
var selectedRow = selectedRows[i];
var PK = selectedRows[i].cells[0].innerText;
}
};

How can I refresh the grid after I edit the Kendo UI grid?

I edit the grid using editable: "popup" as shown on Telerik's demo page. After I edit the grid, I want the grid to refresh. Does the grid have any event that is called after I edit the grid?
I tried to use the databound event. In this event I make the datasource read, but it tells me it is an infinite loop to refresh the grid. I tried to use the saveChanges event, but it is not working.
#(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.ProductViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.ProductName);
columns.Bound(p => p.UnitPrice).Width(100);
columns.Bound(p => p.UnitsInStock).Width(100);
columns.Bound(p => p.Discontinued).Width(100);
columns.Command(command => { command.Edit(); command.Destroy(); }).Width(160);
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Pageable()
.Sortable()
.Scrollable()
.Events(events => events.Change("saveChanges "))
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.ProductID))
.Create(update => update.Action("EditingPopup_Create", "Grid"))
.Read(read => read.Action("EditingPopup_Read", "Grid"))
.Update(update => update.Action("EditingPopup_Update", "Grid"))
.Destroy(update => update.Action("EditingPopup_Destroy", "Grid"))
))
You can subscribe to the Sync event of the grid's data source and call the read method of its data source.
.Events(events => events.Error("error_handler").Sync("sync_handler"))
function sync_handler(e) {
this.read();
}
Add Events into DataSource
.DataSource(dataSource => dataSource.Ajax(
.Events(e => e.RequestEnd("PowerPlantProduction.onRequestEnd"))**
)
Javascript:
onRequestEnd: function (e) {
if (e.type == "update") {
if (!e.response.Errors) {
e.sender.read();
}
}
},
The accepted answer can cause unexpected behaviour if you're using server side validation. The sync event triggers whenever an update is sent to the server regardless of whether the request was successful, so if the request triggers server side validation errors (or any other errors) the grid will still be updated and any changes lost. Still looking at the this but the best solution I've found is to use the data source's onRequestEnd() event and manually check for errors.
For example:
function onRequestEnd(e)
{
var grid = $("#grid").data("kendoGrid");
var data = grid.dataSource;
if (e.type == "create" || e.type == "update") {
if (!e.response.Errors)
data.read();
else console.log("I had some issues");
}
}
This will refresh the Grid
var grid = $("#Name").data("kendoGrid");
grid.dataSource.page(1);
if .page(1) doesn't work try .read, but it should
using AutoSync(true) in ajax mvc kendo grid having pop up edit mode causes the pop up to not show up at all.
So I use this
function onRequestEnd(e) {
if(e.type == "create" || e.type == "destroy" || e.type == "update") {
setTimeout(function myfunction() {
$("#mygrid").data("kendoGrid").dataSource.read();
}, 1000);
}
}
The time out is to make sure you dont over lap the crud operation.
In case someone else needs to know how to do this. You can include the "complete" function in your create as well as update bits.
transport: {
read: {
url: "http://myurl.json"
},
create: {
url: "http://mycreate.json",
type: "POST",
complete: function(e) {
$("#grid").data("kendoGrid").dataSource.read();
}
},
I agree this is very old question, but unfortunately I was also a victim of this error few days back. My scenario was
First time i was able to insert new record in database using popup method
If I add another record in same grid without refresh, grid is sending both the records to server, and unfortunately leads in duplicate value error.
Finally I think I got a solution for my problem, I was not setting primary key value to my record when I insert it into database and returning that object.
Below is my kendo grid code
#(Html.Kendo().Grid<TeamMemberViewModel>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.abcd);
columns.Bound(p => p.abcd_id).Hidden();
columns.Bound(p => p.abcd12_id).Hidden();
columns.Command(command =>
{
command.Edit();
command.Destroy();
});
})
.ToolBar(toolbar =>
{
if (ViewBag.IsAddAllowed)
{
toolbar.Create().Text("Add new");
}
// toolbar.Save().SaveText("Save Changes");
})
.Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("ABCD")
)
.Pageable()
.Navigatable()
.Sortable()
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.ServerOperation(false)
.Events(events =>
{
events.Error("error_handler");
events.RequestEnd("request_end");
}
)
.Model(model =>
{
model.Id(p => p.primarykey_id);
model.Field(p => p.abcd);
})
.Create("ABCD_Create", "TeamMember", new { id = Model.abcd_id})
.Read("ABCD_Read", "TeamMember", new { id = Model.abcd_id })
.Update("ABCD_Update", "TeamMember", new { id = Model.abcd_id })
.Destroy("TeamMember_Destroy", "TeamMember", new { id = Model.hackathon_id })
)
)
Below is error handling code
function error_handler(e) {
if (e.errors) {
var message = "Errors:\n";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
$(".errorMessage").text(message);
alert(message);
}
}
function request_end(e) {
switch (e.type) {
case "create":
if (e.Errors == undefined && e.response.Total > 0) {
// alert("Saved Successfully");
$(".errorMessage").text("Saved Successfully");
}
break;
case "update":
if (e.Errors == undefined && e.response.Total > 0) {
// alert("Updated Successfully");
$(".errorMessage").text("Updated Successfully");
}
break;
case "destroy":
if (e.Errors == undefined && e.response.Total > 0) {
// alert("Deleted Successfully");
$(".errorMessage").text("Deleted Successfully");
}
break;
default:
$(".errorMessage").text("");
break;
}
return true;
}
Server Code
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ABCD_Create([DataSourceRequest] DataSourceRequest request, MyViewModel my, short abcd_id)
{
if (my != null && ModelState.IsValid)
{
MY tm = Mapper.Map<MyViewModel>(my);
tm.abcd_id = abcd_id;
try
{
repo.Create(tm);
my.primarykey_id = tm.primarykey_id; ///This is most important
}
catch (Exception ex)
{
ModelState.AddModelError("Duplicate Value Found", string.Format("error: {0} already exists", my.abcd));
}
}
else
{
ModelState.AddModelError("Error", "Not valid please send data again");
}
return Json(new[] { my }.ToDataSourceResult(request, ModelState));
}
Hope this might help someone
Use this if you want to refresh the grid.
$("#WorkOrderDetails").data("kendoGrid").refresh();
You can call a function on you edit button click and inside that you can refresh the grid:
function EditRow(){
var grid = $("#YourGridName").data("kendoGrid");
grid.dataSource.read();
}
.sync: function (e) {
this.read();
},
I've been trying to figure out how to refresh the grid after creating a new item. Scenario is: Create an item in the client, send request to server, receive response and update client. (Alternatively, I wouldn't mind figuring out why the grid isn't using the item I'm returning it in the server-side create function)
This post mentions the requestEnd event, but it's not exposed in razor. This event seems to fire after a request is finished, that is, after the server processes the event, so new objects created on the client will already be sent to the server for processing; then the client can request the latest information without losing data. Since the grid datasource object was undefined on page load, I ended up using the .Change event to hook the requestEnd event.
#(Html.Kendo().Grid
.Name("user-grid")
...
.Pageable(pageable => pageable
...
.Events( e => e.Remove("grid_remove").Change("hook_request_end"))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Model(m =>
{
m.Id(vm => vm.DocumentId);
m.Field<DateTime>("LastModified").Editable(false);
})
.Read(a => a.Action("KList", "Controller"))
.Create(a => a.Action("KCreate", "Controller"))
.Update(a => a.Action("KUpdate", "Controller"))
)
and then the javascript:
var requestEndHooked = false;
function hook_request_end()
{
if (requestEndHooked == true)
{
return;
}
requestEndHooked = true;
$("#user-grid").data("kendoGrid").dataSource.bind("requestEnd", dataSource_requestEnd);
}
function dataSource_requestEnd(e)
{
try
{
if (e.type == "create")
{
$("#user-grid").data("kendoGrid").dataSource.read();
}
}
catch (e)
{
}
}
If there's a better way, I'd love to know.
To answer your question, there are events other than "create": "read", "update"
I know this is an old question, but there is a perfectly working example (at least for me!) on the Telerik forum: https://www.telerik.com/forums/refresh-grid-after-insert-update
I post this here because that forum question and answer is less than a year old, it might be that that solution wasn't available for the Kendo version at the time of the OP's question.
The solution mentioned there is to attach a dataBound handler function to the grid, which will be executed only once after the save event. In code:
function onGridEdit(e) {
e.sender.one("dataBound", function (e) {
e.sender.dataSource.read();
});
}
function bindDataAndRefresh(e) {
var grid = $("#upcoming-grid").data("kendoGrid");
grid.bind("dataBound", onGridEdit(e));
}
$(document).ready(function () {
var grid = $("#upcoming-grid").data("kendoGrid");
grid.bind("save", bindDataAndRefresh);
});
I used complete property of transport:update section while creating datasource for kendo.
My code
dsource = new kendo.data.DataSource({
transport: {
read: {
url: serverapiUrl + "/emp",
type: 'GET',
dataType: "json",
cache: true,
beforeSend: function (xhr, settings) {
xhr.setRequestHeader('api-key', 'auth key');
}
},
create: {
url: serverapiUrl + "/emp",
type: 'POST',
dataType: 'json',
beforeSend: function (xhr, settings) {
console.log('under create');
xhr.setRequestHeader('api-key', 'authkey');
xhr.setRequestHeader("content-type", "application/json");
console.log('settings', settings);
console.log(xhr);
}
},
update: {
url: serverapiUrl + "/emp",
type: 'PUT',
dataType: 'json',
beforeSend: function (xhr, settings) {
console.log('under update');
xhr.setRequestHeader('api-key', 'authkey');
xhr.setRequestHeader("content-type", "application/json");
console.log('settings', settings);
console.log(xhr);
},
complete: function (eve) {
console.log('update complete');
$("#griddiv").data("kendoGrid").dataSource.read();
}
}
rest follows the normal structure of kendo ui datasource creation documentation.

MVC Kendo UI Grid = Custom Button can't return selected row id

I want to get the selected row "ID" but it just failed... and i have totally no clue what is happening here.
MVC HTML Code :
#(Html.Kendo().Grid(Model)
.Name("grid")
.HtmlAttributes(new { style = "margin-top: 5px" })
.Columns(c =>
{
c.Bound(model => model.mgID);
c.Command(com => { com.Custom("Edit").Click("Edit");});
})
.Pageable()
.Sortable()
.Selectable()
.DataSource(d => d
.Ajax()
.PageSize(20)
.Model(model => model.Id(i => i.mgID))
.Read(r => r.Action("Manage_Read", "Manage"))
.Destroy(o => o.Action("Manage_Destroy", "Manage"))
)
)
Javascript Code :
function Edit() {
var grid = $("#grid").data("kendoGrid");
var row = grid.select();
var selectedRowIndex = row.index(); //Return "-1"
var dataItem = grid.dataItem(row); //Return "Undefined"
}
Please tell me, what am i miss out??
If all you need is get the dataItem of the row containing the clicked "Edit" button, you can use:
function Edit(e) {
var dataItem = this.dataItem($(e.target).closest("tr"));
}
NOTE:
in the context of click event this is the grid.
in that same context e.target is your button, so we look for the closest table row.

Resources