{ 2011.7.2 }

rails と jquery treeview でディレクトリツリーをらくらく実装する

    はてなブックマーク - rails と jquery treeview でディレクトリツリーをらくらく実装する
    このエントリーをはてなブックマークに追加

    ども、Fusic 河野です。
    だいぶ久しぶりですね。

    今度の rubykaigi2011 に参加させて頂くこととなりました!
    会場で見かけたら、ぜひお気軽にお声をかけてくださいませ。

    [rubykaigi2011]
    rubykaigi.org/2011/

    それと、もう一つ告知です。
    来る7月28日(木)、福岡で活動している Androidの会福岡支部九州GTUG
    HTML5+α福岡iDevQ、そして、AppleKnight の4つのコミュニティが
    福岡県Ruby・コンテンツ産業振興センターに集結し、同時に勉強会、懇親会を行います。

    ご興味のある方は、ぜひともご参加ください!!
    参加登録は下記のリンク先より facebook にて参加表明をお願いいたします。

    [futuresync]
    futuresync.jp/

    さて、わたくし、前回の記事でも書きましたが、主に ruby on rails を
    やっており、ZENPRE の iPhone アプリを担当させていただいてます。

    今回とあるお客様の rails 案件にて、ツリービューを作る必要がありました。
    一から作ろうかと思っていたところ、jquery ui の treeview を見つけ、
    使ってみたので、簡単なサンプルとともにご紹介をします。

    いやー、それにしてもコレ凄く便利です!!

    まずは、バージョン確認です。

    $ ruby -v
    ruby 1.9.2p0 (2010-08-18 revision 29036) [i686-linux]
     
    $ rails -v
    Rails 3.0.9

    rails のプロジェクトを作成します。

    $ rails new treeview_test
    $ cd treeview_test/
    $ rm public/index.html

    prototype.js を削除ります。
    サヨナラ〜、お元気で〜♪

    $ vim Gemfile
     
    gem 'jquery-rails'
     
    $ rails g jquery:install

    ツリービューを表示するためのコントローラを作成します。

    $ rails g controller Treeviews index
    $ vim routes.rb
     
      root :to => "treeviews#index"

    そして、本日の主役のご登場!
    jquery treeview を下記よりダウンロードします。
    bassistance.de/jquery-plugins/jquery-plugin-treeview/

    js や css、jpg などを rails の各ディレクトリにコピーします。
    画像は、images に “treeview” というディレクトリを
    作成し、そこにコピーしています。
    そして、jquery.treeview.css に記載されている画像のパスを
    ちょっと変更します。

     images/xxxx → ../images/treeview/

    treeview を取り込みます。

    $ vim app/views/layouts/application.html.erb
     
    <!DOCTYPE html>
    <html>
    <head>
      <title>TreeviewTest</title>
      <%= stylesheet_link_tag :all %>
      <%= javascript_include_tag :defaults %>
      <%= javascript_include_tag 'jquery.treeview' %>
      <%= javascript_include_tag 'jquery.treeview.edit' %>
      <%= javascript_include_tag 'jquery.treeview.async' %>
      <%= csrf_meta_tag %>
    </head>
    <body>
     
    <%= yield %>
     
    </body>
    </html>

    ツリービューを表示するため view を書き換えます。

    $ vim app/views/treeviews/index.html.erb
     
    <script type="text/javascript">
    $(document).ready(function(){
      $("#example").treeview({});
    });
    </script>
     
    <ul id="example" class="filetree">
    	<li><span class="folder">Folder 1</span>
    		<ul>
    			<li><span class="file">Item 1.1</span></li>
    		</ul>
    	</li>
    	<li><span class="folder">Folder 2</span>
    		<ul>
    			<li><span class="folder">Subfolder 2.1</span>
    				<ul>
    					<li><span class="file">File 2.1.1</span></li>
    					<li><span class="file">File 2.1.2</span></li>
    				</ul>
    			</li>
    			<li><span class="file">File 2.2</span></li>
    		</ul>
    	</li>
    	<li class="closed"><span class="folder">Folder 3 (closed at start)</span>
    		<ul>
    			<li><span class="file">File 3.1</span></li>
    		</ul>
    	</li>
    	<li><span class="file">File 4</span></li>
    </ul>

    完成です!!
    いやー、ほんとめちゃくちゃ簡単ですね!!
    まー、これだけだと寂しいのとせっかくの rails も意味がないので
    rails にディレクトリ一覧を返す関数を作成し、ajax 使って
    ディレクトリ階層を動的に表示できるように変更します。
    おー!rails っぽいですね!

    routes にパスを追加します。

    $ vim config/routes</code>
     
      match '/treeviews/get_dir_list' => 'treeviews#get_dir_list'

    さっきの view を書き換えます。

    $ vim app/views/treeviews/index.html.erb
     
    <script type="text/javascript">
    $(document).ready(function(){
      $("#example").treeview({});
      $("#example2").treeview({
    		url: "<%= treeviews_get_dir_list_path %>"
      });
    });
    </script>
     
    <h4>通常のツリービュー表示</h4>
     
    <ul id="example" class="filetree">
    	<li><span class="folder">Folder 1</span>
    		<ul>
    			<li><span class="file">Item 1.1</span></li>
    		</ul>
    	</li>
    	<li><span class="folder">Folder 2</span>
    		<ul>
    			<li><span class="folder">Subfolder 2.1</span>
    				<ul>
    					<li><span class="file">File 2.1.1</span></li>
    					<li><span class="file">File 2.1.2</span></li>
    				</ul>
    			</li>
    			<li><span class="file">File 2.2</span></li>
    		</ul>
    	</li>
    	<li class="closed"><span class="folder">Folder 3 (closed at start)</span>
    		<ul>
    			<li><span class="file">File 3.1</span></li>
    		</ul>
    	</li>
    	<li><span class="file">File 4</span></li>
    </ul>
     
     
    <h4>sync させたツリービュー表示</h4>
    <ul id="example2" class="filetree"></ul>

    treeview の url に先ほど routes に追加したパスを記載します。

    controller もゴニョゴニョと追加します。

    $ vim app/controllers/treeviews_controller.rb
    class TreeviewsController < ApplicationController
     
      def index
      end
     
      def get_dir_list
        root_flg = (params["root"] == "source") ? true : false
        path = "./"
        path = params["root"] unless root_flg
        arry = []
        d = dir_list(path, arry)
        render :json => arry || [], :layout => false
      end
     
    protected
      def dir_list(path, arry=[], root_flg=false)
        Dir.glob("#{path}/*").map do |d|
          classes = "file"
          classes = "folder" if FileTest.directory?(d)
          hasChildren = (FileTest.directory?(d)) ? true : false
        	h = {"id" => d, "text" => File.basename(d), "path" => File.dirname(d), "expanded" => false, "classes" => classes, "hasChildren" => hasChildren, "children" => []}
          arry << h
        end
        arry
      end
     
    end

    dir_list() の関数でディレクトリ情報の hash を作成し、view 側に json で返します。
    返された json を treeview 側が解析してツリービューを表示します。
    返す hash の id のところがミソでして、ここにパスを記載していると
    treeview にてディレクトリを選択された場合、params["root"] に選択された
    ところのパスが渡されます。
    一番上のルートの場合には、params["root"] には、”source” という文字が渡ってきます。

    今回もいつもの如くソースは github にあげてます。
    また、サンプルをここに置いてますので実際の動作を確認できます。
    今回始めて dotcloud を使ってみました。
    これまためちゃくちゃ便利ですねー!
    dotcloud で rails を動かす方法とかは、また次回にでも、デモ。

    それでは、良い rails ライフを〜。

    [ソース]
    github.com/sora0513/TreeViewTest

    [デモ]
    8befe980.dotcloud.com/

    comments

    1. sim より:

      はじめまして。simと申します。日本語で説明されているjquery treeviewのなかで、このサイトが最も分かりやすく、参考にさせていただいています。このサイトを参考にソースを記述しているのですが、DropBox APIで取得したディレクトリ構造をjsonに格納(紹介いただいているような構造で格納しています)し、”render :json => arr2 || [], :layout => false”をコントローラからレンダリングし、viewに渡しているのですが、ブラウザに表示されるものは、json形式のデータのみ([{"id":"/110721_1310~01.jpg","text":"110721_1310~01.jpg","~~]}])が表示され、ディレクトリ表示がされません。何か考えられる原因はわかりますでしょうか。
      環境は, MacOSX (lion)、ruby 1.9.2p180、rails3.2.1、jquery treeview 1.4.1です。

    2. 河野 より:

      >sim さん
      コメントありがとうございます。
      僕がまだ rails 3.2.1 では試していないのですが、もしかして、
      rake assets:precompile とか関係ありますか??
      と想像で言ってみました。