2010-02-18 2 views
8

Исходя из ар revious question где я спросил об отключении кнопку отправки, пока все Ajax звонки не закончили возвращение ...Как предотвратить подачу формы до тех пор, пока не закончится несколько вызовов ajax? JQuery

Кажется, что люди по-прежнему удается отправить форму даже с помощью кнопки отключенным и предупреждающий знак , Я думаю, это может быть от нажатия 'enter' в текстовом вводе.

Как мне отключить всю форму, а не только кнопку отправки?

код до сих пор:

// if we're waiting for any ajax to complete we need to disable the submit 
$(document).ajaxStart(function() { 
    $(".ajaxbutton").attr("disabled", "disabled"); 
    // if it's taken longer than 250ms display waiting message 
    timer = setTimeout(function() { 
    $('#processingAlert').html(' ...please wait one moment'); 
    $('#processingAlert').show(); 
    }, 250); 
}) 
$(document).ajaxComplete(function() { 
    $(".ajaxbutton").removeAttr("disabled"); 
    $('#processingAlert').hide(); 
    // cancel showing the message when the ajax call completes. 
clearTimeout(timer); 
}); 

Еще одна вещь, которую я должен упомянуть, который может быть причиной проблемы является то, что Есть несколько Ajax вызовов происходит в то же самое время, EG один DIV принимает скрытые входы и другой div в другом месте на странице показывает общую цену, например.

Будет ли факт, что некоторые вызовы ajax завершаются быстро, отрицает эффект отключения ajaxStart? EG ajax call1 и ajax call2 оба запускают ajaxStart - вызов1 заканчивается очень быстро, будет ли он снова включать форму, пока мы ждем завершения вызова2?

Есть ли лучший способ сделать это, когда мы могли бы просто проверить, завершены ли все вызовы ajax?

ответ

2

Вы можете добавить обработчик события для отправки формы. Обработчик событий может проверить, разрешен ли допуск, и отменить, если нет. Вот некоторые документы: http://api.jquery.com/submit/

Обратите внимание, что если javascript на странице вызывает .click() на одной из кнопок отправки формы, форма будет отправлена ​​без вызова обработчика .submit(). Это странная проблема jQuery (http://groups.google.com/group/jquery-en/browse_thread/thread/1317bfd4e3a8b233?pli=1), которая, как я думаю, люди jQuery не считают ошибкой. Могут быть и другие подобные случаи, надеюсь, нет.

Если вы используете ASP.NET, в зависимости от того, что в форме, ASP.NET может ввести функцию «__doPostBack». Возможно, вам придется перехватить эту функцию, переопределив ее с помощью специального кода, который вызывает оригинал.

+0

Это звучит в правильном направлении, от руководства:. $ ("форма") представить (функция() { если ($ ("вход: первый".) Вал() == "правильный") { $ ("span"). Text ("Validated ..."). Show(); return true; } $ ("span"). Text ("Недействительно!"). Show(). fadeOut (1000); return false; }); Итак, если я проверю, что все вызовы ajax завершены, я могу вернуть true. Я использую PHP, поэтому, к сожалению, не могу использовать функции ASP. – Ashley

+0

PS Может кто-нибудь дать мне знать, как вставить код, отформатированный в комментарии, мне всегда кажется, что все скребут на одну строку – Ashley

+0

Не думаю, что вы можете форматировать код в комментариях. Я бы продолжил и продлевал ваш вопрос с дополнительными комментариями. –

0

Как о создании глобальной переменной:

var i = 0; 

и приращения каждого вызова AJAX эту переменную в начале вызова и декрементах оно после завершения.

При отправке формы проверьте, превышает ли эта переменная значение 0 и предотвращает отправку.

function submitForm(){ 
     return i == 0; 
    } 

<form onsubmit="submitForm()"....> 

</form> 
+0

Это звучит довольно универсально. В каких точках в вызове ajax мы увеличиваем/уменьшаем. Является ли инкремент сразу после $ .ajax ({ – Ashley

+0

) Я бы предположил, что вы увеличиваете в начале функции ajaxStart и уменьшаетесь в начале функции ajaxComplete –

+0

, это казалось хорошей идеей, но когда я попробовал, все 3 ajax вызовы начинаются одновременно, а счетчик получает значение 1. Затем, когда они заканчиваются в разное время, счетчик переходит к -2. – Ashley

1

Вы можете просто установить объект JS с несколькими свойствами для каждого вызова ajax. Пример:

var requiredCalls = {call1: false, call2: false, call3: false} 

По форме отправьте петлю через каждое свойство, чтобы проверить значение true. Если они ложны, не отправляйте форму.

По завершении каждого вызова ajax задано значение true для его свойства (call1, call2 и т. Д.).

Это один из способов, которым вы могли бы это сделать, будь то лучший способ, я не знаю.

+0

Это звучит неплохо, однако есть несколько разных вызовов, которые могут быть сделаны на этой странице, не все из них инициируются каждым клиентом. У меня будет мнение. – Ashley

+0

в этом случае, если вы правильно поняли, вы установили бы свои значения по умолчанию true.Когда вызывается вызов ajax, вы должны установить его свойство в requiredCalls на false и oncomplete/onsuccess, вы вернете его в true. – Mark

0

Я предполагаю, что у вас есть код вроде этого:

var form = $(...); 
form.bind ('submit', function (...) { 
    $.ajax (
    ..., 
    complete: function (...) { 
     // do something 
    } 
); 
} 

вы можете сделать это:

var form = $(...); 
form.bind ('submit', function (...) { 
    if ($ (this).data ('inprogress') === null) { 
    $ (this).data ('inprogress', 1); 
    // disable submit button 
    $.ajax (
     ..., 
     complete: function (...) { 
     // do something 
     $ (this).data ('inprogress', null) 
     // enable submit button 
     } 
    ); 
    } else { 
    // display notification/warning 
    } 
} 
0

Я почти решил эту проблему, но почему-то люди, кажется, все еще быть в состоянии представить форму до завершения обратных вызовов.

Я не знаю, совпадение ли это, но все люди, которым удалось отправить его, использовали Safari на Mac.

Вот метод, который я использую, было бы здорово, если бы кто-нибудь мог обнаружить недостаток в логике.

Используя предложение Винсента:

// set this to zero before any ajax calls are made 
var ajaxcallcounter = 0; 

тогда, когда я делаю AJAX вызов к примеру:

// UPDATE SHIPPING BOXES 
    var data = 'pickup=1'; 
    ajaxcallcounter++; 
    $.ajax({ 
    type: "POST", 
    url: "incViewbasketShippingBoxes.php", 
    data: data, 
    success: function(response) { 
     $('#shippingBoxes').html(response); 
      ajaxcallcounter--; 
    } 
    }); 

Это работает отлично, у меня есть небольшой скрипт, чтобы дать обратную связь с пользователем - кнопка greyed out, ожидая возвращения ajaxcounters, и если это займет больше 250 мс, анимация также отображается. После того, как все вызовы Ajax завершения, счетчик возвращается к нулю, а кнопка отображается в нормальном режиме:

// when ajaxStart is triggered, keep an eye on the ajaxcallcounter 
$(document).ajaxStart(function() { 
    $(".ajaxbutton").attr("disabled", "disabled"); 
    $('#processingAlert').html(' ...calculating'); 
    $('#processingAlert').show(); 

    // if it's taken longer than 250ms (say) display waiting message 
    timer = setTimeout(function() { 
    $('#processingAlert').html(' ...calculating <img src="../gfx-site/ajax-loader.gif">'); 
    }, 250); 
}); 
// when ajaxComplete is triggered, keep an eye on the ajaxcallcounter 
$(document).ajaxComplete(function() { 
    if (ajaxcallcounter == 0) { 
     $(".ajaxbutton").removeAttr("disabled"); 
     $('#processingAlert').hide(); 
     // cancel showing the message when the ajax call completes. 
    clearTimeout(timer); 
    } 
}); 

Наконец, мы приходим к функции, которая должна предотвратить подачу, но, кажется, не работает :

// can we submit yet? 
    $('#checkoutform').submit(function() { 
    if (ajaxcallcounter == 0) { 
     return true; 
    } 
    return false; 
    }); 

Может ли кто-нибудь определить, что я сделал неправильно здесь?

Спасибо!

Смежные вопросы