// Registers the rules namespace. Drupal.rules = Drupal.rules || {}; (function($) { Drupal.behaviors.rules_autocomplete = { attach: function(context) { var autocomplete_settings = Drupal.settings.rules_autocomplete; $('input.rules-autocomplete').once(function() { var input = this; new Drupal.rules.autocomplete(input, autocomplete_settings[$(input).attr('id')]); }); } }; /** * Rules autocomplete object. */ Drupal.rules.autocomplete = function(input, settings) { this.id = settings.inputId; this.uri = settings.source; this.jqObject = $('#' + this.id); this.cache = new Array(); this.jqObject.addClass('ui-corner-left'); this.opendByFocus = false; this.focusOpens = true; this.groupSelected = false; this.button = $(' '); this.button.attr( { 'tabIndex': -1, 'title': 'Show all items' }); this.button.insertAfter(this.jqObject); this.button.button( { icons: { primary: 'ui-icon-triangle-1-s' }, text: false }); // Don't round the left corners. this.button.removeClass('ui-corner-all'); this.button.addClass('ui-corner-right ui-button-icon rules-autocomplete-button'); this.jqObject.autocomplete(); this.jqObject.autocomplete("option", "minLength", 0); // Add a custom class, so we can style the autocomplete box without // interfering with other jquery autocomplete widgets. this.jqObject.autocomplete("widget").addClass('rules-autocomplete'); // Save the current rules_autocomplete object, so it can be used in // handlers. var instance = this; // Event handlers this.jqObject.focus(function() { if (instance.focusOpens) { instance.toggle(); instance.opendByFocus = true; } else { instance.focusOpens = true; } }); // Needed when the window is closed but the textfield has the focus. this.jqObject.click(function() { // Since the focus event happens earlier then the focus event, we need to // check here, if the window should be opened. if (!instance.opendByFocus) { instance.toggle(); } else { instance.opendByFocus = false; } }); this.jqObject.bind("autocompleteselect", function(event, ui) { // If a group was selected then set the groupSelected to true for the // overridden close function from jquery autocomplete. if (ui.item.value.substring(ui.item.value.length - 1, ui.item.value.length) == ":") { instance.groupSelected = true; } instance.focusOpens = false; instance.opendByFocus = false; }); this.jqObject.autocomplete("option", "source", function(request, response) { if (request.term in instance.cache) { response(instance.cache[request.term]); return; } $.ajax( { url: instance.uri + '/' + request.term, dataType: "json", success: function(data) { instance.success(data, request, response); } }); }); // Newer versions of jQuery UI use element.data('ui-autocomplete'), older // versions use element.data('autocomplete'). var autocompleteDataKey = typeof(this.jqObject.data('autocomplete')) === 'object' ? 'autocomplete' : 'ui-autocomplete'; // Since jquery autocomplete by default strips html text by using .text() // we need our own _renderItem function to display html content. this.jqObject.data(autocompleteDataKey)._renderItem = function(ul, item) { return $("
  • ").data("item.autocomplete", item).append("" + item.label + "").appendTo(ul); }; // Override close function this.jqObject.data(autocompleteDataKey).close = function (event) { var value = this.element.val(); // If the selector is not a group, then trigger the close event an and // hide the menu. if (value === undefined || instance.groupSelected === false) { clearTimeout(this.closing); if (this.menu.element.is(":visible")) { this._trigger("close", event); this.menu.element.hide(); // Use deactivate for older versions of jQuery UI. if (typeof(this.menu.deactivate) === 'function') { this.menu.deactivate(); } } } else { // Else keep all open and trigger a search for the group. instance.jqObject.autocomplete("search", instance.jqObject.val()); // After the suggestion box was opened again, we want to be able to // close it. instance.groupSelected = false; } }; this.button.click(function() { instance.toggle(); }); }; /** * Success function for Rules autocomplete object. */ Drupal.rules.autocomplete.prototype.success = function(data, request, response) { var list = new Array(); jQuery.each(data, function(index, value) { list.push( { label: value, value: index }); }); this.cache[request.term] = list; response(list); }; /** * Open the autocomplete window. * @param searchFor The term for will be searched for. If undefined then the * entered input text will be used. */ Drupal.rules.autocomplete.prototype.open = function(searchFor) { // If searchFor is undefined, we want to search for the passed argument. this.jqObject.autocomplete("search", ((searchFor === undefined) ? this.jqObject.val() : searchFor)); this.button.addClass("ui-state-focus"); }; /** * Close the autocomplete window. */ Drupal.rules.autocomplete.prototype.close = function() { this.jqObject.autocomplete("close"); this.button.removeClass("ui-state-focus"); }; /** * Toggle the autocomplete window. */ Drupal.rules.autocomplete.prototype.toggle = function() { if (this.jqObject.autocomplete("widget").is(":visible")) { this.close(); this.focusOpens = true; } else { var groups = this.jqObject.val().split(":"); var selector = ""; for (var i=0; i