data-confirm-bourbon 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d59c8dad066f27cff956baac9e38ca65d5646c7c
4
+ data.tar.gz: 2254f6a48f701b442447e6e8e2dde4dcc6b8331f
5
+ SHA512:
6
+ metadata.gz: 1e441c67e599efaf9fb1b05aae85ad95a5f803ccfb2016605c6cb88265e0e803435224b279abe4cb6ab6ff4acf0f46c4944a00919d187492a3de0eba59e382b5
7
+ data.tar.gz: fe6ad296af2ec32627933b70c42de9de4c7515cdda71597ca7d2186afdeeda0e490c8e9ec8d721ad16f4e3c51c526d7fcfd405b665a173eecad4dd1e8af762a1
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Trevor Brown <admin@stratus3d.com>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,146 @@
1
+ # Data-Confirm Modal
2
+
3
+ Uses [Bourbon Refill's modals](http://refills.bourbon.io/components/#modal)
4
+ in place of the browser's builtin `confirm()` API for links generated through Rails'
5
+ helpers with the `:confirm` option.
6
+
7
+ Any link with the `data-confirm` attribute will trigger a Bourbon Refill modal.
8
+
9
+ HTML in the modal supported, and also the ability to have the user input a
10
+ certain value, for extra willingness confirmation (inspired by GitHub's
11
+ "delete repository" function).
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ gem 'data-confirm-bourbon', github: 'Stratus3D/data-confirm-bourbon'
18
+
19
+ Then execute:
20
+
21
+ $ bundle
22
+
23
+ Then generate the modal Sass:
24
+
25
+ rails generate refills:import modal
26
+
27
+ Then include it in `application.scss`:
28
+
29
+ @import "refills/_modal";
30
+
31
+ Your `application.scss` file should look something like this we you are finished:
32
+
33
+ @import "base/base";
34
+ @import 'base/grid-settings';
35
+ @import "neat";
36
+ @import "refills/_modal";
37
+
38
+ If you have trouble getting all the imports correct refer to [this refills issue](https://github.com/thoughtbot/refills/issues/113).
39
+
40
+ And then require the JavaScript from your `application.js`:
41
+
42
+ //= require data-confirm-bourbon
43
+
44
+ ## Usage
45
+
46
+ ### With Rails
47
+
48
+ By default, the Gem's Javascript overrides Rails' [data-confirm behaviour][]
49
+ for you, with no change required to your code. The modal is applicable to
50
+ `<a>`, `<button>` and `<input[submit]>` elements by default.
51
+
52
+ Example:
53
+
54
+ <%= link_to 'Delete', data: {confirm: 'Are you sure?'} %>
55
+
56
+ The modal's title will be get from the link's `title` attribute value. The
57
+ modal text will be taken from the `data-confirm` value. Multiple paragraphs
58
+ are created automatically from two newlines (`\n\n`).
59
+
60
+ The modal's 'confirm' button text can be customized using the `data-commit`
61
+ attribute.
62
+
63
+ <%= link_to 'Delete', data: {confirm: 'Are you sure?', commit: 'Sure!'} %>
64
+
65
+ Add a `data-verify` attribute to your input if you want an extra confirmation
66
+ from the user. The modal will contain an extra text input, and the user will be
67
+ asked to type the verification value before being allowed to proceed.
68
+
69
+ <%= link_to 'Delete', data: {confirm: 'Are you sure?', verify: 'Foo', verify_text: 'Type "Foo" to confirm'} %>
70
+
71
+ You can set global setting using `dataConfirmBourbonModal.setDefaults`, for example:
72
+
73
+ dataConfirmBourbonModal.setDefaults({
74
+ title: 'Confirm your action',
75
+ commit: 'Continue',
76
+ cancel: 'Cancel'
77
+ });
78
+
79
+ To restore default settings use `dataConfirmBourbonModal.restoreDefaults()`.
80
+
81
+ [data-confirm-behaviour]: http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html
82
+
83
+ ### Without Rails, with data attributes
84
+
85
+ Given an element with `data-confirm` attributes in place, such as
86
+
87
+ <a id="foo" href="#" data-confirm="Really do this?" data-commit="Do it" data-cancel="Not really"/>
88
+
89
+ you can then invoke `.confirmModal()` on it using:
90
+
91
+ $('#foo').confirmModal();
92
+
93
+ that'll display the confirmation modal. If the user confirms, then the `#foo`
94
+ link will receive a `click` event.
95
+
96
+ ### Without Rails, without data attributes
97
+
98
+ Use `dataConfirmBourbonModal.confirm()` passing any of the supported options, and pass
99
+ an `onConfirm` and `onCancel` callbacks that'll be invoked when the user clicks
100
+ the confirm or the cancel buttons.
101
+
102
+ dataConfirmBourbonModal.confirm({
103
+ title: 'Are you sure?',
104
+ text: 'Really do this?',
105
+ commit: 'Yes do it',
106
+ cancel: 'Not really',
107
+ zIindex: 10099,
108
+ onConfirm: function() { alert('confirmed') },
109
+ onCancel: function() { alert('cancelled') }
110
+ });
111
+
112
+ ### Modal Options
113
+
114
+ The options [bootstrap modal options](http://getbootstrap.com/javascript/#modals-options)
115
+ can be passed either via JavaScript or through data attributes.
116
+
117
+ $('#foo').confirmModal({backdrop: 'static', keyboard: false});
118
+
119
+ or
120
+
121
+ <a href="#" data-confirm="Really?" data-backdrop="static" data-keyboard="false">
122
+
123
+ ## Issues
124
+
125
+ * Can't be used without rails.
126
+ * Can't be called directly from JavaScript.
127
+
128
+ ## Authors
129
+
130
+ * Trevor Brown ([@Stratus3D](http://github.com/Stratus3D))
131
+ * Marcello Barnaba ([@vjt](https://github.com/vjt))
132
+ * LLeir Borras Metje ([@lleirborras](https://github.com/lleirborras))
133
+ * The Open Source [World](https://github.com/ifad/data-confirm-modal/graphs/contributors)
134
+
135
+ ## Background
136
+
137
+ Spinned off a corporate [IFAD](http://github.com/ifad/) application in which
138
+ an user did too much damage because the confirm wasn't *THAT* explicit ... ;-). [Initially built for bootstrap](https://github.com/ifad/data-confirm-modal) and then later converted to work with Bourbon Refills.
139
+
140
+ ## Contributing
141
+
142
+ 1. Fork it
143
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
144
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
145
+ 4. Push to the branch (`git push origin my-new-feature`)
146
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/data-confirm-bourbon/version', __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "data-confirm-bourbon"
6
+ s.version = DataConfirmBourbon::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Trevor Brown"]
9
+ s.email = ["admin@stratus3d.com"]
10
+ s.homepage = "http://github.com/Stratus3D/data-confirm-bourbon"
11
+ s.license = "MIT"
12
+ s.summary = "Use Bourbon Refill modals with Rails' UJS data-confirm"
13
+ s.description = "This gem overrides Rails' UJS behaviour to open up a Bourbon Refill modal component instead of the browser's built in confirm() dialog"
14
+
15
+ s.required_rubygems_version = ">= 1.3.6"
16
+
17
+ s.add_dependency 'railties', '>= 3.0'
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.require_path = 'lib'
21
+ end
@@ -0,0 +1,2 @@
1
+ require 'data-confirm-bourbon/engine'
2
+ require 'data-confirm-bourbon/version'
@@ -0,0 +1,4 @@
1
+ module DataConfirmBourbon
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module DataConfirmBourbon
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,323 @@
1
+ /*
2
+ * Implements a user-facing modal confirmation when link has a
3
+ * "data-confirm" attribute using Bourbon Refill's modal component. MIT license.
4
+ *
5
+ */
6
+ (function ($) {
7
+
8
+ /**
9
+ * Builds the markup for a [Bourbon Refill modal](http://refills.bourbon.io/components/#modal)
10
+ * for the given `element`. Uses the following `data-` parameters to
11
+ * customize it:
12
+ *
13
+ * * `data-confirm`: Contains the modal body text. HTML is allowed.
14
+ * Separate multiple paragraphs using \n\n.
15
+ * * `data-commit`: The 'confirm' button text. "Confirm" by default.
16
+ * * `data-cancel`: The 'cancel' button text. "Cancel" by default.
17
+ * * `data-verify`: Adds a text input in which the user has to input
18
+ * the text in this attribute value for the 'confirm'
19
+ * button to be clickable. Optional.
20
+ * * `data-verify-text`: Adds a label for the data-verify input. Optional
21
+ * * `data-focus`: Define focused input. Supported values are
22
+ * 'cancel' or 'commit', 'cancel' is default for
23
+ * data-method DELETE, 'commit' for all others.
24
+ *
25
+ * You can set global setting using `dataConfirmBourbonModal.setDefaults`, for example:
26
+ *
27
+ * dataConfirmBourbonModal.setDefaults({
28
+ * title: 'Confirm your action',
29
+ * commit: 'Continue',
30
+ * cancel: 'Cancel',
31
+ * fade: false,
32
+ * verifyClass: 'form-control',
33
+ * });
34
+ *
35
+ */
36
+
37
+ var defaults = {
38
+ title: 'Are you sure?',
39
+ commit: 'Confirm',
40
+ commitClass: 'btn-danger',
41
+ cancel: 'Cancel',
42
+ cancelClass: 'btn-default',
43
+ fade: true,
44
+ verifyClass: 'form-control',
45
+ elements: ['a[data-confirm]', 'button[data-confirm]', 'input[type=submit][data-confirm]'],
46
+ focus: 'cancel',
47
+ zIndex: 1050,
48
+ modalClass: false,
49
+ show: true
50
+ };
51
+
52
+ var settings = $.extend({}, defaults);
53
+
54
+ var buildModal = function (options) {
55
+ var id = 'confirm-modal-' + String(Math.random()).slice(2, -1);
56
+ //var fade = settings.fade ? 'fade' : '';
57
+ var modalClass = settings.modalClass || '';
58
+ var element = options.element;
59
+
60
+ var modal = $('<div class="modal">' +
61
+ '<input class="modal-state" id="' + id + '" type="checkbox" />' +
62
+ '<div class="modal-window">' +
63
+ '<div class="modal-inner ' + modalClass + '">' +
64
+ '<label class="modal-close" for="' + id + '"></label>' +
65
+ '<h1 class="modal-title">Modal Title</h1>' +
66
+ '<div class="modal-content"></div>' +
67
+ '<div class="modal-footer">' +
68
+ '<button class="cancel" data-dismiss="modal"></button>' +
69
+ '<button class="commit"></button>' +
70
+ '</div>'+
71
+ '</div>' +
72
+ '</div>' +
73
+ '</div>'
74
+ );
75
+
76
+ $('body').append(modal);
77
+ element.data('confirm-modal-id', id);
78
+
79
+ var modalState = modal.find('.modal-state');
80
+
81
+ modal.find('.modal-title').text(options.title || settings.title);
82
+
83
+ var body = modal.find('.modal-content');
84
+
85
+ $.each((options.text||'').split(/\n{2}/), function (i, piece) {
86
+ body.append($('<p/>').html(piece));
87
+ });
88
+
89
+ var commit = modal.find('.commit');
90
+ commit.text(options.commit || settings.commit);
91
+ commit.addClass(options.commitClass || settings.commitClass);
92
+
93
+ var cancel = modal.find('.cancel');
94
+ cancel.text(options.cancel || settings.cancel);
95
+ cancel.addClass(options.cancelClass || settings.cancelClass);
96
+
97
+ //if (options.remote) {
98
+ // commit.attr('data-dismiss', 'modal');
99
+ //}
100
+
101
+ if (options.verify || options.verifyRegexp) {
102
+ commit.prop('disabled', true);
103
+
104
+ var isMatch;
105
+ if (options.verifyRegexp) {
106
+ var caseInsensitive = options.verifyRegexpCaseInsensitive;
107
+ var regexp = options.verifyRegexp;
108
+ var re = new RegExp(regexp, caseInsensitive ? 'i' : '');
109
+
110
+ isMatch = function (input) { return input.match(re); };
111
+ } else {
112
+ isMatch = function (input) { return options.verify === input; };
113
+ }
114
+
115
+ var verification = $('<input/>', {"type": 'text', "class": settings.verifyClass}).on('keyup', function () {
116
+ commit.prop('disabled', !isMatch($(this).val()));
117
+ });
118
+
119
+ modalState.on('change', function () {
120
+ if (this.checked) {
121
+ verification.focus();
122
+ } else {
123
+ verification.val('').trigger('keyup');
124
+ }
125
+ });
126
+
127
+ if (options.verifyLabel) {
128
+ body.append($('<p>', {text: options.verifyLabel}));
129
+ }
130
+
131
+ body.append(verification);
132
+ }
133
+
134
+ var focusElement;
135
+ if (options.focus) {
136
+ focusElement = options.focus;
137
+ } else if (options.method === 'delete') {
138
+ focusElement = 'cancel';
139
+ } else {
140
+ focusElement = settings.focus;
141
+ }
142
+ focusElement = modal.find('.' + focusElement);
143
+
144
+ modal.data('confirmed', false);
145
+
146
+ var stateChangeHandler = function () {
147
+ if (modalState.is(':checked')) {
148
+ $("body").addClass("modal-open");
149
+ modal.trigger('shown');
150
+ focusElement.focus();
151
+ } else {
152
+ $("body").removeClass("modal-open");
153
+ modal.trigger('hidden');
154
+ }
155
+ };
156
+
157
+ modalState.on('click', function () {
158
+ stateChangeHandler();
159
+ });
160
+
161
+ modalState.on('change', function () {
162
+ stateChangeHandler();
163
+ });
164
+
165
+ modal.find('.commit').on('click', function () {
166
+ if (options.onConfirm && options.onConfirm.call) {
167
+ options.onConfirm.call();
168
+ }
169
+ });
170
+
171
+ modal.find('.cancel').on('click', function () {
172
+ if (options.onCancel && options.onCancel.call) {
173
+ options.onCancel.call();
174
+ }
175
+
176
+ modal.hide();
177
+ });
178
+
179
+ return modal;
180
+ };
181
+
182
+ window.dataConfirmBourbonModal = {
183
+ setDefaults: function (newSettings) {
184
+ settings = $.extend(settings, newSettings);
185
+ },
186
+
187
+ restoreDefaults: function () {
188
+ settings = $.extend({}, defaults);
189
+ },
190
+
191
+ confirm: function (options) {
192
+ // Build an ephemeral modal
193
+ //
194
+ var modal = buildModal(options);
195
+
196
+ modal.show();
197
+
198
+ modal.find('.commit').on('click', function () {
199
+ if (options.onConfirm && options.onConfirm.call) {
200
+ options.onConfirm.call();
201
+ }
202
+
203
+ modal.hide();
204
+ });
205
+
206
+ modal.find('.cancel').on('click', function () {
207
+ if (options.onCancel && options.onCancel.call) {
208
+ options.onCancel.call();
209
+ }
210
+
211
+ modal.hide();
212
+ });
213
+ }
214
+ };
215
+
216
+ window.dataConfirmBourbonModal.restoreDefaults();
217
+
218
+ var buildElementModal = function (element) {
219
+ var options = {
220
+ element: element,
221
+ title: element.data('confirm'),
222
+ text: element.data('text'),
223
+ focus: element.data('focus'),
224
+ method: element.data('method'),
225
+ commit: element.data('commit'),
226
+ commitClass: element.data('commit-class'),
227
+ cancel: element.data('cancel'),
228
+ cancelClass: element.data('cancel-class'),
229
+ remote: element.data('remote'),
230
+ verify: element.data('verify'),
231
+ verifyRegexp: element.data('verify-regexp'),
232
+ verifyLabel: element.data('verify-text'),
233
+ verifyRegexpCaseInsensitive: element.data('verify-regexp-caseinsensitive'),
234
+ backdrop: element.data('backdrop'),
235
+ keyboard: element.data('keyboard'),
236
+ show: element.data('show')
237
+ };
238
+
239
+ var modal = buildModal(options);
240
+
241
+ modal.data('confirmed', false);
242
+ modal.find('.commit').on('click', function () {
243
+ modal.data('confirmed', true);
244
+ element.trigger('click');
245
+ modal.hide();
246
+ });
247
+
248
+ return modal;
249
+ };
250
+
251
+ var decorateModal = function (modal) {
252
+ var modalState = modal.find('.modal-state');
253
+
254
+ modal.isVisible = function() {
255
+ return modalState.is(':checked');
256
+ };
257
+
258
+ modal.hide = function() {
259
+ if (modalState.prop('checked')) {
260
+ modalState.trigger('click');
261
+ }
262
+ };
263
+
264
+ modal.show = function() {
265
+ if (!modalState.prop('checked')) {
266
+ modalState.trigger('click');
267
+ }
268
+ };
269
+
270
+ return modal;
271
+ };
272
+
273
+ var getExistingModal = function (element) {
274
+ var modalId = element.data('confirm-modal-id');
275
+ if (modalId) {
276
+ var modal = $($('#'+modalId).parent()[0]);
277
+ return modal;
278
+ }
279
+
280
+ return;
281
+ };
282
+
283
+ /**
284
+ * Returns a modal already built for the given element or builds a new one,
285
+ * caching it into the element's `confirm-modal` data attribute.
286
+ */
287
+ var getModal = function (element) {
288
+ var modal = getExistingModal(element) || buildElementModal(element);
289
+
290
+ // Decorate the modal with the functions we need
291
+ var decoratedModal = decorateModal(modal);
292
+
293
+ return decoratedModal;
294
+ };
295
+
296
+ if ($.rails) {
297
+ /**
298
+ * Attaches to the Rails' UJS adapter 'confirm' event on links having a
299
+ * `data-confirm` attribute. Temporarily overrides the `$.rails.confirm`
300
+ * function with an anonymous one that returns the 'confirmed' status of
301
+ * the modal.
302
+ *
303
+ * A modal is considered 'confirmed' when an user has successfully clicked
304
+ * the 'confirm' button in it.
305
+ */
306
+ $(document).delegate(settings.elements.join(', '), 'confirm', function() {
307
+ var element = $(this),
308
+ modal = getModal(element),
309
+ confirmed = modal.data('confirmed');
310
+
311
+ if (!confirmed && !modal.isVisible()) {
312
+ modal.show();
313
+
314
+ var confirm = $.rails.confirm;
315
+ $.rails.confirm = function () { return modal.data('confirmed'); };
316
+ modal.on('hidden', function () { $.rails.confirm = confirm; });
317
+ }
318
+
319
+ return confirmed;
320
+ });
321
+ }
322
+
323
+ })(jQuery);
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: data-confirm-bourbon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Trevor Brown
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ description: This gem overrides Rails' UJS behaviour to open up a Bourbon Refill modal
28
+ component instead of the browser's built in confirm() dialog
29
+ email:
30
+ - admin@stratus3d.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - Gemfile
37
+ - LICENSE
38
+ - README.md
39
+ - Rakefile
40
+ - data-confirm-bourbon.gemspec
41
+ - lib/data-confirm-bourbon.rb
42
+ - lib/data-confirm-bourbon/engine.rb
43
+ - lib/data-confirm-bourbon/version.rb
44
+ - vendor/assets/javascripts/data-confirm-bourbon.js
45
+ homepage: http://github.com/Stratus3D/data-confirm-bourbon
46
+ licenses:
47
+ - MIT
48
+ metadata: {}
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 1.3.6
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 2.4.5
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: Use Bourbon Refill modals with Rails' UJS data-confirm
69
+ test_files: []
70
+ has_rdoc: