EnyoJS Tutorial #4 – Building A Simple List

Today’s tutorial focus more on building the most commonly used control in EnyoJS – The List! In this tutorial, we are going to cover on the follows…

  • Making a list based on some local datasource.
  • A little on control styling css.
  • How to make use of default create event in enyo.
  • Controlling elements of the list based on the “this.$” hash.

To save time, let’s start with this template of App.js. I’ve prepared, you may download the whole set of file at the end of this article as usual.

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
enyo.kind({
    name: "App",
    kind: "FittableRows", 
    classes: "enyo-fit enyo-unselectable",
    components: [
      { kind:"Header" },
      {   
          name: "appList", 
          kind: "List", 
          fit:true, 
          count:0, 
          touch:true, 
          onSetupItem: "setupItem", 
          components: [
              {
                  name: "listItem", 
                  classes:'listItemContainer', 
                  ontap:'listItemTapped', 
                  components: [
                      {
                        name: "itemTitle",  
                        content:"Set Title..."
                      }
                  ]
              }
          ]
      },
      { 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");
    }
});

Before we proceed further there’s a few key pointers you should know about enyo’s List.

  • List has it’s own scroller, you DONT need to include scroller. If you do, the list will scroll to white infinitely.
  • onSetupItem will trigger automatically, in a sequence, when “count” properties is more than 1
  • Number of setupItem trigger depending on the count number. We normally setCount to the list by passing the recordset length coming from your datasource.
  • List must always be set to fit:true, unless you specifically want it to be some exact fixed height.

In this tutorial, we are going to add a dummy datasource of records as sample data. I’ve given the list control a name to interact with called “appList”.

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
enyo.kind({
    name: "App",
    kind: "FittableRows", 
    classes: "enyo-fit enyo-unselectable",
    components: [
      { kind:"Header" },
      {   
          name: "appList", 
          kind: "List", 
          fit:true, 
          count:0, 
          touch:true, 
          onSetupItem: "setupItem", 
          components: [
              {
                  name: "listItem", 
                  classes:'listItemContainer', 
                  ontap:'listItemTapped', 
                  components: [
                      {
                        name: "itemTitle",  
                        content:"Set Title..."
                      }
                  ]
              }
          ]
      },
      { kind:"Footer" }
    ],
    datasource:[
        { name:"Alex", age:"13" },
        { name:"Aric", age:"12" },
        { name:"Anthony", age:"12" },
        { name:"Alfonso", age:"11" },
        { name:"Boon", age:"11" },
        { name:"Catherine", age:"11" },
        { name:"Casidy", age:"13" },
        { name:"Cody", age:"13" },
        { name:"Chloe", age:"13" },
        { name:"Cindy", age:"12" },
        { name:"David", age:"12" },
        { name:"Daud", age:"11" },
        { name:"Eddie", age:"13" }
    ],
    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");
    }
});

In the code above I’ve added a sample datasource called datasource. To get the value for properties within same kind, just use this followed by the properties name. In our case, this.datasource. Next, let’s pass in the length of the this.datasource as our count to kick start the list population.

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
enyo.kind({
    name: "App",
    kind: "FittableRows", 
    classes: "enyo-fit enyo-unselectable",
    components: [
      { kind:"Header" },
      {   
          name: "appList", 
          kind: "List", 
          fit:true, 
          count:0, 
          touch:true, 
          onSetupItem: "setupItem", 
          components: [
              {
                  name: "listItem", 
                  classes:'listItemContainer', 
                  ontap:'listItemTapped', 
                  components: [
                      {
                        name: "itemTitle",  
                        content:"Set Title..."
                      }
                  ]
              }
          ]
      },
      { kind:"Footer" }
    ],
    datasource:[
        { name:"Alex", age:"13" },
        { name:"Aric", age:"12" },
        { name:"Anthony", age:"12" },
        { name:"Alfonso", age:"11" },
        { name:"Boon", age:"11" },
        { name:"Catherine", age:"11" },
        { name:"Casidy", age:"13" },
        { name:"Cody", age:"13" },
        { name:"Chloe", age:"13" },
        { name:"Cindy", age:"12" },
        { name:"David", age:"12" },
        { name:"Daud", age:"11" },
        { name:"Eddie", age:"13" }
    ],
    create: function(){
	this.inherited(arguments);
	this.$.appList.setCount(this.datasource.length);
        // using setCount will trigger the onSetupItem event about 13 times.
        // setupItem is where you populate the list.
    },
    setupItem:function(inSender,inEvent) {
       //During the iteration of setupItem, this event will create inEvent.index which is
       //assigned automatically. inEvent.index is very useful, to map array index of datasource later.
       console.log(inEvent); 
    }
});

This code should result in this view being generated. (See picture below). Enyo has prepared and render 13 instances of list items for us. Next we need to fill up the values of each list item.

To do that, we need to access the “itemTitle” control, using “hash”. 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
enyo.kind({
    name: "App",
    kind: "FittableRows", 
    classes: "enyo-fit enyo-unselectable",
    components: [
      { kind:"Header" },
      {   
          name: "appList", 
          kind: "List", 
          fit:true, 
          count:0, 
          touch:true, 
          onSetupItem: "setupItem", 
          components: [
              {
                  name: "listItem", 
                  classes:'listItemContainer', 
                  ontap:'listItemTapped', 
                  components: [
                      {
                        name: "itemTitle",  
                        content:"Set Title..."
                      }
                  ]
              }
          ]
      },
      { kind:"Footer" }
    ],
    datasource:[
        { name:"Alex", age:"13" },
        { name:"Aric", age:"12" },
        { name:"Anthony", age:"12" },
        { name:"Alfonso", age:"11" },
        { name:"Boon", age:"11" },
        { name:"Catherine", age:"11" },
        { name:"Casidy", age:"13" },
        { name:"Cody", age:"13" },
        { name:"Chloe", age:"13" },
        { name:"Cindy", age:"12" },
        { name:"David", age:"12" },
        { name:"Daud", age:"11" },
        { name:"Eddie", age:"13" }
    ],
    create: function(){
	this.inherited(arguments);
	this.$.appList.setCount(this.datasource.length);
        // using setCount will trigger the onSetupItem event about 13 times.
        // setupItem is where you populate the list.
    },
    setupItem:function(inSender,inEvent) {
       //During the iteration of setupItem, this event will create inEvent.index which is
       //assigned automatically. inEvent.index is very useful, to map array index of datasource later.
 
       //In enyo, this.variableName is the same as to var a variable. Only difference is they remained
       //within the closure.
       this.childName = this.datasource[inEvent.index].name; 
       this.$.itemTitle.setContent(this.childName);
    }
});

You might wonder, how does enyo knows which itemTitle to point to if there’s 13 of them. Well that’s because, the setupItem fire in a loop and in each loop, you basically point to a new instance of listItem, and you do your assigning of values from there on.

Completing the code above gives you result seen in the picture below.

Next, let’s do more. Let’s do a simple retrieval process based on inEvent.index, from that index we cross reference with the ones, on this.datasource to retrieve it. We will trigger the event using listItemTapped

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
enyo.kind({
    name: "App",
    kind: "FittableRows", 
    classes: "enyo-fit enyo-unselectable",
    components: [
      { kind:"Header" },
      {   
          name: "appList", 
          kind: "List", 
          fit:true, 
          count:0, 
          touch:true, 
          onSetupItem: "setupItem", 
          components: [
              {
                  name: "listItem", 
                  classes:'listItemContainer', 
                  ontap:'listItemTapped', 
                  components: [
                      {
                        name: "itemTitle",  
                        content:"Set Title..."
                      }
                  ]
              }
          ]
      },
      { kind:"Footer" }
    ],
    datasource:[
        { name:"Alex", age:"13" },
        { name:"Aric", age:"12" },
        { name:"Anthony", age:"12" },
        { name:"Alfonso", age:"11" },
        { name:"Boon", age:"11" },
        { name:"Catherine", age:"11" },
        { name:"Casidy", age:"13" },
        { name:"Cody", age:"13" },
        { name:"Chloe", age:"13" },
        { name:"Cindy", age:"12" },
        { name:"David", age:"12" },
        { name:"Daud", age:"11" },
        { name:"Eddie", age:"13" }
    ],
    create: function(){
	this.inherited(arguments);
	this.$.appList.setCount(this.datasource.length);
        // using setCount will trigger the onSetupItem event about 13 times.
        // setupItem is where you populate the list.
    },
    setupItem:function(inSender,inEvent) {
       //During the iteration of setupItem, this event will create inEvent.index which is
       //assigned automatically. inEvent.index is very useful, to map array index of datasource later.
 
       //In enyo, this.variableName is the same as to var a variable. Only difference is they remained
       //within the closure.
       this.childName = this.datasource[inEvent.index].name; 
       this.childAge = this.datasource[inEvent.index].age;
       // Yup, as simple as assigning properties.
       this.$.itemTitle.age = this.childAge; 
       this.$.itemTitle.setContent(this.childName);
    },
    listItemTapped:function(inSender,inEvent){
       //Best practice you should always refer your index with the ones in memory.
       //Reason being, list can be highly dynamic and some can be sorted and filtered search.
       //Always try to referred the index with the ones in the memory.
      alert("Age of "+this.datasource[inEvent.index].name+" is "+this.datasource[inEvent.index].age);
    }
});

That’s it for today’s simple list tutorial. Hope this is fruitful to you and as usual, for today tutorial…

EnyoJS Tutorial 4 (645 downloads)

 

Comments

comments

Leave a Reply

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