Sunday 23 December 2012

Mobile Quiz Pages

A few months ago, around the time of Dreamforce, I built a Force.com online quiz application.  One of the items on my todo list has been to provide a mechanism to take a quiz via a mobile device.  As I had some spare time in the run up to Christmas this weekend, I've built the first version of this.

I've taken a simplistic approach to this and simply created mobile versions of the various site pages using JQuery Mobile, using the techniques described in one of my earlier blog posts.

Signing up for a test using the latest version of the app at http://tests.bobbuzzard.org will include a QR code in the confirmation page and email, and also a direct link in the email, as shown below:

 

Screen Shot 2012 12 23 at 16 26 49

scanning the QR code takes you to the mobile start page:

Screen Shot 2012 12 23 at 16 31 49

Navigation is much the same as the full site, with the slight change that the buttons appear at the top of the page.  The question pages have the same functionality as the full sight, allowing percentage confidence and notes/feedback to be provided:

Screen Shot 2012 12 23 at 16 32 43  Screen Shot 2012 12 23 at 16 33 28

The View All page displays a list of the actual answers selected, rather than the a,b,c question indices.  The percentage confidence and lack of answers are flagged as before:

Screen Shot 2012 12 23 at 16 33 59Screen Shot 2012 12 23 at 16 40 10

and clicking on any of the list entries takes you back to the question, with the percentage confidence header:

Screen Shot 2012 12 23 at 16 34 11

As I mentioned earlier, this is a simplistic solution.  Its quite slow, as the view state is being transferred backwards and forwards to the server, and the JQuery Mobile transitions can't be used as the mobile browser is being redirected between pages rather than using Ajax.  Javascript Remoting is a better solution for the server side interaction than using Visualforce forms, in my opinion, but that's a topic for another post.

Happy Christmas to all my readers - hope you find the mobile pages useful and be sure to let me know if you hit any problems. 

Saturday 15 December 2012

Building a Templated Web Site with Force.com - Part 4

In Part 1 of this series, I looked at how to turn an HTML page into a Visualforce page in order to use it as a template for a Force.com site. Part 2 covered how to turn the page into a template and create a home page that used the template to provide the common content.  Part 3 explained how to expose the pages to the world via an unauthenticated Force.com site.

Thus far I've focused on a single page, but the site has a number of tabs that are supplied by default in the template - Blogs, Photos, About, Links and Contacts.  For the purposes of this blog post, I'm going to create two additional pages - About and Contacts.

As I already have a home page that uses the template, I've cloned this to create new visualforce pages named 'about' and 'contact'.  These contain minimal content.

The contact page:

Screen Shot 2012 12 15 at 11 53 30

and the about page:

Screen Shot 2012 12 15 at 11 53 44

Next I need to create a way to navigate to the pages.  While the tabs contain links, these are empty anchor tags, as can be seen from the template markup:

<div id="menu">
	<ul>
		<li class="current_page_item"><a href="#">Homepage</a></li>
		<li><a href="#">Blog</a></li>
		<li><a href="#">Photos</a></li>
		<li><a href="#">About</a></li>
		<li><a href="#">Links</a></li>
		<li><a href="#">Contact</a></li>
	</ul>
</div>

Changing the links to point to my Visualforce pages might seem as simple as replacing the '#' with the Visualforce page link.  Unfortunately, Force.com sites need the page to be specified as '/contact', while if the pages are accessed from the Salesforce UI it needs to be specified as '/apex/contact'.  For this reason, its best practice to use the $Page global variable - this will generate the appropriate link based on the user's context.  As I've created pages for the Homepage, About and Contact tabs, the new markup is:

<div id="menu">
	<ul>
		<li class="current_page_item"><a href="{!$Page.Home}">Homepage</a></li>
		<li><a href="#">Blog</a></li>
		<li><a href="#">Photos</a></li>
		<li><a href="{!$Page.about}">About</a></li>
		<li><a href="#">Links</a></li>
		<li><a href="{!$Page.Contact}">Contact</a></li>
	</ul>
</div>

The links now work correctly, but the Homepage tab is always the one highlighted due to the class="current_page_item" attribute. This markup exists in the template, so I need find a way to identify the actual page and set the attribute on the appropriate tab.  

I could write a Visualforce controller for the page, but I'm trying to avoid that at this point and build the site entirely in Visualforce.  I could also add some markup to determine the name of the current URL, and highlight the tab that matches.  The downside to that is if I change the purpose of a page, I have to update the template.  Ideally I'd like to define the tab that should be highlighted in the underlying page, and make the template responsible for the rendering only.

The way that I've handed this is to set the tab name into a variable using the <apex:variable/> component, and then conditionally render the class name based on this variable.

In the underlying pages, its simply another define component - here's the markup from the about page:

<apex:define name="tabdef">
	<apex:variable var="tab" value="about"/>
</apex:define>

there's a little more to do in the template page - I have to define an initial value for the 'tab' variable, otherwise I can't use it elsewhere in the page - I've defaulted to the Homepage tab - that way if I have pages that don't belong to a particular tab, the leftmost will be highlighted.  Then I have to include the value from the underlying page (if this isn't present the default will be used) and finally check the value of tab variable when rendering each tab element.

<div id="menu">
	<apex:variable var="tab" value="home" />
	<apex:insert name="tabdef" />
	<ul>
		<li class="{!IF(tab=='home', 'current_page_item', '')}"><a href="{!$Page.Home}">Homepage</a></li>
		<li><a href="#">Blog</a></li>
		<li><a href="#">Photos</a></li>
		<li class="{!IF(tab=='about', 'current_page_item', '')}"><a href="{!$Page.about}">About</a></li>
		<li><a href="#">Links</a></li>
		<li class="{!IF(tab=='contact', 'current_page_item', '')}"><a href="{!$Page.Contact}">Contact</a></li>
	</ul>
</div>

Looking at my contact page, now, the correct tab is highlighted:

Screen Shot 2012 12 15 at 12 30 49

All that remains is to add the new Visualforce pages to my Force.com site.  On the site setup page (Setup -> App Setup -> Develop -> Sites and click through the site label), select the Edit button on the Site Visualforce Pages section:

Screen Shot 2012 12 15 at 12 32 50

and then add the new pages via the dialog and click the 'Save' button:

Screen Shot 2012 12 15 at 12 36 49

Navigating to the about page via the site's custom URL, shows that all of my new functionality has been made available to the site:

 

Screen Shot 2012 12 15 at 12 38 05

The template, pages and static resources are available in the Part4 directory of the github repository for this blog series at:

https://github.com/keirbowden/blog_force_com_sites

This post is probably the final one in this series, unless another topic occurs to me or is suggested in the comments.