Responsive Design: Real Talk

I had a really wonderful time listening to all of the fantastic minds at the 2013 HighEd Web West conference at the (beautiful) Chapman University.

If you’re interested in viewing my talk on responsive design, you can check out the slides, read through the additional notes and resources on the GitHub repository, and also peruse the slides from the other awesome talks.

Excited for next year!

Posted in Presentations | Tagged | Leave a comment

UCSB HTML5 Workshop

I recently hosted a hands-on workshop on HTML5 at UCSB, including a beginner session in the morning and a more advanced session in the afternoon.

The source code for the examples, the slides (built with reveal.js), and follow-up answers to questions unanswered during the presentation are available in the workshop’s Github repo.

Check out the presentation slides and recordings below!

Morning Session

Afternoon Session

Posted in Presentations | Tagged | Leave a comment

Community Financial Aid Shopping Sheet Template

Recently I’ve been working on an open-source template for the Financial Aid Shopping Sheet.

Background

Let me give you a little background:

On July 24, 2012, the Obama administration introduced the Shopping Sheet, a tool to help students better understand and compare the costs of attending college. U.S. Secretary of Education Duncan followed this announcement with an open letter urging all higher education institutions to adopt the new Shopping Sheet.

On September 28, 2012, the Department of Education provided a HTML template that could be used by instutitons to display the Shopping Sheet on their website.

Why Create a New Template?

Although the Department of Education already provides a viable HTML Shopping Sheet template, the Community Template builds and improves upon this template, including:

  • Separating CSS and HTML for better separation of concerns
  • Reducing the overall size of the HTML markup for improved performance and easier modifiability
  • Reducing the use of images for improved performance and increased control of content through markup and styling
  • Reducing the file size of the images for increased performance
  • Providing customization instructions for easier template customization
  • Adding a “Download XML” modal dialog for better integration of that feature within the interface

Furthermore, the repository itself also provides an open forum for people to suggest continued improvements to the template and also allows developers to further extend the template.

Please help me continue to improve the template!

Posted in Development | Tagged , , , , | Leave a comment

MWF ASP.NET Web Forms

In the 1.3 release of the UCLA Mobile Web Framework, the Forms API was introduced, providing an easy mechanism for styling forms for display on a mobile device.

The CSS rules for the Forms API, however, were attached directly to the form element. In other words, you can simply add a form element to your MWF page:

<form>
	<h1>Sign-up</h1>
	<label>
		<span>Username</span>
		<input type="text" name="username" />
	</label>
	<input class="primary" type="submit" value="Sign-up"/>
</form>

And the MWF Forms API will apply styling directly to this element. This is desired behavior in most cases. However, the ASP.NET Web Forms model, in an effort to simulate a stateful Windows Form, requires wrapping many Server Controls in a form element like so:

<form runat="server">
	<!-- Placing this button outside of the form element causes an exception -->
	<asp:Button runat="server" ID="btnAddItem" Text="Add Item" OnClick="OnClickAddItem" />
</form>

On top of this, the default Web Forms templates in Visual Studio encourage wrapping the entire page in an all-encompassing form element by dropping the following into the MasterPage:

<body>
	<form runat="server">
	<!-- Page Contents -->
	</form>
</body>

However, because the MWF CSS expects that only the traditional form elements will be within a form element on the page, the wrapping form element causes a number of styling errors.

This is a problem that is not likely to go away because it would require adding an API-breaking change to MWF to merely suit the needs of the (arguably misguided) ASP.NET Web Forms model.

Introducing MWF ASP.NET Web Forms

There are two main solutions to this problem:

  • Hack the CSS to fix any styling errors
  • Restructure your page to only use the form element when necessary

The good news here is that I’ve created a repository that covers both of these solutions. More specifically, the repository includes:

  • Override stylesheets to correct the styling errors
  • General guidelines for restructuring ASP.NET Web Forms pages

Instructions for installing and applying the styles are listed in the README. Let me know what you think!

Posted in Development | Tagged , , | Leave a comment

Respect the List

As part of my work, I help people rewrite the content for their website. When combing through the content of a website, I often come across content shoved into a list, like this:

To be eligible for the Franken scholarship, students must:

  • Be a U.S. citizen; Be eligible for federally-funded financial aid
  • Be enrolled full-time in a degree program. Full-time is a minimum of 12 units, determined fifteen days into the semester
    • If a student is enrolled in less than 12 units, the Franken scholarship must be billed back
    • If the scholarship is reduced, it can not be reinstated at a later date
  • Students must maintain a 2.0 cumulative GPA. Transfer students may have their initial eligibility based on units from their previous institution

What’s wrong with this? Lists are supposed to make content easy to read, right? But somehow this content isn’t easy to read at all, it’s a real pain.

But where did this list go wrong? When a reader encounters a list within a body of text, they expect the list to abide by certain rules. But when a list violates this implicit contract, it’s not a list, it’s just a series of staccato paragraphs surrounded by unnecessary margins and bullet images.

So what makes a good list? Let’s talk about it.

Keep Lists Short

In general, a writer includes a list to provide a quick summary of the major points of a topic. However, if the list includes a large number of items or the text within each item is too long, the list is no longer fulfilling its purpose. In other words, what’s the point of an outline if the outline is almost as long as the source content?

As a general rule, try to keep the number of items within a list to around five and keep the text in each list item on one line. Of course, I don’t have any research to back this up and there are exceptions to every rule, but we have to start somewhere.

Keep List Items Consistent

Let’s look at another example:

To make a sandwich, you’ll need:

  • 2 slices of bread
  • 1 leaf of lettuce
  • 1 Slice of Cheese. Cheddar is a nice, basic choice, but you should also try spicing things up with Pepper Jack!
  • Some tomato
  • Lunch meat (not necessary if you want a vegetarian sandwich)

It’s really difficult to grasp the overall structure and pattern of the list: it’s a jumble of choppy, discordant sentences. Within a list, each list item should have a similar format. This provides the list with a patterned flow that will make it easier to read and understand:

To make a sandwich, you’ll need:

  • 2 slices of bread
  • 1 leaf of lettuce
  • 1 slice of cheese
  • 2 slices of tomato
  • 1 piece of lunch meat (optional)

Now the list is much easier to read; the reader knows what to expect moving from one list item to another. You may scoff: but what about that whole cheese aside? You completely omitted it! Ask yourself: does someone skimming your list care about that? If it’s so important, put it in a later paragraph or maybe, after streamlining the list, you’ve realized the content wasn’t so important after all.

List Items Should Be Atomic

Each list item should focus on one thing. There’s no exception to this. This one thing could be anything—a book title, a programming tip, a color—but each list item should only contain one of these things.

Avoid Nested Lists

Of course there’s going to be exceptions to this rule, but avoid putting a list inside another list. This is like having two conversations at once. It’s confusing. Why not put that inner list into its own list and reference it from the outer list?

Fit Content to Lists

Finally, remember that the mere presence of a list does not make content easier to read and understand. If a particular piece of content won’t abide by the above rules, then rewrite the content. If you still can’t make the content work as a list, then maybe it shouldn’t be a list. Really, there’s nothing wrong with a series of concise paragraphs.

If readers were having a trouble parsing your website’s content, shoving black circles next to that same content won’t make it any easier. Respect the list.

Posted in Writing | 4 Comments

Unobtrusive Validation in ASP.NET 4.5

While listening to the 2011 BUILD presentations, I overheard one of the speakers talking about “unobtrusive validation” in ASP.NET 4.5 Web Forms. Well, I had to see this for myself.

Let me give you a little background: validation on the web is a tricky business. To ensure the integrity of data feeding into your web application, you definitely want to validate User input server-side, but to create a responsive experience for your User, you also want to validate the input values through client-side JavaScript. Thus, you end up writing duplicate validation code which can become a real maintenance headache.

ASP.NET Web Forms “solves” this dilemma, by allowing you to put a Validator Server Control on your page:

<asp:TextBox ID="Username" runat="server"></asp:TextBox>

<asp:RequiredFieldValidator
	ErrorMessage="Username is required!"
	ControlToValidate="Username"
	runat="server"></asp:RequiredFieldValidator>

<asp:RegularExpressionValidator
	ErrorMessage="Username can only contain letters!"
	ControlToValidate="Username"
	ValidationExpression="^[A-Za-z]+$"
	runat="server"></asp:RegularExpressionValidator>

These Validator Server Controls handle both the client-side and server-side validation for you. That’s right: you define the validation rules in one place, and everything is taken care of for you. Neat, right? The generated markup has some inline CSS, but it’s not terrible:

<input name="Username" type="text" id="Username" />

<span id="ctl02" style="color:Red;">Username is required!</span>

<span id="ctl03" style="color:Red;visibility:hidden;">Username can only contain letters</span>

Unfortunately, to make this all work, a mess of inline JavaScript is dumped onto your page:

<script type="text/javascript">
//<![CDATA[
var Page_Validators =  new Array(document.getElementById("ctl02"), document.getElementById("ctl03"));
//]]>
</script>

<script type="text/javascript">
//<![CDATA[
var ctl02 = document.all ? document.all["ctl02"] : document.getElementById("ctl02");
ctl02.controltovalidate = "Username";
ctl02.errormessage = "Username is required!";
ctl02.isvalid = "False";
ctl02.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid";
ctl02.initialvalue = "";
var ctl03 = document.all ? document.all["ctl03"] : document.getElementById("ctl03");
ctl03.controltovalidate = "Username";
ctl03.errormessage = "Username can only contain letters";
ctl03.evaluationfunction = "RegularExpressionValidatorEvaluateIsValid";
ctl03.validationexpression = "^[A-Za-z]+$";
//]]>
</script>

<script type="text/javascript">
//<![CDATA[

var Page_ValidationActive = false;
if (typeof(ValidatorOnLoad) == "function") {
	ValidatorOnLoad();
}

function ValidatorOnSubmit() {
	if (Page_ValidationActive) {
		return ValidatorCommonOnSubmit();
	}
	else {
		return true;
	}
}
//]]>
</script

Gross.

Keep in mind that this is in addition to a whole separate external script that includes all of the core validation logic. What’s even going on here? Let’s break it down:

  1. A Page_Validators array is created to contain all of the validator elements on the page
  2. Properties (like “errormessage” and “initialvalue”) are added to those same validator elements
  3. Validation is initialized (via ValidatorOnLoad)

So how does ASP.NET 4.5 clean things up? Instead of dumping inline JavaScript onto the page, ASP.NET 4.5 includes some new client-side scripting that piggybacks on the HTML5 custom data attributes. If you’re not familiar, with HTML5 you can add arbitrary descriptive attributes to an HTML element by prefixing these custom attributes with “data-”:

<span class="game" data-id="3" data-comment="Fun, but takes a long time">Monopoly</span>
<span class="game" data-id="4" data-comment="Nerve-wracking!">Jenga</span>

In this example we tack on “id” and “comment” attribute values to provide some additional data that we can use in our client-side scripting. ASP.NET 4.5 runs with that idea to implement a more “unobtrusive” approach to validation. Here’s the generated markup in ASP.NET 4.5:

<span
	data-val-controltovalidate="Username"
	data-val-errormessage="Username is required!"
	id="RequiredFieldValidator1"
	data-val="true"
	data-val-evaluationfunction="RequiredFieldValidatorEvaluateIsValid"
	data-val-initialvalue=""
	style="visibility:hidden;">Username is required!</span>

<span
	data-val-controltovalidate="Username"
	data-val-errormessage="Username can only contain letters!"
	id="RegularExpressionValidator1"
	data-val="true"
	data-val-evaluationfunction="RegularExpressionValidatorEvaluateIsValid"
	data-val-validationexpression="^[A-Za-z]+$"
	style="visibility:hidden;">Username can only contain letters!</span>

As you can see, all those properties (Step 2 from earlier) have now been flipped into HTML5 custom data attributes. And the best part: no inline JavaScript!

But where did all of that inline JavaScript go? Earlier I mentioned that all of that messy inline JavaScript was in addition to an external script containing the core validation script. The client-side scripting to create the Page_Validators array (Step 1 from before) and initialize the validation (Step 3) has been rolled up into that external script and wrapped within an anonymous function. Here’s the abridged code:

// If jQuery is available, create an anonymous function that executes immediately
if (window.jQuery) { (function ($) {

var dataValidationAttribute = "data-val"

function parse(selector) {
	// parseSpecificAttribute searches for elements with "data-val" set to "true"
	var length = parseSpecificAttribute(selector, dataValidationAttribute, Page_Validators);
	return length;
}

function loadValidators() {
	// Look at the similarities between this code and the inline code from earlier
	if (typeof (ValidatorOnLoad) === "function") {
		ValidatorOnLoad();
	}
	if (typeof (ValidatorOnSubmit) === "undefined") {
		window.ValidatorOnSubmit = function () {
			return Page_ValidationActive ? ValidatorCommonOnSubmit() : true;
		};
	}
}
		
$(function () {
	if (parse(document)) {
		loadValidators();
	}
});

} (jQuery)); }

Actually, believe it or not, it appears that this addition to the script has been sitting out there since ASP.NET 4.0 (look for yourself). I wonder if this feature was planned to be released at an earlier time? (Or is it a secret option nested deep somewhere?)

UPDATE: I was not aware that ASP.NET 4.5 is an in-place update to ASP.NET 4.0. This is likely the reason why I see the extra scripting in my ASP.NET 4.0 projects.

Either way, it’s definitely a step in the right direction for ASP.NET Web Forms, and I would love to see this trend continue.

Unfortunately, I have to be a jerk here and admit that I’m not completely satisfied: I would argue that most of the validation information shouldn’t be stored within the HTML at all. The validation error messages, for example, would be better stored in a separated JavaScript data structure. Right now, we’ve essentially replaced inline client-side script bloat with data attributes bloat.

Furthermore, it would be nice to see some integration with some of the HTML5 input validation attributes: HTML5 includes both a “pattern” attribute and a “required” attribute that perform the same function as the validators used in the examples above (in the browsers that support those attributes, of course).

Posted in Development | Tagged , , , , | Leave a comment

Developing a Web Application Locally with IIS7 and Web Developer Express

This post will guide you through developing a web application locally with IIS7 and Web Developer Express.

1. Install IIS7

Of course, the first thing we’ll need to do is install Internet Information Services (IIS). IIS will be the web server that hosts our web application.

2. Install Visual Web Developer 2010 Express

Next, we’ll install Visual Web Developer 2010 Express, the free integrated development environment (IDE) that we’ll use to build our web application.

3. Create the Web Application

Open up Visual Web Developer and select “File” > “New Project…”. For this tutorial, create a new project with the “ASP.NET Empty Web Application” template under “Visual C#” > “Web” (or “Visual Basic” > “Web”, if you prefer Visual Basic):

Creating a new web application project in Visual Studio

Let’s create a page so we have something to look at when we debug our web application. Go to “Project” > “Add New Item…”, choose “Web Form”, and name it “Default.aspx”:

Adding a Default.aspx to the project

Add a little text to the page (right between the body tags):

<body>
	<form id="form1" runat="server">
	<div>
		Welcome to my website!
	</div>
	</form>
</body>

If you want, you can actually stop at this point. Visual Web Developer contains a built-in server that you can use right away. Just click the green arrow at the top (or press “F5″) and your default web browser should pop open, displaying your new web application. However, often times you’ll want your local development environment to closely match the environment of your actual web application. In other words, if your web application will be hosted on Apache, you’ll want the local web application running on Apache (using something like WampServer). For our purposes, if our web application’s going to be running on IIS, we should host our local web application on IIS.

Before we move onto the next step, make sure you build your web application (go to “Debug” > “Build {Your Project’s Name}”).

4. Create a Local DNS Mapping

Let’s create a local DNS mapping so we can access our local web application through a friendly URL. Open up your hosts file (located in %systemroot%\system32\drivers\etc\) and add a line like the following:

127.0.0.1	example.local

This will redirect all requests to “example.local” back to our local IIS. I like to use “local” as the top-level domain for all of my local websites, but you can use whatever hostname you want here: “examplewebsite.com,” “mywebsite.local,” or “example.sandwich.”

5. Add a Website in IIS

Alright, we’re almost there, now let’s get our web application hosted! Open IIS Manager, right-click the “Sites” node in the left-hand menu and select “Add Web Site…”:

Adding a new website in IIS Manager

For simplicity, use the hostname you chose in Step 4 as your “Site name” and provide that value under the “Host name” field as well. Finally, in the “Physical path” field, provide the directory containing the “Default.aspx” file you created in Step 3:

Configuring the new website in IIS Manager

6. Test Your Web Application

Alright, now let’s test our handiwork. Pop open a browser and navigate to your web application (using the hostname you provided in Step 4). If everything’s working, you should see your Default.aspx page. Congratulations!

7. Debug Your Web Application

The real power of locally developing a web application in IIS comes with debugging your web application’s code right from Visual Studio. Head back into Visual Web Developer, open “Solution Explorer” (go to “View” > “Other Windows” > “Solution Explorer”), and open the “Default.aspx.cs” page (you may need to expand “Default.aspx” to find it):

The Solution Explorer in Visual Web Developer Express

Add the following code to the Page_Load method:

protected void Page_Load(object sender, EventArgs e)
{
	string rawUrl = Request.RawUrl;
}

Add a breakpoint (by clicking in the left sidebar alongside the code) on the closing brace of the Page_Load method:

Adding a breakpoint

Now go back into “Solution Explorer”, right-click the root node of your web application, and select “Properties”. This will open the settings screen for your web application. Select the “Web” tab on the left-hand menu and find the “Use Local IIS Web Server” option (under “Servers”). Select this option and provide your web application’s URL in the “Project URL” field:

Setting up debugging for local IIS

Now try pressing the green arrow at the top or F5 to start debugging. Your web browser should fly open and Visual Studio will display the “Default.aspx.cs” file, stopping at your breakpoint. Awesome, now you’ve got a web application running on your local IIS and you’re debugging that same web application right within Visual Web Developer Express!

Posted in Development | Tagged , , | Leave a comment

Create an Iframe Portal

To get a little practice with CSS3 keyframe animations, let’s do something a little strange: create an iframe portal like the portals in Portal. Check out the demo in either Firefox or Chrome (click anywhere to shoot a portal). Here’s a screenshot of the the end result:

Iframe Portal

To start, let’s make an iframe that looks like a portal. Here’s our markup:

<div class="portal-wrapper">
	<iframe src="" frameborder="0" scrolling="no" class="portal"></iframe>
</div>

We need the wrapper div so that we can expand the dimensions of our portal from the center (this will make sense in a minute). Here’s the CSS:

.portal-wrapper
{
	display: none;
	height: 500px;
	position: absolute;
	text-align: center;
	width: 200px;
}

.portal
{
	border-radius: 100px;
	box-shadow: 0 0 10px #0071F5,
			0 0 20px #0071F5,
			0 0 40px #0071F5,
			0 0 60px #0071F5;
}

If you’re like me, you might be wondering: wait, we can use border-radius on an iframe? Yeah, apparently you can and it works pretty well. We use a high border-radius to round the edges and use multiple box-shadows to create a soft blue glowing effect.

If we wanted this to look more like a portal from the actual game, then we would probably want to use an inset box-shadow to make the glow appear over the actual content of the iframe. However, this won’t work with an iframe (it just doesn’t display).

Now let’s set up the animations. First, we’ll create an animation for opening the portal:

@-webkit-keyframes portal-open
{
	0%
	{
		margin-top: 250px;
		height: 0;
		width: 0;
	}
	
	100%
	{
		margin-top: 0;
		height: 500px;
		width: 200px;
	}
}

With this declaration, we are creating a simple animation (called “portal-open”) that expands the portal from no width and height to its full size. We also animate the top margin so that the portal will expand from the center. We apply that animation with the following CSS:

-webkit-animation-name: portal-open;
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: ease;

We can summarize that in one line:

-webkit-animation: portal-open 1s ease;

Let’s create another animation:

@-webkit-keyframes portal-active
{
	0%
	{
		box-shadow: 0 0 10px #0071F5,
					0 0 20px #0071F5,
					0 0 40px #0071F5,
					0 0 60px #0071F5;
	}
	
	50%
	{
		box-shadow: 0 0 0 #0071F5,
					0 0 10px #0071F5,
					0 0 30px #0071F5,
					0 0 50px #0071F5;
	}
	
	100%
	{
		box-shadow: 0 0 10px #0071F5,
					0 0 20px #0071F5,
					0 0 40px #0071F5,
					0 0 60px #0071F5;
	}
}

With this animation, we dim the surrounding box-shadow and then revert it to create a light glow animation around the portal’s edges. We’ll apply it with the following CSS:

-webkit-animation-name: portal-active;
-webkit-animation-duration: 1.5s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;

We can also get this down to one line:

-webkit-animation: portal-active 1.5s linear infinite;

Now we just add the following to our CSS to trigger both animations:

-webkit-animation: portal-open 1s ease,
			portal-active 1.5s linear infinite;

Of course, we’ll want to trigger these animations through JavaScript. There’s a few different ways we could do this. We could attach the animation properties to elements in the CSS and then flip the animation-play-state from “paused” to “running.” However, the specification suggests that this property may eventually be deprecated and we can’t easily reset an animation with this property.

An alternative method would be to simply add the CSS animation properties using JavaScript. But this is messy; we want to keep our CSS separate from our JavaScript.

Our last option is to toggle the animation-name property. With this method we can declare everything in our CSS and then toggle that property within our JavaScript:

$(function() {

	var PORTAL_HEIGHT = 500;
	var PORTAL_WIDTH = 200;
	
	var ANIM_PORTAL_OPEN = 'portal-open, portal-active';
	var ANIM_PORTAL_CLOSE = 'portal-close';

	var $portalWrapper = $('.portal-wrapper');
	var $portal = $('.portal');

	$(document).click(function(event) {
	
		// Clear the animations
		$portal.css({
			'-webkit-animation-name': ANIM_PORTAL_CLOSE,
			'-moz-animation-name': ANIM_PORTAL_CLOSE,
			'-ms-animation-name': ANIM_PORTAL_CLOSE,
			'animation': ANIM_PORTAL_CLOSE
		});
	
		// Retrieve the User's mouse position
		var mouseX = event.pageX;
		var mouseY = event.pageY;
		
		// Position and display the portal
		$portalWrapper
			.hide()
			.css({
				'top': mouseY - PORTAL_HEIGHT/2,
				'left': mouseX - PORTAL_WIDTH/2
			})
			.show();
			
		// Trigger the animations
		$portal.css({
			'-webkit-animation-name': ANIM_PORTAL_OPEN,
			'-moz-animation-name': ANIM_PORTAL_OPEN,
			'-ms-animation-name': ANIM_PORTAL_OPEN,
			'animation': ANIM_PORTAL_OPEN
		});
	
	});

});

Since we declared everything in our CSS (including the animation-name), we need to add a completely different value (“portal-close”) to clear the animations. If we provide a blank value, the animation-name property will default to the value defined in our CSS, which will keep our open animation from resetting.

Posted in Design, Development | Tagged , , , | Leave a comment

Responsive vs Adaptive Web Design

Here’s the quick and dirty difference:

  • A responsive design fluidly changes to fit any browser size
  • An adaptive design changes to fit a defined set of browser sizes

Further Reading

For a little more context and explanation (along with the benefits to either approach), here are some resources on the difference:

Examples of Adaptive Designs

At the end of the day, it’s best to see it for yourself. Here are some examples of adaptive designs. Slowly resize your browser and notice the sudden shifts in the layout:

Examples of Responsive Designs

In these examples, notice how the layout changes almost immediately to fit the browser size:

Examples were pulled from this excellent post.

Posted in Design | Tagged , , | 3 Comments

Extending the UCLA Mobile Web Framework Geolocation API

If you tried out my UCLA Mobile Web Framework (MWF) treasure hunt demo, you may have noticed that the geolocation was a little spotty. Depending on your phone, service provider, geolocation settings, or any number of other variables, you might be (virtually) digging up treasure in a completely different location than someone (physically) standing right next to you.

I was chatting with one of my buddies at work (Justin Mead), and he explained that the geolocation’s intermittent inaccuracy was because the demo was using getCurrentPosition, rather than polling with watchPosition. watchPosition is a handy little function in the Geolocation API that continuously checks the User’s current position and fires off a function when their position changes. A User’s position could change when he or she moves, but could also change as their mobile device uses different techniques to more accurately determine their location.

So, to extend my demo, I added a getExactPosition function to the UCLA MWF geolocation API:

mwf.touch.geolocation.getExactPosition = function(minAccuracy, timeout, onSuccess, onError) {
	
	var geo;
	
	switch(this.getType())
	{
		case 1:
			geo = navigator.geolocation;
			break;
		case 2:
			geo = google.gears.factory.create('beta.geolocation');
			break;
		default:
			onError && onError('No geolocation support available.');
			return;
	}

	var watchID = geo.watchPosition(
		function(position) {
		
			if(position.coords.accuracy <= minAccuracy) {
				navigator.geolocation.clearWatch(watchID);
				onSuccess && onSuccess({
					'latitude': position.coords.latitude,
					'longitude': position.coords.longitude,
					'accuracy': position.coords.accuracy
				});
			}
	
		},
		function() {
			onError && onError('Geolocation failure.');
		},
		{
			enableHighAccuracy: true,
			timeout: timeout
		}
	);

	return true;
};

You'll notice that this closely mimics UCLA MWF's getPosition function. Like the original, this new function calls callback functions upon a successful retrieval of geolocation data (onSuccess) and also upon failure (onError). Also like the original, this function uses Google Gears if the HTML5 Geolocation API is not supported.

Now, let's bite into the meat of this new function: rather than directly calling getCurrentPosition, this new function begins continuously polling the User's position with watchPosition. After each successful polling attempt, an anonymous function is called that checks whether or not the current reading of the User's geolocation API has an accuracy value less than or equal to the specified minAccuracy (which is measured in meters). Upon retrieving geolocation data with appropriate accuracy, clearWatch is called to stop the constant polling. Finally, if this process takes longer than the provided timeout parameter, the error callback function is called.

This, of course, has the negative side effect of slowing down the application as a mobile device may take a considerable amount of time to determine the User's location within a tight accuracy range. In a real application, if exact geolocation data was not necessary, we would probably want to begin by using the initial geolocation data and then progressively enhance the application as more accurate geolocation data become available. At the very least, it would be helpful to provide the User with some feedback as to the current progress of determining their position.

Posted in Development | Tagged , , | Leave a comment