ARCHIVE: March, 2007

I was at 43Things.com, it is a weird social-networking site that allows you to list down your goals and meet other people who have the same goals. The site asks this simple question, “What you want to do with your life?”

As I am writing this, 943,117 people in 12,075 cities answered that question with 918,625 goals. What is interesting, people associate or tag their goals with some relevant keywords. Don’t you curious what the popular tags would be, well, I was.

So I took a peek at the tag cloud, and I was surprised, but comforted seeing the wisdom of the crowds speaks exactly the top ten goals I have in mind.

43Things

Did you notice that money is not the first priority, fun is. And when was the last time you did something fun?

I love Ajax.InPlaceEditor, cause it allows me quickly edit a field by just clicking on the text value. If you have used Flickr, I am pretty sure you know what I meant.

It is easy to create an in-place-editor if you are using Ruby On Rails (RoR).

  # Controller
  class BlogController < ApplicationController
    in_place_edit_for :post, :title
  end

  # View
  <%= in_place_editor_field :post, 'title' %>

Problem

The problem with InPlaceEditor is when you enter an empty value, you lost the text where you can click to edit.

One way is to extend Ajax.InPlaceEditor to display “click to edit…” text if the value is empty.

But on some cases, that is not what you want. For example if the text field is a numeric value, you would want your model class to peform the ActiveRecord validation and display the validation message if user enters an invalid value. And you probably would not want to re-code the validation rules in Javascript.

Solution

This is a hack that extends ActiveController::Base to include an additional class method in_place_edit_with_validation_for, which basically displays an alert box containing the model error messages is it is not valid.

And this is how you go about doing it:

  1. Create custom_in_place_editing.rb and save it in [app_root]/lib directory.
    module ActionController
      module Macros
       module CustomInPlaceEditing
        def self.included(base)
         base.extend(ClassMethods)
        end
       
        module ClassMethods
         def in_place_edit_with_validation_for(object, attribute)
          define_method("set_#{object}_#{attribute}") do
           klass = object.to_s.camelize.constantize
          @item = klass.find(params[:id])
          @item.send("#{attribute}=", params[:value])
           if @item.save
            render :update do |page| 
             page.replace_html("#{object}_#{attribute}_#{params[:id]}_in_place_editor", 
             @item.send(attribute))
            end
           else
            render :update do |page|
             page.alert(@item.errors.full_messages.join("\n"))
             klass.query_cache.clear_query_cache if klass.method_defined?:query_cache
             @item.reload
             page.replace_html("#{object}_#{attribute}_#{params[:id]}_in_place_editor", 
             @item.send(attribute))
            end
           end
          end
         end
        end
       end
      end
    end
    
    ActionController::Base.class_eval do
      include ActionController::Macros::CustomInPlaceEditing
    end
    
  2. Update the following files accordingly:
       # Controller file
       class ProductController < ApplicationController
         in_place_edit_with_validation_for :product, :price
       end
       
       # View file, remember to set the :script option to true
       # Rails 1.2.3
       <%= in_place_editor_field :product, :price, :script => true %>
    
       # Rails on edge
       <%= in_place_editor_field :product, :price, {}, :script => true %>
    
       # [app_root]/config/environment.rb 
       require 'custom_in_place_editing'
    
  3. Restart your server instance.

And that’s it, there is no other step, you are done.

A Thousand More Livings

WED, 14 MAR 2007

Bako National Park

I was looking through some of the old photos I have, and I found this sunset photo I took about a year and a half ago in Bako National Park, Malaysia.

Nowadays, we hardly can find a quiet beach, and I was lucky that day; after setting up my camera on a tripod, I saw two people taking a stroll on the beach, so I swiftly pressed the remote shutter release and took this beautiful snap.

After taking that snap, I could not resist not to take a stroll at such a beautiful day.

It was the best stroll I ever had in my life, the beach was tranquil, the sky, the sands, my self, and everything else were painted amber; all were warmed by the the gentle sun, slowly hiding itself behind the hill; and the steps I left behind on the sands were quickly washed out by the small waves hitting the beach, the sea water was warm, the air was a bit salty, it was a bit windy, very releaxing, almost perfect, as if God made that day just for me.

I really miss a day like this, and I greed for more in the future, but sometimes we do need to make the time for it; if we do not seek, how then we will ever find.

Thus this year, I promised my wife and myself to climb Mount Kinabalu, and I hope I will be lucky again this time. Hope the sky will be clear and we will have enough stamina to make it to the top. Seeing sunrise on top of the highest mountain in south-east asia… priceless.

Experience like this really makes life worth a living, and… a thousand more livings if God does not forbid.

Nexus 2007, Are You Going?

MON, 12 MAR 2007

NexusThere has been a lot of buzz about un-conferences lately with the events organised by Barcamp and Enterpreneur 27. But this month, the event gets slightly bigger, it’s back to a conference style, called Nexus 2007, organised by Digital Movement.

If you have heard of Barcamp and Entrepreneur 27, you probably should have heard about Digital Movement, if you are not, well, they are basically a bunch of young people who are craving for technology and business, they are the new generation of technology enthusiasts who are ‘curious, fun, informal’, and avoid ‘hierarchy and formality’. Yeah, I don’t like those two as well.

Nexus 2007 aims to discuss fundamental changes happening in business and technology, and how to take the lead in them. Though I have my doubt I’ll be able to take the lead by just attending one conference, I still hope so. Irregardless, I believe it is going to be an exciting event.

It is probably the first conference Digital Movement organise (I looked at the past events, none seems to be a conference), yet I’m already impressed with the people they have lined up:

  • David Miller, President, Asia Pacific/Japan, Lenovo
  • Andreas Weigend, Former Chief Scientist of Amazon.com
  • Cory Ondrejka, CTO, Linden Labs (Second Life)
  • Nathan Torkington, O’Reilly Radar
  • Kathy Teo, MD, CNET Networks Asia Pacific
  • Jennifer Lewis, Editor, Stomp
  • James Seng, Editor, Tomorrow.SG
  • Velvet Puffin, co-founder and CEO, R. Chandrasekar

And there are more, please check out the agenda here.

Since Digital Movement belives in ‘fun’, the registration is only $15, inclusive of 2 tea breaks and lunch; coz it won’t be fun anymore if it costs a couple of hundred bucks, right? Well, I heard some rumours that half the seats are already taken up, so if you are going, you probably should register now.

For those who are going, c ya there.

p.s. I’ve warned you that Digital Movement comprises of highly enthusiastic young people, they won’t be satisfied with Nexus alone, there’s a preliminary event on 22nd March, called GeekOut, a platform where technologists can show off their toys. If you knock off from office early that day, you may want to check it out too.

Bullshit Generator

FRI, 2 MAR 2007

It is easy for people to bullshit about their product or service, in fact it is so easy now that you can automate the process.

Leslie Lee did just that, he has written a JavaScript that randomly combines commonly used verbs, adjectives and nouns people use to bullshit.

I bumped into his script again yesterday; I have tried his bullshit generator before, yet I could not resist not to try it again. This time, I tried five times, and the results sill sound as impressive as before… still sound like pretty good bullshits.

  • optimize leading-edge methodologies
  • target efficient e-business
  • benchmark world-class e-markets
  • empower viral niches
  • iterate holistic supply-chains

Don’t believe me? Go and try it yourself. And I even found a Bullshit book recently.

I used to hate Javascript, but thanks to Sam Stephenson for the Prototype Javascript library, coding Javascript is no longer the same with what it used to be.

One of key features provided by Prototype library is the extension of HTML Elements, Form and Form Elements. Form refers to the form object, while Form Elements refer to the input fields, text area and selection boxes. The extension includes really useful helper methods, such as:

  • for Elements, e.g. addClassName(), descendentOf(), toggle()
  • for Form, e.g. disable(), serialize(), and reset(),
  • for Form Elements, e.g. activate(), clear(), getValue()

Please refer to Prototype API reference documentation for the description of each function, and there are a lot more helper methods available.

To access the helper methods, you need to retrieve the element using Prototype utility method $('[element-name]'):

$('[element-name]').toggle();
$('[form-name]').reset();
$('[form-element-name]').getValue();

While most of the helper methods extension provided by Prototype should satisfy your needs, but at times when you may want to extend those methods. So how do you go about doing that?

A simple example, the Element extension provides the toggle() method that hides and shows an element, but if at times, you may want to toggle an element and at the same time toggle another element. For example, clicking on ‘Add new category’ will hide the link and show the add category form, and vice versa, clicking on ‘Cancel’ will hide the form and show ‘Add new category’ link.

Add Category

So you thought of introducing toggleWith() method, instead of calling two statements seperately:

$('[link-id]').toggle();
$('[form-id]').toggle();

And this is how you can extend the Element methods:

// Extend Element.Methods with new functions 
// For form and form elements, use Form.Methods and 
// Form.Element.Methods
Object.extend(Element.Methods, {
    // the first argument refers to the called element
    toggleWith: function(element, otherElement) {
        element.toggle();
        $(otherElement).toggle();
    }

    [, ... other functions if there's any ]
);

// Call this to reflect the new functions
Element.addMethods();

// Now you can call the new function
$('[link-id]').toggleWith('[form-id]');

If you use Scriptaculous library and you may want to extend your toggle method with the blind down effect:

Object.extend(Element.Methods, {
    toggleWith: function(element, otherElement) {
        element.toggle();
        new Effect.BlindDown(otherElement, {duration: 0.2});
    }
);

If you are learning Prototype, I would suggest that you use Firefox and install DevBoi and DevBoi: Prototype JS Reference; with those in place, you can easily call up Prototype API reference on Firefox sidebar by simply pressing Ctrl-F9.

For form elements like a check box you may want to introduce the toggleAll() method to toggle all other checkboxes with the same class name, and toggleMaster() to uncheck the master checkbox if any of the children boxes is unchecked, they will come in handy.

As for other extensions, no problem for now, you already know how to do it.