autotab-rails 0.0.1

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.
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: []