bettertabs 1.3.6 → 1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,11 +9,14 @@ Bettertabs rails helper depends on the jquery.bettertabs plugin to work properly
9
9
  The jquery.bettertabs plugin is written using CoffeeScript.
10
10
  How to install CoffeeScript: http://jashkenas.github.com/coffee-script/#installation
11
11
 
12
- To install, first make sure you have a working copy of the latest stable version of Node.js, and npm (the Node Package Manager).
12
+ *OR* if you're lazzy and only care about a single compilation, use the online coffee compiler, copy-paste the js code and get back the coffee code, just in the [coffeescript web site](http://jashkenas.github.com/coffee-script/#installation). (if you do this way, please wrap the generated code with `(function() { --code-- }).call(this);`)
13
+
14
+ To install the coffee comand, first make sure you have a working copy of the latest stable version of Node.js, and npm (the Node Package Manager).
15
+
13
16
  You can then install CoffeeScript with npm:
14
17
 
15
18
  npm install coffee-script
16
-
19
+
17
20
 
18
21
  Then you will be able to compile `jquery.bettertabs.js.coffee` into `jquery.bettertabs.js` using the coffee command:
19
22
 
@@ -34,4 +37,4 @@ Online compressors:
34
37
  * http://refresh-sf.com/yui/
35
38
  * http://yui.2clics.net/
36
39
  * http://closure-compiler.appspot.com/home
37
- * http://compressorrater.thruhere.net/
40
+ * http://compressorrater.thruhere.net/
@@ -1,2 +1,15 @@
1
+ require 'bettertabs/configuration'
1
2
  require 'bettertabs/engine'
2
- require 'bettertabs/bettertabs_builder'
3
+ require 'bettertabs/bettertabs_builder'
4
+
5
+ module Bettertabs
6
+ class << self
7
+ def configuration
8
+ @configuration ||= Configuration.new
9
+ end
10
+
11
+ def configure
12
+ yield configuration
13
+ end
14
+ end
15
+ end
@@ -1,37 +1,48 @@
1
1
  class BettertabsBuilder
2
2
  require 'uri' # from standard library
3
-
3
+
4
4
  TAB_TYPES = [:static, :link, :ajax]
5
-
5
+
6
6
  def initialize(bettertabs_id, template, selected_tab_id = nil, options = {})
7
7
  @bettertabs_id = bettertabs_id
8
8
  @template = template
9
9
  @selected_tab_id = selected_tab_id
10
+ @list_html_options = options.delete(:list_html_options) # sets html_options on the :ul element
10
11
  @render_only_active_content = options.delete(:render_only_active_content) # used in ajax calls
11
12
  @wrapper_html_options = options
12
-
13
+
13
14
  @tabs = []
14
15
  @contents = []
15
16
  end
16
-
17
+
17
18
  # Static tabs generator
18
19
  def static(tab_id, *args, &block)
19
20
  get_options(args)[:tab_type] = :static
20
21
  self.for(tab_id, *args, &block)
21
22
  end
22
-
23
+
23
24
  # Linked tabs generator
24
25
  def link(tab_id, *args, &block)
25
26
  get_options(args)[:tab_type] = :link
26
27
  self.for(tab_id, *args, &block)
27
28
  end
28
-
29
+
29
30
  # Ajax tabs generator
30
31
  def ajax(tab_id, *args, &block)
31
32
  get_options(args)[:tab_type] = :ajax
32
33
  self.for(tab_id, *args, &block)
33
34
  end
34
-
35
+
36
+ # No tab generator, to add only content
37
+ def only_content_block(options = {}, &block)
38
+ content_html_options = {class: 'content content-only-block'}
39
+ unless @render_only_active_content
40
+ content = block_given? ? @template.capture(&block) : @template.render(:partial => options[:partial], :locals => options[:locals])
41
+ @contents << { content: content, html_options: content_html_options, tab_type: :only_content_block }
42
+ end
43
+ nil # returning nil allows the user to call this using <%= tab.only_content_block %> or <% tab.only_content_block %>
44
+ end
45
+
35
46
  # Generic tab and content generator
36
47
  def for(tab_id, *args, &block)
37
48
  # Initialize vars and options
@@ -40,25 +51,27 @@ class BettertabsBuilder
40
51
  tab_text = get_tab_text(tab_id, args)
41
52
  raise "Bettertabs: #{tab_html_id_for(tab_id)} error. Used :partial option and a block of content at the same time." if block_given? and options[:partial]
42
53
  partial = options.delete(:partial) || tab_id.to_s unless block_given?
54
+ raise "Bettertabs: #{tab_html_id_for(tab_id)} error. Used :locals option and a block of content at the same time." if block_given? and options[:locals]
55
+ locals = options.delete(:locals) unless block_given?
43
56
  url = options.delete(:url) || @template.params.merge(:"#{@bettertabs_id}_selected_tab" => tab_id)
44
57
  tab_type = (options.delete(:tab_type) || :static).to_sym
45
58
  raise "Bettertabs: #{tab_type.inspect} tab type not supported. Use one of #{TAB_TYPES.inspect} instead." unless TAB_TYPES.include?(tab_type)
46
59
  ajax_url = options.delete(:ajax_url) || url_for_ajax(url) if tab_type == :ajax
47
60
  @selected_tab_id ||= tab_id # defaults to first tab
48
-
61
+
49
62
  if @render_only_active_content
50
63
  if active?(tab_id)
51
- @only_active_content = block_given? ? @template.capture(&block) : @template.render(:partial => partial)
64
+ @only_active_content = block_given? ? @template.capture(&block) : @template.render(:partial => partial, :locals => locals)
52
65
  end
53
66
  else
54
67
  # Tabs
55
68
  tab_html_options = options # any other option will be used as tab html_option
56
69
  @tabs << { tab_id: tab_id, text: tab_text, url: url, ajax_url: ajax_url, html_options: tab_html_options, tab_type: tab_type, active: active?(tab_id) }
57
-
70
+
58
71
  # Content
59
72
  content_html_options = { id: content_html_id_for(tab_id), class: "content #{active?(tab_id) ? 'active' : 'hidden'}" }
60
73
  if active?(tab_id) or tab_type == :static # Only render content for selected tab (static content is always rendered).
61
- content = block_given? ? @template.capture(&block) : @template.render(:partial => partial)
74
+ content = block_given? ? @template.capture(&block) : @template.render(:partial => partial, :locals => locals)
62
75
  else
63
76
  content = ''
64
77
  end
@@ -66,7 +79,7 @@ class BettertabsBuilder
66
79
  end
67
80
  nil # returning nil allows the user to call this using <%= tab.for :xxx %> or <% tab.for :xxx %>
68
81
  end
69
-
82
+
70
83
  # Renders the bettertabs markup.
71
84
  # The following instance variables are available:
72
85
  # * @tabs: list of tabs. Each one is a hash with the followin keys:
@@ -90,16 +103,19 @@ class BettertabsBuilder
90
103
  if @render_only_active_content
91
104
  @only_active_content.html_safe
92
105
  else
93
-
106
+
94
107
  # Wrapper
95
108
  @wrapper_html_options ||= {}
96
109
  @wrapper_html_options[:"data-initial-active-tab-id"] = tab_html_id_for @selected_tab_id
97
- tag(:div, @wrapper_html_options) do
98
-
110
+ content_tag(:div, @wrapper_html_options) do
111
+
99
112
  # Tabs list
100
- tag(:ul, class: 'tabs') do
113
+ @list_html_options ||= {}
114
+ @list_html_options[:class] ||= ''
115
+ @list_html_options[:class] += @list_html_options[:class].empty? ? 'tabs' : ' tabs'
116
+ content_tag(:ul, @list_html_options) do
101
117
  @tabs.map do |tab|
102
- tag(:li, class: ('active' if tab[:active]), id: tab_html_id_for(tab[:tab_id])) do
118
+ content_tag(:li, class: ('active' if tab[:active]), id: tab_html_id_for(tab[:tab_id])) do
103
119
  tab[:html_options][:"data-tab-type"] ||= tab[:tab_type] # for javascript: change click behavior depending on type :static, :link or :ajax
104
120
  tab[:html_options][:"data-show-content-id"] ||= content_html_id_for(tab[:tab_id]) # for javascript: element id to show when select this tab
105
121
  tab[:html_options][:"data-ajax-url"] ||= tab[:ajax_url] if tab[:tab_type] == :ajax # for javascript: url to make ajax call
@@ -109,52 +125,52 @@ class BettertabsBuilder
109
125
  end
110
126
  end.join.html_safe
111
127
  end +
112
-
128
+
113
129
  # Content sections
114
130
  @contents.map do |content|
115
- tag(:div, content[:html_options]) do
131
+ content_tag(:div, content[:html_options]) do
116
132
  content[:content] # this should be blank unless content[:active] or content[:tab_type] == :static
117
133
  end
118
134
  end.join.html_safe
119
135
  end.html_safe
120
-
136
+
121
137
  end
122
138
  end
123
-
124
-
139
+
140
+
125
141
  private
126
-
142
+
127
143
  # Get the options hash from an array of args. If options are not present, create them and initialize to {}
128
144
  def get_options(args)
129
145
  args << {} unless args.last.is_a?(Hash)
130
146
  args.last
131
147
  end
132
-
148
+
133
149
  # Get the default name of the tab, from the args list.
134
150
  def get_tab_text(tab_id, args)
135
151
  String === args.first ? args.first : tab_id.to_s.titleize
136
152
  end
137
-
153
+
138
154
  # Check if this tab_id is the same as @selected_tab_id
139
155
  def active?(tab_id)
140
156
  @selected_tab_id.to_s == tab_id.to_s
141
157
  end
142
-
158
+
143
159
  # Tab html id
144
160
  def tab_html_id_for(tab_id)
145
161
  "#{tab_id}_#{@bettertabs_id}_tab"
146
162
  end
147
-
163
+
148
164
  # Content html id
149
165
  def content_html_id_for(tab_id)
150
166
  "#{tab_id}_#{@bettertabs_id}_content"
151
167
  end
152
-
153
- # Alias of @template.content_tag
154
- def tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
168
+
169
+ # Delegate @template.content_tag
170
+ def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
155
171
  @template.content_tag(name, content_or_options_with_block, options, escape, &block)
156
172
  end
157
-
173
+
158
174
  # Uses @template.url_for() to create the string url, and then URI.parse to add the ajax=true extra param.
159
175
  # This "ajax=true" extra param is important for two reasons:
160
176
  # * It makes easier from the controller to know when a request is ajax or not.
@@ -171,5 +187,5 @@ class BettertabsBuilder
171
187
  original_url
172
188
  end
173
189
  end
174
-
175
- end
190
+
191
+ end
@@ -0,0 +1,10 @@
1
+ module Bettertabs
2
+ class Configuration
3
+ attr_accessor :attach_jquery_bettertabs_inline
4
+
5
+ def initialize
6
+ # defaults
7
+ @attach_jquery_bettertabs_inline = false
8
+ end
9
+ end
10
+ end
@@ -1,3 +1,3 @@
1
1
  module Bettertabs
2
- VERSION = "1.3.6"
3
- end
2
+ VERSION = "1.4"
3
+ end
@@ -1,24 +1,27 @@
1
1
  class BettertabsController < ApplicationController
2
-
2
+
3
3
  def static
4
4
  end
5
-
5
+
6
6
  def link_tab_1
7
7
  end
8
-
8
+
9
9
  def link_tab_2
10
10
  end
11
-
11
+
12
12
  def ajax
13
13
  render partial: 'ajax' and return if request.xhr?
14
14
  end
15
-
15
+
16
+ def only_content_block
17
+ end
18
+
16
19
  def mixed
17
20
  render partial: 'mixed' and return if request.xhr?
18
21
  end
19
-
22
+
20
23
  def mixed_with_erb
21
24
  render partial: 'tab_content' and return if request.xhr? and params[:erb_test_selected_tab] == 'ajax_tab'
22
25
  end
23
-
26
+
24
27
  end
@@ -3,4 +3,6 @@
3
3
  Content for the link tab
4
4
  = tab.static :static_tab do
5
5
  Content for the static tab
6
- = tab.ajax :ajax_tab, partial: 'tab_content'
6
+ = tab.ajax :ajax_tab, partial: 'tab_content'
7
+ = tab.only_content_block do
8
+ This block is always visible (has not tab)
@@ -1 +1,4 @@
1
- tab_content partial content.
1
+ - if local_assigns.has_key? :local_var
2
+ = local_var
3
+ - else
4
+ tab_content partial content.
@@ -5,4 +5,7 @@
5
5
  <% end %>
6
6
  <%= tab.static :static_tab, partial: 'tab_content' %>
7
7
  <%= tab.ajax :ajax_tab, partial: 'tab_content' %>
8
- <% end %>
8
+ <%= tab.only_content_block do %>
9
+ This block is always visible (has not tab)
10
+ <% end %>
11
+ <% end %>
@@ -0,0 +1,12 @@
1
+ %h2 Testing Content Blocks (that have with no tab) mixed with static tabs
2
+ = bettertabs :static, :class => 'bettertabs example', :list_html_options => {:class => 'list_class'} do |tab|
3
+ = tab.only_content_block do
4
+ Content for only_content_block_1
5
+
6
+ = tab.static :static_tab_1 do
7
+ Content for static_tab_1
8
+
9
+ = tab.only_content_block :partial => 'tab_content', :locals => {:local_var => 'Content for only_content_block_2'}
10
+
11
+ = tab.static :static_tab_2 do
12
+ Content for static_tab_2
@@ -1,7 +1,10 @@
1
1
  %h2 Testing static tabs
2
- = bettertabs :static do |tab|
2
+ = bettertabs :static, :class => 'bettertabs example', :list_html_options => {:class => 'list_class'} do |tab|
3
+
3
4
  = tab.static :static_tab_1 do
4
5
  Content for static_tab_1
6
+
5
7
  = tab.static :static_tab_2 do
6
8
  Content for static_tab_2
7
- = tab.static :tab_content, 'Static Tab 3' # should render partial 'tab_content'
9
+
10
+ = tab.static :tab_content, 'Static Tab 3', :locals => {:local_var => 'Content for static_tab_3'} # should render partial 'tab_content'
@@ -14,13 +14,14 @@
14
14
  <%= link_to 'see code in Github', 'http://github.com/agoragames/bettertabs/tree/master/spec/dummy' %></br>
15
15
  For this demo, the hidden content is shown inside a dashed border to see what is loaded when you click a tab,</br>
16
16
  click on the links below to see different types of tabs (static, link or ajax).
17
-
17
+
18
18
  </p>
19
19
  <div class="nav">
20
- <%= link_to 'static', { action: 'static'}, title: 'Using only static tabs' %> |
21
- <%= link_to 'link', { action: 'link_tab_1'}, title: 'Using only link tabs' %> |
22
- <%= link_to 'ajax', { action: 'ajax'}, title: 'Using only ajax tabs' %> |
23
- <%= link_to 'mixed', { action: 'mixed'}, title: 'Using static, link and ajax tabs in the same widget' %> |
20
+ <%= link_to 'static', { action: 'static'}, title: 'Using only static tabs' %> |
21
+ <%= link_to 'link', { action: 'link_tab_1'}, title: 'Using only link tabs' %> |
22
+ <%= link_to 'ajax', { action: 'ajax'}, title: 'Using only ajax tabs' %> |
23
+ <%= link_to 'content blocks', { action: 'only_content_block'}, title: 'Also content with no tabs' %> |
24
+ <%= link_to 'mixed', { action: 'mixed'}, title: 'Using static, link and ajax tabs in the same widget' %> |
24
25
  <%= link_to 'mixed (erb)', { action: 'mixed_with_erb'}, title: 'Using static, link and ajax tabs in a ERB template' %>
25
26
  </div>
26
27
 
@@ -0,0 +1,6 @@
1
+ Bettertabs.configure do |config|
2
+ # Render a Javascript snippet to initialize the tabs automatically after rendering the tabs.
3
+ # This requires that you include jQuery before the tabs are rendered.
4
+ # Default: false
5
+ config.attach_jquery_bettertabs_inline = true
6
+ end
@@ -6,11 +6,12 @@
6
6
  # * options can be:
7
7
  # * :selected_tab => tab_id to select by default
8
8
  # * :selected_tab should be overridden with params[:"#{bettertabs_id}_selected_tab"] if present
9
+ # * :list_html_options => html_options for the :ul element
9
10
  # * any other option is used as wrapper html_options (wrapper is the top-level widget dom element).
10
11
  # * The bettertabs helper should render clear markup:
11
12
  # * A wrapper with class 'bettertabs'
12
13
  # * Tabs markup
13
- # * ul.tabs > li > a
14
+ # * ul.tabs > li > a
14
15
  # * selected tab is ul.tabs > li.active > a
15
16
  # * each a element has element attributes:
16
17
  # * data-tab-type (for javascript: change click behavior depending on type "static", "link" or "ajax")
@@ -34,82 +35,105 @@
34
35
  require 'spec_helper'
35
36
 
36
37
  describe "Bettertabs requests" do
38
+
37
39
  describe "GET /bettertabs/static" do
38
- before(:all) { get '/bettertabs/static' }
39
-
40
+ before(:all) { get '/bettertabs/static' }
41
+
40
42
  it "has a 200 status code" do
41
43
  response.status.should be(200)
42
44
  end
43
-
45
+
44
46
  it "should render all content even for hidden tabs" do
45
47
  response.body.should include("Content for static_tab_1")
46
48
  response.body.should include("Content for static_tab_2")
47
- response.body.should include("tab_content partial content")
49
+ response.body.should include("Content for static_tab_3")
48
50
  end
49
-
51
+
50
52
  it "should not include the attribute data-ajax-url in static tabs" do
51
53
  response.body.should_not include("data-ajax-url")
52
54
  end
55
+
56
+ it "should set the requested wrapper class" do
57
+ response.body.should have_selector("div.bettertabs.example")
58
+ end
59
+
60
+ it "should set the requested list class" do
61
+ response.body.should have_selector("ul.list_class")
62
+ end
53
63
  end
54
-
64
+
55
65
  describe "GET /bettertabs/link_tab_1" do
56
- before(:all) { get '/bettertabs/link_tab_1' }
66
+ before(:all) { get '/bettertabs/link_tab_1' }
57
67
  it "has a 200 status code" do
58
68
  response.status.should be(200)
59
69
  end
60
-
70
+
61
71
  it "should not include the attribute data-ajax-url in link tabs" do
62
72
  response.body.should_not include("data-ajax-url")
63
73
  end
64
-
74
+
65
75
  end
66
76
 
67
77
  describe "GET /bettertabs/link_tab_2" do
68
- before(:all) { get '/bettertabs/link_tab_2' }
78
+ before(:all) { get '/bettertabs/link_tab_2' }
69
79
  it "has a 200 status code" do
70
80
  response.status.should be(200)
71
81
  end
72
82
  end
73
83
 
74
84
  describe "GET /bettertabs/ajax" do
75
- before(:all) { get '/bettertabs/ajax' }
85
+ before(:all) { get '/bettertabs/ajax' }
76
86
  it "has a 200 status code" do
77
87
  response.status.should be(200)
78
88
  end
79
-
89
+
80
90
  it "should include the attribute data-ajax-url in ajax tabs" do
81
91
  response.body.should include("data-ajax-url")
82
92
  end
83
-
93
+
84
94
  it "should include the default ajax=true extra param in the data-ajax-url" do
85
95
  response.body.should include("data-ajax-url=\"/bettertabs/ajax/ajax_tab_2?ajax=true\"")
86
96
  end
87
-
97
+
88
98
  it "should render only the selected tab content" do
89
99
  response.body.should include("Content for the ajax_tab_1")
90
100
  response.body.should_not include("Content for the ajax_tab_2")
91
101
  end
92
-
102
+
93
103
  it "should select another tab if requested in the URL" do
94
104
  get '/bettertabs/ajax?ajax_selected_tab=ajax_tab_2'
95
105
  response.body.should_not include("Content for the ajax_tab_1")
96
106
  response.body.should include("Content for the ajax_tab_2")
97
107
  end
98
108
  end
99
-
109
+
110
+ describe "GET /bettertabs/only_content_block" do
111
+ before(:all) { get '/bettertabs/only_content_block' }
112
+
113
+ it "has a 200 status code" do
114
+ response.status.should be(200)
115
+ end
116
+
117
+ it "should render all content including content blocks" do
118
+ response.body.should include("Content for only_content_block_1")
119
+ response.body.should include("Content for static_tab_1")
120
+ response.body.should include("Content for only_content_block_2")
121
+ response.body.should include("Content for static_tab_2")
122
+ end
123
+ end
124
+
100
125
  describe "GET /bettertabs/mixed" do
101
- before(:all) { get '/bettertabs/mixed' }
126
+ before(:all) { get '/bettertabs/mixed' }
102
127
  it "has a 200 status code" do
103
128
  response.status.should be(200)
104
129
  end
105
130
  end
106
-
131
+
107
132
  describe "GET /bettertabs/mixed_with_erb" do
108
- before(:all) { get '/bettertabs/mixed_with_erb' }
133
+ before(:all) { get '/bettertabs/mixed_with_erb' }
109
134
  it "has a 200 status code" do
110
135
  response.status.should be(200)
111
136
  end
112
- end
137
+ end
113
138
 
114
-
115
139
  end