2015-12-22 9 views
8

Sto lavorando a un sito Web di modulo online dinamico. Nel modulo principale, ho più sotto-forme che possono essere aggiunte ed eliminate dinamicamente.In attesa di tutte le chiamate AJAX che mostrano la finestra di dialogo

<div class='subform'> 
    //form fields 
    <input ...> 
    ... 
    <button class='subform_submit'> 
</div> 

Per ciascun sottomodulo, mi legano una chiamata AJAX sul pulsante di invio della sottomaschera in questo modo:

$('#main').on('click', '.subform_submit', function(){ 
    // Get this subform's user input 
    ... 
    $.ajax({ 
     url: .., 
     type: .., 
     data: /* this subform's data */ 
    }); 
}); 

Quindi, in quella pagina, io possa avere da 0 a 10 sottomoduli a seconda della scelta dell'utente. Ho anche un pulsante di invio principale nella parte inferiore della pagina, che può inviare le sottomaschere ei dati del modulo principale insieme.

$('#main').on('click', '#submit', function(e){ 
    $('.subform_submit').click(); // Submit each subform 
    bootbox.confirm({ }); 
}) 

Una volta che il pulsante principale inviare viene cliccato, voglio mostrare un quadro di carico e poi mostrare una finestra di dialogo (io uso bootbox.confirm() qui) fino a quando tutte le chiamate AJAX hanno completato. Questa finestra di dialogo indica all'utente che è stata inviata tutta la forma, inclusi i moduli secondari. Ma il problema è che ogni chiamata AJAX può richiedere 2 secondi per essere completata e non so in che modo le chiamate potrebbero essere in attesa di completamento. Come faccio a scrivere questo tasto principale sostengono in modo che lo farà:

  1. Mostra il caricamento delle immagini immediatamente e
  2. nascondere l'immagine di carico e mostrare la finestra di dialogo dopo che tutte le chiamate AJAX hanno completato?
+0

Grazie per @Lewis migliore soluzione! – monknom

risposta

2

Si desidera utilizzare .done() per specificare il codice che deve attendere fino al completamento della funzione asincrona AJAX.

$.ajax({ 
    url:.., 
    type: .., 
    data: /* this subform's data*/ }) 
    .done(function() { 
     //Put code here 
    }); 
1

Hai provato .ajaxStop() event handler?

$(document).ajaxStop(function() { 
    // place code to be executed on completion of last outstanding ajax call here 
}); 

Inoltre, controllare this answer

4

tenere traccia di quanti sotto-forme ci sono;

$subFormsCount = $('.subform').length; 

Tenere traccia di quanti moduli sono stati inviati;

$submittedForms = 0; 

Ogni volta che un modulo termina di inviare, aggiungere ai $ submitForms;

$.ajax({ 
    .. 
    .. 
    done: function(){ 
    $submittedForms++; 
    } 
}) 

creare un timer globale per vedere se il numero di moduli inviati corrisponde al numero totale di sottomoduli. Se true, nascondi la finestra di dialogo;

setInterval(function(){ 
    if($submittedForms == $subFormsCount){ 
    $('.dialog').show(); 
    } 
}, 50ms) 

Modifica

Si potrebbe saltare il timer globale (come questo sarà probabilmente pochi millisecondi out) - includere il check-in vostro ajax.done invece;

$.ajax({ 
    .. 
    .. 
    done: function(){ 
    $submittedForms++; 

    if($submittedForms == $subFormsCount){ 
    $('.dialog').show(); 
    } 
    } 
}) 
+0

dove dovrebbe mettere il codice della finestra di dialogo? Se check in ajax.done, cosa succede se ci sono 0 sottomoduli lì e voglio ancora vedere la finestra di dialogo? – monknom

+0

@monknom Non sono sicuro di cosa stai chiedendo. Ho pensato che volevi mostrare un'immagine mentre le sottomaschere stavano presentando e la finestra di dialogo solo quando avevano finito? – Lewis

+0

Mi dispiace per il mio povero inglese, l'immagine è per le sottomissioni che presentano. ma finestra di dialogo voglio dire a persone intero modulo è stato inviato non solo subform – monknom

0

Suppongo che tu abbia 9 sottomaschera e 1 modulo principale. Il codice per 8 sottomaschera sarà lo stesso.

Io uso qui asincrono: falso: significa che il prossimo ajax non sarà chiamato fino a quando il primo non è completato.

Esempio di codice Formato:

var id = 5; 
$.ajax({ 
    url: , 
    type: 'POST', 
    data: {'id':id}, 
    dataType: 'JSON', 
    async: false, 
    error : function(xhr, textStatus, errorThrown) { 
     alert('An error occurred!'); 
    }, 
    success : function(response){ 

    } 
}); 

Basta impostare variabile nel modulo ultima sub che è 9 ° sottomodulo.

success : function(response){ 
     var counter = true; 
    } 

if(counter){ 
    /* Code to show dialog.*/ 
} 
0

È possibile utilizzare $.when per attendere il completamento di ciascuna richiesta. Qualcosa di simile dovrebbe farti avvicinare. In pratica, vorrai memorizzare tutte le richieste Ajax in un array e passarlo a when come argomenti.

$('#main').on('click', '.subform_submit', function() { 

    var formRequests = $('.subform').map(function() { 
    var $form = $(this); 
    return $.ajax({ 
     url: '', 
     data: $form.serialzeArray() 
    }); 
    }).get(); 

    $.when.apply(undefined, formRequests).done(function() { 
    console.log('All done!'); 
    }); 

}); 

qui va un po 'di demo molto simile ho appena inventato: https://jsfiddle.net/g9a06y4t/

Problemi correlati