2010-02-18 8 views
8

Sulla scia ap revious question in cui ho chiesto di disattivazione di un pulsante di invio fino a quando tutte le chiamate Ajax hanno finito di tornare ...Come si impedisce l'invio del modulo fino al completamento di più chiamate Ajax? jquery

Sembra che le persone sono ancora riuscendo a inviare il modulo, anche con il tasto disattivato e un segnale di avvertimento . Immagino che potrebbe essere da premere 'invio' in un inserimento di testo.

Come si disabilita l'intero modulo anziché il pulsante di invio?

Il codice finora è:

// 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); 
}); 

Un altra cosa che vorrei menzionare che potrebbe essere la causa del problema è che ci sono più chiamate AJAX accadendo allo stesso tempo, ad esempio un div riceve ingressi nascosti e un altro div in un'altra pagina mostra per esempio un prezzo totale.

Il fatto che alcune chiamate ajax si stiano completando rapidamente annullerebbe l'effetto disabilitante di ajaxStart? Ad esempio, ajax call1 e ajax call2 sparano entrambi a ajaxStart - call1 termina molto velocemente, riattiverebbe il modulo mentre attendiamo il completamento di call2?

C'è un modo migliore per farlo in cui potremmo semplicemente verificare se TUTTE le chiamate ajax sono state completate?

risposta

2

È possibile aggiungere un gestore di eventi per l'evento di invio del modulo. Il gestore eventi può controllare se l'invio è ancora consentito e interrompere se non lo è. Ecco alcuni documenti: http://api.jquery.com/submit/

Si noti che se javascript nella pagina chiama .click() su uno dei pulsanti di invio modulo, il modulo verrà inviato senza chiamare il gestore .submit(). Questo è un problema strano di jQuery (http://groups.google.com/group/jquery-en/browse_thread/thread/1317bfd4e3a8b233?pli=1) che immagino che la gente di jQuery non consideri un bug. Potrebbero esserci altri casi come questo, spero di no.

Se si utilizza ASP.NET, in base a ciò che è presente nel modulo, ASP.NET può iniettare una funzione "__doPostBack". Potrebbe essere necessario agganciare la funzione invece ridefinendola con un codice personalizzato che chiama l'originale.

+0

questo suona nella giusta direzione, dal manuale:. $ ("forma") presenta (function() { if ($ ("Ingresso: prima"). Val() == "corretto") { $ ("span"). Text ("Validated ..."). Show(); return true; } $ ("span"). Text ("Non valido!"). Show(). fadeOut (1000); return false; }); Quindi, se controllo che tutte le chiamate ajax siano completate, posso restituire true. Sto usando PHP quindi, non posso usare le funzioni ASP purtroppo. – Ashley

+0

PS Qualcuno può farmi sapere come inserire il codice formattato in un commento, mi sembra sempre di ottenere tutto schiacciato su una riga – Ashley

+0

Non penso che sia possibile formattare il codice nei commenti. Vorrei andare avanti ed estendere la tua domanda con commenti aggiuntivi. –

0

ne dite di creare una variabile globale:

var i = 0; 

e ogni incrementi chiamata AJAX questa variabile all'inizio della chiamata e decrementa quando completa.

Al momento dell'invio del modulo, controllare se questa variabile è maggiore di 0 e impedire l'invio.

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

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

</form> 
+0

Sembra abbastanza versatile. In quali punti della chiamata Aj si incrementa/decrementa. L'incremento subito dopo $ .ajax ({ – Ashley

+0

Immaginerei di incrementare all'inizio della funzione ajaxStart e diminuire all'inizio della funzione ajaxComplete –

+0

questa mi è sembrata una buona idea, ma quando l'ho provata, tutte e 3 ajax le chiamate iniziano simultaneamente e il contatore ottiene il valore 1. Quindi, quando si completano in momenti diversi, il contatore passa a -2. – Ashley

1

Si può semplicemente impostare un oggetto JS con proprietà multiple per ogni chiamata Ajax. Esempio:

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

Sul modulo inviare il ciclo attraverso ciascuna proprietà per verificare se è vero. Se qualcuno è falso, non inviare il modulo.

Come ogni chiamata ajax completa, imposta la proprietà (call1, call2, etc) su true.

Questo è un modo per farlo, che sia il modo migliore, non lo so.

+0

Questa sembra una buona idea, tuttavia ci sono diverse chiamate che possono essere fatte su questa pagina, non tutti sono attivati ​​da ciascun cliente, ma penserò: – Ashley

+0

in questo caso, se ho capito bene, avresti impostato i valori predefiniti su true.Quando viene attivata la chiamata ajax, si imposta la proprietà in requiredCalls a false e oncompleta/onsuccess si dovrebbe riportarla su true. – Mark

0

Credo di avere un po 'di codice come questo:

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

si può fare:

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

ho quasi risolto questo ma in qualche modo la gente sembra essere ancora in grado di inviare il modulo prima che i callback siano finiti.

Non so se è una coincidenza, ma tutte le persone che sono riuscite a inviarlo hanno utilizzato Safari su Mac.

Ecco il metodo che sto usando, sarebbe bello se qualcuno potesse individuare il difetto nella logica.

Utilizzando il suggerimento di Vincent:

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

poi quando faccio una chiamata AJAX per esempio:

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

Questo sta lavorando bene, ho anche un bel po 'di script per dare il feedback degli utenti - pulsante è disattivato mentre attende il ritorno di ajaxcounters e se richiede più di 250 ms, viene visualizzata anche un'animazione. Una volta che tutte le chiamate Ajax hanno completato, il contatore è di nuovo a zero e il pulsante viene visualizzato come normale:

// 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); 
    } 
}); 

Infine, arriviamo alla funzione che dovrebbe impedire la presentazione, ma non sembra funzionare :

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

Qualcuno può individuare ciò che ho fatto di sbagliato qui?

Grazie!

Problemi correlati