function PostCode( triggerId, targetConfig ) {
  this.trigger = document.getElementById( triggerId );
  this.targetConfig = targetConfig;
  this.select = document.getElementById( targetConfig.id );
  this.selectChangeListener = null;
  this.remote = null;

  this.onServerResponse = function( response, codePostal ) {
    if ( this.select == null ) {
      var node = this.trigger.parentNode.nextSibling;
      if ( node ) {
        var p = document.createElement( 'p' );
        p.className = 'criteria';
        var lbl = document.createElement( 'label' );
        lbl.setAttribute( 'for', this.targetConfig.id );
        lbl.appendChild( document.createTextNode( this.targetConfig.label ) );
        p.appendChild( lbl );
        this.select = document.createElement( 'select' );
        this.select.name = this.targetConfig.id;
        this.select.id = this.targetConfig.id;
        p.appendChild( this.select );
        node.parentNode.insertBefore( p, node );
      }
    } else {
      while( this.select.childNodes.length > 0 )
        this.select.removeChild( this.select.firstChild );
    }

    var options = response.xml.getElementsByTagName( 'option' );
    var opt_cps = [];
    for( var i=0; i<options.length; i++ ) {
      var cp = options[ i ].getAttribute( 'code' );
      var opt = document.createElement( 'option' );
      opt.value = options[ i ].getAttribute( 'value' );
      opt.appendChild( document.createTextNode( options[ i ].getAttribute( 'label' ) ) );
      if ( codePostal == cp )
        opt.setAttribute( 'selected', 'selected' );
      this.select.appendChild( opt );

      opt_cps[ i ] = cp;
    }
    if ( this.selectChangeListener != null )
      removeListener( this.select, 'change', this.selectChangeListener );
    this.selectChangeListener = Delegate.create( this, 'onSelectChanged', opt_cps );
    addListener( this.select, 'change', this.selectChangeListener );
  }

  this.onSelectChanged = function( e, cps ) {
    var target = DOMEvent.getTarget( e );
    var value = cps[ target.selectedIndex ];
    if ( '' != value && value != null )
      this.trigger.value = value;
  }

  this.onTriggerKeyUp = function( e ) {
    var target = DOMEvent.getTarget( e );
    if ( target.value.length > 2 ) {
      if ( this.remote != null )
        this.remote.abort();
      this.remote = new Remote();
      this.remote.uri = '/xml-postcode.php';
      this.remote.appendData( 'code_postal', target.value );
      this.remote.addListener( 'onLoad', Delegate.create( this, 'onServerResponse', target.value ) );
      this.remote.send( 'get' );
    }
  }

  if ( typeof this.trigger != 'undefined' )
    addListener( this.trigger, 'keyup', Delegate.create( this, 'onTriggerKeyUp' ) );
}