226 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
			
		
		
	
	
			226 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
// $Id$
 | 
						|
 | 
						|
/**
 | 
						|
 * Provides AJAX-like page updating via AHAH (Asynchronous HTML and HTTP).
 | 
						|
 *
 | 
						|
 * AHAH is a method of making a request via Javascript while viewing an HTML
 | 
						|
 * page. The request returns a small chunk of HTML, which is then directly
 | 
						|
 * injected into the page.
 | 
						|
 *
 | 
						|
 * Drupal uses this file to enhance form elements with #ahah[path] and
 | 
						|
 * #ahah[wrapper] properties. If set, this file will automatically be included
 | 
						|
 * to provide AHAH capabilities.
 | 
						|
 */
 | 
						|
 | 
						|
/**
 | 
						|
 * Attaches the ahah behavior to each ahah form element.
 | 
						|
 */
 | 
						|
Drupal.behaviors.ahah = function(context) {
 | 
						|
  for (var base in Drupal.settings.ahah) {
 | 
						|
    if (!$('#'+ base + '.ahah-processed').size()) {
 | 
						|
      var element_settings = Drupal.settings.ahah[base];
 | 
						|
 | 
						|
      $(element_settings.selector).each(function() {
 | 
						|
        element_settings.element = this;
 | 
						|
        var ahah = new Drupal.ahah(base, element_settings);
 | 
						|
      });
 | 
						|
 | 
						|
      $('#'+ base).addClass('ahah-processed');
 | 
						|
    }
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * AHAH object.
 | 
						|
 */
 | 
						|
Drupal.ahah = function(base, element_settings) {
 | 
						|
  // Set the properties for this object.
 | 
						|
  this.element = element_settings.element;
 | 
						|
  this.selector = element_settings.selector;
 | 
						|
  this.event = element_settings.event;
 | 
						|
  this.keypress = element_settings.keypress;
 | 
						|
  this.url = element_settings.url;
 | 
						|
  this.wrapper = '#'+ element_settings.wrapper;
 | 
						|
  this.effect = element_settings.effect;
 | 
						|
  this.method = element_settings.method;
 | 
						|
  this.progress = element_settings.progress;
 | 
						|
  this.button = element_settings.button || { };
 | 
						|
 | 
						|
  if (this.effect == 'none') {
 | 
						|
    this.showEffect = 'show';
 | 
						|
    this.hideEffect = 'hide';
 | 
						|
    this.showSpeed = '';
 | 
						|
  }
 | 
						|
  else if (this.effect == 'fade') {
 | 
						|
    this.showEffect = 'fadeIn';
 | 
						|
    this.hideEffect = 'fadeOut';
 | 
						|
    this.showSpeed = 'slow';
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    this.showEffect = this.effect + 'Toggle';
 | 
						|
    this.hideEffect = this.effect + 'Toggle';
 | 
						|
    this.showSpeed = 'slow';
 | 
						|
  }
 | 
						|
 | 
						|
  // Record the form action and target, needed for iFrame file uploads.
 | 
						|
  var form = $(this.element).parents('form');
 | 
						|
  this.form_action = form.attr('action');
 | 
						|
  this.form_target = form.attr('target');
 | 
						|
  this.form_encattr = form.attr('encattr');
 | 
						|
 | 
						|
  // Set the options for the ajaxSubmit function.
 | 
						|
  // The 'this' variable will not persist inside of the options object.
 | 
						|
  var ahah = this;
 | 
						|
  var options = {
 | 
						|
    url: ahah.url,
 | 
						|
    data: ahah.button,
 | 
						|
    beforeSubmit: function(form_values, element_settings, options) {
 | 
						|
      return ahah.beforeSubmit(form_values, element_settings, options);
 | 
						|
    },
 | 
						|
    success: function(response, status) {
 | 
						|
      // Sanity check for browser support (object expected).
 | 
						|
      // When using iFrame uploads, responses must be returned as a string.
 | 
						|
      if (typeof(response) == 'string') {
 | 
						|
        response = Drupal.parseJson(response);
 | 
						|
      }
 | 
						|
      return ahah.success(response, status);
 | 
						|
    },
 | 
						|
    complete: function(response, status) {
 | 
						|
      if (status == 'error' || status == 'parsererror') {
 | 
						|
        return ahah.error(response, ahah.url);
 | 
						|
      }
 | 
						|
    },
 | 
						|
    dataType: 'json',
 | 
						|
    type: 'POST'
 | 
						|
  };
 | 
						|
 | 
						|
  // Bind the ajaxSubmit function to the element event.
 | 
						|
  $(element_settings.element).bind(element_settings.event, function() {
 | 
						|
    $(element_settings.element).parents('form').ajaxSubmit(options);
 | 
						|
    return false;
 | 
						|
  });
 | 
						|
  // If necessary, enable keyboard submission so that AHAH behaviors
 | 
						|
  // can be triggered through keyboard input as well as e.g. a mousedown
 | 
						|
  // action.
 | 
						|
  if (element_settings.keypress) {
 | 
						|
    $(element_settings.element).keypress(function(event) {
 | 
						|
      // Detect enter key.
 | 
						|
      if (event.keyCode == 13) {
 | 
						|
        $(element_settings.element).trigger(element_settings.event);
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
    });
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Handler for the form redirection submission.
 | 
						|
 */
 | 
						|
Drupal.ahah.prototype.beforeSubmit = function (form_values, element, options) {
 | 
						|
  // Disable the element that received the change.
 | 
						|
  $(this.element).addClass('progress-disabled').attr('disabled', true);
 | 
						|
 | 
						|
  // Insert progressbar or throbber.
 | 
						|
  if (this.progress.type == 'bar') {
 | 
						|
    var progressBar = new Drupal.progressBar('ahah-progress-' + this.element.id, eval(this.progress.update_callback), this.progress.method, eval(this.progress.error_callback));
 | 
						|
    if (this.progress.message) {
 | 
						|
      progressBar.setProgress(-1, this.progress.message);
 | 
						|
    }
 | 
						|
    if (this.progress.url) {
 | 
						|
      progressBar.startMonitoring(this.progress.url, this.progress.interval || 1500);
 | 
						|
    }
 | 
						|
    this.progress.element = $(progressBar.element).addClass('ahah-progress ahah-progress-bar');
 | 
						|
    this.progress.object = progressBar;
 | 
						|
    $(this.element).after(this.progress.element);
 | 
						|
  }
 | 
						|
  else if (this.progress.type == 'throbber') {
 | 
						|
    this.progress.element = $('<div class="ahah-progress ahah-progress-throbber"><div class="throbber"> </div></div>');
 | 
						|
    if (this.progress.message) {
 | 
						|
      $('.throbber', this.progress.element).after('<div class="message">' + this.progress.message + '</div>')
 | 
						|
    }
 | 
						|
    $(this.element).after(this.progress.element);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Handler for the form redirection completion.
 | 
						|
 */
 | 
						|
Drupal.ahah.prototype.success = function (response, status) {
 | 
						|
  var wrapper = $(this.wrapper);
 | 
						|
  var form = $(this.element).parents('form');
 | 
						|
  // Manually insert HTML into the jQuery object, using $() directly crashes
 | 
						|
  // Safari with long string lengths. http://dev.jquery.com/ticket/1152
 | 
						|
  var new_content = $('<div></div>').html(response.data);
 | 
						|
 | 
						|
  // Restore the previous action and target to the form.
 | 
						|
  form.attr('action', this.form_action);
 | 
						|
  this.form_target ? form.attr('target', this.form_target) : form.removeAttr('target');
 | 
						|
  this.form_encattr ? form.attr('target', this.form_encattr) : form.removeAttr('encattr');
 | 
						|
 | 
						|
  // Remove the progress element.
 | 
						|
  if (this.progress.element) {
 | 
						|
    $(this.progress.element).remove();
 | 
						|
  }
 | 
						|
  if (this.progress.object) {
 | 
						|
    this.progress.object.stopMonitoring();
 | 
						|
  }
 | 
						|
  $(this.element).removeClass('progress-disabled').attr('disabled', false);
 | 
						|
 | 
						|
  // Add the new content to the page.
 | 
						|
  Drupal.freezeHeight();
 | 
						|
  if (this.method == 'replace') {
 | 
						|
    wrapper.empty().append(new_content);
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    wrapper[this.method](new_content);
 | 
						|
  }
 | 
						|
 | 
						|
  // Immediately hide the new content if we're using any effects.
 | 
						|
  if (this.showEffect != 'show') {
 | 
						|
    new_content.hide();
 | 
						|
  }
 | 
						|
 | 
						|
  // Determine what effect use and what content will receive the effect, then
 | 
						|
  // show the new content. For browser compatibility, Safari is excluded from
 | 
						|
  // using effects on table rows.
 | 
						|
  if (($.browser.safari && $("tr.ahah-new-content", new_content).size() > 0)) {
 | 
						|
    new_content.show();
 | 
						|
  }
 | 
						|
  else if ($('.ahah-new-content', new_content).size() > 0) {
 | 
						|
    $('.ahah-new-content', new_content).hide();
 | 
						|
    new_content.show();
 | 
						|
    $(".ahah-new-content", new_content)[this.showEffect](this.showSpeed);
 | 
						|
  }
 | 
						|
  else if (this.showEffect != 'show') {
 | 
						|
    new_content[this.showEffect](this.showSpeed);
 | 
						|
  }
 | 
						|
 | 
						|
  // Attach all javascript behaviors to the new content, if it was successfully
 | 
						|
  // added to the page, this if statement allows #ahah[wrapper] to be optional.
 | 
						|
  if (new_content.parents('html').length > 0) {
 | 
						|
    Drupal.attachBehaviors(new_content);
 | 
						|
  }
 | 
						|
 | 
						|
  Drupal.unfreezeHeight();
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Handler for the form redirection error.
 | 
						|
 */
 | 
						|
Drupal.ahah.prototype.error = function (response, uri) {
 | 
						|
  alert(Drupal.ahahError(response, uri));
 | 
						|
  // Resore the previous action and target to the form.
 | 
						|
  $(this.element).parent('form').attr( { action: this.form_action, target: this.form_target} );
 | 
						|
  // Remove the progress element.
 | 
						|
  if (this.progress.element) {
 | 
						|
    $(this.progress.element).remove();
 | 
						|
  }
 | 
						|
  if (this.progress.object) {
 | 
						|
    this.progress.object.stopMonitoring();
 | 
						|
  }
 | 
						|
  // Undo hide.
 | 
						|
  $(this.wrapper).show();
 | 
						|
  // Re-enable the element.
 | 
						|
  $(this.element).removeClass('progess-disabled').attr('disabled', false);
 | 
						|
};
 |