EnyoJS Tutorial #11 – 3rd Party Combo!

This is by far the most enjoyable tutorial I’ve wrote. Today we are going to create a special kind of control, a filterable repeater/list!

For today’s tutorial we will be combining, taffyDB, a kickass third party js. To be exact, we are going make a reusable component, that look like the picture below.

First off, let’s figure out on how to get taffydb loaded into enyojs. I suggest placing all third party library into thirdparty folder within lib. Do remember to change the reference link to specifically target the js file, like this below. We are going to use TaffyDB awesome filtering ability to help simplify our control creation.

1
2
3
4
5
6
7
8
9
10
enyo.depends(
	"$lib/layout",
	"$lib/onyx",
	"$lib/thirdparty/taffy-min.js",
	"../assets/css/app.css",
	"common",
	"Footer.js",
	"Header.js",
	"App.js"
);

This custom control we are creating is divided into two main components

1. SearchInput – nothing but, a simple input decorator and text input which bubble it’s value to the parent.
2. SearchableList – listens to the searchInput and filter content accordingly using TAFFY’s kickass filter function.

SearchInput

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
enyo.kind({
    name: "SearchInput",
    kind: "Control",
    layoutKind: "FittableColumnsLayout",
    components: [
        {
        	kind:"onyx.InputDecorator",
        	name: "inputTextDecorator",
        	fit:true,
        	style:"background:#fff",
        	components:[
        		{
        			kind:"onyx.Input",
        			name:"txtInput",
        			oninput:"inputChanged",
                                onchange:"valueChanged"
        		}
        	]
        }
    ],
    published:{
       placeholder:""		
    },
    create:function() {
    	this.inherited(arguments);
    	this.placeholderChanged();
    },
    placeholderChanged:function() {
    	this.$.txtInput.setAttribute("placeholder",this.placeholder);
    },
    inputChanged:function(inSender,inEvent) {
    	//on Type bubble out an event to the parent.
    	this.bubble("onSearchInput",{value:this.$.txtInput.getValue()});
    }
});

SearchableList

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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
enyo.kind({
    name: "SearchableList",
    kind: "FittableRows",
    fit:true,
    components: [
    	{
    		name:"txtSearchInput",
    		kind:"SearchInput",
    		classes:"padding10px",
    		placeholder:"Search Filter...",
    		onSearchInput:"handleSearchInput"
    	},
        {
    		name: "list", 
    		kind: "List", 
    		fit:true, 
    		count:0, 
    		touch:true, 
    		onSetupItem: "setupItem", 
    		components: [
    			{
    				name: "listItemContainer", 
    				ontap:'listItemTapped', 
    				classes:"listItemContainer",
    				components: [
					{
						name: "item",
						classes:"padding10px",
						content:"Insert Title..."
					}
    				]
    			}
    		]
    	}
    ],
    published:{
        data:null,
        filteredTaffyDB:null,
        resultFilteredArray:null,
        searchInput:""		
    },
    create: function() {
        this.inherited(arguments);
        //Standard routine check if data is null.
        if(this.data != null){
        	this.dataChanged();
        }
    },
    dataChanged:function(){
    	// When setData is called or contructor itself having data, 
    	// then dataChanged will fire.
    	// Meaning there's data passing into this control.
 
        // instead of usual List.setCount(this.data.length);
        // We trigger a function called filterList() which uses
        // Taffy to preprocess / filter our data.
        if (this.data != null){
            this.filteredTaffyDB = TAFFY(this.data);
            // Convert this.data into a fully TAFFYDB object.
            this.filterList();
        }
    },
    filterList:function(){
        // filterList task
        // 1. reset all List.
        // 2. perform a TaffyDB likenocase query based on this.searchInput (by default is "")
        // 3. place resulFilteredArray result length to empower the list.
        // 4. list.refresh ensure all item are rerender should any changes happen again.
        this.$.list.reset();    
 
 
        //likenocase is a TAFFY syntax that filters without any case sensitivity.
        //get is a method to return an array of result.
        console.log( this.filteredTaffyDB({name:{likenocase:this.searchInput}}).get() );
        this.resultFilteredArray = this.filteredTaffyDB({name:{likenocase:this.searchInput}}).get();
        this.$.list.setCount(this.resultFilteredArray.length);
        this.$.list.refresh();
 
 
        // With this resultFilteredArray's length trigger the List to populate.
        // Using the setCount method which trigger (this.data.length) amount 
        // of setupItem.
    },
    setupItem:function(inSender,inEvent) {
        //console.log(this.resultFilteredArray[inEvent.index]);
        this.$.item.setContent(this.resultFilteredArray[inEvent.index].name);
        //console.log(inEvent);
    },
    handleSearchInput:function(inSender,inEvent) {
    	// Capture Input from search's bubble.
        this.searchInput = inEvent.value;
        this.filterList();
    },
    listItemTapped:function(inSender,inEvent) {
        console.log("index : "+inEvent.index+" is clicked");
    }
});

App.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
enyo.kind({
	name: "App",
	kind: "FittableRows", 
	classes: "enyo-fit enyo-unselectable contentBg",
	components: [
           { kind:"Header" },
           {   
              kind:"SearchableList",
              // insert hardcoded data during component form. Same as setData in scripting form. 
              data:[
                  {name:"Apple"},
                  {name:"Banana"},
                  {name:"Kiwi"},
                  {name:"Orange"},
                  {name:"Grapes"},
                  {name:"Watermelon"},
                  {name:"Pineapple"},
                  {name:"Plum"},
                  {name:"Jackfruit"}
              ]
          },
          { kind:"Footer" }
        ],
        create: function(){
           this.inherited(arguments);
	} 
});

Like the usual, today’s Combo Jutsu tutorial file…

EnyoJS Tutorial 11 (708 downloads)

 

Comments

comments