rules.autocomplete.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Registers the rules namespace.
  2. Drupal.rules = Drupal.rules || {};
  3. (function($) {
  4. Drupal.behaviors.rules_autocomplete = {
  5. attach: function(context) {
  6. var autocomplete_settings = Drupal.settings.rules_autocomplete;
  7. $('input.rules-autocomplete').once(function() {
  8. var input = this;
  9. new Drupal.rules.autocomplete(input, autocomplete_settings[$(input).attr('id')]);
  10. });
  11. }
  12. };
  13. /**
  14. * Rules autocomplete object.
  15. */
  16. Drupal.rules.autocomplete = function(input, settings) {
  17. this.id = settings.inputId;
  18. this.uri = settings.source;
  19. this.jqObject = $('#' + this.id);
  20. this.cache = new Array();
  21. this.jqObject.addClass('ui-corner-left');
  22. this.opendByFocus = false;
  23. this.focusOpens = true;
  24. this.groupSelected = false;
  25. this.button = $('<span>&nbsp;</span>');
  26. this.button.attr( {
  27. 'tabIndex': -1,
  28. 'title': 'Show all items'
  29. });
  30. this.button.insertAfter(this.jqObject);
  31. this.button.button( {
  32. icons: {
  33. primary: 'ui-icon-triangle-1-s'
  34. },
  35. text: false
  36. });
  37. // Don't round the left corners.
  38. this.button.removeClass('ui-corner-all');
  39. this.button.addClass('ui-corner-right ui-button-icon rules-autocomplete-button');
  40. this.jqObject.autocomplete();
  41. this.jqObject.autocomplete("option", "minLength", 0);
  42. // Add a custom class, so we can style the autocomplete box without
  43. // interfering with other jquery autocomplete widgets.
  44. this.jqObject.autocomplete("widget").addClass('rules-autocomplete');
  45. // Save the current rules_autocomplete object, so it can be used in
  46. // handlers.
  47. var instance = this;
  48. // Event handlers
  49. this.jqObject.focus(function() {
  50. if (instance.focusOpens) {
  51. instance.toggle();
  52. instance.opendByFocus = true;
  53. }
  54. else {
  55. instance.focusOpens = true;
  56. }
  57. });
  58. // Needed when the window is closed but the textfield has the focus.
  59. this.jqObject.click(function() {
  60. // Since the focus event happens earlier then the focus event, we need to
  61. // check here, if the window should be opened.
  62. if (!instance.opendByFocus) {
  63. instance.toggle();
  64. }
  65. else {
  66. instance.opendByFocus = false;
  67. }
  68. });
  69. this.jqObject.bind("autocompleteselect", function(event, ui) {
  70. // If a group was selected then set the groupSelected to true for the
  71. // overriden close function from jquery autocomplete.
  72. if (ui.item.value.substring(ui.item.value.length - 1, ui.item.value.length) == ":") {
  73. instance.groupSelected = true;
  74. }
  75. instance.focusOpens = false;
  76. instance.opendByFocus = false;
  77. });
  78. this.jqObject.autocomplete("option", "source", function(request, response) {
  79. if (request.term in instance.cache) {
  80. response(instance.cache[request.term]);
  81. return;
  82. }
  83. $.ajax( {
  84. url: instance.uri + '/' + request.term,
  85. dataType: "json",
  86. success: function(data) {
  87. instance.success(data, request, response);
  88. }
  89. });
  90. });
  91. // Since jquery autocomplete by default strips html text by using .text()
  92. // we need our own _renderItem function to display html content.
  93. this.jqObject.data("autocomplete")._renderItem = function(ul, item) {
  94. return $("<li></li>").data("item.autocomplete", item).append("<a>" + item.label + "</a>").appendTo(ul);
  95. };
  96. // Override close function
  97. this.jqObject.data("autocomplete").close = function (event) {
  98. var value = this.element.val();
  99. // If the selector is not a group, then trigger the close event an and
  100. // hide the menu.
  101. if (value === undefined || instance.groupSelected === false) {
  102. clearTimeout(this.closing);
  103. if (this.menu.element.is(":visible")) {
  104. this._trigger("close", event);
  105. this.menu.element.hide();
  106. this.menu.deactivate();
  107. }
  108. }
  109. else {
  110. // Else keep all open and trigger a search for the group.
  111. instance.jqObject.autocomplete("search", instance.jqObject.val());
  112. // After the suggestion box was opened again, we want to be able to
  113. // close it.
  114. instance.groupSelected = false;
  115. }
  116. };
  117. this.button.click(function() {
  118. instance.toggle();
  119. });
  120. };
  121. /**
  122. * Success function for Rules autocomplete object.
  123. */
  124. Drupal.rules.autocomplete.prototype.success = function(data, request, response) {
  125. var list = new Array();
  126. jQuery.each(data, function(index, value) {
  127. list.push( {
  128. label: value,
  129. value: index
  130. });
  131. });
  132. this.cache[request.term] = list;
  133. response(list);
  134. };
  135. /**
  136. * Open the autocomplete window.
  137. * @param searchFor The term for will be searched for. If undefined then the
  138. * entered input text will be used.
  139. */
  140. Drupal.rules.autocomplete.prototype.open = function(searchFor) {
  141. // If searchFor is undefined, we want to search for the passed argument.
  142. this.jqObject.autocomplete("search", ((searchFor === undefined) ? this.jqObject.val() : searchFor));
  143. this.button.addClass("ui-state-focus");
  144. };
  145. /**
  146. * Close the autocomplete window.
  147. */
  148. Drupal.rules.autocomplete.prototype.close = function() {
  149. this.jqObject.autocomplete("close");
  150. this.button.removeClass("ui-state-focus");
  151. };
  152. /**
  153. * Toogle the autcomplete window.
  154. */
  155. Drupal.rules.autocomplete.prototype.toggle = function() {
  156. if (this.jqObject.autocomplete("widget").is(":visible")) {
  157. this.close();
  158. this.focusOpens = true;
  159. }
  160. else {
  161. var groups = this.jqObject.val().split(":");
  162. var selector = "";
  163. for (var i=0; i<groups.length-1; i++) {
  164. selector = selector.concat(groups[i]) + ":";
  165. }
  166. this.focusOpens = false;
  167. this.jqObject.focus();
  168. this.open(selector);
  169. }
  170. };
  171. })(jQuery);