<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>WebOS Boston &#187; Cookie</title>
	<atom:link href="http://www.webosboston.org/tag/cookie/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.webosboston.org</link>
	<description>Developing for WebOS</description>
	<lastBuildDate>Fri, 13 Nov 2009 23:03:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Mojo Lists: Using a Cookie as a Data Source (Part 2)</title>
		<link>http://www.webosboston.org/2009/09/21/mojo-lists-using-a-cookie-as-a-data-source-part-2/</link>
		<comments>http://www.webosboston.org/2009/09/21/mojo-lists-using-a-cookie-as-a-data-source-part-2/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 23:36:21 +0000</pubDate>
		<dc:creator>Joseph Crawford</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Mojo]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Cookie]]></category>
		<category><![CDATA[Lists]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.webosboston.org/?p=173</guid>
		<description><![CDATA[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.  [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.webosboston.org/wp-content/uploads/2009/09/Screen-shot-2009-09-21-at-7.49.39-PM.png" alt="Mojo Lists Part 2" title="Mojo Lists Part 2" width="221" height="332" class="floatleft" />In <a href="http://www.webosboston.org/2009/09/13/mojo-lists-part-1/">Part 1</a> of this tutorial we created the base for our application.  It consisted of a static list that was displayed when the application was launched.  </p>
<p>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.  </p>
<p>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 <a href="http://www.webosboston.org/2009/08/28/working-with-cookies/">Working with Cookies</a> tutorial.</p>
<p>We will be continuing with the code that we created in <a href="http://www.webosboston.org/2009/09/13/mojo-lists-part-1/">Part 1</a> 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.</p>
<pre name="code" class="javascript">
[
    { "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"
    }
]
</pre>
<p><span id="more-173"></span><br />
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.</p>
<pre name="code" class="javascript">
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);
};
</pre>
<p>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.</p>
<p>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.</p>
<pre name="code" class="javascript">
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);
};
</pre>
<p>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 <strong><em>pushes</em></strong> 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.</p>
<pre name="code" class="html">
&lt;!-- cookieListTemplate.phtml --&gt;
&lt;div class=&quot;palm-list&quot;&gt;#{-listElements}&lt;/div&gt;
</pre>
<pre name="code" class="html">
&lt;!-- cookieRowTemplate --&gt;
&lt;div class=&quot;palm-row&quot; x-mojo-touch-feedback=&quot;delayed&quot;&gt;
    &lt;div class=&quot;palm-row-wrapper&quot;&gt;
        &lt;div id=&quot;itemTitle&quot; class=&quot;title truncating-text&quot;&gt;#{title}&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>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.</p>
<pre name="code" class="html">
&lt;!-- cookie-scene.html --&gt;
&lt;div id=&quot;feedTitle&quot; class=&quot;palm-header center&quot;&gt; Cookie List
&lt;/div&gt; &lt;div class=&quot;palm-header-spacer&quot;&gt;&lt;/div&gt; &lt;div id=&quot;mainScene&quot; class=&quot;mainScene&quot;&gt;
&lt;div x-mojo-element=&quot;List&quot; id=&quot;cookieListWgt&quot; &gt;&lt;/div&gt; &lt;/div&gt;
</pre>
<p>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.</p>
<p>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.</p>
<pre name="code" class="html">
&lt;div id=&quot;main&quot; class=&quot;palm-hasheader&quot;&gt;
    &lt;div class=&quot;palm-header left&quot; id=&quot;list-header&quot;&gt;
        Cookie: Alter Value
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;palm-group&quot;&gt;
    &lt;div class=&quot;palm-list&quot;&gt;
        &lt;div class=&quot;palm-row single&quot;&gt;
            &lt;div class=&quot;palm-row-wrapper textfield-group&quot; x-mojo-focus-highlight=&quot;true&quot;&gt;
                &lt;div class=&quot;title&quot;&gt;
                    &lt;div id=&quot;textField&quot; name=&quot;textField&quot;  x-mojo-element=&quot;TextField&quot;&gt;&lt;/div&gt;
		&lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;save_button&quot; name=&quot;save_button&quot; x-mojo-element=&quot;Button&quot;&gt;Save&lt;/div&gt;
</pre>
<p>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.</p>
<pre name="code" class="javascript">
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.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);
};
</pre>
<p>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.  </p>
<p>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.  </p>
<p>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.</p>
<p>This concludes Part 2 of the series.  In <a href="http://www.webosboston.org/2009/10/03/mojo-lists-restructuring-our-code-part-3/">Part 3</a> 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.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.webosboston.org/2009/09/21/mojo-lists-using-a-cookie-as-a-data-source-part-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Working with Cookies</title>
		<link>http://www.webosboston.org/2009/08/28/working-with-cookies/</link>
		<comments>http://www.webosboston.org/2009/08/28/working-with-cookies/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 12:48:30 +0000</pubDate>
		<dc:creator>Joseph Crawford</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Mojo]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Cookie]]></category>
		<category><![CDATA[Storage]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[WebOS]]></category>

		<guid isPermaLink="false">http://www.webosboston.org/?p=78</guid>
		<description><![CDATA[Over the last few days I have been working with the Cookie as a method for storage on the Palm Pre.  I looked in the WebOS Book and there was a nice cookie class that could be used.  This will not be a complete walk-through like the last tutorials have been.  This [...]]]></description>
			<content:encoded><![CDATA[<p>Over the last few days I have been working with the Cookie as a method for storage on the Palm Pre.  I looked in the WebOS Book and there was a nice cookie class that could be used.  This will not be a complete walk-through like the last tutorials have been.  This will show you how to create a cookie object and how to interact with it so that you can store your application preferences.  You can store any type of data you would like in a cookie.  It does not seem to be like the Depot where you can *only* store objects.</p>
<p>At the time of writing I have found an issue with using cookies so be sure to read the second to last paragraph.<br />
Below is the class that was taken from the WebOS Book which we will be using for our Cookie object.</p>
<p><span id="more-78"></span></p>
<pre name="code" class="javascript">
// Globals
WBPrefs = {};
WBPrefs.someOtherValue = false;
WBPrefs.versionString = "0.0.1";

function WBCookie()
{

}

WBCookie.prototype.initialize = function()
{
    this.cookie = new Mojo.Model.Cookie('cookie_name');
    this.oldPrefs = this.cookie.get();
    if(this.oldPrefs)
    {
        // If current version, just update globals &#038; prefs
        if(this.oldPrefs.versionString == WBPrefs.versionString)
        {
            WBPrefs.someOtherValue = this.oldPrefs.someOtherValue;
            WBPrefs.versionString = this.oldPrefs.versionString;
        }
        else
        {
            // migrate old preferences here on updates of FreshBooks App.
        }
    }

    this.storeCookie();
};

WBCookie.prototype.storeCookie = function()
{
    this.cookie.put(
        {
            someOtherValue: WBPrefs.someOtherValue,
            versionString: WBPrefs.versionString
        }
    );
};
</pre>
<p>This code is pretty straight forward.  It creates a WBCookie object which actually interacts with the Mojo.Model.Cookie object.  You can see the initialize command does a few things.  First it creates a new Mojo.Model.Cookie object with the name of your cookie and stores it in a property named this.cookie.  It creates another property called this.oldPrefs which will store the values that are pulled out of the cookie.  It is called oldPrefs because they are the values that were last used for the application.  It then makes sure that oldPrefs is a valid object.  Once it knows we have a valid result we can then compare the versionString stored in the cookie with our application cookie versionString.  This allows us to properly migrate preferences if we ever change the structure of the cookie.  It then calls the this.storeCookie method which saves the current application Preferences into the cookie.  When you are using this method the cookie is updated everytime you update one of the WBPrefs values.  I am not entirely sure what causes it to update with every preference change it must be some magic done by the framework.</p>
<p>Now that we have the cookie class we will need to create a scene assistant which will make use of the cookie.  We will very simply create a view with a text field and a button.  You will be able to change the value in the textbox and tap the button to update the cookie value.  We will start with the following code.</p>
<pre name="code" class="javascript">
function FirstuseAssistant() {

}

FirstAssistant.prototype.setup = function() {
    this.cookie = new WBCookie();
    this.cookie.initialize();

    WBPrefs.someOtherValue = "Joseph Crawford";
}

FirstAssistant.prototype.activate = function(event) {

}

FirstAssistant.prototype.deactivate = function(event) {
        this.cookie.storeCookie();
}

FirstAssistant.prototype.cleanup = function(event) {

}
</pre>
<p>In the assistant code above you can see that we simply update the value of WBPrefs.someOtherValue which updates the cookie.  Next time we run the application the value will have been retained for our use again.  This comes in very handy for detecting which scene you should show.  For instance if your application will require a user to login you can check the cookie for the username / password and if they do not exist then show the sign-in scene otherwise show your main scene.</p>
<p>I am not sure what is happening whether palm has a bug in their code or if it is just my setup however when testing this all out I noticed that my cookies are retained on the emulator.  I have deleted the application from the emulator by holding the option key while tapping and I have also used the Komodo Add-On.  However my cookie seems to be retained across application installs and it should not be.  According to Palm's Documentation the cookies and databases related to an application should be removed from the device when the application is removed.  I personally have not tried it on the device but others have confirmed they have had their cookies be retained on the device as well.  Until this issue is fixed I really do not see a real use for cookies.  The data should not be retained across application installs.  Have you ever had the issue of a cookie being retained like this?  The only way I have found to test to make sure it was all working is to add a this.cookie.remove() before we set the cookie.  This will make the app remove the cookie whenever it is launched.  Obviously that is not production worthy code because the application settings would be removed on every launch.  It did however show me that my cookie was being retained and that my other code was working properly.</p>
<p>The code above is not a full example it just illustrates how to use the cookie model in Mojo.  You will have to do some of your own coding using these methods in order to use it properly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.webosboston.org/2009/08/28/working-with-cookies/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.811 seconds -->
