<%= link_to 'New page', new_page_path %>
<div id="items">
<ul id='page-tree' >
<% for primary_page in @all_top_level_pages %>
<li id="<%= primary_page.dom_id %>">
<%= primary_page.title %><%= link_to "(+)", :action => "new", :id => primary_page%>
<%-if primary_page.children? %>
<ul class="edit_list">
<% for secondary_page in primary_page.children %>
<li id="<%= secondary_page.dom_id %>">
<%= secondary_page.title %><%= link_to "(+)", :action => "new", :id => secondary_page%>
<%- if secondary_page.children? %>
<ul id="sortable_list_<%= secondary_page.dom_id %>">
<% for tertiary_page in secondary_page.children %>
<li id="<%= tertiary_page.dom_id %>"><%= tertiary_page.title %></li>
<%- end -%>
</ul>
<%= sortable_element("sortable_list_#{secondary_page.dom_id}",
:url => {:action => 'update_positions',
:id => "sortable_list_#{secondary_page.dom_id}"}) %>
<% end %>
</li>
<%- end -%>
</ul>
<%- end -%>
</li>
<% end %>
</ul>
</div>
class PagesController < ApplicationController
def update_positions
# returned array contains the Page ids
Page.reorder_siblings(params[params[:id]])
@all_top_level_pages = Page.all_top_level_pages
end
def index
@pages = Page.find(:all)
@all_top_level_pages = Page.all_top_level_pages
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @pages }
end
end
end
# == Schema Information
# Schema version: 20080905194928
#
# Table name: pages
#
# id :integer(11) not null, primary key
# title :string(255)
# summary :string(255)
# body :text
# parent_id :integer(11)
# lft :integer(11)
# rgt :integer(11)
# created_at :datetime
# updated_at :datetime
#
class Page < ActiveRecord::Base
acts_as_nested_set
attr_accessor :child_of
def self.all_top_level_pages
Page.find(:all, :conditions => "parent_id = 1")
end
def self.reorder_siblings(siblings)
index = 0
@parent = nil
last_child = nil
# Heres were most of the work is done
siblings.each do |child|
this_child = Page.find(child)
# If last child is nil, then we know that we are dealing with the first item
# in the array
if(last_child.nil?)
last_child ||= this_child
else
# If we are here the we know that we need to take this child and
# move it to the right of the last child
this_child.move_to_right_of last_child
last_child = this_child
end
end
end
end
Refactorings
No refactoring yet !
Joe Grossberg
September 11, 2008, September 11, 2008 15:32, permalink
Not a refactoring, but three comments:
* are you certain all those LI id's are going to be unique? Otherwise, they're not valid HTML.
* you should split that view into partials, for readability
* if you're getting to the level or tertiary, you're probably trying to fit too much into your navigation; it's a UI "smell"
nathan
September 11, 2008, September 11, 2008 16:21, permalink
Thanks you so much for taking the time to respond. I am certain that the li tags will be unique. If by some chance they were to collide, I would have bigger issues then valid html,, like bad data.
Your right, the tree should be put in to a partial. I have done that this morning.
I agree with you about the UI smell, but unfortunately I have no say in the navigation rules.
I just have to make it work.
Thank you so much Joe! I plan to post later my own refactoring results.
Nate
October 3, 2008, October 03, 2008 02:27, permalink
This looks like a damn decent code snippet. Could I ask for a screenshot of how you have implemented it or of a basic implementation, just so that I can see how it looks? Also, could I please get permission to put this into a CMS project I am working on? Cheers. Nate
I have something, working related to the title, however i wanted to get a second opinion. I am
trying to create a manageable site navigation system using better_nested_set.
Primary level navigation:
is static to the user, and will not be manageable.
Secondary level navigation:
can be added to any primary level navs.
can be sortable
Tertiary level navigation:
can be added to any secondary level navs.
can be sortable.
Using Scriptaculous I wanted to be able and sort the Secondary and Tertiary nav items.
The following works, but leaves me again wonder if there is a better way.
If nothing else this post should be a little helpful for those using better_nested_set for a dynamic navigation.