Grid won't render

14 posts, 1 answers
  1. Richard
    Richard avatar
    9 posts
    Member since:
    Feb 2013

    Posted 11 Feb 2013 Link to this post

    I'm new to Kendo UI and MVC and am working on an ASP.Net MVC3 project using Razor.  I've based my grid on a demo at http://docs.kendoui.com/documentation/getting-started/using-kendo-with/aspnet-mvc/helpers/grid/ajax-binding.   I could easily do this as a traditional ASP.Net project in which I'm expert but want to master this new pattern.

    My problem is that the grid won't render.  The JSON content coming back appears valid to me.  I've got a similar grid in DataTables where I've got the grid to at least render the first level but this one is proving to be stubborn. I'd prefer to use KendoUI if possible.

    I've determined the the Ajax call is working and that JSON content is being returned to the browser.  I'm not sure what might be wrong.  I'm binding to a List collection of Batch objects.  A Batch object has properties to be displayed in the first level of the grid.  The Batch object also has a property that returns a List collection of Transaction objects which will be displayed on demand in the nested grid which I haven't gotten to yet.

    Can anyone point me to where I've gone wrong?  I've no clue what to do next and can't find any articles that look like a solution.

    Here's the code I have so far:

    // the controller      
     
     // called by Index2: returns a list of BatchHeader objects directly from the ROAMHostSvc
            public ActionResult FetchBatchList2()
            {
                DateTime aDate = new DateTime(0001, 1, 1);
                ROAMHostSvc.Notification messages1 = null;
                ROAMHostSvc.ROAMHostSvcClient hostSvc = null;
                 
                KUI_CS_Test1.ROAMHostSvc.BatchHeader[] batchArr;
                //List<KUI_CS_Test1.ROAMHostSvc.BatchHeader> batchCollection = new List<BatchHeader>();
                 
                try
                {
                    hostSvc = new ROAMHostSvc.ROAMHostSvcClient();
                    batchArr = hostSvc.GetBatchCollection(ref messages1, false, aDate, aDate, false, aDate, aDate);
     
                    // assign the objects in the array to the List collection
                    //for (int i = 0; i <= batchArr.Length - 1; i++)
                    //{
                    //    batchCollection.Add(batchArr[i]);
                    //}
     
                    //return View(batchCollection);
                    //return PartialView(batchCollection);
                    //return PartialView(Json(batchCollection, JsonRequestBehavior.AllowGet));
                    return Json(batchArr, JsonRequestBehavior.AllowGet);
                }
                catch (Exception ex)
                {
                    return null;
                }
                finally
                {
                    Close_WCF_Service(ref hostSvc);
                }
            }
     
     
     
            private void Close_WCF_Service(ref ROAMHostSvc.ROAMHostSvcClient hostSvc)
            {
                try
                {
                    if ((hostSvc != null))
                    {
                        if (hostSvc.State == System.ServiceModel.CommunicationState.Opened)
                        {
                            hostSvc.Close();
                            hostSvc = null;
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
     
        }
     
     
    //the view
     
    @model KUI_CS_Test1.ROAMHostSvc.BatchHeader[]
     
    @{
        ViewBag.Title = "Index1";
    }
     
    <h2>Index1</h2>
    @(Html.Kendo().Grid(Model)
        .Name("batchGrid")
        .Columns(columns =>
            {
                columns.Bound(b => b.BatchID);
                columns.Bound(b => b.Transmitted_DateTime);
                columns.Bound(b => b.Completed_DateTime);
                columns.Bound(b => b.Created_DTTM);
                columns.Bound(b => b.Created_EmpID);
            }
        )
        .DataSource(dataSource => dataSource
            .Ajax()
            .Read(read => read.Action("FetchBatchList2", "Home"))
        )
    )

  2. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2284 posts

    Posted 13 Feb 2013 Link to this post

    Hello Richard,

    Welcome to the Kendo UI family. Please take a look at this Grid demo and notice the structure of the Action method which is used as a Read Action for the dataSource. As a minimum It should have a parameter of type [DataSourceRequest] DataSourceRequest which contains the information about the current state of the grid and should return the result using the ToDataSourceResult extension method. I would also suggest you to check this page about Grid Troubleshooting.
     
    Please let me know if this information solved the problem.

    Regards,
    Dimiter Madjarov
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. Richard
    Richard avatar
    9 posts
    Member since:
    Feb 2013

    Posted 19 Feb 2013 Link to this post

    Sorry for the delay... I got pre-empted last week.  I worked it out and have the first level of my grid working now.

    I could use a steer on how to make the next level work and a demo on formatting data.  I looked at the hierarchy demo at  http://demos.kendoui.com/web/grid/hierarchy.html but it's not germane to my case as I'm not querying a database table.

    In my master level grid I get a List of BatchHeader objects.  I want to create a detail level using a collection property of BatchHeader, e.g. a List of Transaction objects.  How to I reference the BatchHeader object of a row that get's clicked in order to access the List collection of Transactions as the data source for my detail grid?  Since I already got those from the service I don't want to have to query the service again.

    Thanks!

    BTW, it would be most helpful if there were a book on the Kendo UI.  The documentation as it currently exists is really difficult to use for someone new to Kendo.  I'm spending a lot of time searching and not finding what I need.
  4. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2284 posts

    Posted 21 Feb 2013 Link to this post

    Hello Richard,

    Since you already received the data for the detail grid, you could set it's dataSource explicitly in the DetailInit event of the master grid.

    E.g.

    @(Html.Kendo().Grid<Customer>()   
        .Name("Grid")
        .Columns(columns => {       
            columns.Bound(p => p.Name);
            columns.Bound(p => p.Years);
        })
        .ClientDetailTemplateId("products")
        .Events(e => e.DetailInit("detailInit"))
        .DataSource(dataSource => dataSource       
            .Ajax()
            .Read(read => read.Action("Customers_Read", "Home"))
        )
    )
     
    <script id="products" type="text/kendo-tmpl">
        @(Html.Kendo().Grid<Product>()
                   .Name("Products_#=Name#")
                   .ToClientTemplate()
         )
    </script>
     
    <script>
        function detailInit(e) {
            var grid = $("#Products_" + e.data.Name).data("kendoGrid");
            grid.dataSource.data(e.data.Products);
        }
    </script>

    Let me know if this covers your scenario.
      Greetings,
    Dimiter Madjarov
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  5. Richard
    Richard avatar
    9 posts
    Member since:
    Feb 2013

    Posted 21 Feb 2013 Link to this post

    Thanks, Dimiter!
    I'll work through this, probably on Monday... I'm off till then.  thanks for the info and I'll post my results soon.
  6. Richard
    Richard avatar
    9 posts
    Member since:
    Feb 2013

    Posted 21 Feb 2013 Link to this post

    I did run into a little snag... I can't figure out the syntax to reference the TranCollection property of the BatchHeader object (which returns a List of Transaction objects).  My model is declared as

    [code]
    @model IEnumerable<KUI_CS_Test1.ROAMHostSvc.BatchHeader>
    [/code]

    I tried

    [code] 
    <script id="transactions" type="text/kendo-tmpl">
        @(Html.Kendo().Grid(KUI_CS_Test1.ROAMHostSvc.BatchHeader.TranCollection)
                        .Name("Transactions_#=BatchID#")
                        .ToClientTemplate()
        )
    </script>
    [/code]

    but the page can't find a reference to that property.  I noticed you used angle brackets vs parentheses.  Does it make any difference?  I used parentheses in the master grid declaration and it works.  I was wondering it it's because the detail grid is declared in a script block that it might change.  I don't seem to get an error either way.

    Thanks!

    Rich
  7. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2284 posts

    Posted 22 Feb 2013 Link to this post

    Hello Richard,


    The model cannot be passed directly in parenthesis for the detail grid, because the grid won't know which row from the master grid are we referring to and which TranCollection to bind to. For the current scenario you should use the angle brackets syntax and set the dataSource in the detailInit event, as shown in the previous example. In the event handler you could refer to the property as e.data.TranCollection.


    Kind regards,
    Dimiter Madjarov
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  8. Richard
    Richard avatar
    9 posts
    Member since:
    Feb 2013

    Posted 25 Feb 2013 Link to this post

    Hi Dimiter!
    I think I'm close but still can't quite figure out the syntax to tell the detail grid it's to receive an enumerable List of type ITransaction, e.g. the BatchHeaders TranCollection property, which at runtime can hold transactions of various types.  One way I tried it gave me an error that I was using a property as a type.  Here's my current code... can you tell me where I'm going wrong?  None of the examples I've seen are quite like what I'm trying to do.  The master level works, but the detail level can't resolve the column properties.  I've tried it a bunch of different ways that don't work.  Perhaps I'm reading the examples wrong?

    Thanks!

    @model IEnumerable<KUI_CS_Test1.ROAMHostSvc.BatchHeader>
     
    @{
        ViewBag.Title = "Kendo UI for MVC (C#) Test App";
    }
     
    <h2>Batch List</h2>
    @(Html.Kendo().Grid(Model)
        .Name("batchGrid")
        .Sortable()
        .Pageable()
        .Filterable()
        .Columns(columns =>
            {
                columns.Bound(b => b.BatchID)
                                        .Width("22%");
                columns.Bound(b => b.Transmitted_DateTime)
                                        .Width("13%")
                                        .Format("{0:MM/dd/yyyy hh:mm tt}")
                                        .Title("Transmitted");
                columns.Bound(b => b.Completed_DateTime)
                                        .Width("13%")
                                        .Format("{0:MM/dd/yyyy hh:mm tt}")
                                        .Title("Completed");
                columns.Bound(b => b.Created_DTTM)
                                        .Width("13%")
                                        .Format("{0:MM/dd/yyyy hh:mm tt}")
                                        .Title("Created");
                columns.Bound(b => b.Created_Emp_Name)
                                        .Width("18%")
                                        .Title("Created By");
            }
        )
        .ClientDetailTemplateId("transactions")
        .Events(e => e.DetailInit("detailInit"))
        .DataSource(dataSource => dataSource
            .Ajax()
            .Read(read => read.Action("FetchBatchList2", "Home"))
        )
    )
     
    <script id="transactions" type="text/kendo-tmpl">
        @(Html.Kendo().Grid<IEnumerable<KUI_CS_Test1.ROAMHostSvc.BatchHeader.ITransaction>>()
                        .Name("Transactions_#=BatchID#")
                        .Columns( columns =>
                        {
                            columns.Bound(t => t.ID).Width("22%");
                            columns.Bound(t => t.Version);
                            columns.Bound(t => t.TranTypeDisplayText);
                            columns.Bound(t => t.PostingFlagDisplayText);
                            columns.Bound(t => t.Posting_DTTM);
                            columns.Bound(t => t.PostingMessage);
                        })
                        .ToClientTemplate()
        )
    </script>
     
    <script type="text/javascript" language="javascript">
        function detailInit(e) {
            var grid = $("#Transactions_" + e.data.TranCollection).data("kendoGrid");
            grid.dataSource.data(e.data.Transactions);
        }
    </script>
  9. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2284 posts

    Posted 27 Feb 2013 Link to this post

    Hello Richard,

    As far as I can see, the child Grid is not correctly referred in the jQuery selector in the detailInit event. Assuming that the name of the Grid is "Transactions_#=BatchID#", it should be selected the following way:

    var grid = $("#Transactions_" + e.data.BatchID).data("kendoGrid");
      All the best,
    Dimiter Madjarov
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  10. Richard
    Richard avatar
    9 posts
    Member since:
    Feb 2013

    Posted 27 Feb 2013 Link to this post

    Thanks, Dimiter!
    I think I'm making progress, but I'm not sure...  sorry to be such a pest... I'm new to both C#, MVC, and Kendo and I never seem to be doing the easy stuff first!

    Now I'm getting an error when the page parses so I'm not sure I've resolved the detail grid object reference correctly.  The error I'm getting is 'Cannot convert lambda expression to typoe 'string' because it is not a delagate type.'

    Type TransactionBase is the ancestor of the current transaction type I'm using which is controlled by interface ITransaction.  All of the properties and methods needed are available in TransactionBase. In the current case BatchHeader contains a List of InventoryTransaction objects derived from TransactionBase.  The interface isn't showing up in the WCF service that provides the List but that's a different problem... I think this should work, although I'd prefer to specify ITransaction.  I can solve for that later though.  

    Now I'm getting past base the object reference but the column binding is complaining.  For some reason I'm no longer getting Intellisense on the code block so I can't tell the that the object reference doesn't resolve until I run the page.

    Here's the code I have now for the detail grid and event...
    <script id="transactions" type="text/kendo-tmpl">
        @(Html.Kendo().Grid<IEnumerable<KUI_CS_Test1.ROAMHostSvc.TransactionBase>>()
                        .Name("Transactions_#=BatchID#")
                        .Columns( columns =>
                        {
                            columns.Bound(t => t.ID).Width("22%");
                            columns.Bound(t => t.Version);
                            columns.Bound(t => t.TranTypeDisplayText);
                            columns.Bound(t => t.PostingFlagDisplayText);
                            columns.Bound(t => t.Posting_DTTM);
                            columns.Bound(t => t.PostingMessage);
                        })
                        .ToClientTemplate()
        )
    </script>
     
    <script type="text/javascript" language="javascript">
        function detailInit(e) {
            var grid = $("#Transactions_" + e.data.BatchID).data("kendoGrid");
            grid.dataSource.data(e.data.TranCollection);
        }
    </script>

  11. Answer
    Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2284 posts

    Posted 28 Feb 2013 Link to this post

    Hello Richard,

    When initializing the Grid, you should use the angle brackets to specify the type of the Grid items. I am assuming that in the current scenario it should be
    @(Html.Kendo().Grid<KUI_CS_Test1.ROAMHostSvc.TransactionBase>()
    instead of
    @(Html.Kendo().Grid<IEnumerable<KUI_CS_Test1.ROAMHostSvc.TransactionBase>>()

    If this does not solve the issue, could you send me a sample project, so I could investigate it locally and assist you further.

     

    Regards,
    Dimiter Madjarov
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  12. Richard
    Richard avatar
    9 posts
    Member since:
    Feb 2013

    Posted 28 Feb 2013 Link to this post

    Wahoo!  That got it!  It was unclear to me what needed to be specified.  I thought the grid needed to know that the type to be received was in an enumerable container when all it needed to know is what singular object would be used for each row.

    One last question... the grid is rendering fine now, but the selector column of the master grid is very wide.  I searched for ways to configure it but didn't find any way to reference that column which seems to be automatically added.  The demos don't show any formatting of this.

    Will this adjust to the aggregate width of all the other columns?

    Thank you very much for your help and your patience!
  13. Richard
    Richard avatar
    9 posts
    Member since:
    Feb 2013

    Posted 28 Feb 2013 Link to this post

    Let me know if I should post this as a separate question... the grid as noted above is rendering and I just got done applying the formatting to the columns of the detail grid.  The detail grid is ignoring the date formatting and displaying a JSON date instead.  I've done some searching around and haven't found anything that looks relevant.  
    Here's the format spec:
    columns.Bound(t => t.Posting_DTTM)
                            .Width("15")
                            .Format("{0:MM/dd/yyyy hh:mm tt}")
                            .Title("Posting Date/Time");
    and here's what's rendering:
    /Date(1361913899000)/

    The entire object List was sent to the browser by the following code:
    public ActionResult FetchBatchList2([Kendo.Mvc.UI.DataSourceRequest]DataSourceRequest request)
    {
        DateTime aDate = new DateTime(0001, 1, 1);
        ROAMHostSvc.Notification messages1 = null;
         
        ROAMHostSvc.ROAMHostSvcClient hostSvc = null;
        KUI_CS_Test1.ROAMHostSvc.BatchHeader[] batchArr;
     
        try
        {
            // call the WCF service for the List of BatchHeader objects
            hostSvc = new ROAMHostSvc.ROAMHostSvcClient();
            batchArr = hostSvc.GetBatchCollection(ref messages1, false, aDate, aDate, false, aDate, aDate);
     
            // assign the result to the DataSourceResult object and return that as Json
            var result = new DataSourceResult()
            {
                Data = batchArr,
                Total = batchArr.Length
            };
            return Json(result);
        }
        catch (Exception ex)
        {
            return null;
        }
        finally
        {
            Close_WCF_Service(ref hostSvc);
        }
    }
    How can I properly format the detail grid dates as needed?  It's not an issue on the master grid.

    Thanks!




  14. Daniel
    Admin
    Daniel avatar
    2219 posts

    Posted 04 Mar 2013 Link to this post

    Hello Richard,

    The dataSource will parse the dates only when they are loaded through its transport. When using the data method, you should parse the dates with custom code before using the method e.g.

    function detailInit(e) {
        var grid = $("#Transactions_" + e.data.BatchID).data("kendoGrid");
        var detailData = e.data.TranCollection;
        for (var i = 0; i < detailData.length; i++) {
            detailData[i].Posting_DTTM = kendo.parseDate(detailData[i].Posting_DTTM);
        }
        grid.dataSource.data(detailData);
    }
    Regards,
    Daniel
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Back to Top