Soapbox Confessional

Projects

Viviti helps you build websites.

InQuickER lets you to go to the emergency department without waiting in the waiting room.

About

I'm Tyler: Entrepreneur, geek, free thinker, bringer of chaos (but not carnage).

I live on the beach on Vancouver Island, where life is wonderful and continues to improve.

Here is some more content.

Tech Notes

Fun with single table inheritance

Posted September 16, 2008

Viviti uses a lot of single table inheritance. Because of the particular details of our project, we've implemented a few quick conventions and extensions to Rails' STI goodness. One of my favorites, extracted from a module we use in several different places:

# STI-friendly new() method automatically instantiates the proper subclass
class MySupertype::Base < ActiveRecord::Base
  def self.new(atts = nil)
    atts ||= {}
    if atts[:type] and klass = "MySupertype::#{atts[:type].classify}".constantize and klass != self and klass.ancestors.include?(self)
      return klass.new( atts )
    end
    
    return super
  end
end
This code allows you to call MySupertype::Base.new with :type => 'MySubclass' and it will Just Work™.

Sane event handling for change events on select tags

Posted September 16, 2008

If you've ever tried to attach an onchange event handler to a <select> tag, you've definitely noticed that different browsers handle them in annoyingly different ways. This afternoon I whipped up a snippet of jquery code that makes them behave like they ought:

// onchange() on select boxes is handled in a variety of retarded ways by different browsers.
// this patch (hopefully) makes them all work like you would expect them to.
$.event.special.change = {
  setup: function() {
    // only monkeypatch if we're dealing with a select element and we're not dealing with Safari.
    if(this.tagName.toLowerCase() != 'select' || $.browser.safari) return false;
    $(this).data('oldVal', $(this).val());
    $(this).bind("click keydown", $.event.special.change.handler);
    return true;
  },

  teardown: function() {
    $(this).unbind("click keydown", $.event.special.change.handler);
  },

  handler: function(event) {
    var args = arguments;
    setTimeout($.bind_function(function() {
      if($(this).val() != $(this).data('oldVal')) {
        $(this).data('oldVal', $(this).val());
        args[0].type = 'change';
        return $.event.handle.apply(this, args);
      } else {
        return true;
      }
    }, this), 1);
    return true;
  }
};