2012-12-07 9 views
11
function ValidateField(){ 
var bAllow= true; 

    //some checking here 

if (bAllow == true && apl.val().trim() == "") 
{ 
    showDialog(); 
    showDialog().done(function() { 
     return true; // wanna return true, but not success 
    }).fail(function() { 
     return false; //wanna return false, but not success 
    }); 
    return false; //stop it to execute to next line 
} 
return bAllow; //success return } 

function showDialog(){ 
var def = $.Deferred(); 
var modPop = '<div id="diaCom" title="Information?"><p>something something</p></div>'; 
$("#diaCom").remove(); 
$(modPop).appendTo('body'); 
$("#diaCom").dialog({ 
    resizable: false, 
    draggable: false, 
    height:150, 
    width:300, 
    modal: true, 
    buttons: { 
     "Ok": function() { 
      def.resolve(); 
      $(this).dialog("close"); 

     }, 
     "Cancel": function() { 
      def.reject(); 
      $(this).dialog("close"); 

     } 
    } 
}); 

return def.promise(); 
} 
//on click 
if (validateField() == true){ 
     //do something 
}else{ 
     //do something 
    } 

ciao a tutti, qualche possibilità di restituire il valore? Desidero restituire il true e il falso tramite showDialog(). Done() e fallire per la funzione validatefield(), ma non funziona come voglio, non posso assegnarlo a bAllow poichè avevo già un return false to hold il dialogo per eseguire la sua prossima riga, qualche idea? O è corretto fare come questi?jQuery Deferred e Dialog box

+0

Non sarà in grado di causare il Javascript per attendere il completamento dell'oggetto differito, quindi non c'è modo di 'ritorno 'più tardi. Non sono sicuro di come "aggiustarlo", ma penso che il modo sia di riorganizzare il codice/logica – Ian

+0

No, non è possibile restituire in modo sincrono da un'attività asincrona. Invece, passa il differito! – Bergi

+0

quindi significa che passo ad un'altra funzione, n uso l'altra funzione per fare il controllo di validazione invece della stessa funzione? Mi può mostrare un modo corretto di farlo? creare una variabile globale, impostarla su true/fase in base al defferend, quindi in un'altra funzione, utilizzare la variabile globale per fare il controllo, dopo di che utilizzare la funzione per restituire true/false?Sono ancora nuovo di deffered, basta cercare attraverso google n puzzle fuori, vieni fuori qualcosa di simile – Se0ng11

risposta

27

Bene, questo può funzionare.

Il vostro dialogo funzione ... showDialog()

function confirmation(question) { 
    var defer = $.Deferred(); 
    $('<div></div>') 
     .html(question) 
     .dialog({ 
      autoOpen: true, 
      modal: true, 
      title: 'Confirmation', 
      buttons: { 
       "Yes": function() { 
        defer.resolve("true");//this text 'true' can be anything. But for this usage, it should be true or false. 
        $(this).dialog("close"); 
       }, 
       "No": function() { 
        defer.resolve("false");//this text 'false' can be anything. But for this usage, it should be true or false. 
        $(this).dialog("close"); 
       } 
      }, 
      close: function() { 
       $(this).remove(); 
      } 
     }); 
    return defer.promise(); 
} 

e quindi il codice in cui si utilizza la funzione ...

function onclick(){ 
    var question = "Do you want to start a war?"; 
    confirmation(question).then(function (answer) { 
     var ansbool = Boolean.parse(answer.toString()); 
     if(ansbool){ 
      alert("this is obviously " + ansbool);//TRUE 
     } else { 
      alert("and then there is " + ansbool);//FALSE 
     } 
    }); 
} 

Questo può sembrare sbagliato per la maggior parte delle persone. Ma ci sono sempre alcune situazioni in cui non puoi andare senza ritorno da JQuery Dialog.

Ciò simula fondamentalmente la funzione confirm(). Ma con un brutto codice e un bel look di conferma :)

Spero che questo aiuti alcune persone.


EDIT: Bootstrap 3 Soluzione


ora sto usando NakuPanda's biblioteca bootstrap, funziona davvero bene. Sostanzialmente come con JQueryUI ma nell'interfaccia utente di Bootstrap.

function bsConfirm(question) { 
    var defer = $.Deferred(); 
    BootstrapDialog.show({ 
     type: BootstrapDialog.TYPE_PRIMARY, 
     title: 'Confirmation', 
     message: question, 
     closeByBackdrop: false, 
     closeByKeyboard: false, 
     draggable: true, 
     buttons: [{ 
      label: 'Yes', 
      action: function (dialog) { 
       defer.resolve(true); 
       dialog.close(); 
      } 
     }, { 
      label: 'No', 
      action: function (dialog) { 
       defer.resolve(false); 
       dialog.close(); 
      } 
     }], 
     close: function (dialog) { 
      dialog.remove(); 
     } 
    }); 
    return defer.promise(); 
} 
function bsAlert(error, message) { 
    BootstrapDialog.show({ 
     type: error ? BootstrapDialog.TYPE_DANGER : BootstrapDialog.TYPE_SUCCESS, 
     title: error ? "Error" : "Success", 
     message: message, 
     closeByBackdrop: false, 
     closeByKeyboard: false, 
     draggable: true, 
     buttons: [{ 
      label: 'OK', 
      action: function (d) { 
       d.close(); 
      } 
     }] 
    }); 
} 

e usarlo (Più o meno allo stesso modo)

bsConfirm("Are you sure Bootstrap is what you wanted?").then(function (a) { 
    if (a) { 
     bsAlert("Well done! You have made the right choice"); 
    } else { 
     bsAlert("I don't like you!"); 
    } 
}); 
+7

Ho usato un approccio simile molte volte. NB: il tuo codice lascerà il '

' configurato nel DOM - hai bisogno di un '$ (this) .dialog ('destroy'). Remove()' nel gestore 'close' del dialog. – Alnitak

+0

@Pierre: Devo aggiungere una libreria aggiuntiva per Deferred e promettere di funzionare? – ChandniShah

+0

@ChandniShah Solo Jquery 1.5+ è una funzione integrata. Vedi 'https: // api.jquery.com/category/deferred-object /' per maggiori informazioni – Pierre

4

ho creato this JSFIDDLE e ha cambiato il parse booleano perché che soffiava su. Grazie, Pierre! Questo mi ha risparmiato un sacco di tempo.

javascript:

function confirmation(question) { 
var defer = $.Deferred(); 
$('<div></div>') 
    .html(question) 
    .dialog({ 
     autoOpen: true, 
     modal: true, 
     title: 'Confirmation', 
     buttons: { 
      "Yes": function() { 
       defer.resolve("true");//this text 'true' can be anything. But for this usage, it should be true or false. 
       $(this).dialog("close"); 
      }, 
      "No": function() { 
       defer.resolve("false");//this text 'false' can be anything. But for this usage, it should be true or false. 
       $(this).dialog("close"); 
      } 
     }, 
     close: function() { 
      //$(this).remove(); 
      $(this).dialog('destroy').remove() 
     } 
    }); 
return defer.promise(); 
}; 

function onclick(){ 
var question = "Do you want to start a war?"; 
confirmation(question).then(function (answer) { 
    console.log(answer); 
    var ansbool = (String(answer) == "true"); 
    if(ansbool){ 
     alert("this is obviously " + ansbool);//TRUE 
    } else { 
     alert("and then there is " + ansbool);//FALSE 
    } 
}); 
} 

$("#item").on('click', onclick); 

HTML:

<button id="item">Hello, click me.</button> 
1

perché non utilizzare lo scarto metodo instaed di volontà ("false"). Sarai quindi in grado di passare un oggetto come argomento. Diciamo che dispone di più fieldsets di ingressi, ognuno con un tasto di cancellazione:

function confirmation(question,obj) { 
    var defer = $.Deferred(); 
    $('<div></div>') 
     .html(question) 
     .dialog({ 
      autoOpen: true, 
      modal: true, 
      title: 'Confirmation', 
      buttons: { 
       "Oui": function() { 
        defer.resolve(obj);// pass the object to delete to the defer object 
        $(this).dialog("close"); 
       }, 
       "Non": function() { 
        defer.reject();//reject, no need to pass the object 
        $(this).dialog("close"); 
       } 
      }, 
      close: function() { 

       $(this).dialog('destroy').remove() 
      } 
     }); 
    return defer.promise(); 
} 

$(document).on("click", ".btn-suppr",function(){// all delete buttons having a class btn-suppr 

var question = "Are you sure to delete this fieldset ?"; 
confirmation(question,$(this)).then(function (obj) { 

           obj.parent('fieldset').remove(); // remove the parent fieldset of the delete button if confirmed 

          }); 
         });