9

I have a form where every user input field is AJAX enabled, and I'd like to disable all of the form elements when one of them is changed - is it possible?

12

Yes, it's possible. For example, you can attach a .js file to your form and extend the Drupal.ajax object.
Every element which can initiate AJAX submission from a form has its own instance of Drupal.ajax. You can find it in the global object Drupal.ajax. And every Drupal.ajax object has the methods success, error, beforeSend etc.
Here is a simple example to demonstrate the idea:

;(function($) {

  Drupal.testAjax = {
    // Our form
    form_id: 'node-type-form'  //Yes, I tested on my extended node creation form
  };

  Drupal.behaviors.testAjax = {
    attach: function(context, settings) {
      // We extend Drupal.ajax objects for all AJAX elements in our form 
      for (ajax_el in settings.ajax) {
        if (Drupal.ajax[ajax_el].element.form) {
          if (Drupal.ajax[ajax_el].element.form.id === Drupal.testAjax.form_id) {
            Drupal.ajax[ajax_el].beforeSubmit = Drupal.testAjax.beforeSubmit;
            Drupal.ajax[ajax_el].success = Drupal.testAjax.success;
            Drupal.ajax[ajax_el].error = Drupal.testAjax.error;
          }
        }
      }
    }   
  };

  // Disable form
  Drupal.testAjax.beforeSubmit = function (form_values, form, options) {
    $(form[0].elements).not(':disabled')
                       .addClass('test-ajax-disabled')
                       .attr('disabled', true);
  }

  // Enable form
  Drupal.testAjax.enableForm = function(form) {
    $(form).find('.test-ajax-disabled')
            .removeClass('test-ajax-disabled')
            .attr('disabled', false);

  }

  Drupal.testAjax.success = function (response, status) {
    Drupal.testAjax.enableForm(this.element.form);
    // Call original method with main functionality
    Drupal.ajax.prototype.success.call(this, response, status);
  }
  Drupal.testAjax.error = function (response, uri) {
    Drupal.testAjax.enableForm(this.element.form);
    // Call original method with main functionality
    Drupal.ajax.prototype.error.call(this, response, uri);
  }

})(jQuery);

This approach may seem a little difficult, but it gives you full control over AJAX in your forms.
Another way is to use jQuery methods like .ajaxStart(), because Drupal uses jQuery AJAX Framework.

  • I ended up not needing this feature in my site and time constraints have prevented me from checking this answer. I'm going to accept this answer despite not checking it because it seems that you put a lot of effort into it and it's unfair to ignore it. Also the two vote-ups help :) – Daniel Jan 15 '12 at 12:14
  • Very useful. Needed to have certain ajax methods disable the form and not others. This helped me a lot and helped me understand how to attach custom success methods. Thank you. – Tanvir Chowdhury Oct 31 '14 at 12:08
3

I created a widget that can completely disable or present a read-only view of the content on your page. It disables all buttons, anchors, removes all click events, etc., and can re-enable them all back again. It even supports all jQuery UI widgets as well. I created it for an application I wrote at work. You're free to use it.

Check it out at ( http://www.dougestep.com/dme/jquery-disabler-widget ).

1

You can disable/enable some elements during ajax using this jQuery script:

  // Disable elements on ajax call.
  $(document)
    .ajaxStart(function() {
      if ($('.ajax-disabling').length) {
        // Disable elements.
        $(".ajax-disabling input").attr("disabled", "disabled");
      }
    })
    .ajaxComplete(function() {
      if ($('.ajax-disabling').length) {
        // Enable elements.
        $(".ajax-disabling input").removeAttr("disabled");
      }
    });

If you will add class ajax-disabling to the <form> or <div> (or any other wrapper) all inputs will be disabled inside during ajax.

You can play around with selectors and disable also selects and textareas.

See also https://drupal.stackexchange.com/a/76838/6309

Update

If you have already disabled elements on form and you want to keep them disabled after ajax use next code:

  // Disable form elements on ajax call.
  $(document)
    .ajaxStart(function() {
      if ($('.ajax-disabling').length) {
        // Disable elements.
        $('.ajax-disabling input, .ajax-disabling select').each(function(){
          if($(this).attr('disabled') !== 'disabled') {
            $(this).addClass('ajax-form-disabled');
            $(this).attr('disabled', 'disabled');
          }
        });
      }
    })
    .ajaxComplete(function() {
      if ($('.ajax-disabling').length) {
        // Enable elements.
        $('.ajax-disabling input, .ajax-disabling select').each(function(){
          if($(this).hasClass('ajax-form-disabled')) {
            $(this).removeClass('ajax-form-disabled');
            $(this).removeAttr('disabled');
          }
        });
      }
    });

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.