This is a migrated thread and some comments may be shown as answers.

Prevent DataBound and DataBinding from being fired more than once

3 Answers 3048 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Fred
Top achievements
Rank 1
Fred asked on 15 Aug 2017, 07:32 PM

Due to the requirements, I had to implement the grid cells so that some of them are always in edit mode (input) and that the grid will fire an ajax call to the API server whenever user finishes updating cell value.

Here's what I have:

Grid DataSource and event handlers

.Events(e => e
    .DataBound("onDataBound")
    .DataBinding("onDataBinding")
)

 

.DataSource(dataSource => dataSource
   .Ajax()

   .Events(e => e.Change("onDataChange"))

   .Read(read => read.Action("action", "controller").Data("GetParams"))

   .Model(mod => mod.Id(m => m.id))
   .PageSize(100)
)

 

Click handler (get new data based on currently selected options)

$("#btn").click(function () {
    $("#Grid").data("kendoGrid").dataSource.read(GetParams());
}); // end click

onDataChange, onDataBinding and onDataBound

function onDataChange(e) {
    if (e.items.length == 1) {
        var updatedCell = e.items[0];
        var queryString = "?id="+updatedCell.id+"&field="+e.field+"&val="+updatedCell[e.field];
        $.ajax({
                         type: "put",
                         url: "@Url.Content("~/controller/action")" + queryString,
          headers: { 'RequestVerificationToken': '@Html.TokenHeaderValue()' },
          success: function (response) {
            var resObj = response.toString();
            if (resObj == "success") popupNotification.show("Auto Save Success!", "error");
            else popupNotification.show("Auto Save Error", "error");
         },
          fail: function (response) { 
              popupNotification.show("Auto Save Error", "error");
          }
       });// end ajax
     }
}
 
function onDataBinding(arg) {
    var rows = this.tbody.children();
    var dataItems = this.dataSource.view();
    for (var i = 0; i < rows.length; i++) {
      kendo.unbind(rows[i]);
    }
}
 
function onDataBound(arg) {
    var rows = this.tbody.children();          
    var dataItems = this.dataSource.view();
    for (var i = 0; i < dataItems.length; i++) {
        var temp = dataItems[i];
        if (temp["RecordTypeID"] == 1 || temp["RecordTypeID"] == 3)
         {
            kendo.bind(rows[i], dataItems[i]);
         }          
    }
    generateChart(PopulateSummaryTable());
}

 

What happens right now is whenever the dataSource.read(GetParams()) gets called for the first time, the following things happen in this particular order:

onDataBinding

onDataBound

onDataChange

which is fine. But if the button is not clicked (which calls dataSource.read(GetParams())), and the user simply edits currently displayed cells, I'm hoping only onDataChange gets called, but it turns out that onDataBinding and onDataBound get called again, and then onDataChange.

Is it possible to prevent onDataBinding and onDataBound from being called more than once?

 

Please see attached for the UI 

 

 

3 Answers, 1 is accepted

Sort by
1
Konstantin Dikov
Telerik team
answered on 17 Aug 2017, 06:48 AM
Hello Fred,

The DataBound and DataBinding events will fire if you are manually change the dataItems value with their "set" method when the user changes a value in the inputs. This is due to the fact that the Change event of the DataSource triggers the DataBound and DataBinding events, so that the Grid could render its items with the changes. If you want to prevent that behavior you could change the value without the "set" method and set their "dirty" property to "true" manually:
dataItem.someField = "new value";
dataItem.dirty = true;

Hope this helps.


Regards,
Konstantin Dikov
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Fred
Top achievements
Rank 1
answered on 17 Aug 2017, 04:07 PM

I actually did not change the dataitems manually. Could you look at my codes again? The input elements are bound to the view model object inside onDataBinding.

Users are the ones that will change the value of these inputs.  I want to capture the event fired when this happens, which is why I add a listener to datasource change event. But at the same time, I dont want onDataBinding and onDataBound to be called.

0
Accepted
Konstantin Dikov
Telerik team
answered on 21 Aug 2017, 10:11 AM
Hello Fred,

When you bind the dataItem to the TR element containing the editors, the binding mechanism will trigger the change event of the dataSource, which in other hand will trigger the dataBound and dataBinding events. When you bind the items with the kendo.bind, this is equivalent to the "set" method of the dataItems. With that in mind, if you want to handle the changes of the input elements without the triggering of the dataBound and dataBinding events, you need to remove the kendo.bind, attach handlers for the change event of each input element and manually change the values using the approach from my previous post. Note that this will not trigger the "change" event of the dataSource. 


Best Regards,
Konstantin Dikov
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
Grid
Asked by
Fred
Top achievements
Rank 1
Answers by
Konstantin Dikov
Telerik team
Fred
Top achievements
Rank 1
Share this question
or