Part 5: Adding Command Menus & Services

Again, make a copy of the project you've already created. Just as a precaution, so you can go back to what you've done previously. You also should have completed part 1, part 2, part 3, and part 4 to do this tutorial.

In this tutorial, we'll add some Command Menus which open up other applications on the Pre/Pixi. In this specific case, we'll open up the Calculator app as well as the E-mail app. We'll even pass some data to the E-mail message.

To do this, open up your project folder that we've been working with throughout these tutorials. Now, let's modify first-assistant.js so it looks like the following: (Bold text is new)

function FirstAssistant() {
/* this is the creator function for your scene assistant object. It will be passed all the
additional parameters (after the scene name) that were passed to pushScene. The reference
to the scene controller (this.controller) has not be established yet, so any initialization
that needs the scene controller should be done in the setup function below. */


}

FirstAssistant.prototype.handleButtonPress = function(event){
// set a variable to the value of the textbox
this.amount=Number(this.amountModel.value); //This also converts the text to a number

// increment the total and update the display
this.total = this.total + this.amount;
this.controller.get('count').update(this.total);
}

FirstAssistant.prototype.handleA = function(event){
// set a variable to the value of the textbox
this.amount=Number(this.amountModel.value); //This also converts the text to a number

// subtract the total and update the display
this.total = this.total - this.amount;
this.controller.get('count').update(this.total);
}

FirstAssistant.prototype.handleC = function(event){

// clear the total and update the display

this.total=0;
this.controller.get('count').update(this.total);
}

FirstAssistant.prototype.handleCommand = function(event) {
if(event.type == Mojo.Event.command) {
switch(event.command)
{
case 'openCalculator':
this.controller.serviceRequest('palm://com.palm.applicationManager', {
method:'launch',
parameters: {
id: 'com.palm.app.calculator',
}
});
break;

case 'openEmail':
this.controller.serviceRequest('palm://com.palm.applicationManager', {
method:'launch',
parameters: {
id: 'com.palm.app.email',
params: {
summary: 'Add/Subtract Count',
text: 'The count is: ' + this.total,
}
}
});
break;
}
}
}


FirstAssistant.prototype.setup = function() {
/* this function is for setup tasks that have to happen when the scene is first created */
/* use Mojo.View.render to render view templates and add them to the scene, if needed. */
/* setup widgets here */
/* add event handlers to listen to events from widgets */

//Set up Command Menu
this.cmdMenuModel = {
visible: true,
items: [
{items:
[
 {label: $L('Email'), command:'openEmail'},
//The next lines you can uncomment to see the various default icons for Command Menus
// {label: $L(iconPath: "stop"), command:'openEmail'},
// {label: $L(iconPath: "forward"), command:'openEmail'},
// {label: $L(iconPath: "refresh"), command:'openEmail'},
// {label: $L(iconPath: "search"), command:'openEmail'},
// {label: $L(iconPath: "new"), command:'openEmail'},
// {label: $L(iconPath: "attach"), command:'openEmail'},
// {label: $L(iconPath: "compose"), command:'openEmail'},
// {label: $L(iconPath: "conversation"), command:'openEmail'},
// {label: $L(iconPath: "delete"), command:'openEmail'},
// {label: $L(iconPath: "file"), command:'openEmail'},
// {label: $L(iconPath: "forward-email"), command:'openEmail'},
// {label: $L(iconPath: "info"), command:'openEmail'},
// {label: $L(iconPath: "priority"), command:'openEmail'},
// {label: $L(iconPath: "reply-all"), command:'openEmail'},
// {label: $L(iconPath: "reply"), command:'openEmail'},
// {label: $L(iconPath: "save"), command:'openEmail'},
// {label: $L(iconPath: "send"), command:'openEmail'},
// {label: $L(iconPath: "sync"), command:'openEmail'},
// {label: $L(iconPath: "edit-profile"), command:'openEmail'},
// {label: $L(iconPath: "make-vip"), command:'openEmail'},
// {label: $L(iconPath: "new-contact"), command:'openEmail'},
// {label: $L(iconPath: "remove-vip"), command:'openEmail'},
// {label: $L(iconPath: "down"), command:'openEmail'},
]},
{},
{items:
[
{label: $L('Calculator'), command:'openCalculator'},
]}
],
};

this.controller.setupWidget(Mojo.Menu.commandMenu, undefined, this.cmdMenuModel);

// set the initial total and display it
this.total=0;
this.controller.get('count').update(this.total);

// Setup Application Menu
this.controller.setupWidget(Mojo.Menu.appMenu, AddSubMenuAttr, AddSubMenuModel);

//Setup Textfield to be numbers only
this.controller.setupWidget(
"mainTextField",
{//Attributes
maxLength: 1, //sets a maximum number of characters to 1
modifierState: Mojo.Widget.numLock, //Turns on the numLock for the text field
focusMode: Mojo.Widget.focusSelectMode, //If the text box is selected, all of the characters are highlighted
charsAllow: function( charCode ) {

return( ( charCode >= 48 && charCode <= 57) ); //uses ASCII codes to only allow 1 - 9
}
},
this.amountModel = {
value: ""
}
);

// a local object for button attributes
this.buttonAttributes = {};

// a local object for button model
this.buttonModel = {
buttonLabel : 'Add',
buttonClass : 'affirmative',
disabled : false
};

// set up the button
this.controller.setupWidget("MyButton", this.buttonAttributes, this.buttonModel);

this.controller.setupWidget("ButtonSubtract", this.buttonAttributes, this.Model = {buttonLabel : 'Subtract', buttonClass : 'negative', disabled : false});

this.controller.setupWidget("ButtonClear", this.buttonAttributes, this.Model = {buttonLabel : 'Clear', buttonClass : '', disabled : false});
// bind the button to its handler
Mojo.Event.listen(this.controller.get('MyButton'), Mojo.Event.tap, this.handleButtonPress.bind(this));

//Bind event handler for Subract button
Mojo.Event.listen(this.controller.get('ButtonSubtract'), Mojo.Event.tap,this.handleA.bind(this));

//Bind event handler for Clear button
Mojo.Event.listen(this.controller.get('ButtonClear'), Mojo.Event.tap,this.handleC.bind(this));

}

FirstAssistant.prototype.activate = function(event) {
/* put in event handlers here that should only be in effect when this scene is active. For
example, key handlers that are observing the document */
}


FirstAssistant.prototype.deactivate = function(event) {
/* remove any event handlers you added in activate and do any other cleanup that should happen before
this scene is popped or another scene is pushed on top */
}

FirstAssistant.prototype.cleanup = function(event) {
/* this function should do any cleanup needed before the scene is destroyed as
a result of being popped off the scene stack */
this.controller.stopListening(this.controller.get('MyButton'), Mojo.Event.tap, this.handleButtonPress.bind(this));
//Cleanup Subtraction button
this.controller.stopListening(this.controller.get('ButtonSubtract'),Mojo.Event.tap,this.handleA.bind(this));

//Cleanup Clear button
this.controller.stopListening(this.controller.get('ButtonClear'),Mojo.Event.tap,this.handleC.bind(this));
}

Let's examine what this code does:

If everything works, then you should see something similar to the following when you start the application: (If you don't see this, there may be issues with the syntax of your application. For example, having DOCTYPE misspelled in the index.htm file.)

Add/Subtract App

Even though the app really isn't all that useful, it is starting to look like a real WebOS app! More information about Command Menus can be found here. For more information about WebOS services, go here.

I hope this information was useful! If you have problems or still need help, I'd recommend asking in the following forums:

Back to Home | Download the v5 Source (.zip) | Download the v5 IPK


© 2010 Richard Neff