Helping people make websites

I like making websites and I love helping other people make sites.

I started learning how to make web pages, writing HTML that is, in 1996. The most important tools back then were a browser (Netscape Navigator), text editor (Notepad) and FTP client (hmmm, I can’t remember what client I used). If you saw something cool on a webpage you could just view the source and learn how that developer had made it work. You could ask anyone you met online for their homepage and they had one. It might have had midi background music and blinking text, but it was theirs and it told their story. Social media is cool, but I can’t help feeling we lost some of that personal creativity.

Fast forward to 2015 and the profession has changed… in some ways a lot, and in other ways not so much. The best tools are still a web browser (Firefox, Chrome, IE, Opera, Safari—all the latest browsers have killer developer tools), text editor (Sublime) and some way to publish your content (FTP, git, other…). Only now there are so many other tools to help with design, development and operations… I am not going to list them here, but I am going to highlight some tools I’ve made to help others.

Global alert bar editor (2015)

Global alert bar editor

My most recent creation, a simple authoring tool for creating the global alert bar used on Queensland Government websites in times of a natural disaster. It’s a simple form with live preview and markup. The initial impetus for this was to get the time element markup correct. I named it GABE for short and you can find it over on codepen: http://codepen.io/bboyle/pen/jEXwZr

It doesn’t publish—it just generates the HTML for old fashioned copy and paste.

Queensland Government templates and patterns (2002–2015)

I’ve helped code the CUE (consistent user experience) and SWE (single website experience) templates for Queensland Government since 2002. Rolling out a template across varied government websites and applications (and many different platforms and frameworks) with minimal conflicts and 4-week releases was a really great achievement. Centrally hosted assets (css, js and images) was the key to rolling out quick changes, and a healthy respect for the diverse platforms the template was integrated in. I might personally be a bit opinionated about troubleshooting CSS conflicts with the PrimeFaces UI framework; but professionally if that’s needed then that’s supported.

Maps with data (desktop)

The pattern library is a collection of UI elements that are supported in that template, ranging from simple content patterns (example: including document metadata in a link) to “advanced” content, such as a creating a single-page mapping application with only a simple CSV data file and some HTML templates.

Always a good challenge: balancing a quality customer experience with an easy authoring process! Two examples I am particularly tickled by are instruction-based form relevance, an approach to progressive disclosure in forms that requires no scripting (by the form author, I did the heavy lifting) and having folks run up angular apps with only CSV data and custom templates (the angular app code is centrally shared).

Form builder (2012)

Form builder prototype

I consider it a “proof-of-concept” but this single-page app has been used to create many of the email forms now live on http://www.qld.gov.au and was instrumental in getting everyone to stop talking about putting “services” online and actually start publishing them! The rush is on now to put more advanced tools in place (bring it on!)

Click anywhere to edit, drag and drop, switch to preview. Builds forms with semantic markup (my particular flavour), including HTML5 validation and progressive disclosure. There are a bunch of poorly documented keyboard shortcuts. I’d love to polish this up one day, it has a lot of potential. (Being usable without training would be a win!)

Get involved survey builder (2011)

Edit consultation dialog (2011)
Add question dialog (2011)

Get involved is the Queensland Government consultation platform. The survey builder is not as easy to use as the form builder (above), in fact it inspired me into thinking “It should easier to make forms!” Still, I helped with the UI design (with some excellent editorial advice from Rory Daly) and it helps people make surveys, consider the language they use, and choose appropriate privacy settings.

Custom quality control tools (2007, 2012)

Diagram of quality control logging tool (2007)

I worked on a couple of browser extensions to automate some of my quality control tasks, staring with custom stylesheets and scripts in Opera in 2007 to help check pages at Department of Communities.

In 2012 we tackled editorial quality by testing for passive voice, non-preferred terms, number formats and more. Computers are great at consistently performing the same checks over and over again, the challenge lies in figuring out how to test for some of these fuzzy concepts, how to present those results in a nice UI, and how to encourage people to use the tool when available. (Okay, behaviour change may be the biggest challenge in that list!)

Content management systems (2002–04, 2012)

Workflow documentation
Workflow email design (2005)

TeamSite pops up every few years in my Queensland Government jobs. I implemented the workflows, templates and deployments for Education Queensland in 2002–04, and helped set up the environment for qld.gov.au in 2012. I’m not a huge fan of CMS products, I like flexibility in my workflow and systems like consistency so that’s an immediate challenge. Still, I am impressed when I see authors getting stuck in and making content! I have mixed opinions about whether or not they should learn HTML along the way 🙂

Jumbostore (1999)

Jumbostore edit product wizard (1999)

Behind the online shopping mall “Jumbomall” there was “Jumbostore”—a content management environment for stores and products. I did a lot of the work on the UI and database to support this, customer support for merchants, and occasionally drew elephants for promotions.

Mentoring

My biggest contribution is mentoring. I’ve always enjoyed this on the job, but over at Thinkful I’ve found the best outlet for helping new developers on the path to mastery!

Yes, I do believe everyone can “learn to code” or more accurately, everyone can create.

Advertisements

when is a number not a number?

text inputs are still best for collecting some numbers on web forms—especially if the user might wish to enter non-numeric formatting characters such as spaces, dashes, letters. Serial numbers and credit card numbers are prime examples.

Sometimes when designing a web form, you need to ask the customer a question where their answer will be a number. Now with HTML5, browsers have started supporting a number input field: Sounds like a perfect fit, right?

But wait a minute—are you really sure the “number” you are asking for really is a number? What is a number anyway? If you are rushing to use the HTML5 number input, a number is a “valid floating point number”.

You see there are lots of things we (humans) call “numbers”—but not all of them are valid floating point numbers. Below are 2 problems I have encountered with differing definition of numbers.

Credit card number entry on Dominos mobile website, showing number formatting issue

Recently I was ordering pizza from dominos on my iPhone. At the payment stage, I had to enter my credit card number. I like to enter it as it appears on my card—with spaces. It is easier to read and check this way. Imagine my surprise when I moved to the next field, and had the first 4 digits formatted as “4,111” and the rest of the digits thrown away. I had to tap out the digits again, and even then it was formatted as “4,111,111,111,111,111”. It worked, but—ugh. Don’t use input type="number" for credit card numbers.

We had a similar situation at work a couple of years back, with ABN. An ABN is always displayed in the format: 53 004 085 616.

Customers could enter their ABN how they wished (including spaces). I was surprised to find the confirmation and receipts screens showing the ABN with the spaces removed, like so: 53004085616. I knew I had not coded the UI that way, and when I raised it as a bug I was told emphatically by a developer that an ABN was a number and that they were now storing it as such and this was how it should be.

There’s some truth in that. But when it comes to how data is presented to end users, the format should be designed for clarity. When there is an existing convention—as there is for ABN—displaying data in that familiar format is best. Happily we resolved the ABN disagreement with a little regexp that put the spaces in for the UI.

Next time you’re working with a number—think about what kind of number it really is.

Suggested input types for different numbers
Type of number Suggested HTML5 input type Why?
Street address text Examples: 3A, 4/353
Postcode text May contain spaces or letters (varies by country)
Phone number tel Specifically for phone numbers
ABN text Contains spaces by convention
Credit card number text Contains spaces by convention
Serial number text Frequently contains letters or spaces
Dates various date and time options May contain dashes, slashes, words (month names)
other number number might be ok 😉

Saturday afternoon coding

It’s high time I talked a little about the coding I do. Since my job transformed into a “User Interface Specialist” I’ve been back to coding — implementing the user interface for web applications. After years of being a backseat developer (i.e. doing QA for other developers) and choosing to try out the BA field instead, this change was thrust upon me. Go figure. Anyway, coding is a lot of fun. Although the pay isn’t quite as good. It is good honest productive work though. Gotta love that!

Those who follow my tweets may often be amused/confused by the references to coding. Our development team has been introducing the agile way into Queensland Government (I am sure we are not the only team doing this). I sometimes get my hands dirty into the java code (usually acceptance tests with Selenium), or even the struts2 setup, but usually I’m working on good ol’ HTML, CSS and javascript. I’m on my own a lot as I resist working in a closed in meeting room. There’s a good vibe in there, but also a distinct lack of natural lighting. Why get up in the day if you don’t even see the sun? I digress …

So I am on my own, fumbling along my own agile journey. Learning the zen of coding. One of the key pieces I have been working on is javascript form validation, and having worked on it the old way — code stuff and deal with problems when it breaks — I’ve been trying this red, green, refactor (aka Test Driven Development) idea. And, I have to say, I am liking it.

I contribute a lot of the code towards that in my own time. I rationalise giving up my time because the code has been made open source, a few of us have “joined forces” on a project named “use the forces”, to collaborate on code and products which we aren’t afforded time to collaborate on at work. We are compelled into meetings to discuss improving productivity, just not encouraged to work together productively. There is paperwork to write after all! Sorry if that sounds a little scathing: I’m a worker, not a talker (outside my blog!), and I have high expectations that leadership have yet to exceed… At any rate, I can make open source contributions as often as I wish, and I can enjoy go home on time day every day at work. It’s sweet and I Like It.

That was a long ramble. For people who wonder how I do what I do, why I do it, what it’s like, here is an insight into a Saturday afternoon coding session. I wrote these notes while coding, for this post. This is what coding is like for me. Distractions, warts and all.

do an update or checkout, make sure the source is the latest

fire up firefox with firebug (portable apps), it’s 3.5.2

good idea to test with multiple browsers, but one while developing. don’t have IE6.

talked myself into runnning IE8. Press F12 to get developer toolbar, toggle to IE7.

using e-texteditor (like textmate) on windows

run the tests. forces tests are in test/jquery-1.3.2.html (this is a wrapper to run all the tests)

find the file and right click and choose open with Firefox (I already had firefox running so it used the portableapps one and not the installed version — it doesn’t have the add-ons I need!)

may be a little slow downloading YUI to run tests (especially if downloading a game from steam in the background over 3G broadband)

1 test failing. find it, fix it, save it. run again.

can run in both Firefox and IE8 in parallel (even if encoding video in the background, if you are an avid multitasker, I recommend a multicore CPU — it’s essential for GTA IV anyway!)

tests passed, all good, don’t forget to check in (even if being distracted by Buffy – the first episode where Spike and Drusilla appear – and the kids playing trains)

now we’re ready to code something new.

(after we send the kids back to the Wii and outside for a splash in the wading pool)

there’s a bug discovered in the confirm validation whilst playing with the UI, which reminds me that there’s a demo form so you can interact with the UI whilst working. whilst coding to tests should be enough, I like the immediate feedback from trying it out (when coding UI), and there’s no real point running the test if I know it isn’t working anyway.

here’s the demo form. it has email and confirm email, and they are setup to work, like this.

type ‘foo@example.com’ and ‘foo’ and tab away (validation runs onblur/onchange) the error appears.

correct the error, ‘foo’ becomes ‘foo@example.com’ and the confirm validation is happy.

but what if it happened the other way? let’s reload the form.

fo@example.com and foo@example.com … confirm validation correctly highlights the problem.

fix the first field and tab on through … the validation hasn’t kicked in.

This is exploratory testing. It’s also a good old fashioned user-centred design technique “put yourself in their shoes”, thinking through how users will interact with the application. Don’t just think of one way they may use it, think of all the different ways they may use it. It’s not just random typing and clicking.

does Buffy really plan to use that machete on spike? oh. on the salad. ok.

look away from the tv.

Is this a bug?

You do have to decide if issues found are bugs, or possible features, or just interesting anomalies to note.

This is a bug, forces validation must be intuitive and easy to use and this clearly fails that. That’s part of the design goals.

now, at this point we could start solving the problem and I already have an idea in my head it’s related to the onblur/onchange trigger happening only on the con
firm field. I probably need to track the dependency between the two fields and run the validation when either changes.

This line of thought is very dangerous, because it overlooks a more important problem.

ALL THE TESTS PASSED.

if there is a bug, shouldn’t that show up? it’s passing all the tests, so there is a gap in the test coverage.

before we do anything else, let’s capture the problem as a test. our test should set the wrong value for email, the right value for confirm email, and verify the confirm validation message appears. it should then correct the email value, and verify that the error has disappeared. This test should fail, because we haven’t fixed the code yet. But, that’s important too, that’s how we verify the test is coded correctly.

ah Angel playing at Angelus. Cool, but not the same as when Angelus really takes over.

Let’s code …

coded a new test. it’s in unit/forms.ui.js

must confess not having a great handle on unit vs integration vs acceptance tests. This feels like it might be more than a unit test, but the important thing for now is getting the tests in place. I am going to need to sort it out one day.

The new test fails, as expected.

Unfortunately it’s failing in the wrong place, the error message didn’t even appear. Debug the test. I insert “this.wait(null, 10000)” in to pause the test so I can see it.

aha, I forgot the setup step. I have to specify that the field needs confirm validation.

That’s done with this: $(‘#confirm-email’).forces_attr(‘type’, ‘confirm’);

I’m going to place that in the setUp method of the test case (see YUI3 for more) because it seems likely I will forget this again. I hope it won’t upset any other tests, but there’s an easy way to check this — run the tests again!

remembering to remove that 10 second wait will help. the test failed on it. which is useful when debugging. and extra useful in this instance for allowing me to grab a screenshot. and I saw the UI displaying the right thing so I have some confidence.

remove the pause, run the tests again.

everything passed. This is not good. Our test has not caught that bug. Let’s put the pause back in and find out why.

The UI is showing the right thing. The value is valid and confirmed, but the alert message is still being displayed. The test is supposed to check it doesn’t show that message. Something is wrong with the test.

ah, I was going to fix using a console log. But I’ve noticed, it is using $(‘#email-confirm’) instead of $(‘#confirm-email’). D’oh. Mistakes like this are the bane of any coder’s life. Especially when they don’t throw any syntax errors.

I can see this error in the previous test (that I copied from). A bit disturbing. Search and replace.

success! the test now fails at the expected point. we’ve now achieved the “Red” from red, green, refactor. We have a working test.

Don’t check in at this point. That would mean the next person who updates their copy from the project has this test failing and probably no idea why. They’ll try to fix it, we’ll be coding ourselves, it could lead to conflicts. It also erodes faith in the build if you update to the latest source and it’s broken. Like when we went to start and had to fix that other broken test. Not good.

So hold off checking in!

But it is a good time to take a quick break and help daughter play Purble place on Windows7. Now that she’s setup and happily occupied …

What comes after red? Green. We have to fix the code now so that it passes the test.

I’m going to change the way confim works, as I said before:

It currently uses this: $(‘#confirm-email’).forces_attr(‘type’, ‘confirm’)

I don’t really like this, the “forces_attr” function is a pseudo for attr() and it makes sense to use attr(‘type’, ’email’) as email is a valid type (HTML5).

There’s no such thing as the “confirm” type.

How about $(‘#confirm-email’).forces_isConfirmationFor(‘#email’) ? I like the explicit way this associates the two fields together. We’ll need to change the tests. It’s an easy change. As with any change, run those tests again.

Now it fails on a javascript error – we haven’t implemented that function.

Let’s solve that.

Coding time! Write a new stub function. It belongs in jquery.forces.forms.core.js

Run the tests.

This has broken the old confirmation validation as well. That’s ok. It needed refactoring, you can see it was a bit heavy on processing, running through all form fields to find the previous one. This direct association will be more efficient.

Although I don’t like the idea of the confirmation being of a field elsewhere in the form, but that may be personal bias. Hmm… I could make this method isConfirmationOfPreviousField() and hard code that. But maybe another designer will have a good reason for separating the fields. In fact, I read something recently about that. Let’s allow it.

Remove the old validation.

*sigh* youngest daughter tipped a whole bunch of paper on the floor. That’s a bit distracting. I better pick it up. ok, tidy again.

let’s recode the validation. We know the tests are ok, let’s just code until it works. I’m not describing my coding here today.

much excitement over the matchup game. two excited girls. “i won daddy!” that’s lovely girls.

I’m coding. Ok, now they’re making me laugh. ok, discipline. code.

Let’s flesh out this forces_isConfirmationFor method.

It occurs to me that now that I am tracking the associated field, I’d like that exposed. The UI code will need to know that, as it knows what label to display (e.g. doesn’t match “Email”)

let’s put a test in for that. That’s so simple it really will be a unit test. I’m putting it in unit/forms.js because it relates to core (not UI) functionality. new test case to find the confirmation field. note that it uses the same method, but passes no arguments. That seems to make sense to me.

Back from emergency track repairs to the new Thomas train set and with relatives arriving for a BBQ, may not accomplish much more. Oh, BBQ later, this is whipper snipping time. I have the best inlaws.

Let’s try to get that test to pass.

First attempt at code, run the tests. Fails, but we get an interesting message.

ok, fixed. I just had to remember we passed “#input1” to the function, not a jquery object, and the function had to turn it into a jquery object. I wonder if it works if we pass a jquery object? That deserves a new test.

It passes. Fantastic. That’s jquery working nicely for us.

Note the comma placement in adding that test. If an extra comma slips in, IE becomes very unhappy. It doesn’t like a comma after the last item in an object. It caught me out recently, so it is fresh in my mind. Let’s check the tests in IE8. It’s much slower. I am looking forward to the performance improvements IE9 promises.

Good. It returns the same results as FF. Let’s recap.

We can now specify a field is a confirmation for another field, and find out what that field is. Those tests
pass, we’re confident that functionality will continue to work.

Let’s work on addressing those other tests, and implement the actual validation. We’ll reproduce the functionality we had before. When the confirmation field is updated, it’s validated. (That won’t solve the original bug).

Doesn’t seem like we’ll need much code. And now I realise I don’t have a good test for this. The tests are based on checking the UI shows the correct value. I just want to test that the field state is correctly flagged as “invalid”. If the field is invalid, the UI should work anyway. But because I’m refactoring I need to work on the UI too. I want more test coverage so I can get confidence this bit is working before I code the UI. Really, I should have those tests already in place. Still learning the ropes and anticipating the right tests.

I will comment out the new code and write the tests (to get them “red”)

Refactored to combine the two previous tests, and added two new ones to check valid/invalid status.

And conveniently missed out a comma which caused a syntax error. Easily fixed.

Good thing about running these tests frequently is you find these things quickly. I probably should be pairing to avoid more of these mistakes in the first place. I’ve made so many mistakes so far, can you imagine if I hadn’t tested anything yet? Sorting through it all later would be a nightmare!!

Some more bugs in the test fixed, and we’re at the right state now.

4 tests are failing. That’s a lot, I think one at a time is ideal. I don’t think red, green refactor is about lots of failing tests! You want a much shorter cycle between red and green. Anyway, 4 tests failing. 2 are the pre-existing UI ones, 2 are to test how the confirmation validation is implemented (not how the UI looks).

Let’s see if uncommenting our code fixes that.

Nope, there was a bug. 11 errors showed up.

When that happens, you know something what you just changed has got a (usually simple) flaw. In this case, “isConfirmationFor()” vs “e.isConformationFor()”. Simple. But important! One can’t call methods without objects (well, you can, but that’s a ninja secret).

Fixing that and we return to 4 errors. That’s a bit better, but means the implementation did not pass the tests. Why not?

Let’s introduce some logging … hmm, it’s not logging anything for those two tests. Is it even validating anything? More logging. Nope, doesn’t seem to be. Aha, in that test case I will need to enable validation for the test form.

That was indeed the problem with the tests, they pass now.

So, we know that validation works for the confirm field (but not the source) field. It’s not working at the UI level though, let’s fix that up.

Wow Super Smash Bros Mega HEAVY brawl is a lot of fun. But it doesn’t get the coding done. That was very distracting Daniel. But great fun!

Quick run through and … we’ve restored things to where they were!

Now, I’m cooking. Not “cooking” as in “coding successfully”, but “cooking” as in “cooking at the BBQ”.

When I’m back, we can fix that bug so the confirmation validation occurs when either field is updated! Write some more unit tests first …!

* * *

Um, didn’t get to any more coding that Saturday. I ate tea, watched Robots, played L4D2 scavenge mode. It was awesome! More coding tomorrow. Maybe.

Ok, 5:51 pm the next day …

running the tests is even slower now YUI3 needs to download over shaped (64 kbps) broadband. If you can call it broadband.

1 test failed. It’s that bug, the confirm alert doesn’t go away when the original field is corrected. I’m gonna write another test for this, that’s not at the UI layer.

Test works. (It failed at the expected point.) Let’s code the validation (not the UI) so it works.

When the confirmation is setup, it now stores the “confirm” field as a “validation dependency” for the original field. When validating, it will check for dependencies and validate them. I’m aware that if this was called twice, things will go a little awry.

For example:

$(‘#confirm1’).forces_isConfirmationFor(‘#email’);

$(‘#confirm2’).forces_isConfirmationFor(‘#email’);

The second call will result in #email having a validation dependency for confirm2, that overwrites the one for confirm1. I don’t consider this a bug, because I don’t currently need to deal with more than one validation at a time. So I have not coded tests around it. Note that $(‘#confirm1,#confirm2’).forces_isConfirmationFor(‘#email’) should work anyway. But consider that an undocumented feature. It is certainly not a requirement so there are no tests guaranteeing it will work.

Tests run and there are lots more failures. Nothing new should be failing, there must be an error in the code changes I made.

This time, I’m using undo to return the code to the state it was. I don’t feel like debugging. Yes, that’s reset everything nicely. Sometimes this is the more efficient approach. You learn to judge when. Depends how much code you invested and how wrong things went!

Coding attempt #2.

OK, the validation dependency is now stored and there’s a test to verify that part works.

Now to invoke that dependency during the onchange validation. It’s not needed onsubmit, because ALL fields within the form are validated anyway.

Wow. Everything just passed with one line of code!

Because jquery runs on an array of objects, it was a snap to add the dependend fields in. Basically the change was control.forces_validate() to control.add(control.data(‘dependents’)).forces_validate().

I love jquery.

The UI has passed as well. I guess it was already setup to work when the valid/invalid events fire.

Still, let’s test the demo form and see it in action.

The demo form isn’t working. It’s still using forces_type(‘confirm’). Let’s update it to the refactored version.

$(‘#email-confirm’).forces_isConfirmationFor($(‘#email’).forces_attr(‘type’, ’email’));

It works!

Important to note that this new validation will not run against empty fields (this is by design). If you *require* confirmation, then you need to make the field required also. Otherwise, it implements optional confirmation, as in it may be omitted, but if present must be valid. I don’t have a use case for that, but it is the design pattern I follow for all validation.

This is the code people are likely to want.

$(‘#email,#email-confirm’).forces_attr(‘required’, true);

$(‘#email’).forces_attr(‘type’, ’email’);

$(‘#email-confirm’).forces_isConfirmationFor(‘#email’);

There are many ways to rewrite the above, but that is a simple way to show how it works.

Let’s do an IE8 check of the tests. All passed.

Ready to check in, preparation steps.

Run compile.bat to combine and minify the JS code.

Run the tests against the minified version. I like to do that in Chrome, just for something different.

All passed.

Let’s check that code in. Don’t forget a handy comment.

We’re done! Let’s eat tea.

Believe it or not, that’s how I code. It is far less adhoc than it seems. And when I am less tired, I might even add in all the extra screenshots I captured and this post may even make sense.

It might have been quicker to just read the revision notes 😉