Quantcast
Channel: Joseph Crawford » JavaScript
Viewing all articles
Browse latest Browse all 5

Mojo Lists: Cookie Data Source (Part 2)

$
0
0

In Part 1 of this tutorial we created the base for our application. It consisted of a static list that was displayed when the application was launched.

At the end of Part 1 you were able to build the application and tap on any of the items which would push another scene. In Part 2 of this tutorial we are going to focus on using a cookie as a data source for our list. We will build a list that will display a list based on a cookie’s contents.

When you tap on a list item you will be taken to another scene where you will be able to change the title for the list item and it will be retained in a cookie. I did find an issue with cookies on the emulator and device. There is a known bug that cookies will retain on the emulator and device even after the application is removed. To learn more about this issue and cookies I suggest you read the Working with Cookies tutorial.

We will be continuing with the code that we created in Part 1 so open that application up. We will first be creating a model object that we will use to interact with the Mojo cookie stuff. In your application create the folder /app/lib/ and then create a new file named WBCookie.js and put it in your newly created lib folder. Now you will also have to update your sources.json so that Mojo will know where to find this file. Be sure that your sources.json file looks like the code below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[
    { “source”: “app/lib/WBCookie.js},
    {“source”: “app/assistants/stage-assistant.js},
    {
        “source”: “app/assistants/main-assistant.js,
        “scenes”: “main”
    },
    {
        “source”: “app/assistants/cookie-assistant.js,
        “scenes”: “cookie”
    },
    {
        “source”: “app/assistants/depot-assistant.js,
        “scenes”: “depot”
    },
    {
        “source”: “app/assistants/sqlite-assistant.js,
        “scenes”: “sqlite”
    }
]

Now that we have told Mojo where our model file is going to be it’s time to start working with our model. Open your WBCookie.js file and make it look like the 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
function WBCookie()
{
    this.initialContents = [
        {
            title: “Default 1},
        {
            title: “Default 2},
        {
            title: “Default 3}
    ];
 
    this.listContents = {};
    this.cookie = null;
}
 
WBCookie.prototype.initialize = function()
{
    this.cookie = new Mojo.Model.Cookie(‘wb_cookie_list_demo’);
    this.storedListItems = this.cookie.get();
    this.listContents = this.initialContents;
 
    if(this.storedListItems)
    {
        this.listContents = this.storedListItems;
    }
 
    this.storeCookie();
};
 
WBCookie.prototype.setListContents = function( listContents )
{
    this.listContents = listContents;
    this.storeCookie();
};
 
WBCookie.prototype.getListContents = function()
{
    return this.listContents;
};
 
WBCookie.prototype.storeCookie = function()
{
    this.cookie.put(this.listContents);
};

The code above will take a bit of explaining however it works in much the same way as an assistant object. When the object is created the WBCookie() function is called and we setup a few properties. We first set the initial contents of what our list will contain. This is so that we have something to load up the first time before the cookie is even written. We then declare the listContents as an empty object and set this.cookie to null. Once the object is created we will call the initialize method. This is where quite a bit of the magic happens. The first thing it does is create a new cookie model and set it to this.cookie. The next line of code grabs the contents of the cookie model and stores that in the storedListItems property. Notice that we did not define this property in the constructor, it is due to the if statement called next which checks to see if it is defined. The storeCookie method is where we actually save the data back into the cookie.

Now that we have the model out of the way we are going to work in the cookie assistant to actually setup the list. Make your cookie assistant look like the 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
function CookieAssistant() {
    this.listModel = {};
    this.cookie = null;
}
 
CookieAssistant.prototype.setup = function() {
    this.cookie = new WBCookie();
    this.cookie.initialize();
 
    this.listModel = {
    items: this.cookie.getListContents()
    };
 
    this.controller.setupWidget(“cookieListWgt”,
        {
            itemTemplate: “cookie/cookieRowTemplate”,
            listTemplate: “cookie/cookieListTemplate”,
            swipeToDelete: false,
            renderLimit: 40,
            reorderable: false
        },
    this.listModel
    );
    this.cookieListHandler = this.loadAlterValueScene.bindAsEventListener(this);
    this.controller.listen(this.controller.get(“cookieListWgt”), Mojo.Event.listTap, this.cookieListHandler);
};
 
CookieAssistant.prototype.loadAlterValueScene = function(event)
{
    Mojo.Controller.stageController.pushScene( ‘altercookie’, event.index );
};
 
CookieAssistant.prototype.activate = function(event) {
 
};
 
 
CookieAssistant.prototype.deactivate = function(event) {
 
};
 
CookieAssistant.prototype.cleanup = function(event) {
    Mojo.Event.stopListening(this.controller.get(“cookieListWgt”), Mojo.Event.listTap, this.cookieListHandler);
};

The code for our Cookie Assistant is pretty straight forward. In-fact much of this code is the same as in our Main Assistant. In the constructor we set the listModel property to be an empty object and we set this.cookie to be null; When the setup method is called it instantiates our cookie model object and stores it in this.cookie. It then goes on to call the initialize method on our cookie model and then setup the list for use. Most of the rest of the code is the same as our Main Assistant, there is one thing I want to mention though and that is in our callback method. When you click on an item in our Cookie List it calls the loadAlterValueScene method which pushes the new scene. You will notice here that we are pushing scenes rather than swapping to another scene. I want to take a minute to explain the difference between swapping and pushing a scene. You can think of the scenes as a stack of cards. Every time you push a scene you are placing another card on top. You can remove the top card to get at the previous card. This is exactly what is happening when you use the swipe back gesture. If you swap scenes you are essentially swapping cards. When you swipe back you go to the previous card. However it is not the scene before the swap because that scene is replaced. It is the scene that was below the scene that you swapped with. In this pushScene call we are passing an extra parameter, this will just be passed through to the scene so that it can be used when we make the alteration to our cookie. Before we move on we actually have to create the view file and if you recall since we are using a list we will also have to create the template files for our list named cookieRowTemplate and cookieListTemplate. Go ahead and create these two files now. Once you have them created make them look like the following.

1
2
<!– cookieListTemplate.phtml –>
<div class=“palm-list”>#{-listElements}</div>
1
2
3
4
5
6
<!– cookieRowTemplate –>
<div class=“palm-row” x-mojo-touch-feedback=“delayed”>
    <div class=“palm-row-wrapper”>
        <div id=“itemTitle” class=“title truncating-text”>#{title}</div>
    </div>
</div>

I am not going to explain these files again as I have already gone over them in past tutorials. Once these are in place it is time to make our cookie-scene.html file look like the code below.

1
2
3
4
5
<!– cookie-scene.html –>
<div id=“feedTitle” class=“palm-header center”> Cookie List</div>
  <div class=“palm-header-spacer”></div> <div id=“mainScene” class=“mainScene”>
  <div x-mojo-element=“List” id=“cookieListWgt”></div>
</div>

If you were to save all of your files and run this application on the emulator everything will work fine. You will see the main list load up and display your options of Cookie, Depot or SqLite. Currently the only one that will do anything when clicked on is the Cookie item. When you click on this it pushes you to another scene which shows a list and is populated with our cookie. If you recall when we first load this up we get the default list items which we defined in the WBCookie object. However when you tap on an item in our cookie list we have begun setting the stage for an another scene to be pushed. The idea is that when you are on viewing the cookie list you should be able to tap on any item and be taken to the altercookie view which will have a textbox and a button. When you alter the text in the textbox and tap the button the value should be saved to our cookie and then we should be passed back to the cookie scene where we will be able to see the changes made.

With the cookie assistant all working the way we want it to it’s time to create the final scene for this part of the tutorial. We are going to create a scene named altercookie which will actually change the data in our cookie. Once you have the scene created you need to make the altercookie-scene file look like the code below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id=“main” class=“palm-hasheader”>
    <div class=“palm-header left” id=“list-header”>
        Cookie: Alter Value
    </div>
</div>
 
<div class=“palm-group”>
    <div class=“palm-list”>
        <div class=“palm-row single”>
            <div class=“palm-row-wrapper textfield-group” x-mojo-focus-highlight=“true”>
                <div class=“title”>
                    <div id=“textField” name=“textField”  x-mojo-element=“TextField”></div>
        </div>
            </div>
        </div>
    </div>
</div>
 
<div id=“save_button” name=“save_button” x-mojo-element=“Button”>Save</div>

In the code above we are not doing anything too extreme. You will see that the scene has a header which uses some palm style classes. We also have a palm-group which is a way to group multiple elements together. The final element on the scene is a button. Now we just need to wire these up in our altercookie assistant and make them work together. Make your altercookie-assistant.js file look like the 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
function AltercookieAssistant( index ) {
    this.itemIndex = index;
}
 
AltercookieAssistant.prototype.setup = function() {
    this.cookie = new WBCookie();
    this.cookie.initialize();
    this.listContents = this.cookie.getListContents();
 
    /* set up our text field */
    var txtFieldAttributes = {
        hintText:,
        modelProperty:  ‘original’,
        autoFocus: true
    };
 
    this.txtFieldModel = {
        ‘original’ : this.listContents[this.itemIndex].title,
        disabled: false
    };
 
    // Setup our Add Value Button and Event Handler
    this.saveBtnAttributes = {};
 
    this.saveBtnModel = {
        buttonLabel : ‘Save’,
        buttonClass : ‘affirmative’,
        disabled : false
    };
 
    this.controller.setupWidget(“save_button”, this.saveBtnAttributes, this.saveBtnModel);
 
    this.controller.setupWidget(‘textField’, txtFieldAttributes, this.txtFieldModel);
 
    this.saveHandler = this.save.bindAsEventListener(this);
    Mojo.Event.listen(this.controller.get(‘save_button’), Mojo.Event.tap, this.saveHandler);
 
};
 
 
AltercookieAssistant.prototype.save = function(){
    // change the item and then store the cookie again
    this.listContents[this.itemIndex].title = this.txtFieldModel.original;
    this.cookie.setListContents( this.listContents );
    this.cookie.storeCookie();
 
    // swap back to the cookie scene
    Mojo.Controller.stageController.swapScene( ‘cookie’ );
};
 
AltercookieAssistant.prototype.activate = function(event) {
 
};
 
 
AltercookieAssistant.prototype.deactivate = function(event) {
 
};
 
AltercookieAssistant.prototype.cleanup = function(event) {
    Mojo.Event.stopListening(this.controller.get(‘save_button’), Mojo.Event.tap, this.saveHandler);
};

In the AltercookieAssistant code we are doing pretty much the same stuff we have been doing all along in this tutorial. The part that is different is that rather than using a list we have used two other Mojo Widgets. The button and the text field widgets are setup just like a lot of Mojo Widgets are. You provide them with an attributes object and a model object and then call the setupWidget method to get them setup. In the code above we have the constructor which is something new for us. Remember when we made the swapScene call in our Cookie Assistant for the altercookie scene? We passed in that extra parameter.

The parameter was the index number of the item we wanted to alter and that was passed into the constructor and then stored in the this.itemIndex property. So whenever you need to pass some extra parameters to a scene you do so just like we did here. In the setup method we first instantiate and initialize the cookie model that we created earlier in this tutorial and then we get the contents of the list from the cookie and store it in the this.listContents property. Next we continue on to setup the attributes for our text field, the most interesting part about the model is the model property which is set to original. This tells the text field attributes that it should keep updated based on the model property. You will see in our txtFieldModel we have an original property is being set. It might look a bit complex to you but it really is not. All it is doing is taking our list contents, fetching the proper index and grabbing the title property from that indexed element. As you recall we passed in the item index, it was solely for this purpose.

After we setup the text field and button we bind the button listener to the save method and when that is called that’s where the magic happens. The first thing it does is take the value from the text field and store it in our listContents under the same index so that we change the value. It calls the setListContents method of our Model, calls the storeCookie method to save it and then swaps the scene back to the cookie scene. If you build and deploy your application to the emulator or device it should work just as we expect it to. It should load the default list where you can tap on Cookie. It should then show the list from our stored cookie. Keep in mind that on the first run the values will be the Default 1, Default 2, Default 3 that we set in the WBCookie model. If you tap on any of these items you should be taken to the altercookie scene where you can change the value. Once you hit the save button you should be taken back to the cookie list. At this point if you execute the swipe back gesture you should be taken to the main list.

This concludes Part 2 of the series. In Part 3 we are going to take a look at our code and do some restructuring. In Part 4 we will look at using the Depot as a storage mechanism for our lists. If you have any questions or if I have failed to explain something clearly enough for you please feel free to ask for help in the comments.


Viewing all articles
Browse latest Browse all 5

Trending Articles