rails-bootstrap-widgets 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.md +220 -0
- data/Rakefile +40 -0
- data/app/assets/javascripts/rails-bootstrap-widgets/application.js +15 -0
- data/app/assets/javascripts/rails-bootstrap-widgets/filters.js.coffee +12 -0
- data/app/assets/javascripts/rails-bootstrap-widgets/show_modal.js +26 -0
- data/app/helpers/rails-bootstrap-widgets/application_helper.rb +4 -0
- data/app/helpers/rails-bootstrap-widgets/filters_helper.rb +58 -0
- data/app/helpers/rails-bootstrap-widgets/modal_helper.rb +61 -0
- data/config/locales/en.yml +15 -0
- data/config/locales/ru.yml +15 -0
- data/lib/rails-bootstrap-widgets.rb +4 -0
- data/lib/rails-bootstrap-widgets/engine.rb +5 -0
- data/lib/rails-bootstrap-widgets/version.rb +3 -0
- data/lib/tasks/rails-bootstrap-widgets_tasks.rake +4 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +59 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +47 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/helpers/rails-bootstrap-widgets/filters_helper_spec.rb +50 -0
- data/spec/helpers/rails-bootstrap-widgets/modal_helper_spec.rb +75 -0
- data/spec/spec_helper.rb +14 -0
- metadata +356 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
# About [![Build Status](https://travis-ci.org/nepalez/widgets.png?branch=master)](https://travis-ci.org/nepalez/rails-bootstrap-widgets)
|
2
|
+
|
3
|
+
The project defines a collection of widgets to be used inside views. It also contains some js files to provide additional behavior for html elemets, created by those widgets. Both helpers and js are compatible with Twitter Bootstrap framework.
|
4
|
+
|
5
|
+
# Installation
|
6
|
+
|
7
|
+
Add this line to your application's ```Gemfile```:
|
8
|
+
```Ruby
|
9
|
+
gem 'rails-bootstrap-widgets'
|
10
|
+
```
|
11
|
+
And then execute:
|
12
|
+
```
|
13
|
+
$ bundle
|
14
|
+
```
|
15
|
+
Or install it yourself as:
|
16
|
+
```Ruby
|
17
|
+
$ gem install rails-bootstrap-widgets
|
18
|
+
```
|
19
|
+
# Available widgets
|
20
|
+
## List widgets
|
21
|
+
This group consists of two widgets to be used in views that contain items lists.
|
22
|
+
### pagination_widget (helper method)
|
23
|
+
```Ruby
|
24
|
+
pagination_widget(items, options = {})
|
25
|
+
```
|
26
|
+
The widget simply wraps pager (from the ```will-paginate``` gem) into the aside tag with some class.
|
27
|
+
#### Example
|
28
|
+
```Ruby
|
29
|
+
pagination_widget @items, class: 'pagination-top'
|
30
|
+
```
|
31
|
+
This will create
|
32
|
+
```Html
|
33
|
+
<aside class="pagination-top">
|
34
|
+
<!-- Standard result of 'will_paginate(items, inner_window: 0, outer_window: 0)' call -->
|
35
|
+
</aside>
|
36
|
+
```
|
37
|
+
### filters_widget (helper method)
|
38
|
+
```Ruby
|
39
|
+
filters_widget(items, options = {})
|
40
|
+
```
|
41
|
+
The widgets create html for filtering, ordering and paging a list of items. Provided html will include:
|
42
|
+
|
43
|
+
1. Input field to select filter from those are available
|
44
|
+
2. Input field to select order from those are available
|
45
|
+
3. (Hidden) button to reset filter values
|
46
|
+
4. Button to reload the page with new filter values
|
47
|
+
5. Items pager
|
48
|
+
|
49
|
+
This html code should provide basic functionality without js support.
|
50
|
+
|
51
|
+
If js support is turned on in a client's browser, jQuery method will show reset button (js required) and hide reload button. It also makes current page to be updated authomatically after new filter or ordering is selected, or reset button clicked.
|
52
|
+
|
53
|
+
#### Example
|
54
|
+
```Ruby
|
55
|
+
filters_widget (
|
56
|
+
@items,
|
57
|
+
filters: { published: :Published, unpublished: :Unpublished}, # list of filters to select from in a format { key: :name }
|
58
|
+
filter: 'published', # key of the current filter to apply to items
|
59
|
+
orders: { tree: :Tree, feed: :Feed }, # list of types of items ordering to select from
|
60
|
+
order: 'tree' # key of the current order type
|
61
|
+
)
|
62
|
+
```
|
63
|
+
This will provide html:
|
64
|
+
```HTML
|
65
|
+
<form accept-charset="UTF-8" action="/" class="span8" id="filters" method="get">
|
66
|
+
<div style="margin:0;padding:0;display:inline">
|
67
|
+
<input name="utf8" type="hidden" value="✓" />
|
68
|
+
</div>
|
69
|
+
<div class="input-prepend">
|
70
|
+
<span class="add-on">
|
71
|
+
<i class="icon-filter"></i>
|
72
|
+
</span>
|
73
|
+
<select id="filter" name="filter">
|
74
|
+
<option value="published" selected="selected">Published</option>
|
75
|
+
<option value="unpublished">Unpublished</option>
|
76
|
+
</select>
|
77
|
+
</div>
|
78
|
+
<div class="input-prepend">
|
79
|
+
<span class="add-on">
|
80
|
+
<i class="icon-order"></i>
|
81
|
+
</span>
|
82
|
+
<select id="order" name="order">
|
83
|
+
<option value="tree" selected="selected">Tree</option>
|
84
|
+
<option value="feed">Feed</option>
|
85
|
+
</select>
|
86
|
+
</div>
|
87
|
+
<a href="#" class="btn add-on hide" id="reset">
|
88
|
+
<i class="icon-reset"></i>
|
89
|
+
</a>
|
90
|
+
<div class="input-prepend" id="reload">
|
91
|
+
<span class="add-on">
|
92
|
+
<i class="icon-reload"></i>
|
93
|
+
</span>
|
94
|
+
<input class="btn" name="commit" type="submit" value="Reload" />
|
95
|
+
</div>
|
96
|
+
</form>
|
97
|
+
<aside class="span4">
|
98
|
+
<!-- Standard result of 'will_paginate(items, inner_window: 0, outer_window: 0)' call -->
|
99
|
+
</aside>
|
100
|
+
```
|
101
|
+
### Filters js support
|
102
|
+
The module adds file ```filters.js.coffee``` to ```app/assets/js/``` to authomatically reload current page after new filter or ordering selected by a user.
|
103
|
+
|
104
|
+
When current page is reloaded:
|
105
|
+
|
106
|
+
1. Filters reload button is removed (reloading became authomatic instead)
|
107
|
+
2. Filters reset button is added (it clears both filter and order field and reload the page with no filter|order set. They can be set by default within a controller)
|
108
|
+
3. Adds reloading the page on selecting new input field value (filter or order)
|
109
|
+
|
110
|
+
## Modal widgets and js
|
111
|
+
|
112
|
+
### modal_form_widget (helper method)
|
113
|
+
```Ruby
|
114
|
+
modal_form_widget(options = {}, &block)
|
115
|
+
```
|
116
|
+
The widget puts a list of fields (inputs, selectors etc.) into a modal form window (presented by ```<form id='modal' class='modal fade'...>```)
|
117
|
+
#### Details
|
118
|
+
```Ruby
|
119
|
+
modal_form_widget (
|
120
|
+
title: 'modal window title', # required
|
121
|
+
action: 'path to corresponding route', # required
|
122
|
+
method: 'request method for the form', # "post" by default, "post", "get", "put" or "delete" extected
|
123
|
+
button: 'text on the submit button', # I18n.t("buttons.submit") by default
|
124
|
+
cancel: 'text on the cancel form button' # I18n.t("buttons.cancel") by default
|
125
|
+
) do
|
126
|
+
"" # html code of form fields
|
127
|
+
end
|
128
|
+
```
|
129
|
+
#### Example
|
130
|
+
```Ruby
|
131
|
+
modal_form_widget(title: 'Title', button: 'Button', method: :put, action: '/some_addr', cancel: "Cancel") { "content" }
|
132
|
+
```
|
133
|
+
This will create
|
134
|
+
```Html
|
135
|
+
<form accept-charset="UTF-8" action="/some_addr" class="modal fade" data-remote="true" id="modal" method="post">
|
136
|
+
<div style="margin:0;padding:0;display:inline">
|
137
|
+
<input name="utf8" type="hidden" value="✓" />
|
138
|
+
</div>
|
139
|
+
<input id="_method" name="_method" type="hidden" value="put" />
|
140
|
+
<header class="modal-header">
|
141
|
+
<button aria-hidden="true" class="close" data-dismiss="modal" type="button">×</button>
|
142
|
+
<h1>Title</h1>
|
143
|
+
</header>
|
144
|
+
<div class="modal-body">content</div>
|
145
|
+
<div class="modal-footer">
|
146
|
+
<a href="#" aria-hidden="true" class="btn" data-dismiss="modal">Cancel</a>
|
147
|
+
<input class="btn btn-primary" id="submit" name="commit" type="submit" value="Button" />
|
148
|
+
</div>
|
149
|
+
</form>
|
150
|
+
```
|
151
|
+
### modal_view_widget (helper method)
|
152
|
+
```Ruby
|
153
|
+
modal_view_widget(options = {}, &block)
|
154
|
+
```
|
155
|
+
The widget puts html code into a modal window (presented by ```<div id='modal' class='modal fade'>```)
|
156
|
+
#### Details
|
157
|
+
```Ruby
|
158
|
+
modal_view_widget (
|
159
|
+
title: 'modal window title', # required
|
160
|
+
href: 'path for redirection to details', # required
|
161
|
+
redirect: true|false, # whether redirect button should be shown in the modal window footer (true by default),
|
162
|
+
button: 'text on the redirect button', # I18n.t("buttons.details") by default
|
163
|
+
cancel: 'text on the cancel form button' # I18n.t("buttons.cancel") by default
|
164
|
+
) do
|
165
|
+
"" # modal window's html content
|
166
|
+
end
|
167
|
+
```
|
168
|
+
#### Example
|
169
|
+
```Ruby
|
170
|
+
modal_view_widget(title: 'Title', button: 'Button', href: '/some_addr', cancel: "Cancel") { "content" }
|
171
|
+
```
|
172
|
+
This will create
|
173
|
+
```Html
|
174
|
+
<div class="modal fade" id="modal">
|
175
|
+
<header class="modal-header">
|
176
|
+
<button aria-hidden="true" class="close" data-dismiss="modal" type="button">×</button>
|
177
|
+
<h1>Title</h1>
|
178
|
+
</header>
|
179
|
+
<div class="modal-body">content</div>
|
180
|
+
<div class="modal-footer">
|
181
|
+
<a href="#" aria-hidden="true" class="btn" data-dismiss="modal">Cancel</a>
|
182
|
+
<a href="/some_addr" class="btn btn-primary">Button</a>
|
183
|
+
</div>
|
184
|
+
</div>
|
185
|
+
```
|
186
|
+
### showModal (js function)
|
187
|
+
```jQuery
|
188
|
+
showModal(href, template, width = nil)
|
189
|
+
```
|
190
|
+
Provides jQuery method "show_modal" to download and open modal window via ajax.
|
191
|
+
#### Arguments
|
192
|
+
```href``` - path to corresponding ajax request (required).
|
193
|
+
|
194
|
+
*When modal window is loaded, any link with selected ```href``` and ```data-remote='true'``` attribute is converted to modal window call. Direct links (without ```data-remote```) remain unchanged.*
|
195
|
+
|
196
|
+
*Before another modal window is loaded, the calls are reverted back to ajax links. Next time the modal should be downloaded by ajax again. To prevent excess downloading, use http request caching (see <a href='http://railscasts.com/episodes/321-http-caching'>RailsCast episode #321</a> for example).*
|
197
|
+
|
198
|
+
```template``` - path to modal window template (required).
|
199
|
+
|
200
|
+
*This template will be rendered and incerted by ajax to html - before the closing ```</body>``` tag.*
|
201
|
+
|
202
|
+
*Before another modal window is loaded, previous modal window is removed. Therefore at any given time the page will contain no more than one modal window*
|
203
|
+
|
204
|
+
```width``` - width in pixels for the modal link. If not set, the default bootstrap modal window is rendered.
|
205
|
+
|
206
|
+
#### Example
|
207
|
+
In the ```app/views/posts/show.js.coffee``` you could call:
|
208
|
+
```jQuery
|
209
|
+
showModal('<%= post_path(@item) %>', "<%= j render 'modal/show' %>")
|
210
|
+
```
|
211
|
+
# Contributing
|
212
|
+
|
213
|
+
1. Fork it
|
214
|
+
2. Create your feature branch (git checkout -b my-new-feature)
|
215
|
+
3. Commit your changes (git commit -am 'Add some feature')
|
216
|
+
4. Push to the branch (git push origin my-new-feature)
|
217
|
+
5. Create new Pull Request
|
218
|
+
|
219
|
+
# License
|
220
|
+
This project rocks and uses MIT-LICENSE.
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'RailsBootstrapWidgets'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.md')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
29
|
+
|
30
|
+
require 'rake/testtask'
|
31
|
+
|
32
|
+
Rake::TestTask.new(:test) do |t|
|
33
|
+
t.libs << 'lib'
|
34
|
+
t.libs << 'test'
|
35
|
+
t.pattern = 'test/**/*_test.rb'
|
36
|
+
t.verbose = false
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
task :default => :test
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// the compiled file.
|
9
|
+
//
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
12
|
+
//
|
13
|
+
//= require jquery
|
14
|
+
//= require jquery_ujs
|
15
|
+
//= require_tree .
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# removes reload and displays reset button to reset fields via ajax
|
3
|
+
jQuery ->
|
4
|
+
$(document).ready ->
|
5
|
+
$('form#filters #reset').removeClass('hide').removeAttr('href')
|
6
|
+
$('form#filters #reload').remove()
|
7
|
+
$('form#filters select').change ->
|
8
|
+
$('form#filters').submit()
|
9
|
+
$('#reset').click ->
|
10
|
+
$('form#filters select').find('option:first').attr('selected', 'selected').parent('select');
|
11
|
+
$('form#filters select').prop('selectedIndex', -1);
|
12
|
+
$('form#filters').submit()
|
@@ -0,0 +1,26 @@
|
|
1
|
+
var showModal = function(href, template, width) {
|
2
|
+
|
3
|
+
// close and remove previous modals and their calls
|
4
|
+
$('.modal').modal('hide');
|
5
|
+
$('.modal').remove();
|
6
|
+
$("*[data-toggle='modal']").attr('data-remote', 'true').removeAttr('data-target').removeAttr('data-toggle');
|
7
|
+
|
8
|
+
// add new modal and its calls
|
9
|
+
$('body').append(template);
|
10
|
+
$("a[href*='" + href + "'][data-remote='true']").removeAttr('data-remote').attr('data-target', '#modal').attr('data-toggle', 'modal');
|
11
|
+
|
12
|
+
// lock button after sending a request
|
13
|
+
$("#modal").submit(function(){ $('input[type=submit]', this).attr('disabled', 'disabled'); });
|
14
|
+
|
15
|
+
// set width of the modal
|
16
|
+
if (width.length > 0) {
|
17
|
+
$('#modal').modal({ backdrop: true, keyboard: true }).css({ width: width, 'margin-left': function () { return -($(this).width() / 2); }});
|
18
|
+
}
|
19
|
+
|
20
|
+
// add vertical scroll
|
21
|
+
$('.modal-body').css({ "max-height": function() { return ($(window).height() * 0.55); }});
|
22
|
+
$(window).resize(function(){ $('.modal-body').css({ "max-height": function() { return ($(window).height() * 0.5); }}); });
|
23
|
+
|
24
|
+
// open the new modal
|
25
|
+
$('#modal').modal('show');
|
26
|
+
}
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module RailsBootstrapWidgets
|
3
|
+
module FiltersHelper
|
4
|
+
|
5
|
+
def pagination_widget(items, options = {})
|
6
|
+
if items.present?
|
7
|
+
content_tag(:aside, (options[:class].to_s.present? ? { class: options[:class] } : {})) do
|
8
|
+
will_paginate(items, inner_window: 0, outer_window: 0).html_safe
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def filters_widget(items, options = {})
|
14
|
+
if (options = _prepare(options)).present?
|
15
|
+
form_tag(url_for("/"), method: :get, id: :filters, class: :span8) do
|
16
|
+
(_selector(:filter, options[:filters], options[:filter]) << _selector(:order, options[:orders], options[:order]) << _reset << _reload).html_safe
|
17
|
+
end
|
18
|
+
else
|
19
|
+
""
|
20
|
+
end << pagination_widget(items, class: :span4)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def _prepare(options = {})
|
26
|
+
_options = {}
|
27
|
+
_options.merge!({ filters: options[:filters], filter: options[:filter].to_s }) if _consistent?(options[:filters], options[:filter])
|
28
|
+
_options.merge!({ orders: options[:orders], order: options[:order].to_s }) if _consistent?(options[:orders], options[:order])
|
29
|
+
return _options
|
30
|
+
end
|
31
|
+
|
32
|
+
def _consistent?(list, item)
|
33
|
+
list.class == Hash && item.to_s.present? && list.keys.collect{ |key| key.to_s }.include?(item.to_s)
|
34
|
+
end
|
35
|
+
|
36
|
+
def _selector(type, list, item)
|
37
|
+
if list
|
38
|
+
content_tag(:div, class: "input-prepend") do
|
39
|
+
content_tag(:span, class: "add-on") { "<i class=\"icon-#{ type }\"></i>".html_safe } <<
|
40
|
+
select_tag(type, options_for_select(list.to_a.collect{ |i| i.reverse }, item))
|
41
|
+
end
|
42
|
+
else
|
43
|
+
""
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def _reset
|
48
|
+
link_to("<i class=\"icon-reset\"></i>".html_safe, '#', class: "btn add-on hide", id: :reset)
|
49
|
+
end
|
50
|
+
|
51
|
+
def _reload
|
52
|
+
content_tag(:div, id: :reload, class: "input-prepend") do
|
53
|
+
content_tag(:span, class: "add-on") { "<i class=\"icon-reload\"></i>".html_safe } <<
|
54
|
+
submit_tag(I18n.t("buttons.reload"), class: "btn")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module RailsBootstrapWidgets
|
3
|
+
module ModalHelper
|
4
|
+
|
5
|
+
def modal_form_widget(options = {}, &block)
|
6
|
+
if (options = _prepare(options, :form)) && (content = block_given? ? capture(&block) : nil)
|
7
|
+
form_tag(options[:action], method: :post, id: "modal", class: "modal fade", remote: true) do
|
8
|
+
(_hidden(options[:method]) << _header(options[:title]) << _body(content) << _footer(:submit, options[:button], options[:cancel])).html_safe
|
9
|
+
end
|
10
|
+
else
|
11
|
+
''
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def modal_view_widget(options = {}, &block)
|
16
|
+
content = block_given? ? capture(&block) : nil
|
17
|
+
if (options = _prepare(options, :view)) && content
|
18
|
+
content_tag(:div, id: "modal", class: "modal fade") do
|
19
|
+
(_header(options[:title]) << _body(content) << _footer(:button, options[:button], options[:cancel], options[:href], options[:redirect])).html_safe
|
20
|
+
end
|
21
|
+
else
|
22
|
+
''
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def _prepare(options, type)
|
29
|
+
if (options.class == Hash) && %w(form view).include?(type.to_s)
|
30
|
+
options[:redirect] = true unless options[:redirect] == false
|
31
|
+
options[:method] = 'post' unless %w(get put delete).include?(options[:method].to_s)
|
32
|
+
options[:cancel] ||= I18n.t('buttons.cancel')
|
33
|
+
options[:button] ||= (type == :form ? I18n.t('buttons.submit') : I18n.t('buttons.details'))
|
34
|
+
return options if options[:title].present? && (((type == :view) && options[:href].present?) || ((type == :form) && options[:action].present? && options[:cancel].present?))
|
35
|
+
end
|
36
|
+
return nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def _hidden(method)
|
40
|
+
method.to_s == "post" ? "" : hidden_field_tag(:_method, method.to_s)
|
41
|
+
end
|
42
|
+
|
43
|
+
def _header(title)
|
44
|
+
content_tag(:header, class: 'modal-header') do
|
45
|
+
button_tag(type: :button, class: :close, "data-dismiss" => :modal, "aria-hidden" => 'true') { "\×".html_safe } <<
|
46
|
+
content_tag(:h1, title)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def _body(content)
|
51
|
+
content_tag(:div, class: "modal-body") { content }
|
52
|
+
end
|
53
|
+
|
54
|
+
def _footer(type, button, cancel, href = nil, redirect = true)
|
55
|
+
content_tag(:div, class: 'modal-footer') do
|
56
|
+
link_to(cancel, "#", class: "btn", "data-dismiss" => "modal", "aria-hidden" => "true") <<
|
57
|
+
(type == :submit ? submit_tag(button, id: :submit, class: "btn btn-primary") : (redirect ? link_to(button, href, class: "btn btn-primary") : ""))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|