EnyoJS Tutorial #3 – All Kinds of Stuff

Today tutorial will make use of the previous tutorial files. Make sure you learn and grab em before, proceeding.

We will cover more on the followings for today.

  1. How to create a reusable template like kind you can include into every page.
  2. How to broadcast a custom event.
  3. How to bubble a single custom event to it’s parent control.

In previous tutorial, we stopped here. See code below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
enyo.kind({
	name: "App",
	kind: "FittableRows", 
	classes: "enyo-fit enyo-unselectable",
	components: [
         {
             kind: "onyx.Toolbar",
             layoutKind:"FittableColumnsLayout",
              components: [
              {
                  kind:onyx.Button,
                  style:"width:80px;background:green;",
                  ontap:"handleBtnBack", 
                  content:"Back"
              },
              {
                  content:"Header",
                  style:"text-align:center;",
                  fit:true
              },
              {
                  kind:onyx.Button,
                  style:"width:80px;background:red;",
                  ontap:"handleBtnNext",
                  content:"Next"
              }
          ]
      },
      {
          kind: "Scroller", 
          horizontal:"hidden", 
          touch:true,
          fit:true,
          thumb:true, 
          components:[
             {
                  tag:"h1",
                  content:"This is content area...Hello World!!!"
              }
          ]              
      },
      {
            kind: "onyx.Toolbar",
            // The footer
            layoutKind:"FittableColumnsLayout",
            components:[
                {
                      kind:"onyx.Button",
                      content:"Go Next Page",
                      ontap:"handleBtnNextPage",
                      fit:true   
                }
            ]
      }
	],
	create: function(){
		this.inherited(arguments);
		console.log("App is created in memory");
	},
	rendered : function(){
		this.inherited(arguments);
		console.log("App is created in rendered into DOM");
	},
        handleBtnNextPage : function(inSender,inEvent){
            new Page2().renderInto(document.body);
        },
        handleBtnNext: function(inSender,inEvent){
            new Page2().renderInto(document.body);
        },
        handleBtnBack: function(inSender,inEvent){
            alert("Back Button");
        }
});

Header and footer, are one of the most repetitive controls you will use in entire project. So, make sure you group them up in a control kind and load them as a “Kind”. Here let me show you how. Copy, line 6 to 28 of the code above. Create another file in source called “Header.js”. A basic enyo control looked like the code below. Now you need to transport your codes into the components.

1
2
3
4
5
6
7
8
9
enyo.kind({
    name: "Header",
    kind: "Control",
    components: [
        {
          //You codes here.
        }
    ]
});

The code should look like this. Remove extra brackets if necessary. Save it as Header.js into source folder. To use this kind, don’t forget to add, Header.js into package.js within the source folder.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
enyo.kind({
    name: "Header",
    // Make sure the name matches the file name.
    kind: "Control",
    components: [
        {
             kind: "onyx.Toolbar",
             layoutKind:"FittableColumnsLayout",
              components: [
              {
                  kind:onyx.Button,
                  style:"width:80px;background:green;",
                  ontap:"handleBtnBack", 
                  content:"Back"
              },
              {
                  content:"Header",
                  style:"text-align:center;",
                  fit:true
              },
              {
                  kind:onyx.Button,
                  style:"width:80px;background:red;",
                  ontap:"handleBtnNext",
                  content:"Next"
              }
          ]
        }
    ]
});

We modify, the codes of the App.js to include the control as a Kind.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
enyo.kind({
	name: "App",
	kind: "FittableRows", 
	classes: "enyo-fit enyo-unselectable",
	components: [
         {
             kind: "Header",
             // In just one line? you kidding? o.O
         },
         {
             kind: "Scroller", 
             horizontal:"hidden", 
             touch:true,
             fit:true,
             thumb:true, 
             components:[
                {
                  tag:"h1",
                  content:"This is content area...Hello World!!!"
                }
             ]              
         },
         {
            kind: "onyx.Toolbar",
            // The footer
            layoutKind:"FittableColumnsLayout",
            components:[
                {
                      kind:"onyx.Button",
                      content:"Go Next Page",
                      ontap:"handleBtnNextPage",
                      fit:true   
                }
            ]
        }
	],
	create: function(){
		this.inherited(arguments);
		console.log("App is created in memory");
	},
	rendered : function(){
		this.inherited(arguments);
		console.log("App is created in rendered into DOM");
	},
        handleBtnNextPage : function(inSender,inEvent){
            new Page2().renderInto(document.body);
        },
        handleBtnNext: function(inSender,inEvent){
            new Page2().renderInto(document.body);
        },
        handleBtnBack: function(inSender,inEvent){
            alert("Back Button");
        }
});

Fun isn’t it, now your code is more manageable. Let’s do the footer now. Now select and copy line 23 – 35. Create a control called Footer.js. Do the same routine again. Your footer code should look like below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
enyo.kind({
    name: "Footer",
    kind: "Control",
    components: [
        {
            kind: "onyx.Toolbar",
            // The footer
            layoutKind:"FittableColumnsLayout",
            components:[
                {
                      kind:"onyx.Button",
                      content:"Go Next Page",
                      ontap:"handleBtnNextPage",
                      fit:true   
                }
            ]
        }
    ]
});

Now, lets reduced even more codes in App.js. See below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
enyo.kind({
	name: "App",
	kind: "FittableRows", 
	classes: "enyo-fit enyo-unselectable",
	components: [
         {
             kind: "Header",
             // In just one line? you kidding? o.O
         },
         {
             kind: "Scroller", 
             horizontal:"hidden", 
             touch:true,
             fit:true,
             thumb:true, 
             components:[
                {
                  tag:"h1",
                  content:"This is content area...Hello World!!!"
                }
             ]              
         },
         {
            kind: "Footer"
         }
	],
	create: function(){
		this.inherited(arguments);
		console.log("App is created in memory");
	},
	rendered : function(){
		this.inherited(arguments);
		console.log("App is created in rendered into DOM");
	},
        handleBtnNextPage : function(inSender,inEvent){
            new Page2().renderInto(document.body);
        },
        handleBtnNext: function(inSender,inEvent){
            new Page2().renderInto(document.body);
        },
        handleBtnBack: function(inSender,inEvent){
            alert("Back Button");
        }
});

Noticed that the button event no longer work? Why? This is because, every kind control in enyo will have their own event “encapsulated” into their own. Meaning methods like handleBtnNext and handleBtnBack will work “within” Header.js, you can try copy handleBtnNext and handleBtnBack into Header.js. Let’s try.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
enyo.kind({
    name: "Header",
    // Make sure the name matches the file name.
    kind: "Control",
    components: [
        {
             kind: "onyx.Toolbar",
             layoutKind:"FittableColumnsLayout",
              components: [
              {
                  kind:onyx.Button,
                  style:"width:80px;background:green;",
                  ontap:"handleBtnBack", 
                  content:"Back"
              },
              {
                  content:"Header",
                  style:"text-align:center;",
                  fit:true
              },
              {
                  kind:onyx.Button,
                  style:"width:80px;background:red;",
                  ontap:"handleBtnNext",
                  content:"Next"
              }
          ]
        }
    ],
    create:function(){
       this.inherited(arguments);
       // Noticed even you can override create and rendered. Because, they exist in every enyo.kind
    },
    handleBtnNext: function(inSender,inEvent){
         new Page2().renderInto(document.body);
    },
    handleBtnBack: function(inSender,inEvent){
         alert("Back Button");
    }
});

You can try moving the method handleBtnNextPage into Footer too. The next question you will ask is,

How to bubble the event, to parent control e.g. From Header.js to App.js

Two ways, of doing this…

  1. One we use a simple event bubble (only works between control to it’s parent).
  2. The 2nd way is to broadcast a global event.

To do this exercise, I’m going to modify the Header.js (this will include how to bubble an event to the parent) and Footer.js’s button will broadcast a global event. See code below for Header.js.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
enyo.kind({
    name: "Header",
    // Make sure the name matches the file name.
    kind: "Control",
    components: [
        {
             kind: "onyx.Toolbar",
             layoutKind:"FittableColumnsLayout",
              components: [
              {
                  kind:onyx.Button,
                  style:"width:80px;background:green;",
                  ontap:"handleBtnBack", 
                  content:"Back"
              },
              {
                  content:"Header",
                  style:"text-align:center;",
                  fit:true
              },
              {
                  kind:onyx.Button,
                  style:"width:80px;background:red;",
                  ontap:"handleBtnNext",
                  content:"Next"
              }
          ]
        }
    ],
    create:function(){
       this.inherited(arguments);
       // Noticed even you can override create and rendered. Because, they exist in every enyo.kind
    },
    handleBtnNext: function(inSender,inEvent){
        // It's a good practice to also send the inSender back to the parent as identification. 
        // Parent control can know which control is sending.
        this.bubble("onBtnNextTap",inSender);
    },
    handleBtnBack: function(inSender,inEvent){
        // It's a good practice to also send the inSender back to the parent. Alternatively you
        // can send with only one parameter which is the "custom event name".
        this.bubble("onBtnBackTap",inSender);
    }
});

For Footer.js the syntax differs because, we are broadcasting a global event. Global event are great if you are doing certain task which requires time. A good example of using this will be getting stuff from server-side. While doing so, the loader screen appears and starts spinning, waiting for another global event to fire when the task is complete. Anyway, in this tutorial the footer is just an example on how to broadcast the signal for custom event.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
enyo.kind({
    name: "Footer",
    kind: "Control",
    components: [
        {
            kind: "onyx.Toolbar",
            // The footer
            layoutKind:"FittableColumnsLayout",
            components:[
                {
                      kind:"onyx.Button",
                      content:"Go Next Page",
                      ontap:"handleBtnNextPage",
                      fit:true   
                }
            ]
        }
    ],
    handleBtnNextPage:function(inSender,inEvent) {
      //Broadcast a global signal using enyo.Signal.
      enyo.Signals.send("onHandleBtnNextPageTap");
    }
});

Next, let’s attached listeners for our bubbles and a global “listener” for our global signal. See the reference code below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
enyo.kind({
	name: "App",
	kind: "FittableRows", 
	classes: "enyo-fit enyo-unselectable",
	components: [
		  // Notice a global event doesn't depend on "parent control", 
                  // it can be anywhere as long it's loaded in the same page.
                  { 
                     kind:"Signals", 
                     onHandleBtnNextPageTap:"handleBtnNextPageSignal"
                  },
                  {
                      kind:"Header",
                      // Here is how we bind event listener to capture, bubbles.
                      onBtnNextTap:"handleBtnNextBubble",
                      onBtnBackTap:"handleBtnBackBubble"
                  },
                  {
                      kind: "Scroller", 
                      horizontal:"hidden", 
                      touch:true,
                      fit:true,
                      thumb:true, 
                      components:[
                           {
                              tag:"h1",
                              classes:"padding15px",
                              content:"This is content area...Hello World!!!"
                          }
                     ]              
                 },
                 {
                     kind:"Footer"
                 }
	],
	create: function(){
		this.inherited(arguments);
		console.log("App is created in memory");
	},
	rendered : function(){
		this.inherited(arguments);
		console.log("App is created in rendered into DOM");
	},
        handleBtnNextPageSignal : function(inSender,inEvent){
                alert("Global Event Triggered");
                new Page2().renderInto(document.body);
        },
        handleBtnNextBubble: function(inSender,inEvent){
                new Page2().renderInto(document.body);
        },
        handleBtnBackBubble: function(inSender,inEvent){
               alert("Back Button");
        }
});

Well, this is it, you now have all the necessary knowledge to make generic “kind” controls and handling all kinds of events in EnyoJS. If you think this is cool begining, you aint see nothing yet. There’s many many more possibilities to combo with enyoJS. Next tutorial, will be slightly casual, we move on to handling dynamic content!

For today’s tutorial reference file.
Enyo Tutorial #3 (662 downloads)

 

Comments

comments

Leave a Reply

Your email address will not be published. Required fields are marked *