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?
3 Answers
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 :)– DanielJan 15, 2012 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. Oct 31, 2014 at 12:08
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 ).
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');
}
});
}
});