how to return a value (from async call) to a grid's cell template?

8 posts, 1 answers
  1. Clint
    Clint avatar
    58 posts
    Member since:
    Feb 2011

    Posted 01 Oct 2013 Link to this post

    Trying to pass a value from an async call back to a grid column cell template.  Obviously returning a value from an async call can be difficult.  How do I get a result back into the kendo grid cell?

    ....
     field: "PTORecorded",  
               title: "PTO Recorded",
               template:  function (data){
    getData(data).done(handleData);
    }

    },

    ----
    function getData(data) {
     var person = data.Person;
        return $.ajax({
            url : url + person,
            type: 'GET',
            headers: {
             "Accept": "application/json; odata=verbose"
         },  
        });
    }
    function handleData(data) {
        var ptoArray = [];
         $.each(data.d.results, function (index, item) {
                 if (item.PTOValue != null) {
                     var _item = item.PTOValue;
                     ptoArray.push(_item);
                 }
             });
             var ptoRecorded = 0;
             for (var i = 0; i < ptoArray.length; i++) {
                 ptoRecorded += ptoArray[i] << 0;
     
       return ptoRecorded;
        }
      }
    I'm basically trying to call a remote datasource, filtering it via a value in the grid row (data.Person), calculating a returned value, and passing it back to a grid cell template.  How do I get that async call to pass a value back to the grid?  I know the async call presents a problem.  Suggestions?
  2. Answer
    Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2206 posts

    Posted 03 Oct 2013 Link to this post

    Hi Clint,

     
    Basically current behavior is expected as the "ajax" method of jQuery releases current thread and the execution of the function continues. In current scenario you can return div element with "id" attribute based on current model ID. Then when the ajax call is completed you can find that div element and insert the calculated result as it's content. For convenience I created small example:

    • Define column template:  
      template: "#=createAsync(data)#"
    • Define the "createAsync" function:  
      function createAsync(data) {
       
          $.ajax({
              url: "/Home/GetCustomData",
              type: "POST",
              data: { id: data.OrderID },
              success: function (response) {
                  //find the returned element and insert the response
                  $("#async_" + data.OrderID).html(response.text);
              }
          });
       
          //return container with id generated from current model ID field
          return "<div id='async_" + data.OrderID + "'> </div>"
      }
    •        
    Kind Regards,
    Vladimir Iliev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. Clint
    Clint avatar
    58 posts
    Member since:
    Feb 2011

    Posted 03 Oct 2013 Link to this post

    That approach works great.  Thank you!  I actually was just implementing a similar idea and your sample code helped me out. Much appreciated!
  4. Josh
    Josh avatar
    7 posts
    Member since:
    Jun 2013

    Posted 15 Apr 2014 in reply to Vladimir Iliev Link to this post

    I have a Kendo Grid where I'd like to call an ajax method to populate this cell. The call is made and it does indeed return a value for each row. However it looks like it can't find the cell in order to update the cell. When I use the browsers debugger I do see the div in the gridcell. Any ideas?

    in grid:

    columns.Bound(a => a.Destination).Title("Assigned To").Width("180px").ClientTemplate ("#=createDispNameAsync(Destination)#");

    js call:

    function createDispNameAsync(Destination) { ++rowID;

    $.ajax({
    url: "/report/GetUserName",
    type: "POST",
    data: { userName: Destination },
    success: function (response) {
    $("#async_" + rowID).replaceWith(response);
    }
    });

    return "<div id='async_" + rowID + "'>" + Destination + "</div>";
    }
  5. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2206 posts

    Posted 17 Apr 2014 Link to this post

    Hi Josh,

    My colleague Alex already answered to this query in duplicated support ticket created by you - #810240. Please keep in mind that it is highly recommended that you keep related questions in one support thread or a forum post, so that we can easily keep track of your support history and provide better answers in a shorter time.

    Regards,
    Vladimir Iliev
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  6. Scott Waye
    Scott Waye avatar
    168 posts
    Member since:
    Nov 2009

    Posted 08 Sep 2016 in reply to Clint Link to this post

    Thanks for the question and answers.  If you're using Angular you may need a bit more to get the template out of the controller.  Here's what I've got working:

     

        $scope.lookUpEventNameAsync = function(data) {
     
            refData.events().fetch(function() {
                var eData = refData.events().data();
                var refEvent = eData.find(function(re, i, a) {
                    return re.code === data.eventCode;
                });
                $("#async_tse_" + data.key).html(refEvent.name);
            });
     
            return $sce.trustAsHtml("<div id='async_tse_" + data.key + "'> </div>");
        };
     
        $scope.gridTimesheetColumns = [
            {
                field: "eventCode", title: "Event", width: "100px", editor: eventDropDownEditor, template: "<span ng-bind-html='lookUpEventNameAsync(dataItem)'> </span>"
            },
    ....

     

    refData.events() is the kendoDataSource and $scope.gridTimesheetColumns is attached through the k-columns directive.

  7. Mauricio Alexander
    Mauricio Alexander avatar
    1 posts
    Member since:
    Feb 2014

    Posted 19 Jun 2018 in reply to Vladimir Iliev Link to this post

    I need the answer to this question...
  8. Stefan
    Admin
    Stefan avatar
    3008 posts

    Posted 21 Jun 2018 Link to this post

    Hi,

    This is the answer in the ticket:

    "
    This happens because the request is asynchronous, meaning that the template is rendered before the response is received. Basically, there are two approaches:
    Make the request synchronous by setting the async option to false
    Use the item's uid to find the row and the cell once the response arrives. For example: 

    ClientTemplate("#=createDispNameAsync(data.uid)#");
     
       
     
    function createName(uid) {
     
        var item = $("#MyGridID").data("kendoGrid").dataSource.getByUid(uid);
     
        $.ajax({
     
            url : "/report/GetUserName",
     
            type : "POST",
     
            data : {
     
                userName : item.Destination
     
            },
     
            success : function (response) {
     
                $("#grid tr[data-uid='" + uid + "'] td:eq(0)").text(response.myResponseField)
     
            }
     
        });
     
        return ""
     
       
     
    }

    "

    I hope this is helpful.

    Regards,
    Stefan
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top