right-rails 0.3.0
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.
- data/MIT-LICENSE +20 -0
- data/README.textile +50 -0
- data/Rakefile +23 -0
- data/generators/right_rails/right_rails_generator.rb +41 -0
- data/generators/right_rails/templates/iframed.html.erb +10 -0
- data/generators/right_scaffold/right_scaffold_generator.rb +53 -0
- data/generators/right_scaffold/templates/controller.rb +99 -0
- data/generators/right_scaffold/templates/helper.rb +2 -0
- data/generators/right_scaffold/templates/layout.html.erb +18 -0
- data/generators/right_scaffold/templates/style.css +54 -0
- data/generators/right_scaffold/templates/view__form.html.erb +16 -0
- data/generators/right_scaffold/templates/view__item.html.erb +13 -0
- data/generators/right_scaffold/templates/view_edit.html.erb +6 -0
- data/generators/right_scaffold/templates/view_index.html.erb +9 -0
- data/generators/right_scaffold/templates/view_new.html.erb +5 -0
- data/generators/right_scaffold/templates/view_show.html.erb +10 -0
- data/init.rb +12 -0
- data/javascripts/right-autocompleter-src.js +303 -0
- data/javascripts/right-autocompleter.js +9 -0
- data/javascripts/right-behavior-src.js +240 -0
- data/javascripts/right-behavior.js +8 -0
- data/javascripts/right-calendar-src.js +855 -0
- data/javascripts/right-calendar.js +9 -0
- data/javascripts/right-dnd-src.js +555 -0
- data/javascripts/right-dnd.js +9 -0
- data/javascripts/right-effects-src.js +425 -0
- data/javascripts/right-effects.js +6 -0
- data/javascripts/right-events-src.js +369 -0
- data/javascripts/right-events.js +6 -0
- data/javascripts/right-json-src.js +176 -0
- data/javascripts/right-json.js +6 -0
- data/javascripts/right-lightbox-src.js +597 -0
- data/javascripts/right-lightbox.js +9 -0
- data/javascripts/right-rails-src.js +269 -0
- data/javascripts/right-rails.js +9 -0
- data/javascripts/right-rater-src.js +248 -0
- data/javascripts/right-rater.js +9 -0
- data/javascripts/right-selectable-src.js +507 -0
- data/javascripts/right-selectable.js +7 -0
- data/javascripts/right-slider-src.js +291 -0
- data/javascripts/right-slider.js +7 -0
- data/javascripts/right-sortable-src.js +221 -0
- data/javascripts/right-sortable.js +9 -0
- data/javascripts/right-src.js +4939 -0
- data/javascripts/right-tabs-src.js +776 -0
- data/javascripts/right-tabs.js +6 -0
- data/javascripts/right-tooltips-src.js +130 -0
- data/javascripts/right-tooltips.js +9 -0
- data/javascripts/right-ui-i18n-de.js +29 -0
- data/javascripts/right-ui-i18n-en-us.js +11 -0
- data/javascripts/right-ui-i18n-es.js +29 -0
- data/javascripts/right-ui-i18n-fr.js +29 -0
- data/javascripts/right-ui-i18n-jp.js +33 -0
- data/javascripts/right-ui-i18n-ru.js +29 -0
- data/javascripts/right-ui-i18n-uk.js +29 -0
- data/javascripts/right.js +10 -0
- data/lib/right-rails.rb +11 -0
- data/lib/right_rails/controller_extensions.rb +85 -0
- data/lib/right_rails/helpers/basic.rb +111 -0
- data/lib/right_rails/helpers/forms.rb +239 -0
- data/lib/right_rails/helpers/misc.rb +164 -0
- data/lib/right_rails/helpers/rails.rb +166 -0
- data/lib/right_rails/helpers.rb +5 -0
- data/lib/right_rails/java_script_generator.rb +313 -0
- data/lib/right_rails.rb +6 -0
- data/spec/lib/right_rails/controller_extensions_spec.rb +60 -0
- data/spec/lib/right_rails/helpers/basic_spec.rb +74 -0
- data/spec/lib/right_rails/helpers/forms_spec.rb +51 -0
- data/spec/lib/right_rails/helpers/misc_spec.rb +120 -0
- data/spec/lib/right_rails/helpers/rails_spec.rb +149 -0
- data/spec/lib/right_rails/java_script_generator_spec.rb +317 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +15 -0
- metadata +128 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
#
|
2
|
+
# Basic RightRails feature helpers container
|
3
|
+
#
|
4
|
+
module RightRails::Helpers::Basic
|
5
|
+
|
6
|
+
#
|
7
|
+
# Automatically generates the javascript include tags
|
8
|
+
#
|
9
|
+
# USAGE:
|
10
|
+
# <%= rightjs_scripts %>
|
11
|
+
#
|
12
|
+
# you can also predefine the list of modules to load
|
13
|
+
#
|
14
|
+
# <%= rightjs_scripts 'lightbox', 'calendar' %>
|
15
|
+
#
|
16
|
+
def rightjs_scripts(*modules)
|
17
|
+
scripts = ['right']
|
18
|
+
|
19
|
+
# including the submodules
|
20
|
+
rightjs_include_module *modules
|
21
|
+
((@_right_scripts || []) + ['rails']).each do |package|
|
22
|
+
scripts << "right/#{package}"
|
23
|
+
end
|
24
|
+
|
25
|
+
# use the sources in the development environment
|
26
|
+
if defined? RAILS_ENV && RAILS_ENV == 'development'
|
27
|
+
scripts.collect!{ |name| name + '-src' }
|
28
|
+
end
|
29
|
+
|
30
|
+
# include the localization script if available
|
31
|
+
if defined?(I18n) && defined?(RAILS_ROOT)
|
32
|
+
locale_file = "right/i18n/#{I18n.locale.to_s.downcase}"
|
33
|
+
scripts << locale_file if File.exists? "#{RAILS_ROOT}/public/javascripts/#{locale_file}.js"
|
34
|
+
end
|
35
|
+
|
36
|
+
javascript_include_tag *scripts
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# The javascript generator access from the templates
|
41
|
+
#
|
42
|
+
# USAGE:
|
43
|
+
# Might be used both directly or with a block
|
44
|
+
#
|
45
|
+
# <%= link_to 'Delete', '#', :onclick => rjs[@record].hide('fade') %>
|
46
|
+
# <%= link_to 'Delete', '#', :onclick => rjs{|page| page[@record].hide('fade') }
|
47
|
+
#
|
48
|
+
def rjs(&block)
|
49
|
+
generator = RightRails::JavaScriptGenerator.new(self)
|
50
|
+
yield(generator) if block_given?
|
51
|
+
generator
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Same as the rjs method, but will wrap the generatated code
|
56
|
+
# in a <script></script> tag
|
57
|
+
#
|
58
|
+
# EXAMPLE:
|
59
|
+
# <%= rjs_tag do |page|
|
60
|
+
# page.alert 'boo'
|
61
|
+
# end %>
|
62
|
+
#
|
63
|
+
def rjs_tag(&block)
|
64
|
+
javascript_tag do
|
65
|
+
rjs(&block)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# protected
|
70
|
+
|
71
|
+
#
|
72
|
+
# Notifies the scripts collection that the user needs the module
|
73
|
+
#
|
74
|
+
def rightjs_include_module(*list)
|
75
|
+
@_right_scripts ||= []
|
76
|
+
list.each do |name|
|
77
|
+
@_right_scripts << name.to_s unless @_right_scripts.include?(name.to_s)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Collects the RightJS unit options out of the given list of options
|
83
|
+
#
|
84
|
+
# NOTE: will nuke matching keys out of the original options object
|
85
|
+
#
|
86
|
+
# @param user's options
|
87
|
+
# @param allowed unit options keys
|
88
|
+
#
|
89
|
+
def rightjs_unit_options(options, unit_keys)
|
90
|
+
unit_options = []
|
91
|
+
|
92
|
+
options.dup.each do |key, value|
|
93
|
+
c_key = key.to_s.camelize.gsub!(/^[A-Z]/){ |m| m.downcase }
|
94
|
+
|
95
|
+
if unit_keys.include?(c_key)
|
96
|
+
value = options.delete key
|
97
|
+
|
98
|
+
value = case value.class.name.to_sym
|
99
|
+
when :NilClass then 'null'
|
100
|
+
when :Symbol then "#{value}"
|
101
|
+
when :String then "'#{value}'"
|
102
|
+
else value.inspect
|
103
|
+
end
|
104
|
+
|
105
|
+
unit_options << "#{c_key}:#{value}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
"{#{unit_options.sort.join(',')}}"
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,239 @@
|
|
1
|
+
#
|
2
|
+
# RightJS specific form features module
|
3
|
+
#
|
4
|
+
module RightRails::Helpers::Forms
|
5
|
+
CALENDAR_OPTION_KEYS = %w{
|
6
|
+
format
|
7
|
+
showTime
|
8
|
+
twentyFourHour
|
9
|
+
timePeriod
|
10
|
+
showButtons
|
11
|
+
minDate
|
12
|
+
maxDate
|
13
|
+
firstDay
|
14
|
+
numberOfMonths
|
15
|
+
listYears
|
16
|
+
}
|
17
|
+
|
18
|
+
AUTOCOMPLETER_OPTION_KEYS = %w{
|
19
|
+
param
|
20
|
+
method
|
21
|
+
minLength
|
22
|
+
threshold
|
23
|
+
cache
|
24
|
+
local
|
25
|
+
fxName
|
26
|
+
fxDuration
|
27
|
+
spinner
|
28
|
+
}
|
29
|
+
|
30
|
+
SLIDER_OPTION_KEYS = %w{
|
31
|
+
min
|
32
|
+
max
|
33
|
+
snap
|
34
|
+
value
|
35
|
+
direction
|
36
|
+
update
|
37
|
+
round
|
38
|
+
}
|
39
|
+
|
40
|
+
RATER_OPTION_KEYS = %w{
|
41
|
+
size
|
42
|
+
value
|
43
|
+
update
|
44
|
+
disabled
|
45
|
+
disableOnVote
|
46
|
+
url
|
47
|
+
param
|
48
|
+
Xhr
|
49
|
+
}
|
50
|
+
|
51
|
+
#
|
52
|
+
# Generates the calendar field tag
|
53
|
+
#
|
54
|
+
# The options might contain the usual html options along with the RightJS Calendar options
|
55
|
+
#
|
56
|
+
def calendar_field_tag(name, value=nil, options={})
|
57
|
+
text_field_tag name, value, __add_calendar_field_options(options)
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# The form_for level calendar field generator
|
62
|
+
#
|
63
|
+
def calendar_field(object_name, method, options={})
|
64
|
+
options = __add_calendar_field_options(options)
|
65
|
+
ActionView::Helpers::InstanceTag.new(object_name, method, self, options.delete(:object)).to_calendar_field_tag(options)
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Autocompletion field tag
|
70
|
+
#
|
71
|
+
# The options should contain an url or a list of local options
|
72
|
+
#
|
73
|
+
def autocomplete_field_tag(name, value, options)
|
74
|
+
text_field_tag name, value, __add_autocomplete_field_options(options)
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# The form_for level autocomplete-field generator
|
79
|
+
#
|
80
|
+
def autocomplete_field(object_name, method, options)
|
81
|
+
options = __add_autocomplete_field_options(options)
|
82
|
+
ActionView::Helpers::InstanceTag.new(object_name, method, self, options.delete(:object)).to_autocomplete_field_tag(options)
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# The slider widget generator
|
87
|
+
#
|
88
|
+
def slider_tag(name, value=nil, options={})
|
89
|
+
hidden_field_tag(name, value, __add_slider_options(options)) + "\n" + __slider_generator(options.merge(:value => value), name)
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# The form_for level slider widget generator
|
94
|
+
#
|
95
|
+
def slider(object_name, method, options={})
|
96
|
+
ActionView::Helpers::InstanceTag.new(object_name, method, self,
|
97
|
+
options.delete(:object)).to_slider_tag(__add_slider_options(options)) +
|
98
|
+
"\n" + __slider_generator(options, object_name, method)
|
99
|
+
end
|
100
|
+
|
101
|
+
#
|
102
|
+
# The rater widget basic generator
|
103
|
+
#
|
104
|
+
def rater_tag(name, value, options={})
|
105
|
+
hidden_field_tag(name, value, __add_rater_options(options)) + "\n" + __rater_generator(options.merge(:value => value), name)
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
# The form level rater generator
|
110
|
+
#
|
111
|
+
def rater(object_name, method, options={})
|
112
|
+
ActionView::Helpers::InstanceTag.new(object_name, method, self,
|
113
|
+
options.delete(:object)).to_rater_tag(__add_rater_options(options)) +
|
114
|
+
"\n" + __rater_generator(options, object_name, method)
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# Builds a dummy rater, just for displaying purposes
|
119
|
+
#
|
120
|
+
def rater_display(value, options={})
|
121
|
+
content_tag :div, (0...(options[:size] || 5)).to_a.collect{ |i|
|
122
|
+
content_tag :div, '★', :class => i < value ? 'right-rater-glow' : nil
|
123
|
+
}.join(''), :class => 'right-rater right-rater-disabled'
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def __add_calendar_field_options(options={})
|
129
|
+
rightjs_include_module 'calendar'
|
130
|
+
|
131
|
+
options['rel'] = 'calendar'
|
132
|
+
|
133
|
+
calendar_options = rightjs_unit_options(options, CALENDAR_OPTION_KEYS)
|
134
|
+
options['data-calendar-options'] = calendar_options unless calendar_options == '{}'
|
135
|
+
|
136
|
+
options
|
137
|
+
end
|
138
|
+
|
139
|
+
def __add_autocomplete_field_options(options)
|
140
|
+
rightjs_include_module 'autocompleter'
|
141
|
+
|
142
|
+
options['rel'] = "autocompleter[#{escape_javascript(url_for(options.delete(:url)))}]"
|
143
|
+
|
144
|
+
autocompleter_options = rightjs_unit_options(options, AUTOCOMPLETER_OPTION_KEYS)
|
145
|
+
options['data-autocompleter-options'] = autocompleter_options unless autocompleter_options == '{}'
|
146
|
+
options['autocomplete'] = 'off'
|
147
|
+
|
148
|
+
options
|
149
|
+
end
|
150
|
+
|
151
|
+
def __add_slider_options(options)
|
152
|
+
rightjs_include_module 'dnd', 'slider'
|
153
|
+
options.reject { |key, value| SLIDER_OPTION_KEYS.include?(key.to_s) }
|
154
|
+
end
|
155
|
+
|
156
|
+
def __slider_generator(options, name, method=nil)
|
157
|
+
value = options[:value]
|
158
|
+
value ||= ActionView::Helpers::InstanceTag.value_before_type_cast(instance_variable_get("@#{name}"), method.to_s) if method
|
159
|
+
name = "#{name}[#{method}]" if method
|
160
|
+
id = options[:id] || sanitize_to_id(name)
|
161
|
+
options = rightjs_unit_options(options.merge(:value => value), SLIDER_OPTION_KEYS)
|
162
|
+
javascript_tag "new Slider(#{options}).insertTo('#{id}','after').assignTo('#{id}');"
|
163
|
+
end
|
164
|
+
|
165
|
+
def __add_rater_options(options)
|
166
|
+
rightjs_include_module 'rater'
|
167
|
+
options.reject { |key, value| RATER_OPTION_KEYS.include?(key.to_s) }
|
168
|
+
end
|
169
|
+
|
170
|
+
def __rater_generator(options, name, method=nil)
|
171
|
+
value = options[:value]
|
172
|
+
value ||= ActionView::Helpers::InstanceTag.value_before_type_cast(instance_variable_get("@#{name}"), method.to_s) if method
|
173
|
+
name = "#{name}[#{method}]" if method
|
174
|
+
id = options[:id] || sanitize_to_id(name)
|
175
|
+
options = rightjs_unit_options(options.merge(:value => value), RATER_OPTION_KEYS)
|
176
|
+
javascript_tag "new Rater(#{options}).insertTo('#{id}','after').assignTo('#{id}');"
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
|
181
|
+
###################################################################################
|
182
|
+
#
|
183
|
+
# The ActiveView native form-builder extensions
|
184
|
+
#
|
185
|
+
###################################################################################
|
186
|
+
|
187
|
+
module FormBuilderMethods
|
188
|
+
def calendar_field(name, options={})
|
189
|
+
@template.calendar_field(@object_name, name, objectify_options(options))
|
190
|
+
end
|
191
|
+
|
192
|
+
def autocomplete_field(name, options={})
|
193
|
+
@template.autocomplete_field(@object_name, name, objectify_options(options))
|
194
|
+
end
|
195
|
+
|
196
|
+
def slider(name, options={})
|
197
|
+
@template.slider(@object_name, name, objectify_options(options))
|
198
|
+
end
|
199
|
+
|
200
|
+
def rater(name, options={})
|
201
|
+
@template.rater(@object_name, name, objectify_options(options))
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
module InstanceTagMethods
|
206
|
+
def to_calendar_field_tag(options)
|
207
|
+
options = options.stringify_keys
|
208
|
+
|
209
|
+
# formatting the date/time value if the format is specified
|
210
|
+
if !options["value"] && options["data-calendar-options"]
|
211
|
+
format = options["data-calendar-options"].scan(/format:('|")(.+?)\1/)
|
212
|
+
time = value_before_type_cast(object)
|
213
|
+
if time && time.respond_to?(:to_time) && format.size == 1
|
214
|
+
options["value"] = time.to_time.strftime(format[0][1])
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
to_input_field_tag('text', options)
|
219
|
+
end
|
220
|
+
|
221
|
+
def to_autocomplete_field_tag(options)
|
222
|
+
to_input_field_tag('text', options)
|
223
|
+
end
|
224
|
+
|
225
|
+
def to_slider_tag(options)
|
226
|
+
to_input_field_tag('hidden', options)
|
227
|
+
end
|
228
|
+
|
229
|
+
def to_rater_tag(options)
|
230
|
+
to_input_field_tag('hidden', options)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def self.included(base)
|
235
|
+
ActionView::Helpers::FormBuilder.instance_eval{ include FormBuilderMethods }
|
236
|
+
ActionView::Helpers::InstanceTag.instance_eval{ include InstanceTagMethods }
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
#
|
2
|
+
# Misc view helpers for RightJS
|
3
|
+
#
|
4
|
+
module RightRails::Helpers::Misc
|
5
|
+
#
|
6
|
+
# Just a simple flashes generator, might be replaced in the application
|
7
|
+
#
|
8
|
+
def flashes
|
9
|
+
content_tag(:div, flash.collect{ |key, text|
|
10
|
+
content_tag(:div, text, :class => key)
|
11
|
+
}.sort, :id => :flashes, :style => (flash.empty? ? 'display: none' : nil))
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
#
|
16
|
+
# the autocompletion list result
|
17
|
+
#
|
18
|
+
# USAGE:
|
19
|
+
# it might work in several ways
|
20
|
+
#
|
21
|
+
# autocomplete_result(list_of_strings)
|
22
|
+
# autocomplete_result(list_of_strings, :highlight => 'search')
|
23
|
+
# autocomplete_result(list_of_strings, :highlight => 'search', :escape => false)
|
24
|
+
#
|
25
|
+
# autocomplete_result(list_of_objects, method)
|
26
|
+
# autocomplete_result(list_of_objects, method, :highlight => 'search')
|
27
|
+
#
|
28
|
+
def autocomplete_result(entries, *args)
|
29
|
+
return if entries.empty?
|
30
|
+
|
31
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
32
|
+
highlight = options[:highlight]
|
33
|
+
escape = options[:escape].nil? ? true : options[:escape]
|
34
|
+
field = args.first
|
35
|
+
|
36
|
+
content_tag :ul, entries.collect{ |entry|
|
37
|
+
entry = entry.send(field) if field
|
38
|
+
content_tag :li, highlight ? highlight(entry, highlight) : escape ? h(entry) : entry
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
#
|
44
|
+
# Generates a link that whil load the refered address in a lightbox
|
45
|
+
#
|
46
|
+
# USAGE:
|
47
|
+
# Same as the #link_to method, plus you might specify the :roadtrip argument
|
48
|
+
# to make it a link to a lightbox roadtrip
|
49
|
+
#
|
50
|
+
# <%= link_to_lightbox image_tag('/image.thmb'), '/image.full', :roadtrip => true %>
|
51
|
+
#
|
52
|
+
def link_to_lightbox(name, url={}, html_options=nil, &block)
|
53
|
+
rightjs_include_module 'lightbox'
|
54
|
+
|
55
|
+
html_options ||= {}
|
56
|
+
html_options[:rel] = 'lightbox'
|
57
|
+
html_options[:rel] << "[roadtrip]" if html_options.delete(:roadtrip)
|
58
|
+
|
59
|
+
link_to name, url, html_options, &block
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Tabs container generator
|
64
|
+
#
|
65
|
+
# USAGE:
|
66
|
+
#
|
67
|
+
# <% tabs do %>
|
68
|
+
# <% tab "Tab 1", :id => :my-tab-1 do %>
|
69
|
+
# content for tab 1
|
70
|
+
# <% end -%>
|
71
|
+
# <% tab "Tab 2", :url => tab2_path %>
|
72
|
+
# <% end -%>
|
73
|
+
#
|
74
|
+
# You also can use the :type option with :carousel or :harmonica value
|
75
|
+
# and you can pass along any standard Tabs unit options along with it
|
76
|
+
#
|
77
|
+
# <% tabs :type => :carousel, :url => '/tabs/%{id}', :cache => true do %>
|
78
|
+
# <% tab image_tag(image1.thumb_url), :id => image1.id %>
|
79
|
+
# <% tab image_tag(image2.thumb_url), :id => image2.id %>
|
80
|
+
#
|
81
|
+
def tabs(options={}, &block)
|
82
|
+
rightjs_include_module 'tabs'
|
83
|
+
@__tabs = []
|
84
|
+
yield()
|
85
|
+
|
86
|
+
options.stringify_keys!
|
87
|
+
|
88
|
+
tabs_type = options.delete('type')
|
89
|
+
options['id'] = options.delete('id') || "tabs-#{rand.to_s.split('.').last}"
|
90
|
+
|
91
|
+
# checking for the carousel class
|
92
|
+
if tabs_type == :carousel
|
93
|
+
options['class'] ||= ''
|
94
|
+
options['class'] << (options['class'] == '' ? '' : ' ') + 'right-tabs-carousel'
|
95
|
+
end
|
96
|
+
|
97
|
+
tabs_options = rightjs_unit_options(options, TABS_OPTION_KEYS)
|
98
|
+
options['data-tabs-options'] = tabs_options unless tabs_options == '{}'
|
99
|
+
|
100
|
+
# extracting the tab id prefix option
|
101
|
+
tab_id_prefix = tabs_options.scan(/idPrefix:('|")(.+?)\1/)
|
102
|
+
tab_id_prefix = tab_id_prefix.size == 1 ? tab_id_prefix[0][1] : ''
|
103
|
+
|
104
|
+
# simple tabs and carousels generator
|
105
|
+
content = if tabs_type != :harmonica
|
106
|
+
content_tag(:ul,
|
107
|
+
# tabs list
|
108
|
+
content_tag(:ul,
|
109
|
+
@__tabs.collect{ |tab|
|
110
|
+
content_tag(:li, content_tag(:a, tab[:title],
|
111
|
+
:href => tab[:options][:id] ? "##{tab[:options][:id]}" : tab[:options][:url]
|
112
|
+
))
|
113
|
+
}.join("\n")
|
114
|
+
) + "\n"+
|
115
|
+
|
116
|
+
# contents list
|
117
|
+
@__tabs.collect{|tab|
|
118
|
+
tab[:content] ? content_tag(:li, tab[:content], :id => "#{tab_id_prefix}#{tab[:options][:id]}") + "\n" : ''
|
119
|
+
}.join(""),
|
120
|
+
options
|
121
|
+
)
|
122
|
+
else
|
123
|
+
# the harmonicas generator
|
124
|
+
content_tag(:dl,
|
125
|
+
@__tabs.collect{ |tab|
|
126
|
+
content_tag(:dt, content_tag(:a, tab[:title],
|
127
|
+
:href => tab[:options][:id] ? "##{tab[:options][:id]}" : tab[:options][:url]
|
128
|
+
)) + "\n" +
|
129
|
+
content_tag(:dd, tab[:content] || '', :id => tab[:options][:id] ? "#{tab_id_prefix}#{tab[:options][:id]}" : nil)
|
130
|
+
}.join("\n"),
|
131
|
+
options
|
132
|
+
)
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
concat(content + "\n" + javascript_tag("new Tabs('#{options['id']}');"))
|
137
|
+
end
|
138
|
+
|
139
|
+
def tab(title, options={}, &block)
|
140
|
+
options[:id] = "tab-#{rand.to_s.split('.').last}" if !options[:id] && !options[:url]
|
141
|
+
|
142
|
+
@__tabs << {
|
143
|
+
:title => title,
|
144
|
+
:options => options,
|
145
|
+
:content => block_given? ? capture(&block) : nil
|
146
|
+
}
|
147
|
+
end
|
148
|
+
|
149
|
+
TABS_OPTION_KEYS = %w{
|
150
|
+
idPrefix
|
151
|
+
resizeFx
|
152
|
+
resizeDuration
|
153
|
+
scrollTabs
|
154
|
+
scrollDuration
|
155
|
+
selected
|
156
|
+
disabled
|
157
|
+
closable
|
158
|
+
url
|
159
|
+
cache
|
160
|
+
Xhr
|
161
|
+
Cookie
|
162
|
+
}
|
163
|
+
|
164
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
#
|
2
|
+
# This module contains the ruby-on-rails native (Prototype) helper replacements
|
3
|
+
#
|
4
|
+
module RightRails::Helpers::Rails
|
5
|
+
#
|
6
|
+
# Replacing the prototype's javascript generator with our own javascript generator
|
7
|
+
# so that the #link_to_function method was working properly
|
8
|
+
#
|
9
|
+
def update_page(&block)
|
10
|
+
rjs(&block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def remote_function(options)
|
14
|
+
cmd = build_xhr_request(options)
|
15
|
+
|
16
|
+
cmd = "#{options[:before]};#{cmd}" if options[:before]
|
17
|
+
cmd << ";#{options[:after]}" if options[:after]
|
18
|
+
|
19
|
+
cmd = "if(#{options[:condition]}){#{cmd}}" if options[:condition]
|
20
|
+
cmd = "if(confirm('#{escape_javascript(options[:confirm])}')){#{cmd}}" if options[:confirm]
|
21
|
+
|
22
|
+
cmd
|
23
|
+
end
|
24
|
+
|
25
|
+
def submit_to_remote(name, value, options = {})
|
26
|
+
options[:submit] ||= '$(this.form)'
|
27
|
+
|
28
|
+
html_options = options.delete(:html) || {}
|
29
|
+
html_options[:name] = name
|
30
|
+
|
31
|
+
button_to_remote(value, options, html_options)
|
32
|
+
end
|
33
|
+
|
34
|
+
def periodically_call_remote(options={})
|
35
|
+
frequency = options[:frequency] || 10 # every ten seconds by default
|
36
|
+
code = "function(){#{remote_function(options)}}.periodical(#{frequency * 1000})"
|
37
|
+
javascript_tag(code)
|
38
|
+
end
|
39
|
+
|
40
|
+
# stubbing the draggables generator to make our autoscripts stuff working
|
41
|
+
def draggable_element_js(*args)
|
42
|
+
rightjs_include_module 'dnd'
|
43
|
+
|
44
|
+
super *args
|
45
|
+
end
|
46
|
+
|
47
|
+
# stubbing the droppables generator
|
48
|
+
def drop_receiving_element_js(*args)
|
49
|
+
rightjs_include_module 'dnd'
|
50
|
+
|
51
|
+
super(*args).gsub!('Droppables.add', 'new Droppable'
|
52
|
+
).gsub!('element.id', 'draggable.element.id'
|
53
|
+
).gsub!('(element)', '(draggable)')
|
54
|
+
end
|
55
|
+
|
56
|
+
# catching the sortables generator
|
57
|
+
def sortable_element_js(id, options={})
|
58
|
+
rightjs_include_module 'dnd', 'sortable'
|
59
|
+
|
60
|
+
script = "new Sortable('#{id}'"
|
61
|
+
|
62
|
+
# processing the options
|
63
|
+
options[:url] = escape_javascript(url_for(options[:url])) if options[:url]
|
64
|
+
s_options = rightjs_unit_options(options, SORTABLE_OPTION_KEYS)
|
65
|
+
script << ",#{s_options}" unless s_options == '{}'
|
66
|
+
|
67
|
+
script << ")"
|
68
|
+
end
|
69
|
+
|
70
|
+
protected
|
71
|
+
|
72
|
+
SORTABLE_OPTION_KEYS = %w{
|
73
|
+
url
|
74
|
+
direction
|
75
|
+
tags
|
76
|
+
method
|
77
|
+
idParam
|
78
|
+
posParam
|
79
|
+
parseId
|
80
|
+
}
|
81
|
+
|
82
|
+
XHR_OPTION_KEYS = %w{
|
83
|
+
method
|
84
|
+
encoding
|
85
|
+
async
|
86
|
+
evalScripts
|
87
|
+
evalResponse
|
88
|
+
evalJSON
|
89
|
+
secureJSON
|
90
|
+
urlEncoded
|
91
|
+
spinner
|
92
|
+
spinnerFx
|
93
|
+
params
|
94
|
+
}
|
95
|
+
|
96
|
+
# builds the xhr request string
|
97
|
+
def build_xhr_request(options)
|
98
|
+
xhr = options[:submit] ? "new Xhr(" : "Xhr.load("
|
99
|
+
|
100
|
+
# assigning the url address
|
101
|
+
url = options[:url]
|
102
|
+
url = url.merge(:escape => false) if url.is_a?(Hash)
|
103
|
+
xhr << "'#{escape_javascript(url_for(url))}'"
|
104
|
+
|
105
|
+
# building the options
|
106
|
+
xhr_options = { :onSuccess => '', :onFailure => '', :onComplete => '' }
|
107
|
+
|
108
|
+
# grabbing the standard XHR options
|
109
|
+
options.each do |key, value|
|
110
|
+
if XHR_OPTION_KEYS.include?(key.to_s)
|
111
|
+
xhr_options[key] = case value.class.name.to_sym
|
112
|
+
when :NilClass then 'null'
|
113
|
+
when :Symbol then "#{value}"
|
114
|
+
when :String then "'#{value}'"
|
115
|
+
else value.inspect
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# checking the parameters options
|
121
|
+
xhr_options[:params] = options[:with] if options[:with]
|
122
|
+
|
123
|
+
# checking the callbacks
|
124
|
+
xhr_options[:onSuccess] = "#{options[:success]};" if options[:success]
|
125
|
+
xhr_options[:onFailure] = "#{options[:failure]};" if options[:failure]
|
126
|
+
xhr_options[:onComplete] = "#{options[:complete]};" if options[:complete]
|
127
|
+
|
128
|
+
# checking the update option
|
129
|
+
if options[:update]
|
130
|
+
template = options[:position] ? "$('%s').insert(this.text,'%s')" : "$('%s').update(this.text)%s"
|
131
|
+
|
132
|
+
if options[:update].is_a?(Hash)
|
133
|
+
xhr_options[:onSuccess] << template % [options[:update][:success], options[:position]] if options[:update][:success]
|
134
|
+
xhr_options[:onFailure] << template % [options[:update][:failure], options[:position]] if options[:update][:failure]
|
135
|
+
else
|
136
|
+
xhr_options[:onComplete] << template % [options[:update], options[:position]]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# converting the callbacks
|
141
|
+
[:onSuccess, :onFailure, :onComplete].each do |key|
|
142
|
+
if xhr_options[key] == '' then xhr_options.delete key
|
143
|
+
else xhr_options[key] = "function(request){#{xhr_options[key]}}"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# ebbedding the xhr options
|
148
|
+
pairs = xhr_options.collect do |key, value|
|
149
|
+
if value == '' then nil
|
150
|
+
else
|
151
|
+
"#{key}:#{value}"
|
152
|
+
end
|
153
|
+
end.compact.sort
|
154
|
+
|
155
|
+
xhr << ",{#{pairs.join(',')}}" unless pairs.empty?
|
156
|
+
|
157
|
+
xhr << ')'
|
158
|
+
|
159
|
+
# forms sending adjustements
|
160
|
+
xhr << ".send(#{options[:submit]})" if options[:submit]
|
161
|
+
xhr.gsub! /^.+?,/, '$(this).send(' if options[:form]
|
162
|
+
|
163
|
+
xhr
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|