data-confirm-bourbon 0.1.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.
@@ -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: