Chao Lam

Working on the next small things …

Javascript: HTML Text Input Field with Default Text

with one comment

While our CoolQs project wasn’t a success, I wrote a few small javascript classes I thought I’d share in the next series of posts.

Often, I’ve wanted a HTML text <input> field to show some default text, usually in light grey background text. This has the twin benefits of telling the user what the input field is for while not taking up any extra space, as the screenshot taken from the Safari browser shows:

Safari search box showing it'll search google

Safari search box showing it'll search google

Here’s the prototype-based javascript code:

// see https://chaolam.wordpress.com/2009/07/30/javascript-html-text-input-field-with-default-text/
var DefaultTextInput = Class.create();
DefaultTextInput.prototype = {
  initialize: function(inputElt, defaultText, defaultClass) {
    inputElt = this._inputElt = $(inputElt);
    this._defaultText = defaultText || inputElt.value;
    this._defaultClass = defaultClass || 'ex';
    this.fixParentFormSubmit();
    inputElt.observe('change', this.onChange.bindAsEventListener(this));
    inputElt.observe('focus', this.onFocus.bindAsEventListener(this));
    inputElt.observe('blur', this.onChange.bindAsEventListener(this));
    this.onChange();
  },
  onChange: function() {
    var inputElt = this._inputElt;
    if (!inputElt.value) {inputElt.value = this._defaultText;}
    if (inputElt.value == this._defaultText) {inputElt.addClassName(this._defaultClass);}
    else {inputElt.removeClassName(this._defaultClass);}
  },
  onFocus: function() {
    if (this._inputElt.value == this._defaultText && !this._isFocussing) {
      this._isFocussing = true;
      this._inputElt.removeClassName(this._defaultClass);
      this._inputElt.select();
      this._inputElt.value = '';
      this._isFocussing = false;
    }
  },
  fixParentFormSubmit: function() {
    var inputElt = this._inputElt;
    var form = inputElt.ancestors().find(function(elt) {return elt.tagName == 'FORM';});
    var self = this;
    if (form) {
      var oldSubmitFunc = form.onsubmit;
      form.onsubmit = function() {
        self.onFocus();
        if (oldSubmitFunc) {return oldSubmitFunc.call(form);}
      };
    }
  }
};

To make a text input field show default text, the usage is:

new DefaultTextInput(<input element>, <default text>, <default css class to grey out default text>)

The last two parameters are optional. I use the text field’s value as the default text by default. “ex” is the default css class.

I’m using unobstrusive javascript to allow html separation from javascript. The usual usage is to turn all input fields of a certain class (e.g. “dti”) into DefaultTextInput instances:

$$('.dti').each(function(inputField) {new DefaultTextInput(inputField);});

The only tricky part of the code is that I cascade the onsubmit callback of a input field’s potential parent. I call onsubmit to ensure the default text is never submitted as part of the form data.

Advertisements

Written by Chao

July 30, 2009 at 12:30 am

Posted in Uncategorized

One Response

Subscribe to comments with RSS.

  1. Hi,

    I have a modified version (using Prototype.js) if you want to use multiple such form fields on a page. I needed this, and it works fine.

    However, your blog spam filter discards JS input (it seems), so mail me if you want to publish my patch. 😉

    Regards,
    Jens

    Jens

    February 7, 2010 at 5:37 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: