rails_tokeninput 1.6.1.rc1 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ /*! jquery.tokeninput 2014-04-02 */
2
+ !function(a){function b(a){return String(null===a||void 0===a?"":a)}function c(a){return b(a).replace(i,function(a){return h[a]})}var d={method:"GET",queryParam:"q",searchDelay:300,minChars:1,propertyToSearch:"name",jsonContainer:null,contentType:"json",excludeCurrent:!1,excludeCurrentParameter:"x",prePopulate:null,processPrePopulate:!1,hintText:"Type in a search term",noResultsText:"No results",searchingText:"Searching...",deleteText:"&#215;",animateDropdown:!0,placeholder:null,theme:null,zindex:999,resultsLimit:null,enableHTML:!1,resultsFormatter:function(a){var b=a[this.propertyToSearch];return"<li>"+(this.enableHTML?b:c(b))+"</li>"},tokenFormatter:function(a){var b=a[this.propertyToSearch];return"<li><p>"+(this.enableHTML?b:c(b))+"</p></li>"},tokenLimit:null,tokenDelimiter:",",preventDuplicates:!1,tokenValue:"id",allowFreeTagging:!1,allowTabOut:!1,autoSelectFirstResult:!1,onResult:null,onCachedResult:null,onAdd:null,onFreeTaggingAdd:null,onDelete:null,onReady:null,idPrefix:"token-input-",disabled:!1},e={tokenList:"token-input-list",token:"token-input-token",tokenReadOnly:"token-input-token-readonly",tokenDelete:"token-input-delete-token",selectedToken:"token-input-selected-token",highlightedToken:"token-input-highlighted-token",dropdown:"token-input-dropdown",dropdownItem:"token-input-dropdown-item",dropdownItem2:"token-input-dropdown-item2",selectedDropdownItem:"token-input-selected-dropdown-item",inputToken:"token-input-input-token",focused:"token-input-focused",disabled:"token-input-disabled"},f={BEFORE:0,AFTER:1,END:2},g={BACKSPACE:8,TAB:9,ENTER:13,ESCAPE:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,NUMPAD_ENTER:108,COMMA:188},h={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;"},i=/[&<>"'\/]/g,j={init:function(b,c){var e=a.extend({},d,c||{});return this.each(function(){a(this).data("settings",e),a(this).data("tokenInputObject",new a.TokenList(this,b,e))})},clear:function(){return this.data("tokenInputObject").clear(),this},add:function(a){return this.data("tokenInputObject").add(a),this},remove:function(a){return this.data("tokenInputObject").remove(a),this},get:function(){return this.data("tokenInputObject").getTokens()},toggleDisabled:function(a){return this.data("tokenInputObject").toggleDisabled(a),this},setOptions:function(b){return a(this).data("settings",a.extend({},a(this).data("settings"),b||{})),this},destroy:function(){if(this.data("tokenInputObject")){this.data("tokenInputObject").clear();var a=this,b=this.parent();return b.empty(),a.show(),b.append(a),a}}};a.fn.tokenInput=function(a){return j[a]?j[a].apply(this,Array.prototype.slice.call(arguments,1)):j.init.apply(this,arguments)},a.TokenList=function(b,d,h){function i(d){return a(b).data("settings").enableHTML?d:c(d)}function j(c){a(b).data("settings").disabled="boolean"==typeof c?c:!a(b).data("settings").disabled,P.attr("disabled",a(b).data("settings").disabled),U.toggleClass(a(b).data("settings").classes.disabled,a(b).data("settings").disabled),R&&q(a(R),f.END),Q.attr("disabled",a(b).data("settings").disabled)}function k(){return null!==a(b).data("settings").tokenLimit&&N>=a(b).data("settings").tokenLimit?(P.hide(),void u()):void 0}function l(){if(L!==(L=P.val())){var a=U.width()-P.offset().left-U.offset().left;X.html(c(L)||c(h.placeholder)),P.width(Math.min(U.width(),Math.max(a,X.width()+30)))}}function m(){var c=a.trim(P.val()),d=c.split(a(b).data("settings").tokenDelimiter);a.each(d,function(c,d){if(d){a.isFunction(a(b).data("settings").onFreeTaggingAdd)&&(d=a(b).data("settings").onFreeTaggingAdd.call(Q,d));var e={};e[a(b).data("settings").tokenValue]=e[a(b).data("settings").propertyToSearch]=d,o(e)}})}function n(c){var d=a(a(b).data("settings").tokenFormatter(c)),e=c.readonly===!0?!0:!1;e&&d.addClass(a(b).data("settings").classes.tokenReadOnly),d.addClass(a(b).data("settings").classes.token).insertBefore(V),e||a("<span>"+a(b).data("settings").deleteText+"</span>").addClass(a(b).data("settings").classes.tokenDelete).appendTo(d).click(function(){return a(b).data("settings").disabled?void 0:(s(a(this).parent()),Q.change(),!1)});var f=c;return a.data(d.get(0),"tokeninput",c),M=M.slice(0,S).concat([f]).concat(M.slice(S)),S++,t(M,Q),N+=1,null!==a(b).data("settings").tokenLimit&&N>=a(b).data("settings").tokenLimit&&(P.hide(),u()),d}function o(c){var d=a(b).data("settings").onAdd;if(N>0&&a(b).data("settings").preventDuplicates){var e=null;if(U.children().each(function(){var b=a(this),d=a.data(b.get(0),"tokeninput");return d&&d[h.tokenValue]===c[h.tokenValue]?(e=b,!1):void 0}),e)return p(e),V.insertAfter(e),void I(P)}P.width(1),(null==a(b).data("settings").tokenLimit||N<a(b).data("settings").tokenLimit)&&(n(c),P.attr("placeholder",null),k()),P.val(""),u(),a.isFunction(d)&&d.call(Q,c)}function p(c){a(b).data("settings").disabled||(c.addClass(a(b).data("settings").classes.selectedToken),R=c.get(0),P.val(""),u())}function q(c,d){c.removeClass(a(b).data("settings").classes.selectedToken),R=null,d===f.BEFORE?(V.insertBefore(c),S--):d===f.AFTER?(V.insertAfter(c),S++):(V.appendTo(U),S=N),I(P)}function r(b){var c=R;R&&q(a(R),f.END),c===b.get(0)?q(b,f.END):p(b)}function s(c){var d=a.data(c.get(0),"tokeninput"),e=a(b).data("settings").onDelete,f=c.prevAll().length;f>S&&f--,c.remove(),R=null,I(P),M=M.slice(0,f).concat(M.slice(f+1)),0==M.length&&P.attr("placeholder",h.placeholder),S>f&&S--,t(M,Q),N-=1,null!==a(b).data("settings").tokenLimit&&(P.show().val(""),I(P)),a.isFunction(e)&&e.call(Q,d)}function t(c,d){var e=a.map(c,function(c){return"function"==typeof a(b).data("settings").tokenValue?a(b).data("settings").tokenValue.call(this,c):c[a(b).data("settings").tokenValue]});d.val(e.join(a(b).data("settings").tokenDelimiter))}function u(){W.hide().empty(),T=null}function v(){W.css({position:"absolute",top:U.offset().top+U.outerHeight(!0),left:U.offset().left,width:U.width(),"z-index":a(b).data("settings").zindex}).show()}function w(){a(b).data("settings").searchingText&&(W.html("<p>"+i(a(b).data("settings").searchingText)+"</p>"),v())}function x(){a(b).data("settings").hintText&&(W.html("<p>"+i(a(b).data("settings").hintText)+"</p>"),v())}function y(a){return a.replace(Z,"\\$&")}function z(a,b){return a.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+y(b)+")(?![^<>]*>)(?![^&;]+;)","gi"),function(a,b){return"<b>"+i(b)+"</b>"})}function A(a,b,c){return a.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+y(b)+")(?![^<>]*>)(?![^&;]+;)","g"),z(b,c))}function B(c){if(a(b).data("settings").excludeCurrent){var d=a(b).data("tokenInputObject").getTokens(),e=[];d.length&&(a.each(c,function(c,f){var g=!0;a.each(d,function(c,d){return f[a(b).data("settings").propertyToSearch]==d[a(b).data("settings").propertyToSearch]?(g=!1,!1):void 0}),g&&e.push(f)}),c=e)}return c}function C(c,d){if(d=B(d),d&&d.length){W.empty();var e=a("<ul/>").appendTo(W).mouseover(function(b){D(a(b.target).closest("li"))}).mousedown(function(b){return o(a(b.target).closest("li").data("tokeninput")),Q.change(),!1}).hide();a(b).data("settings").resultsLimit&&d.length>a(b).data("settings").resultsLimit&&(d=d.slice(0,a(b).data("settings").resultsLimit)),a.each(d,function(d,f){var g=a(b).data("settings").resultsFormatter(f);g=A(g,f[a(b).data("settings").propertyToSearch],c),g=a(g).appendTo(e),g.addClass(d%2?a(b).data("settings").classes.dropdownItem:a(b).data("settings").classes.dropdownItem2),0===d&&a(b).data("settings").autoSelectFirstResult&&D(g),a.data(g.get(0),"tokeninput",f)}),v(),a(b).data("settings").animateDropdown?e.slideDown("fast"):e.show()}else a(b).data("settings").noResultsText&&(W.html("<p>"+i(a(b).data("settings").noResultsText)+"</p>"),v())}function D(c){c&&(T&&E(a(T)),c.addClass(a(b).data("settings").classes.selectedDropdownItem),T=c.get(0))}function E(c){c.removeClass(a(b).data("settings").classes.selectedDropdownItem),T=null}function F(){var c=P.val();c&&c.length&&(R&&q(a(R),f.AFTER),c.length>=a(b).data("settings").minChars?(w(),clearTimeout(K),K=setTimeout(function(){G(c)},a(b).data("settings").searchDelay)):u())}function G(c){var d=c+H(),e=O.get(d);if(e)a.isFunction(a(b).data("settings").onCachedResult)&&(e=a(b).data("settings").onCachedResult.call(Q,e)),C(c,e);else if(a(b).data("settings").url){var f=H(),g={};if(g.data={},f.indexOf("?")>-1){var i=f.split("?");g.url=i[0];var j=i[1].split("&");a.each(j,function(a,b){var c=b.split("=");g.data[c[0]]=c[1]})}else g.url=f;if(g.data[a(b).data("settings").queryParam]=c,g.type=a(b).data("settings").method,g.dataType=a(b).data("settings").contentType,a(b).data("settings").crossDomain&&(g.dataType="jsonp"),a(b).data("settings").excludeCurrent){var k=a(b).data("tokenInputObject").getTokens(),l=a.map(k,function(c){return"function"==typeof a(b).data("settings").tokenValue?a(b).data("settings").tokenValue.call(this,c):c[a(b).data("settings").tokenValue]});g.data[a(b).data("settings").excludeCurrentParameter]=l.join(a(b).data("settings").tokenDelimiter)}g.success=function(e){O.add(d,a(b).data("settings").jsonContainer?e[a(b).data("settings").jsonContainer]:e),a.isFunction(a(b).data("settings").onResult)&&(e=a(b).data("settings").onResult.call(Q,e)),P.val()===c&&C(c,a(b).data("settings").jsonContainer?e[a(b).data("settings").jsonContainer]:e)},h.onSend&&h.onSend(g),a.ajax(g)}else if(a(b).data("settings").local_data){var m=a.grep(a(b).data("settings").local_data,function(d){return d[a(b).data("settings").propertyToSearch].toLowerCase().indexOf(c.toLowerCase())>-1});O.add(d,m),a.isFunction(a(b).data("settings").onResult)&&(m=a(b).data("settings").onResult.call(Q,m)),C(c,m)}}function H(){var c=a(b).data("settings").url;return"function"==typeof a(b).data("settings").url&&(c=a(b).data("settings").url.call(a(b).data("settings"))),c}function I(a){setTimeout(function(){a.focus()},50)}if("string"==typeof d||"function"==typeof d){a(b).data("settings").url=d;var J=H();void 0===a(b).data("settings").crossDomain&&"string"==typeof J&&(a(b).data("settings").crossDomain=-1===J.indexOf("://")?!1:location.href.split(/\/+/g)[1]!==J.split(/\/+/g)[1])}else"object"==typeof d&&(a(b).data("settings").local_data=d);a(b).data("settings").classes?a(b).data("settings").classes=a.extend({},e,a(b).data("settings").classes):a(b).data("settings").theme?(a(b).data("settings").classes={},a.each(e,function(c,d){a(b).data("settings").classes[c]=d+"-"+a(b).data("settings").theme})):a(b).data("settings").classes=e;var K,L,M=[],N=0,O=new a.TokenList.Cache,P=a('<input type="text" autocomplete="off" autocapitalize="off"/>').css({outline:"none"}).attr("id",a(b).data("settings").idPrefix+b.id).focus(function(){return a(b).data("settings").disabled?!1:((null===a(b).data("settings").tokenLimit||a(b).data("settings").tokenLimit!==N)&&x(),void U.addClass(a(b).data("settings").classes.focused))}).blur(function(){u(),a(b).data("settings").allowFreeTagging&&m(),a(this).val(""),U.removeClass(a(b).data("settings").classes.focused)}).bind("keyup keydown blur update",l).keydown(function(c){var d,e;switch(c.keyCode){case g.LEFT:case g.RIGHT:case g.UP:case g.DOWN:if(0===this.value.length)d=V.prev(),e=V.next(),d.length&&d.get(0)===R||e.length&&e.get(0)===R?c.keyCode===g.LEFT||c.keyCode===g.UP?q(a(R),f.BEFORE):q(a(R),f.AFTER):c.keyCode!==g.LEFT&&c.keyCode!==g.UP||!d.length?c.keyCode!==g.RIGHT&&c.keyCode!==g.DOWN||!e.length||p(a(e.get(0))):p(a(d.get(0)));else{var h=null;c.keyCode===g.DOWN||c.keyCode===g.RIGHT?(h=a(W).find("li").first(),T&&(h=a(T).next())):(h=a(W).find("li").last(),T&&(h=a(T).prev())),D(h)}break;case g.BACKSPACE:if(d=V.prev(),0===this.value.length)return R?(s(a(R)),Q.change()):d.length&&p(a(d.get(0))),!1;1===a(this).val().length?u():setTimeout(function(){F()},5);break;case g.TAB:case g.ENTER:case g.NUMPAD_ENTER:case g.COMMA:if(T)o(a(T).data("tokeninput")),Q.change();else{if(a(b).data("settings").allowFreeTagging){if(a(b).data("settings").allowTabOut&&""===a(this).val())return!0;m()}else if(a(this).val(""),a(b).data("settings").allowTabOut)return!0;c.stopPropagation(),c.preventDefault()}return!1;case g.ESCAPE:return u(),!0;default:String.fromCharCode(c.which)&&setTimeout(function(){F()},5)}});h.placeholder&&P.attr("placeholder",h.placeholder);var Q=a(b).hide().val("").focus(function(){I(P)}).blur(function(){return P.blur(),Q}),R=null,S=0,T=null,U=a("<ul />").addClass(a(b).data("settings").classes.tokenList).click(function(b){var c=a(b.target).closest("li");c&&c.get(0)&&a.data(c.get(0),"tokeninput")?r(c):(R&&q(a(R),f.END),I(P))}).mouseover(function(c){var d=a(c.target).closest("li");d&&R!==this&&d.addClass(a(b).data("settings").classes.highlightedToken)}).mouseout(function(c){var d=a(c.target).closest("li");d&&R!==this&&d.removeClass(a(b).data("settings").classes.highlightedToken)}).insertBefore(Q),V=a("<li />").addClass(a(b).data("settings").classes.inputToken).appendTo(U).append(P),W=a("<div/>").addClass(a(b).data("settings").classes.dropdown).appendTo("body").hide(),X=a("<tester/>").insertAfter(P).css({position:"absolute",top:-9999,left:-9999,width:"auto",fontSize:P.css("fontSize"),fontFamily:P.css("fontFamily"),fontWeight:P.css("fontWeight"),letterSpacing:P.css("letterSpacing"),whiteSpace:"nowrap"});Q.val("");var Y=a(b).data("settings").prePopulate||Q.data("pre");a(b).data("settings").processPrePopulate&&a.isFunction(a(b).data("settings").onResult)&&(Y=a(b).data("settings").onResult.call(Q,Y)),Y&&Y.length&&a.each(Y,function(a,b){n(b),k(),P.attr("placeholder",null)}),a(b).data("settings").disabled&&j(!0),"function"==typeof a(b).data("settings").onReady&&a(b).data("settings").onReady.call(),this.clear=function(){U.children("li").each(function(){0===a(this).children("input").length&&s(a(this))})},this.add=function(a){o(a)},this.remove=function(b){U.children("li").each(function(){if(0===a(this).children("input").length){var c=a(this).data("tokeninput"),d=!0;for(var e in b)if(b[e]!==c[e]){d=!1;break}d&&s(a(this))}})},this.getTokens=function(){return M},this.toggleDisabled=function(a){j(a)},l();var Z=new RegExp("[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\-]","g")},a.TokenList.Cache=function(b){var c,d,e={},f=0;c=a.extend({max_size:500},b),d=function(){e={},f=0},this.add=function(a,b){f>c.max_size&&d(),e[a]||(f+=1),e[a]=b},this.get=function(a){return e[a]}}}(jQuery);
@@ -7,7 +7,7 @@ ul.token-input-list {
7
7
  border: 1px solid #999;
8
8
  cursor: text;
9
9
  font-size: 12px;
10
- font-family: Verdana;
10
+ font-family: Verdana, sans-serif;
11
11
  z-index: 999;
12
12
  margin: 0;
13
13
  padding: 0;
@@ -28,6 +28,21 @@ ul.token-input-list li input {
28
28
  -webkit-appearance: caret;
29
29
  }
30
30
 
31
+ ul.token-input-disabled,
32
+ ul.token-input-disabled li input {
33
+ background-color: #E8E8E8;
34
+ }
35
+
36
+ ul.token-input-disabled li.token-input-token {
37
+ background-color: #D9E3CA;
38
+ color: #7D7D7D
39
+ }
40
+
41
+ ul.token-input-disabled li.token-input-token span {
42
+ color: #CFCFCF;
43
+ cursor: default;
44
+ }
45
+
31
46
  li.token-input-token {
32
47
  overflow: hidden;
33
48
  height: auto !important;
@@ -72,7 +87,7 @@ div.token-input-dropdown {
72
87
  border-bottom: 1px solid #ccc;
73
88
  cursor: default;
74
89
  font-size: 12px;
75
- font-family: Verdana;
90
+ font-family: Verdana, sans-serif;
76
91
  z-index: 1;
77
92
  }
78
93
 
@@ -110,4 +125,3 @@ div.token-input-dropdown ul li em {
110
125
  div.token-input-dropdown ul li.token-input-selected-dropdown-item {
111
126
  background-color: #d0efa0;
112
127
  }
113
-
@@ -1,3 +1,3 @@
1
1
  module RailsTokeninput
2
- VERSION = "1.6.1.rc1"
2
+ VERSION = "1.7.0"
3
3
  end
@@ -12,11 +12,11 @@ Gem::Specification.new do |s|
12
12
  s.description = %q{Gem installation of jquery tokeninput scripts and stylesheets}
13
13
 
14
14
  s.rubyforge_project = "rails_tokeninput"
15
-
15
+
16
16
  s.files = `git ls-files`.split("\n")
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
- s.require_paths = ["lib", "vendor"]
19
+ s.require_paths = ["lib", "app"]
20
20
 
21
21
  s.add_dependency "railties", ">= 3.1.0"
22
22
  s.add_development_dependency "bundler", "~> 1.0.0"
metadata CHANGED
@@ -1,49 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_tokeninput
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.1.rc1
5
- prerelease: 6
4
+ version: 1.7.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Han
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-07-04 00:00:00.000000000Z
11
+ date: 2015-02-15 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: railties
16
- requirement: &70250781782560 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: 3.1.0
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *70250781782560
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 3.1.0
25
27
  - !ruby/object:Gem::Dependency
26
28
  name: bundler
27
- requirement: &70250781782060 !ruby/object:Gem::Requirement
28
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ~>
31
+ - - "~>"
31
32
  - !ruby/object:Gem::Version
32
33
  version: 1.0.0
33
34
  type: :development
34
35
  prerelease: false
35
- version_requirements: *70250781782060
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.0
36
41
  - !ruby/object:Gem::Dependency
37
42
  name: rails
38
- requirement: &70250781781500 !ruby/object:Gem::Requirement
39
- none: false
43
+ requirement: !ruby/object:Gem::Requirement
40
44
  requirements:
41
- - - ~>
45
+ - - "~>"
42
46
  - !ruby/object:Gem::Version
43
47
  version: '3.1'
44
48
  type: :development
45
49
  prerelease: false
46
- version_requirements: *70250781781500
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.1'
47
55
  description: Gem installation of jquery tokeninput scripts and stylesheets
48
56
  email:
49
57
  - han@logicallsat.com
@@ -51,46 +59,42 @@ executables: []
51
59
  extensions: []
52
60
  extra_rdoc_files: []
53
61
  files:
54
- - .DS_Store
55
- - .gitignore
62
+ - ".gitignore"
56
63
  - Gemfile
64
+ - MIT_LICENSE
57
65
  - README.md
58
66
  - Rakefile
59
- - lib/.DS_Store
67
+ - app/assets/javascripts/jquery.tokeninput.js
68
+ - app/assets/javascripts/jquery.tokeninput.min.js
69
+ - app/assets/stylesheets/token-input-facebook.css
70
+ - app/assets/stylesheets/token-input-mac.css
71
+ - app/assets/stylesheets/token-input.css
60
72
  - lib/rails_tokeninput.rb
61
73
  - lib/rails_tokeninput/engine.rb
62
74
  - lib/rails_tokeninput/version.rb
63
75
  - rails_tokeninput.gemspec
64
- - vendor/.DS_Store
65
- - vendor/assets/.DS_Store
66
- - vendor/assets/javascripts/jquery.tokeninput.js
67
- - vendor/assets/stylesheets/token-input-facebook.css
68
- - vendor/assets/stylesheets/token-input-mac.css
69
- - vendor/assets/stylesheets/token-input.css
70
76
  homepage: ''
71
77
  licenses: []
78
+ metadata: {}
72
79
  post_install_message:
73
80
  rdoc_options: []
74
81
  require_paths:
75
82
  - lib
76
- - vendor
83
+ - app
77
84
  required_ruby_version: !ruby/object:Gem::Requirement
78
- none: false
79
85
  requirements:
80
- - - ! '>='
86
+ - - ">="
81
87
  - !ruby/object:Gem::Version
82
88
  version: '0'
83
89
  required_rubygems_version: !ruby/object:Gem::Requirement
84
- none: false
85
90
  requirements:
86
- - - ! '>'
91
+ - - ">="
87
92
  - !ruby/object:Gem::Version
88
- version: 1.3.1
93
+ version: '0'
89
94
  requirements: []
90
95
  rubyforge_project: rails_tokeninput
91
- rubygems_version: 1.8.6
96
+ rubygems_version: 2.2.2
92
97
  signing_key:
93
- specification_version: 3
98
+ specification_version: 4
94
99
  summary: Jquery Tokeninput automated install for Rails 3.1+
95
100
  test_files: []
96
- has_rdoc:
data/.DS_Store DELETED
Binary file
Binary file
Binary file
Binary file
@@ -1,930 +0,0 @@
1
- /*
2
- * jQuery Plugin: Tokenizing Autocomplete Text Entry
3
- * Version 1.6.0
4
- *
5
- * Copyright (c) 2009 James Smith (http://loopj.com)
6
- * Licensed jointly under the GPL and MIT licenses,
7
- * choose which one suits your project best!
8
- *
9
- */
10
-
11
- (function ($) {
12
- // Default settings
13
- var DEFAULT_SETTINGS = {
14
- // Search settings
15
- method: "GET",
16
- queryParam: "q",
17
- searchDelay: 300,
18
- minChars: 1,
19
- propertyToSearch: "name",
20
- jsonContainer: null,
21
- contentType: "json",
22
-
23
- // Prepopulation settings
24
- prePopulate: null,
25
- processPrePopulate: false,
26
-
27
- // Display settings
28
- hintText: "Type in a search term",
29
- noResultsText: "No results",
30
- searchingText: "Searching...",
31
- deleteText: "&times;",
32
- animateDropdown: true,
33
- theme: null,
34
- zindex: 999,
35
- resultsLimit: null,
36
- resultsFormatter: function(item){ return "<li>" + item[this.propertyToSearch]+ "</li>" },
37
- tokenFormatter: function(item) { return "<li><p>" + item[this.propertyToSearch] + "</p></li>" },
38
-
39
- // Tokenization settings
40
- tokenLimit: null,
41
- tokenDelimiter: ",",
42
- preventDuplicates: false,
43
- tokenValue: "id",
44
-
45
- // Callbacks
46
- onResult: null,
47
- onAdd: null,
48
- onDelete: null,
49
- onReady: null,
50
-
51
- // Other settings
52
- idPrefix: "token-input-",
53
-
54
- // Keep track if the input is currently in disabled mode
55
- disabled: false
56
- };
57
-
58
- // Default classes to use when theming
59
- var DEFAULT_CLASSES = {
60
- tokenList: "token-input-list",
61
- token: "token-input-token",
62
- tokenReadOnly: "token-input-token-readonly",
63
- tokenDelete: "token-input-delete-token",
64
- selectedToken: "token-input-selected-token",
65
- highlightedToken: "token-input-highlighted-token",
66
- dropdown: "token-input-dropdown",
67
- dropdownItem: "token-input-dropdown-item",
68
- dropdownItem2: "token-input-dropdown-item2",
69
- selectedDropdownItem: "token-input-selected-dropdown-item",
70
- inputToken: "token-input-input-token",
71
- focused: "token-input-focused",
72
- disabled: "token-input-disabled"
73
- };
74
-
75
- // Input box position "enum"
76
- var POSITION = {
77
- BEFORE: 0,
78
- AFTER: 1,
79
- END: 2
80
- };
81
-
82
- // Keys "enum"
83
- var KEY = {
84
- BACKSPACE: 8,
85
- TAB: 9,
86
- ENTER: 13,
87
- ESCAPE: 27,
88
- SPACE: 32,
89
- PAGE_UP: 33,
90
- PAGE_DOWN: 34,
91
- END: 35,
92
- HOME: 36,
93
- LEFT: 37,
94
- UP: 38,
95
- RIGHT: 39,
96
- DOWN: 40,
97
- NUMPAD_ENTER: 108,
98
- COMMA: 188
99
- };
100
-
101
- // Additional public (exposed) methods
102
- var methods = {
103
- init: function(url_or_data_or_function, options) {
104
- var settings = $.extend({}, DEFAULT_SETTINGS, options || {});
105
-
106
- return this.each(function () {
107
- $(this).data("tokenInputObject", new $.TokenList(this, url_or_data_or_function, settings));
108
- });
109
- },
110
- clear: function() {
111
- this.data("tokenInputObject").clear();
112
- return this;
113
- },
114
- add: function(item) {
115
- this.data("tokenInputObject").add(item);
116
- return this;
117
- },
118
- remove: function(item) {
119
- this.data("tokenInputObject").remove(item);
120
- return this;
121
- },
122
- get: function() {
123
- return this.data("tokenInputObject").getTokens();
124
- },
125
- toggleDisabled: function(disable) {
126
- this.data("tokenInputObject").toggleDisabled(disable);
127
- return this;
128
- }
129
- }
130
-
131
- // Expose the .tokenInput function to jQuery as a plugin
132
- $.fn.tokenInput = function (method) {
133
- // Method calling and initialization logic
134
- if(methods[method]) {
135
- return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
136
- } else {
137
- return methods.init.apply(this, arguments);
138
- }
139
- };
140
-
141
- // TokenList class for each input
142
- $.TokenList = function (input, url_or_data, settings) {
143
- //
144
- // Initialization
145
- //
146
-
147
- // Configure the data source
148
- if($.type(url_or_data) === "string" || $.type(url_or_data) === "function") {
149
- // Set the url to query against
150
- settings.url = url_or_data;
151
-
152
- // If the URL is a function, evaluate it here to do our initalization work
153
- var url = computeURL();
154
-
155
- // Make a smart guess about cross-domain if it wasn't explicitly specified
156
- if(settings.crossDomain === undefined && typeof url === "string") {
157
- if(url.indexOf("://") === -1) {
158
- settings.crossDomain = false;
159
- } else {
160
- settings.crossDomain = (location.href.split(/\/+/g)[1] !== url.split(/\/+/g)[1]);
161
- }
162
- }
163
- } else if(typeof(url_or_data) === "object") {
164
- // Set the local data to search through
165
- settings.local_data = url_or_data;
166
- }
167
-
168
- // Build class names
169
- if(settings.classes) {
170
- // Use custom class names
171
- settings.classes = $.extend({}, DEFAULT_CLASSES, settings.classes);
172
- } else if(settings.theme) {
173
- // Use theme-suffixed default class names
174
- settings.classes = {};
175
- $.each(DEFAULT_CLASSES, function(key, value) {
176
- settings.classes[key] = value + "-" + settings.theme;
177
- });
178
- } else {
179
- settings.classes = DEFAULT_CLASSES;
180
- }
181
-
182
-
183
- // Save the tokens
184
- var saved_tokens = [];
185
-
186
- // Keep track of the number of tokens in the list
187
- var token_count = 0;
188
-
189
- // Basic cache to save on db hits
190
- var cache = new $.TokenList.Cache();
191
-
192
- // Keep track of the timeout, old vals
193
- var timeout;
194
- var input_val;
195
-
196
- // Create a new text input an attach keyup events
197
- var input_box = $("<input type=\"text\" autocomplete=\"off\">")
198
- .css({
199
- outline: "none"
200
- })
201
- .attr("id", settings.idPrefix + input.id)
202
- .focus(function () {
203
- if (settings.disabled) {
204
- return false;
205
- } else
206
- if (settings.tokenLimit === null || settings.tokenLimit !== token_count) {
207
- show_dropdown_hint();
208
- }
209
- token_list.addClass(settings.classes.focused);
210
- })
211
- .blur(function () {
212
- hide_dropdown();
213
- $(this).val("");
214
- token_list.removeClass(settings.classes.focused);
215
- })
216
- .bind("keyup keydown blur update", resize_input)
217
- .keydown(function (event) {
218
- var previous_token;
219
- var next_token;
220
-
221
- switch(event.keyCode) {
222
- case KEY.LEFT:
223
- case KEY.RIGHT:
224
- case KEY.UP:
225
- case KEY.DOWN:
226
- if(!$(this).val()) {
227
- previous_token = input_token.prev();
228
- next_token = input_token.next();
229
-
230
- if((previous_token.length && previous_token.get(0) === selected_token) || (next_token.length && next_token.get(0) === selected_token)) {
231
- // Check if there is a previous/next token and it is selected
232
- if(event.keyCode === KEY.LEFT || event.keyCode === KEY.UP) {
233
- deselect_token($(selected_token), POSITION.BEFORE);
234
- } else {
235
- deselect_token($(selected_token), POSITION.AFTER);
236
- }
237
- } else if((event.keyCode === KEY.LEFT || event.keyCode === KEY.UP) && previous_token.length) {
238
- // We are moving left, select the previous token if it exists
239
- select_token($(previous_token.get(0)));
240
- } else if((event.keyCode === KEY.RIGHT || event.keyCode === KEY.DOWN) && next_token.length) {
241
- // We are moving right, select the next token if it exists
242
- select_token($(next_token.get(0)));
243
- }
244
- } else {
245
- var dropdown_item = null;
246
-
247
- if(event.keyCode === KEY.DOWN || event.keyCode === KEY.RIGHT) {
248
- dropdown_item = $(selected_dropdown_item).next();
249
- } else {
250
- dropdown_item = $(selected_dropdown_item).prev();
251
- }
252
-
253
- if(dropdown_item.length) {
254
- select_dropdown_item(dropdown_item);
255
- }
256
- }
257
- return false;
258
- break;
259
-
260
- case KEY.BACKSPACE:
261
- previous_token = input_token.prev();
262
-
263
- if(!$(this).val().length) {
264
- if(selected_token) {
265
- delete_token($(selected_token));
266
- hidden_input.change();
267
- } else if(previous_token.length) {
268
- select_token($(previous_token.get(0)));
269
- }
270
-
271
- return false;
272
- } else if($(this).val().length === 1) {
273
- hide_dropdown();
274
- } else {
275
- // set a timeout just long enough to let this function finish.
276
- setTimeout(function(){do_search();}, 5);
277
- }
278
- break;
279
-
280
- case KEY.TAB:
281
- case KEY.ENTER:
282
- case KEY.NUMPAD_ENTER:
283
- case KEY.COMMA:
284
- if(selected_dropdown_item) {
285
- add_token($(selected_dropdown_item).data("tokeninput"));
286
- hidden_input.change();
287
- return false;
288
- }
289
- break;
290
-
291
- case KEY.ESCAPE:
292
- hide_dropdown();
293
- return true;
294
-
295
- default:
296
- if(String.fromCharCode(event.which)) {
297
- // set a timeout just long enough to let this function finish.
298
- setTimeout(function(){do_search();}, 5);
299
- }
300
- break;
301
- }
302
- });
303
-
304
- // Keep a reference to the original input box
305
- var hidden_input = $(input)
306
- .hide()
307
- .val("")
308
- .focus(function () {
309
- focus_with_timeout(input_box);
310
- })
311
- .blur(function () {
312
- input_box.blur();
313
- });
314
-
315
- // Keep a reference to the selected token and dropdown item
316
- var selected_token = null;
317
- var selected_token_index = 0;
318
- var selected_dropdown_item = null;
319
-
320
- // The list to store the token items in
321
- var token_list = $("<ul />")
322
- .addClass(settings.classes.tokenList)
323
- .click(function (event) {
324
- var li = $(event.target).closest("li");
325
- if(li && li.get(0) && $.data(li.get(0), "tokeninput")) {
326
- toggle_select_token(li);
327
- } else {
328
- // Deselect selected token
329
- if(selected_token) {
330
- deselect_token($(selected_token), POSITION.END);
331
- }
332
-
333
- // Focus input box
334
- focus_with_timeout(input_box);
335
- }
336
- })
337
- .mouseover(function (event) {
338
- var li = $(event.target).closest("li");
339
- if(li && selected_token !== this) {
340
- li.addClass(settings.classes.highlightedToken);
341
- }
342
- })
343
- .mouseout(function (event) {
344
- var li = $(event.target).closest("li");
345
- if(li && selected_token !== this) {
346
- li.removeClass(settings.classes.highlightedToken);
347
- }
348
- })
349
- .insertBefore(hidden_input);
350
-
351
- // The token holding the input box
352
- var input_token = $("<li />")
353
- .addClass(settings.classes.inputToken)
354
- .appendTo(token_list)
355
- .append(input_box);
356
-
357
- // The list to store the dropdown items in
358
- var dropdown = $("<div>")
359
- .addClass(settings.classes.dropdown)
360
- .appendTo("body")
361
- .hide();
362
-
363
- // Magic element to help us resize the text input
364
- var input_resizer = $("<tester/>")
365
- .insertAfter(input_box)
366
- .css({
367
- position: "absolute",
368
- top: -9999,
369
- left: -9999,
370
- width: "auto",
371
- fontSize: input_box.css("fontSize"),
372
- fontFamily: input_box.css("fontFamily"),
373
- fontWeight: input_box.css("fontWeight"),
374
- letterSpacing: input_box.css("letterSpacing"),
375
- whiteSpace: "nowrap"
376
- });
377
-
378
- // Pre-populate list if items exist
379
- hidden_input.val("");
380
- var li_data = settings.prePopulate || hidden_input.data("pre");
381
- if(settings.processPrePopulate && $.isFunction(settings.onResult)) {
382
- li_data = settings.onResult.call(hidden_input, li_data);
383
- }
384
- if(li_data && li_data.length) {
385
- $.each(li_data, function (index, value) {
386
- insert_token(value);
387
- checkTokenLimit();
388
- });
389
- }
390
-
391
- // Check if widget should initialize as disabled
392
- if (settings.disabled) {
393
- toggleDisabled(true);
394
- }
395
-
396
- // Initialization is done
397
- if($.isFunction(settings.onReady)) {
398
- settings.onReady.call();
399
- }
400
-
401
- //
402
- // Public functions
403
- //
404
-
405
- this.clear = function() {
406
- token_list.children("li").each(function() {
407
- if ($(this).children("input").length === 0) {
408
- delete_token($(this));
409
- }
410
- });
411
- }
412
-
413
- this.add = function(item) {
414
- add_token(item);
415
- }
416
-
417
- this.remove = function(item) {
418
- token_list.children("li").each(function() {
419
- if ($(this).children("input").length === 0) {
420
- var currToken = $(this).data("tokeninput");
421
- var match = true;
422
- for (var prop in item) {
423
- if (item[prop] !== currToken[prop]) {
424
- match = false;
425
- break;
426
- }
427
- }
428
- if (match) {
429
- delete_token($(this));
430
- }
431
- }
432
- });
433
- }
434
-
435
- this.getTokens = function() {
436
- return saved_tokens;
437
- }
438
-
439
- this.toggleDisabled = function(disable) {
440
- toggleDisabled(disable);
441
- }
442
-
443
- //
444
- // Private functions
445
- //
446
-
447
- // Toggles the widget between enabled and disabled state, or according
448
- // to the [disable] parameter.
449
- function toggleDisabled(disable) {
450
- if (typeof disable === 'boolean') {
451
- settings.disabled = disable
452
- } else {
453
- settings.disabled = !settings.disabled;
454
- }
455
- input_box.prop('disabled', settings.disabled);
456
- token_list.toggleClass(settings.classes.disabled, settings.disabled);
457
- // if there is any token selected we deselect it
458
- if(selected_token) {
459
- deselect_token($(selected_token), POSITION.END);
460
- }
461
- hidden_input.prop('disabled', settings.disabled);
462
- }
463
-
464
- function checkTokenLimit() {
465
- if(settings.tokenLimit !== null && token_count >= settings.tokenLimit) {
466
- input_box.hide();
467
- hide_dropdown();
468
- return;
469
- }
470
- }
471
-
472
- function resize_input() {
473
- if(input_val === (input_val = input_box.val())) {return;}
474
-
475
- // Enter new content into resizer and resize input accordingly
476
- var escaped = input_val.replace(/&/g, '&amp;').replace(/\s/g,' ').replace(/</g, '&lt;').replace(/>/g, '&gt;');
477
- input_resizer.html(escaped);
478
- input_box.width(input_resizer.width() + 30);
479
- }
480
-
481
- function is_printable_character(keycode) {
482
- return ((keycode >= 48 && keycode <= 90) || // 0-1a-z
483
- (keycode >= 96 && keycode <= 111) || // numpad 0-9 + - / * .
484
- (keycode >= 186 && keycode <= 192) || // ; = , - . / ^
485
- (keycode >= 219 && keycode <= 222)); // ( \ ) '
486
- }
487
-
488
- // Inner function to a token to the list
489
- function insert_token(item) {
490
- var $this_token = $(settings.tokenFormatter(item));
491
- var readonly = item.readonly === true ? true : false;
492
-
493
- if(readonly) $this_token.addClass(settings.classes.tokenReadOnly);
494
-
495
- $this_token.addClass(settings.classes.token).insertBefore(input_token);
496
-
497
- // The 'delete token' button
498
- if(!readonly) {
499
- $("<span>" + settings.deleteText + "</span>")
500
- .addClass(settings.classes.tokenDelete)
501
- .appendTo($this_token)
502
- .click(function () {
503
- if (!settings.disabled) {
504
- delete_token($(this).parent());
505
- hidden_input.change();
506
- return false;
507
- }
508
- });
509
- }
510
-
511
- // Store data on the token
512
- var token_data = item;
513
- $.data($this_token.get(0), "tokeninput", item);
514
-
515
- // Save this token for duplicate checking
516
- saved_tokens = saved_tokens.slice(0,selected_token_index).concat([token_data]).concat(saved_tokens.slice(selected_token_index));
517
- selected_token_index++;
518
-
519
- // Update the hidden input
520
- update_hidden_input(saved_tokens, hidden_input);
521
-
522
- token_count += 1;
523
-
524
- // Check the token limit
525
- if(settings.tokenLimit !== null && token_count >= settings.tokenLimit) {
526
- input_box.hide();
527
- hide_dropdown();
528
- }
529
-
530
- return $this_token;
531
- }
532
-
533
- // Add a token to the token list based on user input
534
- function add_token (item) {
535
- var callback = settings.onAdd;
536
-
537
- // See if the token already exists and select it if we don't want duplicates
538
- if(token_count > 0 && settings.preventDuplicates) {
539
- var found_existing_token = null;
540
- token_list.children().each(function () {
541
- var existing_token = $(this);
542
- var existing_data = $.data(existing_token.get(0), "tokeninput");
543
- if(existing_data && existing_data.id === item.id) {
544
- found_existing_token = existing_token;
545
- return false;
546
- }
547
- });
548
-
549
- if(found_existing_token) {
550
- select_token(found_existing_token);
551
- input_token.insertAfter(found_existing_token);
552
- focus_with_timeout(input_box);
553
- return;
554
- }
555
- }
556
-
557
- // Insert the new tokens
558
- if(settings.tokenLimit == null || token_count < settings.tokenLimit) {
559
- insert_token(item);
560
- checkTokenLimit();
561
- }
562
-
563
- // Clear input box
564
- input_box.val("");
565
-
566
- // Don't show the help dropdown, they've got the idea
567
- hide_dropdown();
568
-
569
- // Execute the onAdd callback if defined
570
- if($.isFunction(callback)) {
571
- callback.call(hidden_input,item);
572
- }
573
- }
574
-
575
- // Select a token in the token list
576
- function select_token (token) {
577
- if (!settings.disabled) {
578
- token.addClass(settings.classes.selectedToken);
579
- selected_token = token.get(0);
580
-
581
- // Hide input box
582
- input_box.val("");
583
-
584
- // Hide dropdown if it is visible (eg if we clicked to select token)
585
- hide_dropdown();
586
- }
587
- }
588
-
589
- // Deselect a token in the token list
590
- function deselect_token (token, position) {
591
- token.removeClass(settings.classes.selectedToken);
592
- selected_token = null;
593
-
594
- if(position === POSITION.BEFORE) {
595
- input_token.insertBefore(token);
596
- selected_token_index--;
597
- } else if(position === POSITION.AFTER) {
598
- input_token.insertAfter(token);
599
- selected_token_index++;
600
- } else {
601
- input_token.appendTo(token_list);
602
- selected_token_index = token_count;
603
- }
604
-
605
- // Show the input box and give it focus again
606
- focus_with_timeout(input_box);
607
- }
608
-
609
- // Toggle selection of a token in the token list
610
- function toggle_select_token(token) {
611
- var previous_selected_token = selected_token;
612
-
613
- if(selected_token) {
614
- deselect_token($(selected_token), POSITION.END);
615
- }
616
-
617
- if(previous_selected_token === token.get(0)) {
618
- deselect_token(token, POSITION.END);
619
- } else {
620
- select_token(token);
621
- }
622
- }
623
-
624
- // Delete a token from the token list
625
- function delete_token (token) {
626
- // Remove the id from the saved list
627
- var token_data = $.data(token.get(0), "tokeninput");
628
- var callback = settings.onDelete;
629
-
630
- var index = token.prevAll().length;
631
- if(index > selected_token_index) index--;
632
-
633
- // Delete the token
634
- token.remove();
635
- selected_token = null;
636
-
637
- // Show the input box and give it focus again
638
- focus_with_timeout(input_box);
639
-
640
- // Remove this token from the saved list
641
- saved_tokens = saved_tokens.slice(0,index).concat(saved_tokens.slice(index+1));
642
- if(index < selected_token_index) selected_token_index--;
643
-
644
- // Update the hidden input
645
- update_hidden_input(saved_tokens, hidden_input);
646
-
647
- token_count -= 1;
648
-
649
- if(settings.tokenLimit !== null) {
650
- input_box
651
- .show()
652
- .val("");
653
- focus_with_timeout(input_box);
654
- }
655
-
656
- // Execute the onDelete callback if defined
657
- if($.isFunction(callback)) {
658
- callback.call(hidden_input,token_data);
659
- }
660
- }
661
-
662
- // Update the hidden input box value
663
- function update_hidden_input(saved_tokens, hidden_input) {
664
- var token_values = $.map(saved_tokens, function (el) {
665
- if(typeof settings.tokenValue == 'function')
666
- return settings.tokenValue.call(this, el);
667
-
668
- return el[settings.tokenValue];
669
- });
670
- hidden_input.val(token_values.join(settings.tokenDelimiter));
671
-
672
- }
673
-
674
- // Hide and clear the results dropdown
675
- function hide_dropdown () {
676
- dropdown.hide().empty();
677
- selected_dropdown_item = null;
678
- }
679
-
680
- function show_dropdown() {
681
- dropdown
682
- .css({
683
- position: "absolute",
684
- top: $(token_list).offset().top + $(token_list).outerHeight(),
685
- left: $(token_list).offset().left,
686
- width: $(token_list).outerWidth(),
687
- 'z-index': settings.zindex
688
- })
689
- .show();
690
- }
691
-
692
- function show_dropdown_searching () {
693
- if(settings.searchingText) {
694
- dropdown.html("<p>"+settings.searchingText+"</p>");
695
- show_dropdown();
696
- }
697
- }
698
-
699
- function show_dropdown_hint () {
700
- if(settings.hintText) {
701
- dropdown.html("<p>"+settings.hintText+"</p>");
702
- show_dropdown();
703
- }
704
- }
705
-
706
- var regexp_special_chars = new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\-]', 'g');
707
- function regexp_escape(term) {
708
- return term.replace(regexp_special_chars, '\\$&');
709
- }
710
-
711
- // Highlight the query part of the search term
712
- function highlight_term(value, term) {
713
- return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + regexp_escape(term) + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<b>$1</b>");
714
- }
715
-
716
- function find_value_and_highlight_term(template, value, term) {
717
- return template.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + regexp_escape(value) + ")(?![^<>]*>)(?![^&;]+;)", "g"), highlight_term(value, term));
718
- }
719
-
720
- // Populate the results dropdown with some results
721
- function populate_dropdown (query, results) {
722
- if(results && results.length) {
723
- dropdown.empty();
724
- var dropdown_ul = $("<ul>")
725
- .appendTo(dropdown)
726
- .mouseover(function (event) {
727
- select_dropdown_item($(event.target).closest("li"));
728
- })
729
- .mousedown(function (event) {
730
- add_token($(event.target).closest("li").data("tokeninput"));
731
- hidden_input.change();
732
- return false;
733
- })
734
- .hide();
735
-
736
- if (settings.resultsLimit && results.length > settings.resultsLimit) {
737
- results = results.slice(0, settings.resultsLimit);
738
- }
739
-
740
- $.each(results, function(index, value) {
741
- var this_li = settings.resultsFormatter(value);
742
-
743
- this_li = find_value_and_highlight_term(this_li ,value[settings.propertyToSearch], query);
744
-
745
- this_li = $(this_li).appendTo(dropdown_ul);
746
-
747
- if(index % 2) {
748
- this_li.addClass(settings.classes.dropdownItem);
749
- } else {
750
- this_li.addClass(settings.classes.dropdownItem2);
751
- }
752
-
753
- if(index === 0) {
754
- select_dropdown_item(this_li);
755
- }
756
-
757
- $.data(this_li.get(0), "tokeninput", value);
758
- });
759
-
760
- show_dropdown();
761
-
762
- if(settings.animateDropdown) {
763
- dropdown_ul.slideDown("fast");
764
- } else {
765
- dropdown_ul.show();
766
- }
767
- } else {
768
- if(settings.noResultsText) {
769
- dropdown.html("<p>"+settings.noResultsText+"</p>");
770
- show_dropdown();
771
- }
772
- }
773
- }
774
-
775
- // Highlight an item in the results dropdown
776
- function select_dropdown_item (item) {
777
- if(item) {
778
- if(selected_dropdown_item) {
779
- deselect_dropdown_item($(selected_dropdown_item));
780
- }
781
-
782
- item.addClass(settings.classes.selectedDropdownItem);
783
- selected_dropdown_item = item.get(0);
784
- }
785
- }
786
-
787
- // Remove highlighting from an item in the results dropdown
788
- function deselect_dropdown_item (item) {
789
- item.removeClass(settings.classes.selectedDropdownItem);
790
- selected_dropdown_item = null;
791
- }
792
-
793
- // Do a search and show the "searching" dropdown if the input is longer
794
- // than settings.minChars
795
- function do_search() {
796
- var query = input_box.val();
797
-
798
- if(query && query.length) {
799
- if(selected_token) {
800
- deselect_token($(selected_token), POSITION.AFTER);
801
- }
802
-
803
- if(query.length >= settings.minChars) {
804
- show_dropdown_searching();
805
- clearTimeout(timeout);
806
-
807
- timeout = setTimeout(function(){
808
- run_search(query);
809
- }, settings.searchDelay);
810
- } else {
811
- hide_dropdown();
812
- }
813
- }
814
- }
815
-
816
- // Do the actual search
817
- function run_search(query) {
818
- var cache_key = query + computeURL();
819
- var cached_results = cache.get(cache_key);
820
- if(cached_results) {
821
- populate_dropdown(query, cached_results);
822
- } else {
823
- // Are we doing an ajax search or local data search?
824
- if(settings.url) {
825
- var url = computeURL();
826
- // Extract exisiting get params
827
- var ajax_params = {};
828
- ajax_params.data = {};
829
- if(url.indexOf("?") > -1) {
830
- var parts = url.split("?");
831
- ajax_params.url = parts[0];
832
-
833
- var param_array = parts[1].split("&");
834
- $.each(param_array, function (index, value) {
835
- var kv = value.split("=");
836
- ajax_params.data[kv[0]] = kv[1];
837
- });
838
- } else {
839
- ajax_params.url = url;
840
- }
841
-
842
- // Prepare the request
843
- ajax_params.data[settings.queryParam] = query;
844
- ajax_params.type = settings.method;
845
- ajax_params.dataType = settings.contentType;
846
- if(settings.crossDomain) {
847
- ajax_params.dataType = "jsonp";
848
- }
849
-
850
- // Attach the success callback
851
- ajax_params.success = function(results) {
852
- if($.isFunction(settings.onResult)) {
853
- results = settings.onResult.call(hidden_input, results);
854
- }
855
- cache.add(cache_key, settings.jsonContainer ? results[settings.jsonContainer] : results);
856
-
857
- // only populate the dropdown if the results are associated with the active search query
858
- if(input_box.val() === query) {
859
- populate_dropdown(query, settings.jsonContainer ? results[settings.jsonContainer] : results);
860
- }
861
- };
862
-
863
- // Make the request
864
- $.ajax(ajax_params);
865
- } else if(settings.local_data) {
866
- // Do the search through local data
867
- var results = $.grep(settings.local_data, function (row) {
868
- return row[settings.propertyToSearch].toLowerCase().indexOf(query.toLowerCase()) > -1;
869
- });
870
-
871
- if($.isFunction(settings.onResult)) {
872
- results = settings.onResult.call(hidden_input, results);
873
- }
874
- cache.add(cache_key, results);
875
- populate_dropdown(query, results);
876
- }
877
- }
878
- }
879
-
880
- // compute the dynamic URL
881
- function computeURL() {
882
- var url = settings.url;
883
- if(typeof settings.url == 'function') {
884
- url = settings.url.call(settings);
885
- }
886
- return url;
887
- }
888
-
889
- // Bring browser focus to the specified object.
890
- // Use of setTimeout is to get around an IE bug.
891
- // (See, e.g., http://stackoverflow.com/questions/2600186/focus-doesnt-work-in-ie)
892
- //
893
- // obj: a jQuery object to focus()
894
- function focus_with_timeout(obj) {
895
- setTimeout(function() { obj.focus(); }, 50);
896
- }
897
-
898
- };
899
-
900
- // Really basic cache for the results
901
- $.TokenList.Cache = function (options) {
902
- var settings = $.extend({
903
- max_size: 500
904
- }, options);
905
-
906
- var data = {};
907
- var size = 0;
908
-
909
- var flush = function () {
910
- data = {};
911
- size = 0;
912
- };
913
-
914
- this.add = function (query, results) {
915
- if(size > settings.max_size) {
916
- flush();
917
- }
918
-
919
- if(!data[query]) {
920
- size += 1;
921
- }
922
-
923
- data[query] = results;
924
- };
925
-
926
- this.get = function (query) {
927
- return data[query];
928
- };
929
- };
930
- }(jQuery));