rt 4.2.16
[freeside.git] / rt / share / static / js / autocomplete.js
1 if (!window.RT)              window.RT = {}
2 if (!window.RT.Autocomplete) window.RT.Autocomplete = {}
3
4 window.RT.Autocomplete.bind = function(from) {
5     var cssClassMap = {
6         Users: 'user',
7         Groups: 'group',
8         Tickets: 'tickets'
9     };
10
11     jQuery("input[data-autocomplete]", from).each(function(){
12         var input = jQuery(this);
13         var what  = input.attr("data-autocomplete");
14         var wants = input.attr("data-autocomplete-return");
15
16         if (!what || !what.match(/^(Users|Groups|Tickets)$/)) // Did you update cssClassMap above?
17             return;
18
19         // Don't re-bind the autocompleter
20         if (input.data("ui-autocomplete"))
21             return;
22
23         var queryargs = [];
24         var options = {
25             source: RT.Config.WebHomePath + "/Helpers/Autocomplete/" + what
26         };
27
28         if ( wants ) {
29             queryargs.push("return=" + wants);
30         }
31
32         if (input.is('[data-autocomplete-privileged]')) {
33             queryargs.push("privileged=1");
34         }
35
36         if (input.is('[data-autocomplete-multiple]')) {
37             if ( what != 'Tickets' ) {
38                 queryargs.push("delim=,");
39             }
40
41             options.focus = function () {
42                 // prevent value inserted on focus
43                 return false;
44             }
45
46             options.select = function(event, ui) {
47                 var terms = this.value.split(what == 'Tickets' ? /\s+/ : /,\s*/);
48                 terms.pop();                    // remove current input
49                 terms.push( ui.item.value );    // add selected item
50                 if ( what == 'Tickets' ) {
51                     // remove non-integers in case subject search with spaces in (like "foo bar")
52                     terms = jQuery.grep(terms, function(term) {
53                         var str = term + ''; // stringify integers to call .match
54                         return str.match(/^\d+$/);
55                     } );
56                 }
57                 terms.push(''); // add trailing delimeter so user can input another value directly
58                 this.value = terms.join(what == 'Tickets' ? ' ' : ", ");
59                 return false;
60             }
61         }
62
63         var exclude = input.attr('data-autocomplete-exclude');
64         if (exclude) {
65             queryargs.push("exclude="+exclude);
66         }
67
68         if (queryargs.length)
69             options.source += "?" + queryargs.join("&");
70
71         input.addClass('autocompletes-' + cssClassMap[what] )
72             .autocomplete(options)
73             .data("ui-autocomplete")
74             ._renderItem = function(ul, item) {
75                 var rendered = jQuery("<a/>");
76
77                 if (item.html == null)
78                     rendered.text( item.label );
79                 else
80                     rendered.html( item.html );
81
82                 return jQuery("<li/>")
83                     .data( "item.autocomplete", item )
84                     .append( rendered )
85                     .appendTo( ul );
86             };
87     });
88 };
89 jQuery(function(){ RT.Autocomplete.bind(document) });