/dev/nikc/blog

Kuolleiden purjehduskenkien seura

Shorts

Jan 29th 2013

Stop breaking your forms

20:13

A good form is invisible: it just works. In contrast, a broken form makes you want to pull your hair out, simply because it forces you to put your efforts into a side effect, not into what you're trying to accomplish.

Broken keyboard access

When I fill out a form I often submit it by hitting enter. I'm already using the keyboard, so that's the logical thing to do. Too often one of two scenarios occur:

  1. nothing at all happens, e.g. the form is not submitted
  2. the action I was attempting to do fails

The first scenario is related to broken markup; the inputs are not wrapped in a form element, so the browser can't possibly know where and how to submit the data. (Back in the days it could've simply been a missing submit-input, but browsers are nowadays less picky about that.)

The second scenario is harder to define, but most likely happens because the form handler listens to the wrong event and/or the form's action isn't directed to its proper handler.

If you fail at this, you should probably also read up on how to setup proper tab order.

Broken validation

Client side validation is useful. It saves me from the frustration of submitting a form, only to be presented with the same form again (hopefully with an added error message). In the worst case all the inputs are also left blank.

Using a modern browser, I find it lovely how it nowadays1 can fill out forms for me, e.g. shipping information in online stores. Just a few days ago, I made a purchase at a store where each approved input was flagged with a small green tick next to it. It didn't, however, manage to validate more than the first input, when my browser filled out the whole form at once. In the end, I was forced to tab through each input –leaving the contents untouched– to be able to submit the form and complete my purchase.

The reason for this is most likely lacking understanding of Javascript events. Instead of listening to (change) events on the containing form element, each input is observed separately, thus necessitating a focus and sometimes also the blur event to happen on each input separately.

Sadly, browser support for input validation isn't yet a complete replacement. However, you should use feature detection and revert to Javascript validation only when it's needed. (And when you do, you should make sure it works, not just that it works on my computer.)

Broken login

By far my biggest pet peeve is broken login forms, since I use them very often. Especially since the usefulness of the reason for breaking them is marginal at best; placeholder values.

It's far too common to populate the username input with the value "username" and the password with the value "password", and then leaving out actual labels to save space in the layout. That last sentence should already tell you you're doing something wrong, but at the very least the fact that password inputs don't display the default value as readable text should give you a hint.

The original intent might be benign, but when done wrong it breaks my password manager2, in the end actually causing me several extra steps to use the form, which is hardly a good outcome.

If you really want to use placeholders, use the placeholder attribute. It will work as you expect and already works in most browsers. If it isn't supported in a browser, it should hardly be considered a showstopper, as you're already describing the inputs with labels, aren't you.

1 IIRC, Netscape Navigator was able to do this, so it's hardly a novel feature.

2 I use 1Password, not my browser, to store my passwords.

Shorts

Jan 10th 2013

Quick prototyping and codesharing

10:47

If you need to quickly prototype a piece of code, possibly also share it with someone, you have plenty of tools to choose from. Here's a few I've run into.

  • Codepad
    • The only one that's not targeted at browser code
    • Has the broadest set of runnable languages of the lot, but no way of providing input
    • Great for 99 Bottles prototyping, if you don't want to install the compiler/interpreter locally
  • JSFiddle
    • The swiss army knife of browser code prototyping and sharing.
    • Emphasis on scripting, like the name suggests
    • Allows bootstrapping to several JS frameworks
    • External resources supported
  • JSBin
    • Provides a vast selection of libraries to include
    • Allows editing the whole html document
  • Tinker.io
    • Open Source JSBin-like tool
    • No external resources provided
  • Dabblet
    • Has nowadays expanded to JS territory, too, but emphasize is on HTML and CSS prototyping.
    • Stores your code as a Github Gist
  • Github Gist
    • Snippets of code (or text) for public or private storage.
    • Highlights several languages, but doesn't run anything
    • Can optionally contain multiple files in a single Gist
  • Tinkerbin
    • Supports compile-to-languages, i.e. HAML, Sass and CoffeeScript
  • Tmpltr
    • Rapid prototyping of data bound templates
    • Include external resources by drag-and-drop upload
  • Plnkr.co
    • Collaborative tool for creating "Plunks", which can be forked by others, and optionally also private
  • CodePen
    • Looks quite similar to many others, but offers a Pro-version with an improved feature set
    • Seems to focus more on brandishing a complete creation, rather than just sharing a snippet of code
Dec 20th 2012

Jumping jack tab

15:07

I use the console a lot. I also like to patch together small scripts to make my shell experience smoother and more efficient. (Read: indulge my laziness.) Inspired by a talk by Paul Irish where he introduces his selection of tools - specifically a command for quickly jumping into a project folder, which I naturally immediately adopted. Just to show off, I also included tab-completion.

If you feel you could use it, snag the source code below (and party on!), or download it from the gist.

Setting up is pretty straight forward and is "documented" in the comments at the top. If you don't like z for the command, just change the name of the function. (It's the last function in the source.) Don't forget to change the command on the last line or you'll lose the tab-completion.

#!bash

#  Usage:
#
#  In your .bashrc
#
#  export PROJECTS_HOME=<path_to_projects_root>
#  source jump-to-project.bash
#
#  In you shell:
#
#  $ z <project name>[ENTER]
#
#  Use [TAB] for auto-completion, double tap for a list.
#
#  Optionals:
#
#  export PROJECTS_SUFFIX=<optional suffix to strip>
#
#  For prettier tab-completion, fill PROJECTS_SUFFIX with a
#  value you want to strip from folder names. I use '.dev.local'
#
#  export PROJECTS_TALKATIVE=1
#
#  For some feedback when switching into a project folder,
#  fill PROJECTS_TALKATIVE with any value.

if [ "x$PROJECTS_HOME" = "x" ]; then
    echo "PROJECTS_HOME not set"
    return
fi

_find_all_projects () {
    if [ "x$1" = "x" ];
    then
        find $PROJECTS_HOME -maxdepth 1|xargs basename -s "$PROJECTS_SUFFIX"
    else
        find $PROJECTS_HOME -maxdepth 1 -name "$1*"|xargs basename -s "$PROJECTS_SUFFIX"
    fi
    return 0
}

_find_project_path () {
    find $PROJECTS_HOME -maxdepth 1 -name "$1*"
}

_find_project () {
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts=$(_find_all_projects)

    COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
    return 0
}

z () {
    if [ "x$HOME" = "x" ]; then
        echo "\$HOME not set"
        return 1
    fi

    MATCHES=($(_find_all_projects $1))

    if [ "x$1" = "x" ]; then
        echo "Usage: zz <project>"
        echo "Projects:"
        echo ${MATCHES[@]}
        return 0
    fi

    if [ ${#MATCHES[@]} -eq 0 ]; then
        echo "No match for $1"
        return 0
    fi

    if [ ${#MATCHES[@]} -gt 1 ];
    then
        echo "Ambiguous match '$1': ${MATCHES[@]}"
    fi

    cd $(_find_project_path ${MATCHES[0]}) && [ ! -z "$PROJECTS_TALKATIVE" ] && echo "Project ${MATCHES[0]} in $(pwd)"

    return 0
}

complete -F _find_project z

Shorts

  • This is responsive - Patterns, resources and news for creating responsive web experiences.

    (0) #

  • Now that responsive design is the hottest word on the block, it was only a matter of time before it expanded beyond CSS. Here's a couple of helpers to snaz up your JavaScript: min-width.js with relocate.js, and enquire.js.

    (0) #

  • Holder.js is a client side placeholder image generator.

    (0) #

  • Generate data, will, as the name suggests, generate data for inserting into your pristine, empty database.

    (0) #

  • Since I have no real content to share, I'll post a few more dummy content providers. Fixie.js (not moustache complete) FlickrHoldr (moustache complete).

    (0) #

  • Just when you thought your website was complete, you found Clippy-js.

    (0) #

  • I've been using Dummyimage.com for generating placeholder images for a while now, but it seems there are now at least two three alternatives; Placekitten.com for when you need cute, and Placesheen.com for when you don't. Placehold.it seems to be pretty much a clone of dummyimage.com. And if you need a noisy background image, look no further than NoisePNG.

    (0) #

Meta

Pages

Search blog

Latest comments