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

Initialization of two kendo widgets in different pages

10 Answers 204 Views
SPA
This is a migrated thread and some comments may be shown as answers.
Andre
Top achievements
Rank 1
Andre asked on 14 Apr 2013, 07:08 PM
I'm trying to set up two pages: 1 with a listview and another with a grid. The problem is that the grid isn't being initialized and isn't shown...

Important parts of the code: 
<div id="app" class="contentPages">
    <button data-bind="click: gotopage1">Page 1</button>
    <button data-bind="click: gotopage2">Page 2</button>
</div>
 
<script id="page1" type="text/x-kendo-template">
    <ul id="listView1" data-bind="source: photossource"></ul>
</script>
 
<script id="page2" type="text/x-kendo-template">
    <div id="grid">
    </div>
</script>
 
<script id="layout" type="text/x-kendo-template">
    <header>Header</header><section id=content></section>
</script>
<script type="text/x-kendo-template" id="templatelistitem">
    <div class="item">
        <img data-bind="attr: { src: src }" />
        <p data-bind="text: description" style="text-align: center"></p>
    </div>
</script>
<script>
var
set1 = new Array();
 
   for (var i = 0; i <= 71; i++) {
       //fill set1
   }
 
   var appViewModel = new kendo.observable({
       gotopage1: function () {
           router.navigate("/");
       },
       gotopage2: function () {
           router.navigate("/page2");
       }
   });
   kendo.bind($("#app"), appViewModel);
 
   var pageViewModel = new kendo.observable({
       photossource: set1
   });
 
   var page1 = new kendo.View("#page1", { model: pageViewModel });
   var page2 = new kendo.View("#page2", { model: pageViewModel });
 
   var layout = new kendo.Layout("#layout");
 
   var router = new kendo.Router();
 
   router.route("/", function () {
       layout.showIn("#content", page1);
   });
 
   router.route("/page2", function () {
       layout.showIn("#content", page2);
   });
 
   $(function () {
       router.start();
       layout.render($("#app"));
       layout.showIn("#content", page1);
   });
 
   kendo.bind($("#listView1"), pageViewModel);
 
   var listview1, grid;
 
   $(document).ready(function () {
       listview1 = $("#listView1").kendoListView({
           template: kendo.template($("#templatelistitem").html()),
           change: onChange,
           selectable: true
       }).data("kendoListView");
       grid = $("#grid").kendoGrid({
           columns: [
               {
                   field: "FirstName",
                   title: "First Name"
               },
               {
                   field: "LastName",
                   title: "Last Name"
               }],
           dataSource: {
               data: [
                   {
                       FirstName: "Joe",
                       LastName: "Smith"
                   },
                   {
                       FirstName: "Jane",
                       LastName: "Smith"
                   }]
           }
       });
 
   });
</script>
With the debugger I can see that the listview and the grid have different types after running the ready() method (see attachment).

Why this happen?

10 Answers, 1 is accepted

Sort by
0
mgs
Top achievements
Rank 1
answered on 15 Apr 2013, 06:27 AM
Hello Andre,
quick feedback, just having looked at the source. The different types are to be expected.
  • The "listview1" variables is created by executing the "data" method. So it contains the Kendo widget.
  • The "grid" variable is just created from a jQuery selector. So it does not contain a Kendo Widget.
Michael G. Schneider
0
Andre
Top achievements
Rank 1
answered on 15 Apr 2013, 08:52 AM
Thanks for your help!

But when I add the data() method to the grid (.data("kendoGrid")) nothing changes... And if I remove the that method from the listview, the listview is initializing...
So I think the problem is not that. I think it could be something related with the render or showIn methods for page2...

Another suggestion?
0
mgs
Top achievements
Rank 1
answered on 15 Apr 2013, 09:15 AM
Hello Andre,

I did not have the time to really setup a sample from your code. Some short notes...
  • A jsFiddle might help.
  • The sentence "The problem is..." from your first post seems to be incomplete. I do not yet know, which one does not show. The grid or the listview?
  • Does it work, if you leave out the SPA code? Just a simple html page with a listview and a grid?
Michael G. Schneider
0
Petyo
Telerik team
answered on 15 Apr 2013, 09:18 AM
Hi Andre,

You have stumbled upon one of the biggest differences (and common sources of confusion) between the SPA pattern compared to the 'normal' web page scripting - the usage of the document.ready (or the $(function() {} shorthand).

By the time you try to initiate the grid in the document ready event handler, the second view is not yet instantiated and rendered. The #grid element is not present in the DOM yet.  

The correct event handler to instantiate the grid in would be the respective view init event handler.

You may also consider instantiating and configurating the widgets using data attributes

All the best,
Petyo
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Andre
Top achievements
Rank 1
answered on 15 Apr 2013, 10:48 AM
Right now I can't set up a jsFiddle, but I will try to do it later...
The problem is in the Grid that isn't being shown (I already edited the question).
Without the SPA code it works fine.
0
Andre
Top achievements
Rank 1
answered on 15 Apr 2013, 11:00 AM
Probably I'm a little bit confused with those 2 patterns...
With the init event handler for the two pages, like this:
var page1 = new kendo.View("#page1", {
        model: pageViewModel,
        init: function () {
            listview1 = $("#listView1").kendoListView({
                template: kendo.template($("#templatelistitem").html()),
                change: onChange,
                selectable: true
            }).data("kendoListView");
        }
    });
    var page2 = new kendo.View("#page2", {
        model: pageViewModel,
        init: function () {
            grid = $("#grid").kendoGrid({
                    columns: [
                        {
                            field: "FirstName",
                            title: "First Name"
                        },
                        {
                            field: "LastName",
                            title: "Last Name"
                        }],
                    dataSource: {
                        data: [
                            {
                                FirstName: "Joe",
                                LastName: "Smith"
                            },
                            {
                                FirstName: "Jane",
                                LastName: "Smith"
                            }]
                    }
                }).data("kendoGrid");
        }
    });
Either the listview and the grid aren't being initialized... I can see that the 2 init event are executed (first the init of page one and when I go to page 2 the init of page 2 )... This should follow some specific order? (setup router and after setup the pages, reverse order, another, etc....)

With the Data Attribute Initialization it seems to work, but I would like to know the two ways if possible...
0
Accepted
Petyo
Telerik team
answered on 17 Apr 2013, 06:38 AM
Hello Andre,

Can you try accessing the grid element through the view.element - something like this:

grid = page2.element.find("#grid").kendoGrid({


Greetings,
Petyo
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Andre
Top achievements
Rank 1
answered on 17 Apr 2013, 08:46 AM
Thanks! this solved the problem.
var listview1, grid;
 
    var page1 = new kendo.View("#page1", {
        model: pageViewModel,
        init: function () {
            listview1 = page1.element.find("#listView1").kendoListView({
                template: kendo.template($("#templatelistitem").html()),
                change: onChange,
                selectable: true
            }).data("kendoListView");
        }
    });
    var page2 = new kendo.View("#page2", {
        model: pageViewModel,
        init: function () {
            grid = page2.element.find("#grid").kendoGrid({
                columns: [
                    {
                        field: "FirstName",
                        title: "First Name"
                    },
                    {
                        field: "LastName",
                        title: "Last Name"
                    }],
                dataSource: {
                    data: [
                        {
                            FirstName: "Joe",
                            LastName: "Smith"
                        },
                        {
                            FirstName: "Jane",
                            LastName: "Smith"
                        }]
                }
            }).data("kendoGrid");
        }
    });
But I don't understand why a regular jQuery selector doesn't work... Can you explain?
0
Henri
Top achievements
Rank 1
answered on 01 Apr 2014, 12:43 PM
I also would like to know why the jquery selector does not work
0
Petyo
Telerik team
answered on 01 Apr 2014, 03:54 PM
Hello Henri,

The jQuery selector does not work because the element is not yet available in the document (but yet it is instantiated). 

Regards,
Petyo
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
Tags
SPA
Asked by
Andre
Top achievements
Rank 1
Answers by
mgs
Top achievements
Rank 1
Andre
Top achievements
Rank 1
Petyo
Telerik team
Henri
Top achievements
Rank 1
Share this question
or