/dev/nikc/blog

Kuolleiden purjehduskenkien seura

Jun 27th 2013

How to turn your smartphone (nearly) useless in one simple step

17:16

I've owned a smartphone for a long time now. I purchased a Nokia N95 back in 2007 (in Finnish only, sorry), which I would consider my first smartphone. Albeit somewhat different from modern pocket computers, it did among other things have apps, a decent onboard camera, a gyroscope, a GPS-chip for pinpoint location services. Pretty much the most used features modern smartphones equip, although recent years' development have added improved usability into the mix.

One monolithic issue still remains though, which hasn't much changed since those early years; the minute you leave your home country, your phone becomes useless, save for the camera, and possibly the GPS if you have the luxury of offline maps.

Unless you're willing to endure the horror of a colossal phone bill from enabling roaming mobile data, you won't be using the routing feature in your maps app (unless you have an onboard address database, which I don't); you won't be looking up addresses for that shop you were looking for; you won't be updating social networks with your witty comments and/or stunning photographs. To top it all off, open wi-fi networks can be surprisingly hard to find, unless you happen to be in a busy area laden with cafés, restaurants or bars.

Not having an internet connection on a smartphone makes it about as useful as a wheel-less wheelchair: you can still sit comfortably, but you're not really getting anywhere.

Luckily, within the EU, there is a set rate ceiling of 0,70 euros/MB from July 1st 2013 (again in Finnish only, sorry), and a maximum charge of approximately 60 euros, after which your data connection will be terminated. Having a ceiling for data costs is an improvement, surely, but that will only give you a measly 85 MB, which is quite little considering the amount of data flowing in and out of handsets these days.

While waiting for better days for roaming data, do travellers a favour: open up your wi-fi network, even a fraction of your bandwidth is a great help.

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

Meta

Pages

Search blog

Latest comments