bootstrap_tokenfield_rails 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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: