For both of these forms, we can use tabs to hide panes of information that aren't of interest and show panes that are of interest. Since this capability requires JavaScript, we'll make it so that all the panes are visible when the browser does not have JavaScript enabled. So it will still be ugly and ungainly but the JavaScript-enabled version will be nice and compact.
I'm going to try Ajax Tabs developed by Flinn Mueller, not that any of our panels will necessarily be loading from Ajax but because they look nice (I like Flinn's simple CSS) and because the code looks clean. Of course, I'll be modifying his code to suit our purposes but it's a good start.
For the contract form, there's an interesting challenge in that there will be two sets of tabbed panes. I don't think that will be a problem for the JavaScript to handle but we'll see. I'll document the final design.
UPDATE: I decided to go with the .tabs feature that is built-in to the jQuery UI library, which made the JS code nice and simple, inserted in the _tabs.html.haml partial (serializing the tab_container_id allows multiple tabbed panes on one page):
- id ||= "ui-tab-container#{i}"
= javascript_tag "jQuery(document).ready(function($) { $('##{id}').tabs() });"
I created a Rails helper function to create each pane and store it in an instance variable and then concat it into the view. It's working very nicely:
#---
# create a section for tabbing
# options:
# css_class = section div class (defaults to 'right')
#---
def create_tab(title, opts={}, &block)
raise ArgumentError, "Missing block" unless block_given?
@tabs ||= []
@tab_count ||= 1 # allow for multiple tab containers
# remove whitespace and create the CSS ID from the title (#title-pane)
id = "#{ActiveSupport::Inflector.underscore(title).gsub(/\W+/,'_')}-pane"
# capture into a string, the pane that the block creates
content = capture(&block)
# if client is not running javascript, create a fieldset as an alternate way of grouping it
# TODO: come up with a better CSS method to handle none-form panes
unless @js
content = capture { render :partial => 'shared/fieldset', :locals => {:legend => title, :content => content} }
end
# save off this pane for later output
@tabs << { :id => id, :title => title, :css_class => (opts[:css_class] || 'right'), :content => content }
end
def output_tabs(id=nil)
concat(capture { render :partial => "shared/tabs", :object => @tabs, :locals => {:id => id, :i => @tab_count} })
@tabs = []
@tab_count += 1
end
Oh, and although I built the ability to have multiple tabbed panes, I decided that the contract form really only needed one.
0 comments:
Post a Comment