36

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"))
))
ruffin
  • 16,507
  • 9
  • 88
  • 138
flower
  • 2,212
  • 3
  • 29
  • 44

13 Answers13

49

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();
}
Atanas Korchev
  • 30,562
  • 8
  • 59
  • 93
  • 2
    Can you tell me what is the `.Sync("sync_handler")` event and when to use it? – flower Feb 20 '14 at 13:59
  • This would address my issue, but cant see to get sync handler triggered? – DaniDev Nov 04 '16 at 20:30
  • dataSource.read() doesn't refresh the grid, it just invokes the read function, which (if you follow telerik's tutorials and style) will just reset the grid to it's initial conditions, wiping out all the changes you've made to the dataSource. – GreySage Dec 20 '18 at 23:02
21

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();
            }
        }
    },
TrieuH
  • 564
  • 3
  • 13
  • tried this. didn't work. it works on a different project which is weird. for another project, i use the .Sync() handler and that works. upvoted you anyway. – Vince Jun 27 '18 at 14:50
7

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");
    }
}
Andy Hoffman
  • 18,436
  • 4
  • 42
  • 61
Gumbo
  • 81
  • 1
  • 2
4

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

CSharper
  • 5,420
  • 6
  • 28
  • 54
  • This is actually good answer if you are adding prepopulated row using custom button in the toolbar and have paging enabled. Thank you! – Konrad Mikuła Jan 13 '20 at 14:09
4

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.

Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112
  • 1
    This looks pretty horrible, but having tried all other solutions it's the only one that seems to work for me. There seems no way when using KendoMVC to tap into an event which fires after a datasource operation has completed and the DOM has been updated with the server response from the CRUD operation. – Rich Freeman Sep 16 '19 at 12:59
4

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(); 
        }
    },
GenXisT
  • 298
  • 4
  • 10
4

I agree this is very old question, but unfortunately I was also a victim of this error few days back. My scenario was

  1. First time i was able to insert new record in database using popup method
  2. 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

3

Use this if you want to refresh the grid.

$("#WorkOrderDetails").data("kendoGrid").refresh();
Gonzalo.-
  • 12,512
  • 5
  • 50
  • 82
Shazhad Ilyas
  • 1,183
  • 8
  • 14
1

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();              
}
  • I am afraid it is not good.Because the grid must be refresh after the row is edit,it means the the data has already been changed in database. – flower Feb 19 '14 at 17:23
  • Above code is for refreshing the grid only after your saving of the data. –  Feb 20 '14 at 04:36
  • How can I know I have save my data?I use `grid.dataSource.read()` in saveShanges events,but it seems that the grid is refresh first and then to save the data. – flower Feb 20 '14 at 12:28
  • I found after add preventDefault method,sometimes it is ok to first save data,but sometimes is first to refresh the gird.`function onSaveChanges(e) { if (e.model.dirty) { e.preventDefault(); var grid = $("#MyGrid").data("kendoGrid"); grid.saveChanges(); grid.dataSource.read(); } }` – flower Feb 20 '14 at 13:58
1
.sync: function (e) {
this.read();
},
  • 2
    This might be the correct answer, but it provides no explanation on why. You should improve your answer by giving an explanatation. – Daniel Jul 29 '15 at 22:02
0

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"

BurnsBA
  • 4,347
  • 27
  • 39
0

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);
});
  • A link to a solution is welcome, but please ensure your answer is useful without it: [add context around the link](//meta.stackexchange.com/a/8259) so your fellow users will have some idea what it is and why it’s there, then quote the most relevant part of the page you're linking to in case the target page is unavailable. [Answers that are little more than a link may be deleted.](/help/deleted-answers) – 4b0 Feb 26 '21 at 11:04
  • 1
    Okay sorry, I added a description and the code in case the link will become unavailable. – Lex Wassenberg Feb 26 '21 at 12:00
0

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.

Rahul Ranjan
  • 1,028
  • 1
  • 10
  • 27