bootstrap_tokenfield_rails 0.0.4 → 0.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f3d4cbd95d07bf80fb85a296164a4d7d1bf9533a
4
- data.tar.gz: 744fcb50397de2b1f5d6abef4b2c06c86e1efd8d
3
+ metadata.gz: c533323348030827ed5e4aa4eee743ffd435b4d7
4
+ data.tar.gz: b6862dacd523e99ce27c70e42f3d08d721112016
5
5
  SHA512:
6
- metadata.gz: f8c4b25ed5582ee998b5bbef75812291a507246c42d04e374d0080327e6f3c649f81842a440b3468dd5c2c6419d5a92afcef4da145ea29be40d8c066c03a5623
7
- data.tar.gz: 0c6e60aab1fa060cc81901d097711a07b0daf935a3731ddbea25ca87bc1f7b87ee09b1d7ef7cd6e723e02a6292d6094f49492be6b937ed2dd96d4e814eb19075
6
+ metadata.gz: f3d34d14b0a4ad365eab53c23bff25e2ae9b60c620e7dad34a68e731fc724d2ea77ec4c010fb282e4756a132325d68ecdc6bf8f901ead01aa84833d6431c3ff9
7
+ data.tar.gz: e749645820da94d53d92fbd609b3f8e3d66c82603e32a5b47c412d2df7a17fa8d8dd59146187afb7e9cd65c751a8dec0bdc695e54d8603dfd05d08aedc91e31a
@@ -1,3 +1,3 @@
1
1
  module BootstrapTokenfieldRails
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -1,11 +1,17 @@
1
1
  /* ============================================================
2
- * bootstrap-tokenfield.js v0.9.9-2
2
+ * bootstrap-tokenfield.js v0.11.0
3
3
  * ============================================================
4
4
  *
5
5
  * Copyright 2013 Sliptree
6
6
  * ============================================================ */
7
7
 
8
- !function ($) {
8
+ (function (root, factory) {
9
+ if (typeof define === 'function' && define.amd) {
10
+ define(['jquery'], factory);
11
+ } else {
12
+ root.Tokenfield = factory(root.jQuery);
13
+ }
14
+ }(this, function ($) {
9
15
 
10
16
  "use strict"; // jshint ;_;
11
17
 
@@ -16,10 +22,11 @@
16
22
  var _self = this
17
23
 
18
24
  this.$element = $(element)
19
-
25
+ this.textDirection = this.$element.css('direction');
26
+
20
27
  // Extend options
21
28
  this.options = $.extend({}, $.fn.tokenfield.defaults, { tokens: this.$element.val() }, options)
22
-
29
+
23
30
  // Setup delimiters and trigger keys
24
31
  this._delimiters = (typeof this.options.delimiter === 'string') ? [this.options.delimiter] : this.options.delimiter
25
32
  this._triggerKeys = $.map(this._delimiters, function (delimiter) {
@@ -41,19 +48,18 @@
41
48
  }
42
49
 
43
50
  // Move original input out of the way
44
- this.$element.css({
45
- 'position': 'absolute',
46
- 'left': '-10000px'
47
- }).prop('tabindex', -1);
51
+ var hidingPosition = $('body').css('direction') === 'rtl' ? 'right' : 'left';
52
+ this.$element.css('position', 'absolute').css(hidingPosition, '-10000px').prop('tabindex', -1)
48
53
 
49
54
  // Create a wrapper
50
55
  this.$wrapper = $('<div class="tokenfield form-control" />')
51
56
  if (this.$element.hasClass('input-lg')) this.$wrapper.addClass('input-lg')
52
57
  if (this.$element.hasClass('input-sm')) this.$wrapper.addClass('input-sm')
58
+ if (this.textDirection === 'rtl') this.$wrapper.addClass('rtl')
53
59
 
54
60
  // Create a new input
55
61
  var id = this.$element.prop('id') || new Date().getTime() + '' + Math.floor((1 + Math.random()) * 100)
56
- this.$input = $('<input type="text" class="token-input" />')
62
+ this.$input = $('<input type="text" class="token-input" autocomplete="off" />')
57
63
  .appendTo( this.$wrapper )
58
64
  .prop( 'placeholder', this.$element.prop('placeholder') )
59
65
  .prop( 'id', id + '-tokenfield' )
@@ -65,11 +71,8 @@
65
71
  }
66
72
 
67
73
  // Set up a copy helper to handle copy & paste
68
- this.$copyHelper = $('<input type="text" />').css({
69
- 'position': 'absolute',
70
- 'left': '-10000px'
71
- }).prop('tabindex', -1).prependTo( this.$wrapper )
72
-
74
+ this.$copyHelper = $('<input type="text" />').css('position', 'absolute').css(hidingPosition, '-10000px').prop('tabindex', -1).prependTo( this.$wrapper )
75
+
73
76
  // Set wrapper width
74
77
  if (elStyleWidth) {
75
78
  this.$wrapper.css('width', elStyleWidth);
@@ -91,13 +94,13 @@
91
94
  this.$mirror = $('<span style="position:absolute; top:-999px; left:0; white-space:pre;"/>');
92
95
  this.$input.css('min-width', this.options.minWidth + 'px')
93
96
  $.each([
94
- 'fontFamily',
95
- 'fontSize',
96
- 'fontWeight',
97
- 'fontStyle',
98
- 'letterSpacing',
99
- 'textTransform',
100
- 'wordSpacing',
97
+ 'fontFamily',
98
+ 'fontSize',
99
+ 'fontWeight',
100
+ 'fontStyle',
101
+ 'letterSpacing',
102
+ 'textTransform',
103
+ 'wordSpacing',
101
104
  'textIndent'
102
105
  ], function (i, val) {
103
106
  _self.$mirror[0].style[val] = _self.$input.css(val);
@@ -110,7 +113,7 @@
110
113
 
111
114
  // Calculate inner input width
112
115
  this.update()
113
-
116
+
114
117
  // Create initial tokens, if any
115
118
  this.setTokens(this.options.tokens, false, false)
116
119
 
@@ -119,9 +122,10 @@
119
122
 
120
123
  // Initialize autocomplete, if necessary
121
124
  if ( ! $.isEmptyObject( this.options.autocomplete ) ) {
125
+ var side = this.textDirection === 'rtl' ? 'right' : 'left'
122
126
  var autocompleteOptions = $.extend({}, this.options.autocomplete, {
123
127
  minLength: this.options.showAutocompleteOnFocus ? 0 : null,
124
- position: { my: "left top", at: "left bottom", of: this.$wrapper }
128
+ position: { my: side + " top", at: side + " bottom", of: this.$wrapper }
125
129
  })
126
130
  this.$input.autocomplete( autocompleteOptions )
127
131
  }
@@ -146,25 +150,14 @@
146
150
  if (typeof triggerChange === 'undefined') {
147
151
  triggerChange = true
148
152
  }
149
-
153
+
150
154
  var _self = this
151
155
  , value = $.trim(attrs.value)
152
156
  , label = attrs.label.length ? $.trim(attrs.label) : value
153
157
 
154
158
  if (!value.length || !label.length || value.length < this.options.minLength) return
155
159
 
156
- if (!this.options.allowDuplicates && $.grep(this.getTokens(), function (token) {
157
- return token.value === value
158
- }).length) {
159
- // Allow listening to when duplicates get prevented
160
- var duplicateEvent = $.Event('preventDuplicateToken')
161
- duplicateEvent.token = {
162
- value: value,
163
- label: label
164
- }
165
- this.$element.trigger( duplicateEvent )
166
- return
167
- }
160
+ if (this.options.limit && this.getTokens().length >= this.options.limit) return
168
161
 
169
162
  // Allow changing token data before creating it
170
163
  var beforeCreateEvent = $.Event('beforeCreateToken')
@@ -179,6 +172,25 @@
179
172
  value = beforeCreateEvent.token.value
180
173
  label = beforeCreateEvent.token.label
181
174
 
175
+ // Check for duplicates
176
+ if (!this.options.allowDuplicates && $.grep(this.getTokens(), function (token) {
177
+ return token.value === value
178
+ }).length) {
179
+ // Allow listening to when duplicates get prevented
180
+ var duplicateEvent = $.Event('preventDuplicateToken')
181
+ duplicateEvent.token = {
182
+ value: value,
183
+ label: label
184
+ }
185
+ this.$element.trigger( duplicateEvent )
186
+ // Add duplicate warning class to existing token for 250ms
187
+ var duplicate = this.$wrapper.find( '.token[data-value="' + value + '"]' ).addClass('duplicate')
188
+ setTimeout(function() {
189
+ duplicate.removeClass('duplicate');
190
+ }, 250)
191
+ return false
192
+ }
193
+
182
194
  var token = $('<div class="token" />')
183
195
  .attr('data-value', value)
184
196
  .append('<span class="token-label" />')
@@ -198,7 +210,7 @@
198
210
  // Determine maximum possible token label width
199
211
  if (!this.maxTokenWidth) {
200
212
  this.maxTokenWidth =
201
- this.$wrapper.width() - closeButton.outerWidth() -
213
+ this.$wrapper.width() - closeButton.outerWidth() -
202
214
  parseInt(closeButton.css('margin-left'), 10) -
203
215
  parseInt(closeButton.css('margin-right'), 10) -
204
216
  parseInt(token.css('border-left-width'), 10) -
@@ -231,8 +243,8 @@
231
243
  e.preventDefault()
232
244
  return _self.toggle( token )
233
245
  }
234
-
235
- _self.activate( token, e.shiftKey, e.shiftKey )
246
+
247
+ _self.activate( token, e.shiftKey, e.shiftKey )
236
248
  })
237
249
  .on('dblclick', function (e) {
238
250
  if (_self.disabled) return false;
@@ -255,7 +267,7 @@
255
267
  this.update()
256
268
 
257
269
  return this.$input.get(0)
258
- }
270
+ }
259
271
 
260
272
  , setTokens: function (tokens, add, triggerChange) {
261
273
  if (!tokens) return
@@ -311,7 +323,7 @@
311
323
  , getTokensList: function(delimiter, beautify, active) {
312
324
  delimiter = delimiter || this._delimiters[0]
313
325
  beautify = ( typeof beautify !== 'undefined' && beautify !== null ) ? beautify : this.options.beautify
314
-
326
+
315
327
  var separator = delimiter + ( beautify && delimiter !== ' ' ? ' ' : '')
316
328
  return $.map( this.getTokens(active), function (token) {
317
329
  return token.value
@@ -341,7 +353,7 @@
341
353
 
342
354
  this.$copyHelper
343
355
  .on('focus', $.proxy(this.focus, this))
344
- .on('blur', $.proxy(this.blur, this))
356
+ .on('blur', $.proxy(this.blur, this))
345
357
  .on('keydown', $.proxy(this.keydown, this))
346
358
  .on('keyup', $.proxy(this.keyup, this))
347
359
 
@@ -354,7 +366,7 @@
354
366
  .on('autocompletecreate', function() {
355
367
  // Set minimum autocomplete menu width
356
368
  var $_menuElement = $(this).data('ui-autocomplete').menu.element
357
-
369
+
358
370
  var minWidth = _self.$wrapper.outerWidth() -
359
371
  parseInt( $_menuElement.css('border-left-width'), 10 ) -
360
372
  parseInt( $_menuElement.css('border-right-width'), 10 )
@@ -362,10 +374,11 @@
362
374
  $_menuElement.css( 'min-width', minWidth + 'px' )
363
375
  })
364
376
  .on('autocompleteselect', function (e, ui) {
365
- _self.$input.val('')
366
- _self.createToken( ui.item )
367
- if (_self.$input.data( 'edit' )) {
368
- _self.unedit(true)
377
+ if (_self.createToken( ui.item )) {
378
+ _self.$input.val('')
379
+ if (_self.$input.data( 'edit' )) {
380
+ _self.unedit(true)
381
+ }
369
382
  }
370
383
  return false
371
384
  })
@@ -380,10 +393,11 @@
380
393
  })
381
394
 
382
395
  // Create token
383
- _self.createToken( datum[valueKey] )
384
- _self.$input.typeahead('setQuery', '')
385
- if (_self.$input.data( 'edit' )) {
386
- _self.unedit(true)
396
+ if (_self.createToken( datum[valueKey] )) {
397
+ _self.$input.typeahead('setQuery', '')
398
+ if (_self.$input.data( 'edit' )) {
399
+ _self.unedit(true)
400
+ }
387
401
  }
388
402
  })
389
403
  .on('typeahead:autocompleted', function (e, datum, dataset) {
@@ -403,6 +417,8 @@
403
417
 
404
418
  if (!this.focused) return
405
419
 
420
+ var _self = this
421
+
406
422
  switch(e.keyCode) {
407
423
  case 8: // backspace
408
424
  if (!this.$input.is(document.activeElement)) break
@@ -410,88 +426,20 @@
410
426
  break
411
427
 
412
428
  case 37: // left arrow
413
- if (this.$input.is(document.activeElement)) {
414
- if (this.$input.val().length > 0) break
415
-
416
- var prev = this.$input.hasClass('tt-query') ? this.$input.parent().prevAll('.token:first') : this.$input.prevAll('.token:first')
417
-
418
- if (!prev.length) break
419
-
420
- this.preventInputFocus = true
421
- this.preventDeactivation = true
422
-
423
- this.activate( prev )
424
- e.preventDefault()
425
-
426
- } else {
427
-
428
- this.prev( e.shiftKey )
429
- e.preventDefault()
430
- }
429
+ leftRight( this.textDirection === 'rtl' ? 'next': 'prev' )
431
430
  break
432
431
 
433
432
  case 38: // up arrow
434
- if (!e.shiftKey) return
435
-
436
- if (this.$input.is(document.activeElement)) {
437
- if (this.$input.val().length > 0) break
438
-
439
- var prev = this.$input.hasClass('tt-query') ? this.$input.parent().prevAll('.token:last') : this.$input.prevAll('.token:last')
440
- if (!prev.length) return
441
-
442
- this.activate( prev )
443
- }
444
-
445
- var _self = this
446
- this.firstActiveToken.nextAll('.token').each(function() {
447
- _self.deactivate( $(this) )
448
- })
449
-
450
- this.activate( this.$wrapper.find('.token:first'), true, true )
451
- e.preventDefault()
433
+ upDown('prev')
452
434
  break
453
435
 
454
436
  case 39: // right arrow
455
- if (this.$input.is(document.activeElement)) {
456
-
457
- if (this.$input.val().length > 0) break
458
-
459
- var next = this.$input.hasClass('tt-query') ? this.$input.parent().nextAll('.token:first') : this.$input.nextAll('.token:first')
460
-
461
- if (!next.length) break
462
-
463
- this.preventInputFocus = true
464
- this.preventDeactivation = true
465
-
466
- this.activate( next )
467
- e.preventDefault()
468
-
469
- } else {
470
- this.next( e.shiftKey )
471
- e.preventDefault()
472
- }
437
+ leftRight( this.textDirection === 'rtl' ? 'prev': 'next' )
473
438
  break
474
439
 
475
440
  case 40: // down arrow
476
- if (!e.shiftKey) return
477
-
478
- if (this.$input.is(document.activeElement)) {
479
- if (this.$input.val().length > 0) break
480
-
481
- var next = this.$input.hasClass('tt-query') ? this.$input.parent().nextAll('.token:first') : this.$input.nextAll('.token:first')
482
- if (!next.length) return
483
-
484
- this.activate( next )
485
- }
486
-
487
- var _self = this
488
- this.firstActiveToken.prevAll('.token').each(function() {
489
- _self.deactivate( $(this) )
490
- })
491
-
492
- this.activate( this.$wrapper.find('.token:last'), true, true )
493
- e.preventDefault()
494
- break
441
+ upDown('next')
442
+ break
495
443
 
496
444
  case 65: // a (to handle ctrl + a)
497
445
  if (this.$input.val().length > 0 || !(e.ctrlKey || e.metaKey)) break
@@ -504,20 +452,66 @@
504
452
 
505
453
  // We will handle creating tokens from autocomplete in autocomplete events
506
454
  if (this.$input.data('ui-autocomplete') && this.$input.data('ui-autocomplete').menu.element.find("li:has(a.ui-state-focus)").length) break
455
+
507
456
  // We will handle creating tokens from typeahead in typeahead events
508
457
  if (this.$input.hasClass('tt-query') && this.$wrapper.find('.tt-is-under-cursor').length ) break
509
458
  if (this.$input.hasClass('tt-query') && this.$wrapper.find('.tt-hint').val().length) break
510
-
459
+
511
460
  // Create token
512
461
  if (this.$input.is(document.activeElement) && this.$input.val().length || this.$input.data('edit')) {
513
- this.createTokensFromInput(e, this.$input.data('edit'))
462
+ return this.createTokensFromInput(e, this.$input.data('edit'));
514
463
  }
464
+
465
+ // Edit token
515
466
  if (e.keyCode === 13) {
516
467
  if (!this.$copyHelper.is(document.activeElement) || this.$wrapper.find('.token.active').length !== 1) break
517
468
  this.edit( this.$wrapper.find('.token.active') )
518
469
  }
519
470
  }
520
471
 
472
+ function leftRight(direction) {
473
+ if (_self.$input.is(document.activeElement)) {
474
+ if (_self.$input.val().length > 0) return
475
+
476
+ direction += 'All'
477
+ var token = _self.$input.hasClass('tt-query') ? _self.$input.parent()[direction]('.token:first') : _self.$input[direction]('.token:first')
478
+ if (!token.length) return
479
+
480
+ _self.preventInputFocus = true
481
+ _self.preventDeactivation = true
482
+
483
+ _self.activate( token )
484
+ e.preventDefault()
485
+
486
+ } else {
487
+ _self[direction]( e.shiftKey )
488
+ e.preventDefault()
489
+ }
490
+ }
491
+
492
+ function upDown(direction) {
493
+ if (!e.shiftKey) return
494
+
495
+ if (_self.$input.is(document.activeElement)) {
496
+ if (_self.$input.val().length > 0) return
497
+
498
+ var token = _self.$input.hasClass('tt-query') ? _self.$input.parent()[direction + 'All']('.token:first') : _self.$input[direction + 'All']('.token:first')
499
+ if (!token.length) return
500
+
501
+ _self.activate( token )
502
+ }
503
+
504
+ var opposite = direction === 'prev' ? 'next' : 'prev'
505
+ , position = direction === 'prev' ? 'first' : 'last'
506
+
507
+ _self.firstActiveToken[opposite + 'All']('.token').each(function() {
508
+ _self.deactivate( $(this) )
509
+ })
510
+
511
+ _self.activate( _self.$wrapper.find('.token:' + position), true, true )
512
+ e.preventDefault()
513
+ }
514
+
521
515
  this.lastKeyDown = e.keyCode
522
516
  }
523
517
 
@@ -543,7 +537,7 @@
543
537
  case 8: // backspace
544
538
  if (this.$input.is(document.activeElement)) {
545
539
  if (this.$input.val().length || this.lastInputValue.length && this.lastKeyDown === 8) break
546
-
540
+
547
541
  this.preventDeactivation = true
548
542
  var prev = this.$input.hasClass('tt-query') ? this.$input.parent().prevAll('.token:first') : this.$input.prevAll('.token:first')
549
543
 
@@ -587,16 +581,16 @@
587
581
  }
588
582
 
589
583
  if (!this.preventCreateTokens && (this.$input.data('edit') && !this.$input.is(document.activeElement) || this.options.createTokensOnBlur )) {
590
- this.createTokensFromInput(e)
584
+ this.createTokensFromInput(e)
591
585
  }
592
-
586
+
593
587
  this.preventDeactivation = false
594
588
  this.preventCreateTokens = false
595
589
  }
596
590
 
597
591
  , paste: function (e) {
598
592
  var _self = this
599
-
593
+
600
594
  // Add tokens to existing ones
601
595
  setTimeout(function () {
602
596
  _self.createTokensFromInput(e)
@@ -605,16 +599,19 @@
605
599
 
606
600
  , change: function (e) {
607
601
  if ( e.initiator === 'tokenfield' ) return // Prevent loops
608
-
602
+
609
603
  this.setTokens( this.$element.val() )
610
604
  }
611
605
 
612
606
  , createTokensFromInput: function (e, focus) {
613
- if (this.$input.val().length < this.options.minLength) return
607
+ if (this.$input.val().length < this.options.minLength)
608
+ return // No input, simply return
614
609
 
615
610
  var tokensBefore = this.getTokensList()
616
611
  this.setTokens( this.$input.val(), true )
617
- if (tokensBefore == this.getTokensList() && this.$input.val().length) return // No tokens were added, do nothing
612
+
613
+ if (tokensBefore == this.getTokensList() && this.$input.val().length)
614
+ return false // No tokens were added, do nothing (prevent form submit)
618
615
 
619
616
  if (this.$input.hasClass('tt-query')) {
620
617
  // Typeahead acts weird when simply setting input value to empty,
@@ -628,9 +625,8 @@
628
625
  this.unedit(focus)
629
626
  }
630
627
 
631
- e.preventDefault()
632
- e.stopPropagation()
633
- }
628
+ return false // Prevent form being submitted
629
+ }
634
630
 
635
631
  , next: function (add) {
636
632
  if (add) {
@@ -690,7 +686,7 @@
690
686
  if (!add) {
691
687
  this.$wrapper.find('.active').removeClass('active')
692
688
  if (remember) {
693
- this.firstActiveToken = token
689
+ this.firstActiveToken = token
694
690
  } else {
695
691
  delete this.firstActiveToken
696
692
  }
@@ -748,7 +744,7 @@
748
744
  }
749
745
  beforeEditEvent.relatedTarget = token.get(0)
750
746
  this.$element.trigger( beforeEditEvent )
751
-
747
+
752
748
  if (!beforeEditEvent.token) return
753
749
 
754
750
  value = beforeEditEvent.token.value
@@ -772,12 +768,12 @@
772
768
  , unedit: function (focus) {
773
769
  var $_input = this.$input.hasClass('tt-query') ? this.$input.parent() : this.$input
774
770
  $_input.appendTo( this.$wrapper )
775
-
771
+
776
772
  this.$input.data('edit', false)
777
773
 
778
774
  this.update()
779
775
 
780
- // Because moving the input element around in DOM
776
+ // Because moving the input element around in DOM
781
777
  // will cause it to lose focus, we provide an option
782
778
  // to re-focus the input after appending it to the wrapper
783
779
  if (focus) {
@@ -792,7 +788,7 @@
792
788
  if (this.$input.is(document.activeElement) || this.disabled) return
793
789
 
794
790
  var token = (e.type === 'click') ? $(e.target).closest('.token') : this.$wrapper.find('.token.active')
795
-
791
+
796
792
  if (e.type !== 'click') {
797
793
  if (!direction) var direction = 'prev'
798
794
  this[direction]()
@@ -839,7 +835,7 @@
839
835
  if (value === this.$mirror.text()) return
840
836
 
841
837
  this.$mirror.text(value)
842
-
838
+
843
839
  var mirrorWidth = this.$mirror.width() + 10;
844
840
  if ( mirrorWidth > this.$wrapper.width() ) {
845
841
  return this.$input.width( this.$wrapper.width() )
@@ -849,7 +845,10 @@
849
845
  }
850
846
  else {
851
847
  this.$input.css( 'width', this.options.minWidth + 'px' )
852
- this.$input.width( this.$wrapper.offset().left + this.$wrapper.width() - this.$input.offset().left + 5 )
848
+ if (this.textDirection === 'rtl') {
849
+ return this.$input.width( this.$input.offset().left + this.$input.outerWidth() - this.$wrapper.offset().left - parseInt(this.$wrapper.css('padding-left'), 10) - 1 )
850
+ }
851
+ this.$input.width( this.$wrapper.offset().left + this.$wrapper.width() + parseInt(this.$wrapper.css('padding-left'), 10) - this.$input.offset().left )
853
852
  }
854
853
  }
855
854
 
@@ -897,7 +896,7 @@
897
896
  $.fn.tokenfield = function (option, param) {
898
897
  var value
899
898
  , args = []
900
-
899
+
901
900
  Array.prototype.push.apply( args, arguments );
902
901
 
903
902
  var elements = this.each(function () {
@@ -920,6 +919,7 @@
920
919
  minWidth: 60,
921
920
  minLength: 0,
922
921
  allowDuplicates: false,
922
+ limit: 0,
923
923
  autocomplete: {},
924
924
  typeahead: {},
925
925
  showAutocompleteOnFocus: false,
@@ -939,4 +939,6 @@
939
939
  return this
940
940
  }
941
941
 
942
- }(window.jQuery);
942
+ return Tokenfield;
943
+
944
+ }));
@@ -6,21 +6,35 @@
6
6
  .tokenfield.focus {
7
7
  border-color: #66afe9;
8
8
  outline: 0;
9
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
10
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
9
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);
10
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);
11
+ }
12
+ .has-warning .tokenfield.focus {
13
+ border-color: #66512c;
14
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
15
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
16
+ }
17
+ .has-error .tokenfield.focus {
18
+ border-color: #843534;
19
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
20
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
21
+ }
22
+ .has-success .tokenfield.focus {
23
+ border-color: #2b542c;
24
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
25
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
11
26
  }
12
-
13
27
  .tokenfield .token {
14
28
  box-sizing: border-box;
15
- -moz-box-sizing: border-box; /* Firefox */
29
+ -moz-box-sizing: border-box;
16
30
  display: inline-block;
17
31
  border: 1px solid #d9d9d9;
18
32
  background-color: #ededed;
19
33
  -webkit-border-radius: 3px;
20
34
  -moz-border-radius: 3px;
21
35
  border-radius: 3px;
22
- white-space: nowrap;
23
- margin: -1px 5px 5px 0;
36
+ white-space: nowrap;
37
+ margin: -1px 5px 5px 0;
24
38
  height: 22px;
25
39
  vertical-align: top;
26
40
  cursor: default;
@@ -28,12 +42,42 @@
28
42
  .tokenfield .token:hover {
29
43
  border-color: #b9b9b9;
30
44
  }
31
-
32
45
  .tokenfield .token.active {
33
- border-color: rgb(82, 168, 236);
46
+ border-color: #52a8ec;
34
47
  border-color: rgba(82, 168, 236, 0.8);
35
48
  }
36
-
49
+ .tokenfield .token.duplicate {
50
+ border-color: #b94a48;
51
+ -webkit-animation-direction: normal;
52
+ -webkit-animation-duration: 0.1s;
53
+ -webkit-animation-iteration-count: infinite;
54
+ -webkit-animation-name: blink;
55
+ -webkit-animation-timing-function: ease;
56
+ }
57
+ @-webkit-keyframes 'blink' {
58
+ 0% {
59
+ border-color: #ededed;
60
+ }
61
+ 100% {
62
+ border-color: #b94a48;
63
+ }
64
+ }
65
+ @-moz-keyframes 'blink' {
66
+ 0% {
67
+ border-color: #ededed;
68
+ }
69
+ 100% {
70
+ border-color: #b94a48;
71
+ }
72
+ }
73
+ @keyframes 'blink' {
74
+ 0% {
75
+ border-color: #ededed;
76
+ }
77
+ 100% {
78
+ border-color: #b94a48;
79
+ }
80
+ }
37
81
  .tokenfield .token .token-label {
38
82
  display: inline-block;
39
83
  overflow: hidden;
@@ -41,7 +85,6 @@
41
85
  padding-left: 4px;
42
86
  vertical-align: top;
43
87
  }
44
-
45
88
  .tokenfield .token .close {
46
89
  font-family: Arial;
47
90
  display: inline-block;
@@ -54,7 +97,6 @@
54
97
  vertical-align: top;
55
98
  padding-right: 4px;
56
99
  }
57
-
58
100
  .tokenfield .token-input {
59
101
  background: none;
60
102
  width: 60px;
@@ -72,17 +114,16 @@
72
114
  outline: 0;
73
115
  /* IE6-9 */
74
116
  -webkit-box-shadow: none;
75
- -moz-box-shadow: none;
76
- box-shadow: none;
117
+ -moz-box-shadow: none;
118
+ box-shadow: none;
77
119
  }
78
-
79
120
  /* Invalid token */
80
121
  .tokenfield .token.invalid {
81
122
  background: none;
82
123
  border: 1px solid transparent;
83
124
  -webkit-border-radius: 0;
84
125
  -moz-border-radius: 0;
85
- border-radius: 0;
126
+ border-radius: 0;
86
127
  border-bottom: 1px dotted #b94a48;
87
128
  }
88
129
  .tokenfield .token.invalid.active {
@@ -92,7 +133,6 @@
92
133
  -moz-border-radius: 3px;
93
134
  border-radius: 3px;
94
135
  }
95
-
96
136
  /* Disabled tokenfield */
97
137
  .tokenfield.disabled {
98
138
  cursor: not-allowed;
@@ -105,7 +145,6 @@
105
145
  cursor: not-allowed;
106
146
  opacity: 0.2;
107
147
  }
108
-
109
148
  /* Different sizes */
110
149
  .tokenfield.input-sm,
111
150
  .input-group-sm .tokenfield {
@@ -122,7 +161,6 @@
122
161
  height: 18px;
123
162
  margin-bottom: 5px;
124
163
  }
125
-
126
164
  .tokenfield.input-lg,
127
165
  .input-group-lg .tokenfield {
128
166
  min-height: 45px;
@@ -147,3 +185,15 @@
147
185
  margin-bottom: 6px;
148
186
  vertical-align: top;
149
187
  }
188
+ /* RTL */
189
+ .tokenfield.rtl {
190
+ direction: rtl;
191
+ text-align: right;
192
+ }
193
+ .tokenfield.rtl .token {
194
+ margin: -1px 0 5px 5px;
195
+ }
196
+ .tokenfield.rtl .token .token-label {
197
+ padding-left: 0px;
198
+ padding-right: 4px;
199
+ }
@@ -0,0 +1,137 @@
1
+ /* General Typeahead styling, from http://jsfiddle.net/ragulka/Dy9au/1/ */
2
+ .twitter-typeahead {
3
+ width: 100%;
4
+ position: relative;
5
+ vertical-align: top;
6
+ }
7
+ .twitter-typeahead .tt-query,
8
+ .twitter-typeahead .tt-hint {
9
+ margin: 0;
10
+ width: 100%;
11
+ vertical-align: middle;
12
+ background-color: #ffffff;
13
+ }
14
+ .twitter-typeahead .tt-hint {
15
+ color: #999999;
16
+ z-index: 1;
17
+ border: 1px solid transparent;
18
+ }
19
+ .twitter-typeahead .tt-query {
20
+ color: #555555;
21
+ z-index: 2;
22
+ }
23
+ .twitter-typeahead .tt-query,
24
+ .twitter-typeahead .tt-hint {
25
+ height: 34px;
26
+ padding: 6px 12px;
27
+ font-size: 14px;
28
+ line-height: 1.428571429;
29
+ }
30
+ .twitter-typeahead .input-sm.tt-query,
31
+ .twitter-typeahead .hint-sm.tt-hint {
32
+ border-radius: 3px;
33
+ }
34
+ .twitter-typeahead .input-lg.tt-query,
35
+ .twitter-typeahead .hint-lg.tt-hint {
36
+ border-radius: 6px;
37
+ }
38
+ .input-group .twitter-typeahead:first-child .tt-query,
39
+ .input-group .twitter-typeahead:first-child .tt-hint {
40
+ border-radius: 4px 0 0 4px !important;
41
+ }
42
+ .input-group .twitter-typeahead:last-child .tt-query,
43
+ .input-group .twitter-typeahead:last-child .tt-hint {
44
+ border-radius: 0 4px 4px 0 !important;
45
+ }
46
+ .input-group.input-group-sm .twitter-typeahead:first-child .tt-query,
47
+ .input-group.input-group-sm .twitter-typeahead:first-child .tt-hint {
48
+ border-radius: 3px 0 0 3px !important;
49
+ }
50
+ .input-group.input-group-sm .twitter-typeahead:last-child .tt-query,
51
+ .input-group.input-group-sm .twitter-typeahead:last-child .tt-hint {
52
+ border-radius: 0 3px 3px 0 !important;
53
+ }
54
+ .input-sm.tt-query,
55
+ .hint-sm.tt-hint,
56
+ .input-group.input-group-sm .tt-query,
57
+ .input-group.input-group-sm .tt-hint {
58
+ height: 30px;
59
+ padding: 5px 10px;
60
+ font-size: 12px;
61
+ line-height: 1.5;
62
+ }
63
+ .input-group.input-group-lg .twitter-typeahead:first-child .tt-query,
64
+ .input-group.input-group-lg .twitter-typeahead:first-child .tt-hint {
65
+ border-radius: 6px 0 0 6px !important;
66
+ }
67
+ .input-group.input-group-lg .twitter-typeahead:last-child .tt-query,
68
+ .input-group.input-group-lg .twitter-typeahead:last-child .tt-hint {
69
+ border-radius: 0 6px 6px 0 !important;
70
+ }
71
+ .input-lg.tt-query,
72
+ .hint-lg.tt-hint,
73
+ .input-group.input-group-lg .tt-query,
74
+ .input-group.input-group-lg .tt-hint {
75
+ height: 45px;
76
+ padding: 10px 16px;
77
+ font-size: 18px;
78
+ line-height: 1.33;
79
+ }
80
+ .tt-dropdown-menu {
81
+ width: 100%;
82
+ min-width: 160px;
83
+ margin-top: 2px;
84
+ padding: 5px 0;
85
+ background-color: #ffffff;
86
+ border: 1px solid #ccc;
87
+ border: 1px solid rgba(0, 0, 0, 0.15);
88
+ *border-right-width: 2px;
89
+ *border-bottom-width: 2px;
90
+ border-radius: 6px;
91
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
92
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
93
+ -webkit-background-clip: padding-box;
94
+ -moz-background-clip: padding;
95
+ background-clip: padding-box;
96
+ }
97
+ .tt-suggestion {
98
+ display: block;
99
+ padding: 3px 20px;
100
+ }
101
+ .tt-suggestion.tt-is-under-cursor {
102
+ color: #262626;
103
+ background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
104
+ background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
105
+ background-repeat: repeat-x;
106
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
107
+ }
108
+ .tt-suggestion.tt-is-under-cursor a {
109
+ color: #ffffff;
110
+ }
111
+ .tt-suggestion p {
112
+ margin: 0;
113
+ }
114
+ /* Tokenfield-specific Typeahead styling */
115
+ .tokenfield .twitter-typeahead {
116
+ width: auto;
117
+ }
118
+ .tokenfield .twitter-typeahead .tt-hint {
119
+ padding: 0;
120
+ margin-left: -1px;
121
+ height: 20px;
122
+ }
123
+ .tokenfield.input-sm .twitter-typeahead .tt-query,
124
+ .tokenfield.input-sm .twitter-typeahead .tt-hint {
125
+ height: 18px;
126
+ font-size: 12px;
127
+ line-height: 1.5;
128
+ }
129
+ .tokenfield.input-lg .twitter-typeahead .tt-query,
130
+ .tokenfield.input-lg .twitter-typeahead .tt-hint {
131
+ height: 23px;
132
+ font-size: 18px;
133
+ line-height: 1.33;
134
+ }
135
+ .tokenfield .twitter-typeahead .tt-suggestions {
136
+ font-size: 14px;
137
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootstrap_tokenfield_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akash Devaraju
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-18 00:00:00.000000000 Z
11
+ date: 2014-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -49,6 +49,7 @@ files:
49
49
  - lib/bootstrap_tokenfield_rails.rb
50
50
  - lib/bootstrap_tokenfield_rails/version.rb
51
51
  - vendor/assets/stylesheets/bootstrap-tokenfield.css
52
+ - vendor/assets/stylesheets/tokenfield-typeahead.css
52
53
  - vendor/assets/javascripts/bootstrap-tokenfield.js
53
54
  homepage: http://www.icicletech.com/open-source-software/bootstrap-tokenfield-rails
54
55
  licenses:
@@ -75,3 +76,4 @@ signing_key:
75
76
  specification_version: 4
76
77
  summary: A jQuery tagging / tokenizer input plugin for Twitter's Bootstrap
77
78
  test_files: []
79
+ has_rdoc: