Making a Mobile MVC Music Store Part 6: Making a WP7 Application Bar

Today I want to show you how to build a Windows Phone 7 Application Bar for your mobile web sites. If you have not done any native Windows Phone 7 developer one of the standard features is the ability to build a toolbar containing up to 4 icons and a list of menu options. Nancy Strickland has a great series introducing native Windows Phone 7 development. You can learn how to program an Application Bar in one of the videos.

I have been particularly interested in the application bar as a way to build mobile web navigation for a while now. There are four features I want to include in my web version; must reside at the bottom of the screen, display up to four icons horizontally, include an ellipses link to expand the bar to display links and of course optionally include a hidden links section.

Part 1 Creating a Common Service Layer
Part 2 Creating the Core Mobile Layout
Part 3 Creating the Controllers and Views
Part 4 Creating the Home Page
Part 5 Designing the Genre and Album Pages
Part 6 The Shopping Cart

Fixed Positioning

Accomplishing this in a desktop web browser is actually pretty easy. Applying a position:fixed CSS rule to an element will do the trick. In the following rule fixed positioning, a z-index above the page and setting the bottom position to 0px places the element firmly at the bottom of the browser now matter where the user vertically scrolls.

footer

.appBar


{

position

:

fixed;


left

: 0;

display

:

inline;


height

:

35;


line-height

:

35;


width

:

100%;


z-index:

100;


bottom

:

0px;


}

Unfortunately fixed positioning does not work the same in mobile browsers as it does on the desktop. In the desktop the position is based on the actually viewable area in the browser with the bottom left corner being 0,0. In mobile browsers this does not apply. Instead they apply fixed positioning relative to the page itself. So if you position an element using bottom: 0px it will stay fixed at the bottom of the page's content. In most cases this means it will only be visible when the user scrolls all the way to the bottom of the page. You can read the small section toward the end of the PDF the IE Mobile team produced explaining this in IE 7 mobile.

Using jQuery to Position the AppBar

Obviously that is not an acceptable user experience. Instead of using a simple CSS rule you now need to rely on AJAX to solve the problem by continually recalculating the actual viewable page's bottom.

But wait, it gets more complicated. Beyond doing math on a mobile screen I found hooking into the scroll event to be spotty at best. This is due to the touch nature of smartphones. At this point I have only tested my solution on the Windows Phone 7, which sadly does not support touch events at this time. This makes it even more difficult because you have to hook into fake mouse events that may ore may not fire.

In Internet Explorer 7 mobile when a user touches the screen if the entire event sequence is actually fired you see MouseMove, MouseDown and MouseUp events fired, in that order. Sadly I found this sequence to be inconsistent and typically does not fire at all when a user swipes up or down to scroll the page.

When a user 'scrolls' the scroll event does not fire until the scroll action is completed. To my knowledge in desktop browsers as the user moves the scroll bar or moves the cursor down the page's content the scroll event fires. If you think about it in the context of a mobile touch device browser this sort of makes sense. To the browser the user is not actually scrolling, but panning around a document. So firing a scroll event as the user holds and moves the page is not quite accurate. When the user swipes the page it scrolls like a slot machine and eventually stops. There is one actual user action taking place there and the event fires when the momentum has completed.

So here I had to accept a compromise with my AppBar. My initial thoughts were to simply hide the AppBar when a touch is initiated and show it again after the touch action is complete. This is what jQuery Mobile has chosen to do with their toolbars component. I was actually relieved to see this is the strategy they chose after I spent time experimenting with this issue. One thing I did notice in the latest release, they chose not to enable the fixed toolbars in Internet Explorer Mobile 7. I think this is because the faux touch events are extremely unreliable in the current release of Internet Explorer Mobile 7. My expectation is IE9 mobile will fully support real touch events, but we will have to wait till August/September to find out for sure. Maybe I will find out next week at MIX!

AppBar Markup

The Windows Phone 7 AppBar component has several features I wanted to replicate in my web solutions. First the AppBar displays a row of clickable simple icons. These icons can open new pages invoke on page invoke actions like reloading a list of places in Foursquare, etc.

In HTML this is simply a horizontal list of image hyperlinks. I chose to use the AppBar as the primary music store site navigation tool so each of the icons will open new pages. The last icon will open the desktop site, which is a good mobile architecture best practice. The last link is used to expand the AppBar to reveal additional links. You could also capture each of these click events to perform some AJAX, like reloading a list in foursquare. So honestly there is not much to limit their usage. They are after all just hyperlinks.

If you examine the markup I used the HTML5 FOOTER tag as the main element. Inside the footer I used a series of unordered lists to organize the contents. There is one list item for the icon bar and another item for the collapsed links. The icon list is styled to be horizontal, while the hidden links create a vertical list. This is all handled using CSS.

<

footer

class

="appBar"

id

="appBar"

>


<

nav

>


<

ul

class

="vertical"

>


<

li

>


<

ul

class

="horizontal"

>


<

li

>


<

a

href

="@Url.Content("

~/

")"

>


<

img

src

="@Url.Content("

~/

img

/

home

.

png

")"

alt

="Home"


width

="32"

height

="32"

/></

a

></

li

>


<

li

>


<

a

href

="@Url.Content("

~/

Store

/

")"

>


<

img

src

="@Url.Content("

~/

img

/

headphone

.

png

")"


alt

="Categories"

width

="32"

height

="32"

/></

a

></

li

>


<

li

>


<

a

href

="@Url.Content("

~/

Shoppingcart

/

")"

>


<

img

src

="@Url.Content("

~/

img

/

container

.

png

")"


alt

="Shopping Cart"

width

="32"

height

="32"

/></

a

></

li

>


<

li

>


<

a

href

="http://mvcmusic.extremewebworks.com/"

>


<

img

src

="@Url.Content("

~/

img

/

computer

.

png

")"


alt

="Desktop Site"

width

="32"

height

="32"

/></

a

></

li

>


<

li

><

a

href

="#"

class

="expand-appbar"

>

...

</

a

></

li

>


</

ul

>


</

li

>


<

li

>


<

ul

class

="vertical appbar-links"

>


<

li

><

a

href

="@Url.Content("

~/

Store

/

Browse

?

genre

=

Metal

")"

>

Metal

</

a

></

li

>


<

li

><

a

href

="@Url.Content("

~/

Store

/

Browse

?

genre

=

Jazz

")"

>

Jazz

</

a

></

li

>


<

li

><

a

href

="@Url.Content("

~/

Store

/

Browse

?

genre

=

Rock

")"

>

Rock

</

a

></

li

>


</

ul

>


</

li

>


</

ul

>


</

nav

>


</

footer

>


The initial AppBar state displays the icon list, but hides the link lists. The ''' link on the AppBar's right is used to expand the list into view.

I am not going to go into details with the AppBar CSS rules. You can review them for yourself.

ul

.vertical


{

width

:

100%;


padding

: 0;

margin

:

5 0 25 0;


}

ul

.vertical

>

li


{

list-style

-type:

none;


list-style

-image:

none;


line-height

:

2.0em;


margin

-

top

:

4px;


margin

-

bottom

:

4px;


width

:

100%;


float

:

left;


}

footer

.appBar


{

position

:

fixed;


left

: 0;

display

:

inline;


height

:

35;


line-height

:

35;


width

:

100%;


z-index:

100;


/* bottom: 0px; */


}

/*


footer.appBar


{


display: none;


}


*/



footer

.appBar

ul

.horizontal

>

li

a
{

font-size

:

1.5em;


}

ul

.appbar-links


{

display

:

none;


padding

-

bottom

:

10px;


}

ul

.appbar-links

li


{

line-height

:

1.6em;


}

nav

ul

li

ul

.appbar-links

li

a
{

font-size

:

1.5em;


line-height

:

1.75em;


width

:

100%;


text-align

:

left;


}

When the AppBar is expanded the list of hidden links is revealed. This is done by intercepting the link's click event and using the jQuery sildeToggle method to show and hide it as needed. I made the sliding a little smoother by using the jQuery 'swing' easing method. This makes it look more natural than just popping into view.

The JavaScript to show and hide the AppBar links.

$(

".expand-appbar"

).click(

function

(e) {
e.preventDefault();
$(

".appbar-links"

).slideToggle(600,

'swing'

);
e.stopPropagation();
});

Differentiating Between Desktop and Mobile

This is pretty cool to have working on a mobile platform, but I felt this functionality could be pretty useful on the desktop. Remember fixed positioning works nicely on the desktop so invoking all the JavaScript to calculate positioning. So I found a quick and dirty jQuery extension to detect browser platform, version, etc at http://detectmobilebrowser.com/.

So I am using that extension to determine if the user is mobile and if they are using IE. I then check the version and perform the calculation based on the version. In the course of evaluating how to solve the positioning problem I determined in portrait mode on Windows Phone 7 you actually have 431 pixels of viewable area in the browser. When the phone is in landscape mode you have 288 pixels. Part of the reason you do not get the entire screen is the built in Internet Explorer AppBar taking up real estate.

if

($.browser.mobile && $.browser.msie) {

if

($.browser.version ==

"7.0"

) {

var

offset = (w.width() === 320) ? 431 : 288;

var

bottom = $(document).height() - offset - w.scrollTop();
$(

"#appBar"

).css(

"bottom"

, bottom +

"px"

);
}

else

if

($.browser.version ==

"9.0"

) {
$(

"#appBar"

).css(

"bottom"

, 355 - w.scrollTop());
}
}

else

{
$(

"#appBar"

).css(

"bottom"

,

"0px"

).show();
}

After calculating this vertical offset the bottom viewable pixel value is calculated by subtracting the offset and how far the user has scrolled from the document's height. The w variable is $(window) and not shown in the code snippet above. You can read more about jQuery dimension helpers if you don't know what is being returned in the above code.

At this point I have not tested my code on a Droid or iPhone. I hope to try it out on those platforms soon. I suspect there will be some other quirks to work through on those platforms too.

If the user is not mobile I use the code to set the bottom CSS value for the AppBar and the CSS rules take over from there to keep the bar positioned at the bottom of the page.

Conclusion

While the rest of this project may not have been over the top earth shattering I hope this step has you thinking. Honestly I want you to start realizing that just because you are repeatedly told you cant create rich mobile user experience in the browser you won't believe the hype. You can create great mobile web experiences. Sure at this point you have some limitations, but that is because the phone OS vendors have chosen not to implement all the W3c device specs (more on that another day). But the vast majority of native mobile application features can be easily be accomplished in the browser with less headaches.

Remember web is available on all the platforms. You have instant deployment and you control your own destiny for marketing. Plus you do NOT have to share your revenues with the search engines if you don't want to.

At this point this solution is not 100% complete. I want to turn this into a jQuery plugin and make it support Droids, iPhone and create a viable alternative for older browsers on non-smartphones. Feel free to visit the mobile music store on your phone or desktop for that matter, http://m.mvcmusic.extremewebworks.com.

Visit the Mobile Music Store

Part 1 Creating a Common Service Layer
Part 2 Creating the Core Mobile Layout
Part 3 Creating the Controllers and Views
Part 4 Creating the Home Page
Part 5 Designing the Genre and Album Pages
Part 6 The Shopping Cart

Next week I have another series planned creating another mobile web presence that implements another WP7 native control. If you want to see it in action I will be giving a presentation tomorrow at the Philly Code Camp at 2:30 EST. I am planning on streaming my session live via Live Meeting and you are welcome to join. I think you will be blown away with what I am going to do!

Share This Article With Your Friends!