2008/08/22

me.com simple UI










Well, on my ubuntu 8.04 file attachment was not working properly. It seems that the UI is so simple that it even makes me feels paying for this app is expensive.

Rails 2.1 OSX Finder like ColumnNav.

original google code : http://columnav.googlecode.com/svn/trunk/index.html

Update(22/8/2008):
Since ResponseHeader was "applicatoin/json ;utf8 ",
The original code does not work.

in columnav.js,
Before:
var contentType = o.getResponseHeader['Content-Type'];
if ('application/json' == contentType.replace(/\s+$/,'')) {

After:
var contentType = o.getResponseHeader['Content-Type'];
var compareString = contentType.replace(/\s+$/,'')
if (compareString.include('application/json')) {



It was not easy to implement "finder" with extjs. And furthermore, my codes were getting ugly. Almost hard to see. So I abandoned Extjs on the user-view. I've decided to use it on admin pages.



ColumNav is a hierarchical menu implementation utilizing Bill Scott's Yahoo UI Carousel component. Content is loaded from an unordered list and displayed in a scrollable viewport, similar to Column View in the Mac OS X Finder.


Features include:


  • infinite extensibility using Ajax to build sub-menus
  • instantiation from DOM or JSON data sources
  • a highly customizable look and feel using CSS
  • support for multiple columns
  • support for keyboard-only navigation (CTRL + arrow keys)
  • cross-browser compatibility

App/views/Categories/index.html



<% content_for :head do%>


<%= stylesheet_link_tag 'cssbits_notice' %>
<%= stylesheet_link_tag 'columnav', 'columnav_apply' %>
<%= javascript_include_tag :defaults %>
<%= javascript_include_tag "columnav/yui/yahoo-min" %>
<%= javascript_include_tag "columnav/yui/utilities" %>
<%= javascript_include_tag "columnav/yui/container_core-min" %>

<%= javascript_include_tag "columnav/carousel_min" %>
<%= javascript_include_tag "columnav/columnav" %>
<%= javascript_include_tag "columnav/columnav_json_parsing" %>


<% javascript_tag do %>
try { document.execCommand('BackgroundImageCache', false, true); } catch(e) {}


function init() {
var cn_cfg = {
numVisible: 3,
prevElement: 'columnav-prev',
datasource: '/categories/columntree/1.json'
};
var cn = new YAHOO.extension.ColumNav('columnav', cn_cfg);
}
YAHOO.util.Event.addListener(window, 'load', init);
<% end %>

<% end %>







App/controllers/Categories_controller.rb



def columntree(id = params[:id])
categories = Category.find_all_by_parent_id(id)

data = get_tree(categories, id)
respond_to do |format|
format.json { render :text => data[0].to_json, :layout => false }
end
end


def get_tree(categories, parent_id)
parent = Category.find_by_id(parent_id)
data = Array.new
data.concat([ "ul" => insert(categories, parent) ])
return data
end

def insert(categories, parent)
result = Array.new
result.concat(["li" => insert_data(categories, parent) ])
return result[0]
end

def insert_data(categories, parent)
iterated = Array.new
categories.each { |category|
if !category.leaf?
iterated.concat(["a" => {"#text" => category.text, "@href" => "/categories/columntree/"+category.id.to_s+".json", "@rel" => "ajax"}, "id" => category.id]) # "@rel" => "ajax" 면 폴더로 인식.
else
iterated.concat(["a" => {"#text" => category.text, "@href" => "http://peepcode.com"}, "id" => category.id])
end
}
return iterated
end



app/models/category.rb


class Category < dependent =""> :nullify
has_many :portfolios, :dependent => :nullify

acts_as_nested_set

validates_presence_of :text

has_attached_file :photo,
:styles => { :medium => "220x180#", :thumb => "100x82#" },
:path => "#{RAILS_ROOT}/public/images/category_photos/:id/:style_:basename.:extension",
:url => "/images/category_photos/:id/:style_:basename.:extension",
:default_url => "/images/category_photos/missing.png",
:whiny_thumbnails => true


#liquid
liquid_methods :text

# extjs를 위한 코드임

def self.root_nodes
find(:all, :conditions => 'parent_id IS NULL')
end

def self.find_children(start_id = nil)
start_id.to_i == 0 ? root_nodes : find(start_id).direct_children
end

def children
Category.find_all_by_parent_id(self.id)
end

def self.find_level1
find_all_by_parent_id(1)
end

def leaf
unknown? || children_count == 0
end

def leaf?
unknown? || children_count == 0
end


def to_json_with_leaf(options = {})
self.to_json_without_leaf(options.merge(:methods => :leaf))
end
alias_method_chain :to_json, :leaf
private
end

2008/08/14

SproutCore !!




For about 2 weeks, I studied and struggled to use extjs on my recent project.
As time goes, It became a mess. Because of javascript codes that are not organized well. For example, I wanted to make a browser like Finder which is default file browser on OSX. I had to find some way embed erb code in javascript(I used extscaffold plugin and I personally added some codes) By using extjs It was so hard that I almost thought it is time to move on. And I clicked on Sprout and dug into it while searching for snippets on google search results. I barely knew about beauty of it by the time I saw the test screen. You better see it by yourself. It's really awesome.

But one thing that bothers me is that it still does not support IE6, and IE7. I think it would take 3 or 4 months to be stable. And there will be "Merb in Action". It would be great to use Sproutcore with Merb. :)