autotab-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9351c775fcd31092b75263022302081712754caf
4
+ data.tar.gz: c62d02214f1f6d6c2fad18603aab24d6e46c48bd
5
+ SHA512:
6
+ metadata.gz: 7f6c9b6a08e5cc15765c57cf121c551b368b28a5de0c91d98750288aee4615af1e728b419acae402e8ae4170f8b84df4bfd9622d970157ae2a5548b9bed510b1
7
+ data.tar.gz: 3c0aa3a3b2a07db7f14e5c6426acd38ee7612ba2fe5a8618e3f7a807b4d773a498002a103617cdbc43c0c97cf163bcba7f99960e8dcbb28f5defb11007f16300
data/.gitignore ADDED
@@ -0,0 +1,18 @@
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
18
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in autotab-rails.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2013 by Sachin Singh
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # AutoTab for rails asset pipeline
2
+
3
+ [Autotab](https://github.com/Mathachew/jquery-autotab) is a jQuery plugin that provides auto tabbing and filtering on text fields in a form. Once the maximum number of characters has been reached within a text field, the focus is automatically set to a defined element. Likewise, clearing out the text field's content by pressing backspace eventually places the focus on a previous element.
4
+
5
+ The `autotab-rails` gem integrates the `AutoTab` with the Rails asset pipeline.
6
+
7
+ ## Usage
8
+
9
+ ### Install autotab-rails gem
10
+
11
+ Include `autotab-rails` in Gemefile
12
+
13
+ gem 'autotab-rails'
14
+
15
+ Then run `bundle install`
16
+
17
+ ### Include autotab javascript assets
18
+
19
+ Add to your `app/assets/javascripts/application.js` if use with jQuery
20
+
21
+ //= require autotab-jquery
22
+
23
+ ### Enable autotab javascript by specific css class
24
+
25
+ Add to one coffee script file, like `custom.js.coffee`
26
+
27
+ $(document).ready ->
28
+ $("#first").autotab
29
+ target: "second"
30
+ format: "numeric"
31
+
32
+ $("#second").autotab
33
+ target: "third"
34
+ format: "numeric"
35
+ previous: "first"
36
+
37
+ $("#third").autotab
38
+ previous: "second"
39
+ format: "numeric"
40
+
41
+ return
42
+
43
+ And this file must be included in `application.js`
44
+
45
+ //= require autotab-jquery
46
+ //= require custom
47
+
48
+
49
+ ## Gem maintenance
50
+
51
+ Maintain `autotab-rails` gem with `Rake` commands.
52
+
53
+ Update origin autotab source files.
54
+
55
+ rake update-autotab
56
+
57
+ Publish gem.
58
+
59
+ rake release
60
+
61
+ ## License
62
+
63
+ use MIT license.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
3
+ require File.expand_path('../lib/autotab-rails/source_file', __FILE__)
4
+
5
+ desc "Update with Harvest's AutoTab Library"
6
+ task 'update-autotab', 'repository_url', 'branch' do |task, args|
7
+ remote = args['repository_url'] || 'https://github.com/sachin87/autotab-rails'
8
+ branch = args['branch'] || 'master'
9
+ files = SourceFile.new
10
+ files.fetch remote, branch
11
+ files.cleanup
12
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/autotab-rails/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ['Sachin Singh']
6
+ gem.email = ['sachin.y87@hmail.com']
7
+ gem.description = %q{AutoTab is a is a jQuery plugin that provides auto tabbing and filtering on text fields in a form.}
8
+ gem.summary = %q{Integrate AutoTab javascript library with Rails asset pipeline}
9
+ gem.homepage = 'https://github.com/sachin87/autotab-rails'
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = 'autotab-rails'
15
+ gem.require_paths = ['lib']
16
+ gem.version = AutoTab::Rails::VERSION
17
+
18
+ gem.add_dependency 'railties', '>= 3.0'
19
+
20
+ gem.add_development_dependency 'bundler', '>= 1.0'
21
+ gem.add_development_dependency 'rails', '>= 3.0'
22
+ gem.add_development_dependency 'thor', '>= 0.14'
23
+ end
@@ -0,0 +1,15 @@
1
+ require 'autotab-rails/version'
2
+
3
+ module AutoTab
4
+ module Rails
5
+ end
6
+ end
7
+
8
+ case ::Rails.version.to_s
9
+ when /^4/
10
+ require 'autotab-rails/engine'
11
+ when /^3\.[12]/
12
+ require 'autotab-rails/engine3'
13
+ when /^3\.[0]/
14
+ require 'autotab-rails/railtie'
15
+ end
@@ -0,0 +1,9 @@
1
+ module AutoTab
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ rake_tasks do
5
+ load 'autotab-rails/tasks.rake'
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ module Autotab
2
+ module Rails
3
+ class Engine3 < ::Rails::Engine
4
+ initializer 'autotab.assets.precompile' do |app|
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ module AutoTab
2
+ module Rails
3
+ class Railtie < ::Rails::Railtie
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,33 @@
1
+ require 'thor'
2
+ require 'json'
3
+
4
+ class SourceFile < Thor
5
+ include Thor::Actions
6
+
7
+ desc 'fetch source files', 'fetch source files from GitHub'
8
+ def fetch remote, branch
9
+ self.destination_root = 'vendor/assets'
10
+ get "#{remote}/raw/#{branch}/js/autotab-jquery.js", 'javascripts/autotab-jquery.js'
11
+ get "#{remote}/raw/#{branch}/js/autotab-jquery.min.js", 'javascripts/autotab-jquery.min.js'
12
+ get "#{remote}/raw/#{branch}/component.json", 'component.json'
13
+ bump_version
14
+ end
15
+
16
+ desc 'clean up useless files', 'clean up useless files'
17
+ def cleanup
18
+ self.destination_root = 'vendor/assets'
19
+ remove_file 'component.json'
20
+ end
21
+
22
+ protected
23
+
24
+ def bump_version
25
+ inside destination_root do
26
+ component_json = JSON.load(File.open('component.json'))
27
+ version = component_json['version']
28
+ gsub_file '../../lib/autotab-rails/version.rb', /AUTO_TAB_VERSION\s=\s'(\d|\.)+'$/ do |match|
29
+ %Q{AUTO_TAB_VERSION = '#{version}'}
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ require 'fileutils'
2
+
3
+ desc 'Create nondigest versions of all autotab digest assets'
4
+ task 'assets:precompile' do
5
+ fingerprint = /\-[0-9a-f]{32}\./
6
+ Dir['public/assets/jquery.autotab*'].each do |file|
7
+ next unless file =~ fingerprint
8
+ nondigest = file.sub fingerprint, '.'
9
+ FileUtils.cp file, nondigest, verbose: true
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ module AutoTab
2
+ module Rails
3
+ VERSION = '0.0.1'
4
+ AUTO_TAB_VERSION = '0.0.1'
5
+ end
6
+ end
@@ -0,0 +1,524 @@
1
+ /**
2
+ * Autotab - jQuery plugin 1.5.5
3
+ * https://github.com/Mathachew/jquery-autotab
4
+ *
5
+ * Copyright (c) 2013 Matthew Miller
6
+ *
7
+ * Licensed under the MIT licensing:
8
+ * http://www.opensource.org/licenses/mit-license.php
9
+ */
10
+
11
+ (function ($) {
12
+ var platform = navigator.platform,
13
+ settings = {
14
+ tabPause: 800,
15
+ focusChange: null,
16
+ iOS: (platform === 'iPad' || platform === 'iPhone' || platform === 'iPod'),
17
+ firefox: (typeof InstallTrigger !== 'undefined')
18
+ };
19
+
20
+ // Native get/setAttribute methods are much faster than $.data, so $.data is used for objects only: http://jsperf.com/dataset-vs-jquery-data/4
21
+ // When removing then resetting auto tab, storing an object resulted in overwritten values, leading to this implementation
22
+ var setSettings = function (e, settings) {
23
+ if (settings === null || typeof settings === 'undefined') {
24
+ return;
25
+ }
26
+
27
+ for (var key in settings) {
28
+ $(e).data('autotab-' + key, settings[key]);
29
+ }
30
+ };
31
+
32
+ var getSettings = function (e) {
33
+ var settings = {
34
+ format: 'all',
35
+ loaded: false,
36
+ disabled: false,
37
+ pattern: null,
38
+ uppercase: false,
39
+ lowercase: false,
40
+ nospace: false,
41
+ maxlength: 2147483647,
42
+ target: null,
43
+ previous: null,
44
+ trigger: null,
45
+ originalValue: '',
46
+ changed: false
47
+ };
48
+
49
+ for (var key in settings) {
50
+ settings[key] = $(e).data('autotab-' + key) || settings[key];
51
+ }
52
+
53
+ // Save settings on first run
54
+ if (!settings.loaded) {
55
+ if (settings.trigger !== null && typeof settings.trigger === 'string') {
56
+ settings.trigger = settings.trigger.toString();
57
+ }
58
+
59
+ setSettings(e, settings);
60
+ }
61
+
62
+ return settings;
63
+ };
64
+
65
+ // The 1ms timeouts allow for keypress events to complete in case a
66
+ // custom function or exterior method calls for a manual auto tab
67
+ $.autotab = {
68
+ next: function () {
69
+ var e = $(document.activeElement);
70
+
71
+ if (e.length) {
72
+ e.trigger('autotab-next');
73
+ }
74
+ },
75
+ previous: function () {
76
+ var e = $(document.activeElement);
77
+
78
+ if (e.length) {
79
+ e.trigger('autotab-previous');
80
+ }
81
+ }
82
+ };
83
+
84
+ $.fn.autotab = function (method, options) {
85
+ if (!this.length) {
86
+ return this;
87
+ }
88
+
89
+ // Apply filter options
90
+ if (method == 'filter') {
91
+ if (typeof options === 'string' || typeof options === 'function') {
92
+ options = { format: options };
93
+ }
94
+
95
+ for (var i = 0, length = this.length; i < length; i++) {
96
+ var defaults = getSettings(this[i]),
97
+ newOptions = options;
98
+
99
+ // Retain the established target/previous values as this area is for filtering only
100
+ newOptions.target = defaults.target;
101
+ newOptions.previous = defaults.previous;
102
+
103
+ $.extend(defaults, newOptions);
104
+ setSettings(this[i], defaults);
105
+ }
106
+ }
107
+ // Disable auto tab and filtering
108
+ else if (method == 'remove' || method == 'destroy' || method == 'disable') {
109
+ for (var i = 0, length = this.length; i < length; i++) {
110
+ var defaults = getSettings(this[i]);
111
+
112
+ defaults.disabled = true;
113
+
114
+ setSettings(this[i], defaults);
115
+ }
116
+ }
117
+ // Re-enable auto tab and filtering
118
+ else if (method == 'restore' || method == 'enable') {
119
+ for (var i = 0, length = this.length; i < length; i++) {
120
+ var defaults = getSettings(this[i]);
121
+
122
+ defaults.disabled = false;
123
+
124
+ setSettings(this[i], defaults);
125
+ }
126
+ }
127
+ else {
128
+ if (method === null || typeof method === 'undefined') {
129
+ options = {};
130
+ }
131
+ else if (typeof method === 'string' || typeof method === 'function') {
132
+ options = { format: method };
133
+ }
134
+ else if (typeof method === 'object') {
135
+ options = method;
136
+ }
137
+
138
+ // Bind key events to element(s) passed
139
+ if (this.length > 1) {
140
+ for (var i = 0, length = this.length; i < length; i++) {
141
+ var n = i + 1,
142
+ p = i - 1,
143
+ newOptions = options;
144
+
145
+ if (i > 0 && n < length) {
146
+ newOptions.target = this[n];
147
+ newOptions.previous = this[p];
148
+ }
149
+ else if (i > 0) {
150
+ newOptions.target = null;
151
+ newOptions.previous = this[p];
152
+ }
153
+ else {
154
+ newOptions.target = this[n];
155
+ newOptions.previous = null;
156
+ }
157
+
158
+ autotabBind(this[i], newOptions);
159
+ }
160
+ }
161
+ else {
162
+ autotabBind(this[0], options);
163
+ }
164
+ }
165
+
166
+ return this;
167
+ };
168
+
169
+ var filterValue = function (e, value, defaults) {
170
+ if (typeof defaults.format === 'function') {
171
+ return defaults.format(value, e);
172
+ }
173
+
174
+ var pattern = null;
175
+
176
+ switch (defaults.format) {
177
+ case 'text':
178
+ pattern = new RegExp('[0-9]+', 'g');
179
+ break;
180
+
181
+ case 'alpha':
182
+ pattern = new RegExp('[^a-zA-Z]+', 'g');
183
+ break;
184
+
185
+ case 'number':
186
+ case 'numeric':
187
+ pattern = new RegExp('[^0-9]+', 'g');
188
+ break;
189
+
190
+ case 'alphanumeric':
191
+ pattern = new RegExp('[^0-9a-zA-Z]+', 'g');
192
+ break;
193
+
194
+ case 'hex':
195
+ case 'hexadecimal':
196
+ pattern = new RegExp('[^0-9A-Fa-f]+', 'g');
197
+ break;
198
+
199
+ case 'custom':
200
+ pattern = new RegExp(defaults.pattern, 'g');
201
+ break;
202
+
203
+ case 'all':
204
+ default:
205
+ break;
206
+ }
207
+
208
+ if (pattern !== null) {
209
+ value = value.replace(pattern, '');
210
+ }
211
+
212
+ if (defaults.nospace) {
213
+ pattern = new RegExp('[ ]+', 'g');
214
+ value = value.replace(pattern, '');
215
+ }
216
+
217
+ if (defaults.uppercase) {
218
+ value = value.toUpperCase();
219
+ }
220
+
221
+ if (defaults.lowercase) {
222
+ value = value.toLowerCase();
223
+ }
224
+
225
+ return value;
226
+ };
227
+
228
+ var autotabBind = function (element, options) {
229
+ var defaults = getSettings(element);
230
+
231
+ if (defaults.disabled) {
232
+ defaults.disabled = false;
233
+ defaults.target = null;
234
+ defaults.previous = null;
235
+ }
236
+
237
+ $.extend(defaults, options);
238
+
239
+ // Sets targets to element based on the name or ID passed if they are not currently objects
240
+ if (typeof defaults.target === 'string' || !(defaults.target instanceof jQuery)) {
241
+ defaults.target = $(defaults.target);
242
+ }
243
+
244
+ if (typeof defaults.previous === 'string' || !(defaults.previous instanceof jQuery)) {
245
+ defaults.previous = $(defaults.previous);
246
+ }
247
+
248
+ var oldMaxlength = element.maxLength;
249
+
250
+ // defaults.maxlength has not changed and maxlength was specified
251
+ if (defaults.maxlength == 2147483647 && oldMaxlength != 2147483647 && oldMaxlength != -1) {
252
+ defaults.maxlength = oldMaxlength;
253
+ }
254
+ // defaults.maxlength overrides maxlength
255
+ else if (defaults.maxlength > 0) {
256
+ element.maxLength = defaults.maxlength;
257
+ }
258
+ // defaults.maxlength and maxlength have not been specified
259
+ // A target cannot be used since there is no defined maxlength
260
+ else {
261
+ defaults.target = null;
262
+ }
263
+
264
+ if (!defaults.loaded) {
265
+ defaults.loaded = true;
266
+ setSettings(element, defaults);
267
+ }
268
+ else {
269
+ setSettings(element, defaults);
270
+ return;
271
+ }
272
+
273
+ $(element).on('autotab-next', function (event, defaults) {
274
+ var self = this;
275
+ setTimeout(function () {
276
+ if (!defaults) {
277
+ defaults = getSettings(self);
278
+ }
279
+
280
+ if (!defaults.disabled && defaults.target.length) {
281
+ // Using focus on iOS devices is a pain, so use the browser's next/previous buttons to proceed
282
+ if (!settings.iOS) {
283
+ defaults.target.focus().select();
284
+ settings.focusChange = new Date();
285
+ }
286
+ }
287
+ }, 1);
288
+ }).on('autotab-previous', function (event, defaults) {
289
+ var self = this;
290
+ setTimeout(function () {
291
+ if (!defaults) {
292
+ defaults = getSettings(self);
293
+ }
294
+
295
+ var previous = defaults.previous;
296
+
297
+ if (!defaults.disabled && previous.length) {
298
+ var value = previous.val();
299
+
300
+ if (value.length) {
301
+ previous.focus().val(value.substring(0, value.length - 1));
302
+ setSettings(previous, { changed: true });
303
+ }
304
+ else {
305
+ previous.focus();
306
+ }
307
+
308
+ settings.focusChange = null;
309
+ }
310
+ }, 1);
311
+ }).on('focus', function () {
312
+ setSettings(this, { originalValue: this.value });
313
+ }).on('blur', function () {
314
+ var defaults = getSettings(this);
315
+
316
+ if (defaults.changed && this.value != defaults.originalValue) {
317
+ setSettings(this, { changed: false });
318
+ $(this).change();
319
+ }
320
+ }).on('keydown', function (e) {
321
+ var defaults = getSettings(this);
322
+
323
+ if (!defaults || defaults.disabled) {
324
+ return true;
325
+ }
326
+
327
+ var keyCode = e.which || e.charCode;
328
+
329
+ // Go to the previous element when backspace
330
+ // is pressed in an empty input field
331
+ if (keyCode == 8) {
332
+ if (this.value.length === 0 && defaults.previous.length) {
333
+ $(this).trigger('autotab-previous', defaults);
334
+ }
335
+ else {
336
+ setSettings(this, { changed: (this.value != defaults.originalValue) });
337
+ }
338
+ }
339
+ else if (keyCode == 9 && settings.focusChange !== null) {
340
+ // Tab backwards
341
+ if (e.shiftKey) {
342
+ settings.focusChange = null;
343
+ return;
344
+ }
345
+
346
+ if ((new Date().getTime() - settings.focusChange.getTime()) < settings.tabPause) {
347
+ settings.focusChange = null;
348
+ return false;
349
+ }
350
+ }
351
+ }).on('keypress', function (e) {
352
+ var defaults = getSettings(this),
353
+ keyCode = e.which || e.keyCode;
354
+
355
+ // e.charCode == 0 indicates a special key has been pressed, which only Firefox triggers
356
+ if (!defaults || defaults.disabled || (settings.firefox && e.charCode === 0) || e.ctrlKey || e.altKey || keyCode == 13 || this.type != 'text') {
357
+ return true;
358
+ }
359
+
360
+ var keyChar = String.fromCharCode(keyCode);
361
+
362
+ // Prevents auto tabbing when defaults.trigger is pressed
363
+ if (defaults.trigger !== null && defaults.trigger.indexOf(keyChar) >= 0) {
364
+ if (settings.focusChange !== null && (new Date().getTime() - settings.focusChange.getTime()) < settings.tabPause) {
365
+ settings.focusChange = null;
366
+ }
367
+ else {
368
+ $(this).trigger('autotab-next', defaults);
369
+ }
370
+
371
+ return false;
372
+ }
373
+
374
+ settings.focusChange = null;
375
+
376
+ var hasValue = document.selection && document.selection.createRange ? true : (e.charCode > 0);
377
+
378
+ keyChar = filterValue(this, keyChar, defaults);
379
+
380
+ if (hasValue && (keyChar === null || keyChar === '')) {
381
+ return false;
382
+ }
383
+
384
+ // Many, many thanks to Tim Down for this solution: http://stackoverflow.com/a/3923320/94656
385
+ if (hasValue && (this.value.length <= this.maxLength)) {
386
+ var start, end,
387
+ selectionType = 0;
388
+
389
+ if (typeof this.selectionStart === 'number' && typeof this.selectionEnd === 'number') {
390
+ // Non-IE browsers and IE 9
391
+ start = this.selectionStart;
392
+ end = this.selectionEnd;
393
+ selectionType = 1;
394
+ }
395
+ else if (document.selection && document.selection.createRange) {
396
+ // For IE up to version 8
397
+ var selectionRange = document.selection.createRange(),
398
+ textInputRange = this.createTextRange(),
399
+ precedingRange = this.createTextRange(),
400
+ bookmark = selectionRange.getBookmark();
401
+ textInputRange.moveToBookmark(bookmark);
402
+ precedingRange.setEndPoint("EndToStart", textInputRange);
403
+ start = precedingRange.text.length;
404
+ end = start + selectionRange.text.length;
405
+ selectionType = 2;
406
+ }
407
+
408
+ // Text is fully selected, so it needs to be replaced
409
+ if (start === 0 && end == this.value.length) {
410
+ this.value = keyChar;
411
+ setSettings(this, { changed: (this.value != defaults.originalValue) });
412
+ }
413
+ else {
414
+ if (this.value.length == this.maxLength && start === end) {
415
+ $(this).trigger('autotab-next', defaults);
416
+ return false;
417
+ }
418
+
419
+ this.value = this.value.slice(0, start) + keyChar + this.value.slice(end);
420
+ setSettings(this, { changed: (this.value != defaults.originalValue) });
421
+ }
422
+
423
+ // Prevents the cursor position from being set to the end of the text box
424
+ // This is called even if the text is fully selected and replaced due to an unexpected behavior in IE6 and up (#32)
425
+ if (this.value.length != defaults.maxlength) {
426
+ start++;
427
+
428
+ if (selectionType == 1) {
429
+ this.selectionStart = this.selectionEnd = start;
430
+ }
431
+ else if (selectionType == 2) {
432
+ var range = this.createTextRange();
433
+ range.collapse(true);
434
+ range.moveEnd('character', start);
435
+ range.moveStart('character', start);
436
+ range.select();
437
+ }
438
+ }
439
+ }
440
+
441
+ if (this.value.length == defaults.maxlength) {
442
+ $(this).trigger('autotab-next', defaults);
443
+ }
444
+
445
+ return false;
446
+ }).on('paste', function (e) {
447
+ var defaults = getSettings(this);
448
+
449
+ if (!defaults) {
450
+ return true;
451
+ }
452
+
453
+ this.maxLength = 2147483647;
454
+
455
+ (function (e, originDefaults) {
456
+ setTimeout(function () {
457
+ var lastIndex = -1,
458
+ hiddenInput = document.createElement('input');
459
+ hiddenInput.type = 'hidden';
460
+ hiddenInput.value = e.value.toLowerCase();
461
+
462
+ e.maxLength = originDefaults.maxlength;
463
+ e.value = filterValue(e, e.value, originDefaults).substr(0, originDefaults.maxlength);
464
+
465
+ var handlePaste = function (e, previousValue) {
466
+ if (!e) {
467
+ return;
468
+ }
469
+
470
+ for (var i = 0, count = previousValue.length; i < count; i++) {
471
+ lastIndex = hiddenInput.value.indexOf(previousValue.charAt(i), lastIndex) + 1;
472
+ }
473
+
474
+ var defaults = getSettings(e),
475
+ trimmedValue = hiddenInput.value.substr(lastIndex),
476
+ filteredValue = filterValue(e, trimmedValue, defaults).substr(0, defaults.maxlength);
477
+
478
+ if (!filteredValue) {
479
+ e.value = '';
480
+ return;
481
+ }
482
+
483
+ e.value = filteredValue;
484
+
485
+ if (filteredValue.length == defaults.maxlength) {
486
+ $(e).trigger('autotab-next', defaults);
487
+
488
+ if (!settings.iOS) {
489
+ handlePaste(defaults.target[0], filteredValue);
490
+ }
491
+ }
492
+
493
+ };
494
+
495
+ if (e.value.length == originDefaults.maxlength) {
496
+ $(e).trigger('autotab-next', defaults);
497
+
498
+ if (!settings.iOS) {
499
+ handlePaste(originDefaults.target[0], e.value.toLowerCase());
500
+ }
501
+ }
502
+ }, 1);
503
+ })(this, defaults);
504
+ });
505
+ };
506
+
507
+ // Backwards compatibility
508
+ $.fn.autotab_magic = function (focus) {
509
+ $(this).autotab();
510
+ };
511
+ $.fn.autotab_filter = function (options) {
512
+ var defaults = {};
513
+
514
+ if (typeof options === 'string' || typeof options === 'function') {
515
+ defaults.format = options;
516
+ }
517
+ else {
518
+ $.extend(defaults, options);
519
+ }
520
+
521
+ $(this).autotab('filter', defaults);
522
+ };
523
+
524
+ })(jQuery);
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Autotab - jQuery plugin 1.5.5
3
+ * https://github.com/Mathachew/jquery-autotab
4
+ *
5
+ * Copyright (c) 2013 Matthew Miller
6
+ *
7
+ * Licensed under the MIT licensing:
8
+ * http://www.opensource.org/licenses/mit-license.php
9
+ */
10
+
11
+ (function(e){var n=navigator.platform,m=null,p="iPad"===n||"iPhone"===n||"iPod"===n,t="undefined"!==typeof InstallTrigger,h=function(b,c){if(null!==c&&"undefined"!==typeof c)for(var a in c)e(b).data("autotab-"+a,c[a])},k=function(b){var c={format:"all",loaded:!1,disabled:!1,pattern:null,uppercase:!1,lowercase:!1,nospace:!1,maxlength:2147483647,target:null,previous:null,trigger:null,originalValue:"",changed:!1},a;for(a in c)c[a]=e(b).data("autotab-"+a)||c[a];c.loaded||(null!==c.trigger&&"string"===
12
+ typeof c.trigger&&(c.trigger=c.trigger.toString()),h(b,c));return c};e.autotab={next:function(){var b=e(document.activeElement);b.length&&b.trigger("autotab-next")},previous:function(){var b=e(document.activeElement);b.length&&b.trigger("autotab-previous")}};e.fn.autotab=function(b,c){if(!this.length)return this;if("filter"==b){if("string"===typeof c||"function"===typeof c)c={format:c};for(var a=0,d=this.length;a<d;a++){var f=k(this[a]),l=c;l.target=f.target;l.previous=f.previous;e.extend(f,l);h(this[a],
13
+ f)}}else if("remove"==b||"destroy"==b||"disable"==b)for(a=0,d=this.length;a<d;a++)f=k(this[a]),f.disabled=!0,h(this[a],f);else if("restore"==b||"enable"==b)for(a=0,d=this.length;a<d;a++)f=k(this[a]),f.disabled=!1,h(this[a],f);else if(null===b||"undefined"===typeof b?c={}:"string"===typeof b||"function"===typeof b?c={format:b}:"object"===typeof b&&(c=b),1<this.length)for(a=0,d=this.length;a<d;a++){var f=a+1,r=a-1,l=c;0<a&&f<d?(l.target=this[f],l.previous=this[r]):0<a?(l.target=null,l.previous=this[r]):
14
+ (l.target=this[f],l.previous=null);s(this[a],l)}else s(this[0],c);return this};var q=function(b,c,a){if("function"===typeof a.format)return a.format(c,b);b=null;switch(a.format){case "text":b=RegExp("[0-9]+","g");break;case "alpha":b=RegExp("[^a-zA-Z]+","g");break;case "number":case "numeric":b=RegExp("[^0-9]+","g");break;case "alphanumeric":b=RegExp("[^0-9a-zA-Z]+","g");break;case "hex":case "hexadecimal":b=RegExp("[^0-9A-Fa-f]+","g");break;case "custom":b=RegExp(a.pattern,"g")}null!==b&&(c=c.replace(b,
15
+ ""));a.nospace&&(b=RegExp("[ ]+","g"),c=c.replace(b,""));a.uppercase&&(c=c.toUpperCase());a.lowercase&&(c=c.toLowerCase());return c},s=function(b,c){var a=k(b);a.disabled&&(a.disabled=!1,a.target=null,a.previous=null);e.extend(a,c);"string"!==typeof a.target&&a.target instanceof jQuery||(a.target=e(a.target));"string"!==typeof a.previous&&a.previous instanceof jQuery||(a.previous=e(a.previous));var d=b.maxLength;2147483647==a.maxlength&&2147483647!=d&&-1!=d?a.maxlength=d:0<a.maxlength?b.maxLength=
16
+ a.maxlength:a.target=null;a.loaded?h(b,a):(a.loaded=!0,h(b,a),e(b).on("autotab-next",function(a,b){var c=this;setTimeout(function(){b||(b=k(c));b.disabled||!b.target.length||p||(b.target.focus().select(),m=new Date)},1)}).on("autotab-previous",function(a,b){var c=this;setTimeout(function(){b||(b=k(c));var a=b.previous;if(!b.disabled&&a.length){var f=a.val();f.length?(a.focus().val(f.substring(0,f.length-1)),h(a,{changed:!0})):a.focus();m=null}},1)}).on("focus",function(){h(this,{originalValue:this.value})}).on("blur",
17
+ function(){var a=k(this);a.changed&&this.value!=a.originalValue&&(h(this,{changed:!1}),e(this).change())}).on("keydown",function(a){var b=k(this);if(!b||b.disabled)return!0;var c=a.which||a.charCode;if(8==c)0===this.value.length&&b.previous.length?e(this).trigger("autotab-previous",b):h(this,{changed:this.value!=b.originalValue});else if(9==c&&null!==m)if(a.shiftKey)m=null;else if(800>(new Date).getTime()-m.getTime())return m=null,!1}).on("keypress",function(a){var b=k(this),c=a.which||a.keyCode;
18
+ if(!b||b.disabled||t&&0===a.charCode||a.ctrlKey||a.altKey||13==c||"text"!=this.type)return!0;c=String.fromCharCode(c);if(null!==b.trigger&&0<=b.trigger.indexOf(c))return null!==m&&800>(new Date).getTime()-m.getTime()?m=null:e(this).trigger("autotab-next",b),!1;m=null;a=document.selection&&document.selection.createRange?!0:0<a.charCode;c=q(this,c,b);if(a&&(null===c||""===c))return!1;if(a&&this.value.length<=this.maxLength){var g,d;a=0;if("number"===typeof this.selectionStart&&"number"===typeof this.selectionEnd)g=
19
+ this.selectionStart,d=this.selectionEnd,a=1;else if(document.selection&&document.selection.createRange){d=document.selection.createRange();g=this.createTextRange();a=this.createTextRange();var u=d.getBookmark();g.moveToBookmark(u);a.setEndPoint("EndToStart",g);g=a.text.length;d=g+d.text.length;a=2}if(0===g&&d==this.value.length)this.value=c;else{if(this.value.length==this.maxLength&&g===d)return e(this).trigger("autotab-next",b),!1;this.value=this.value.slice(0,g)+c+this.value.slice(d)}h(this,{changed:this.value!=
20
+ b.originalValue});this.value.length!=b.maxlength&&(g++,1==a?this.selectionStart=this.selectionEnd=g:2==a&&(c=this.createTextRange(),c.collapse(!0),c.moveEnd("character",g),c.moveStart("character",g),c.select()))}this.value.length==b.maxlength&&e(this).trigger("autotab-next",b);return!1}).on("paste",function(a){var b=k(this);if(!b)return!0;this.maxLength=2147483647;(function(a,c){setTimeout(function(){var d=-1,f=document.createElement("input");f.type="hidden";f.value=a.value.toLowerCase();a.maxLength=
21
+ c.maxlength;a.value=q(a,a.value,c).substr(0,c.maxlength);var h=function(a,b){if(a){for(var c=0,g=b.length;c<g;c++)d=f.value.indexOf(b.charAt(c),d)+1;c=k(a);g=f.value.substr(d);(g=q(a,g,c).substr(0,c.maxlength))?(a.value=g,g.length==c.maxlength&&(e(a).trigger("autotab-next",c),p||h(c.target[0],g))):a.value=""}};a.value.length==c.maxlength&&(e(a).trigger("autotab-next",b),p||h(c.target[0],a.value.toLowerCase()))},1)})(this,b)}))};e.fn.autotab_magic=function(b){e(this).autotab()};e.fn.autotab_filter=
22
+ function(b){var c={};"string"===typeof b||"function"===typeof b?c.format=b:e.extend(c,b);e(this).autotab("filter",c)}})(jQuery);
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: autotab-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sachin Singh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-16 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
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: thor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0.14'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0.14'
69
+ description: AutoTab is a is a jQuery plugin that provides auto tabbing and filtering
70
+ on text fields in a form.
71
+ email:
72
+ - sachin.y87@hmail.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - LICENSE
80
+ - README.md
81
+ - Rakefile
82
+ - autotab-rails.gemspec
83
+ - lib/autotab-rails.rb
84
+ - lib/autotab-rails/engine.rb
85
+ - lib/autotab-rails/engine3.rb
86
+ - lib/autotab-rails/railtie.rb
87
+ - lib/autotab-rails/source_file.rb
88
+ - lib/autotab-rails/tasks.rake
89
+ - lib/autotab-rails/version.rb
90
+ - vendor/assets/javascripts/autotab-jquery.js
91
+ - vendor/assets/javascripts/autotab-jquery.min.js
92
+ homepage: https://github.com/sachin87/autotab-rails
93
+ licenses: []
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 2.0.3
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: Integrate AutoTab javascript library with Rails asset pipeline
115
+ test_files: []