2009-05-18 34 views
31

miró a su alrededor un poco, y parece que no puede encontrar una solución jQuery (tal vez es sólo una limitación de JavaScript) para esto:¿Es posible usar un cuadro de confirmación modal usando JQuery?

<a href="somelink.php" 
    onclick="return confirm('Go to somelink.php?');">Click Here</a> 

En el ejemplo anterior, cuando un usuario hace clic en el enlace, solo irá a su href si el usuario hace clic en Aceptar en el cuadro de confirmación.

Lo que estoy tratando de hacer es obtener un aspecto más moderno usando una ventana emergente. Tal vez algo como esto:

<a href="somelink.php" 
    onclick="return jq_confirm('Go to somelink.php?');">Click Here</a> 

(Donde jq_confirm es una función confirman jQuery personalizado que aparece un bonito div con un SÍ/NO o Aceptar/Cancelar botón par).

Sin embargo, no puedo encontrar tal cosa.

He mirado en algunas bibliotecas de widgets jQuery, etc, que ofrecen una funcionalidad similar, pero ninguno a esperar a la respuesta del usuario (al menos, no en el escenario descrito anteriormente), pero en cambio sólo proceden y tomar el usuario al enlace (o ejecute cualquier código JavaScript incrustado en la pieza href = '' del enlace). Sospecho que esto se debe a que aunque puede adjuntar una función de devolución de llamada a muchos de estos widgets para devolver un valor verdadero/falso, el evento onclick onclick no espera una respuesta (callbacks son asincrónicos), lo que frustra el propósito del confirmar cuadro.

Lo que necesito es el mismo tipo de funcionalidad de detención-todo-javascript (modal) que proporciona el comando confirm(). ¿Es esto posible en JQuery (o incluso en JavaScript)?

Como no soy un experto en JavaScript ni en JQuery, difiero a tus gurús. Cualquier solución de JQuery (o incluso JavaScript pura) es bienvenida (si es posible).

Gracias -

+0

Tengo la pregunta de símil ..! esperará a que alguien responda tu pregunta ...! – bugBurger

Respuesta

8

Echa un vistazo a http://www.84bytes.com/2008/06/02/jquery-modal-dialog-boxes/

Tienen una buena variedad de modales cajas para jQuery.

creo que debería ver http://www.ericmmartin.com/simplemodal/

Una anulación de diálogo modal de la función JavaScript confirmar. Demuestra el uso de onShow y la forma de mostrar una confirmación de diálogo modal en lugar del cuadro de diálogo de confirmación de JavaScript predeterminado.

+4

Evalué ese mismo código, pero no funcionó para el escenario que describo. El problema es que tengo cientos de estos códigos de confirmación a través de un sitio codificado como lo describo, y prefiero simplemente reemplazar -> confirmar() con jq_confirmar que tener que recodificar cuidadosamente todos los códigos href y onclick en cientos de páginas (si es posible, eso es). – OneNerd

+0

http://www.84bytes.com/2008/06/02/jquery-modal-dialog-boxes/ ya no disponible – arjuncc

1

Ponga la redirección dentro de la función como:

<script> 
    function confirmRedirect(url, desciption) { 
     if (confirmWindow(desciption)) { 
      window.location = url; 
     } 
    } 
</script> 

y lo llaman así:

<a href="javascript:confirmRedirect('somlink.php','Are you sure?')">Go!</a> 
+1

Sugeriría no utilizar el código en línea javascript: function(), ya que no se degrada bien cuando javascript está deshabilitado. El enlace no hará nada si ese es el caso. En su lugar, use click here o click here como se hizo en la pregunta original. – ryanulit

+0

El problema es que tengo cientos de estos códigos de confirmación a través de un sitio codificado como lo describo, y prefiero simplemente reemplazar -> confirmar() con jq_confirmar que tener que recodificar cuidadosamente todos los códigos href y onclick en cientos de páginas (si es posible, eso es). – OneNerd

+8

Usuarios sin javascript = a quién le importa – Adam

2

Usted debe ser capaz de anular la ventana estándar.confirmar la función escribiendo el siguiente código.

window.confirm = modalConfirm 

entonces usted tendrá que hacer una función como esta

function modalConfirm(message){ 
    // put your code here and bind "return true/false" to the click event 
    // of the "Yes/No" buttons. 
} 

Esto debería funcionar, aunque no he probado todavía. Voy a hacer exactamente esto ahora y les dejaré saber cómo funcionó.

Editar: He probado mi ejemplo anterior ahora y no era posible, que tendrá que pasar en una función de devolución de llamada a la función sobrescribe confirman así:

function modalConfirm(message, callback){ 
    ... 
    $("button.yes").click(function(){ 
    callback(result); 
    }); 
    ... 
} 

..making su llamada a el aspecto función como esta:

confirm("Are you sure?", function(result){ 
    alert(result); 
}); 

En otras palabras, no es posible anular por completo la función por defecto window.confirm sin causar un bucle desagradable que hace que el navegador se cuelgue. Creo que tendrá que modificar sus llamadas de confirmación como se indicó anteriormente.

+0

si funciona, hágamelo saber - – OneNerd

7
+1

Gracias, muchos de los plugins dudosos aparecieron en mi Google - esto es lo que necesitaba! –

+2

esto no resuelve el problema de confirmación – Toskan

+1

@Toskan - Leí la pregunta como OP que desea poder diseñar y personalizar de manera efectiva el diálogo que aparece con 'confirm()'.Dado que el estilo es específico del navegador, el OP tendrá que recurrir a una implementación de script del lado del cliente de un cuadro de diálogo, que es lo que estoy recomendando. ¿Cómo no resuelve esto el problema de confirmación? –

21

sólo tenía que resolver el mismo problema. Terminé usando el widget dialog de JQuery UI. Pude implementar esto sin usar devoluciones de llamada con la advertencia de que el dialog debe inicializarse parcialmente en el controlador de eventos click para el enlace con el que desea usar la funcionalidad de confirmación (si desea usar esto para más de un enlace). Esto se debe a que la URL de destino del enlace se debe inyectar en el controlador de eventos para que haga clic en el botón de confirmación.

Aquí está mi solución, abstraída para ser adecuada para un ejemplo. Uso una clase de CSS para indicar qué enlaces deben tener el comportamiento de confirmación.

<div id="dialog" title="Confirmation Required"> 
    Are you sure about this? 
</div> 

<script type="text/javascript"> 
    $(document).ready(function() { 
    $("#dialog").dialog({ 
     autoOpen: false, 
     modal: true 
    }); 

    $(".confirmLink").click(function(e) { 
    e.preventDefault(); 
    var targetUrl = $(this).attr("href"); 

    $("#dialog").dialog({ 
     buttons : { 
     "Confirm" : function() { 
      window.location.href = targetUrl; 
     }, 
     "Cancel" : function() { 
      $(this).dialog("close"); 
     } 
     } 
    }); 

    $("#dialog").dialog("open"); 
    }); 




    }); // end of $(document).ready 


</script> 

<a class="confirmLink" href="http://someLinkWhichRequiresConfirmation.com">Click here</a> 
<a class="confirmLink" href="http://anotherSensitiveLink">Or, you could click here</a> 
+10

Me pregunto por qué se aceptó esta solución (y 12 votos ascendentes). La respuesta a la pregunta OP es: no existe tal cosa que detenga todo el procesamiento de javascript como confirmar. La solución sorprendentemente aceptada (supongo) probablemente ejecutará aleatoriamente algunos eventos de clic en caso de que haya alguno. Probablemente también depende del navegador. El reemplazo completo del diálogo de confirmación parece no tener una solución limpia. – Toskan

+1

Totalmente de acuerdo con Toskan. Además, aquellos usuarios con js disabled no serán dirigidos a ninguna parte si simplemente se basa en eventos de clic basados ​​en js. Sin embargo, supongo que esto es exactamente por qué vas por esto, ¿no? – Chris

+0

Para el registro, NO ACEPTÉ esto como la respuesta. – OneNerd

1

Mi forma de evitar este problema fue la de añadir algunos datos arbitrarios a el objeto y verifica esos datos al hacer clic. Si existió, proceda con la función como siempre, de lo contrario confirme con un sí/no (en mi caso usando una superposición jqtools). Si el usuario hace clic en sí, inserte los datos en el objeto, simule otro clic y limpie los datos. Si hacen clic en no, simplemente cierre la superposición.

Aquí está mi ejemplo:

$('button').click(function(){ 
    if ($(this).data('confirmed')) { 
     // Do stuff 
    } else { 
     confirm($(this)); 
    } 
}); 

Y esto es lo que hice para anular la función de confirmación (usando una superposición de herramientas jQuery):

window.confirm = function(obj){ 
    $('#dialog').html('\ 
     <div>\ 
      <h2>Confirm</h2>\ 
      <p>Are you sure?</p>\ 
      <p>\ 
       <button name="confirm" value="yes" class="facebox-btn close">Yes</button>\ 
       <button name="confirm" value="no" class="facebox-btn close">No</button>\ 
      </p>\ 
     </div>').overlay().load(); 
    $('button[name=confirm]').click(function(){ 
     if ($(this).val() == 'yes') { 
      $('#dialog').overlay().close(); 
      obj.data('confirmed', true).click().removeData('confirmed'); 
     } else { 
      $('#dialog').overlay().close(); 
     } 
    }); 
} 
1

Basándose en la cima de la solución de Banu (gracias una tonelada!) para que sea una solución de una sola vez en la parte superior de cada página.Pega este código dentro:

$(document).ready 

Y agregar la clase "confirmLinkFollow" a todos los enlaces que desea Confirmado:

$(".confirmLinkFollow").click(function(e) { 
    e.preventDefault(); 
    var targetUrl = $(this).attr("href"); 
var $dialog_link_follow_confirm = $('<div></div>'). 
     html("<p>Are you sure?</p>"). 
     dialog({autoOpen: false, 
     title: 'Please Confirm', 
     buttons : { 
      "Confirm" : function() { 
       window.location.href = targetUrl; 
     }, 
     "Cancel" : function() { 
       $(this).dialog("close"); 
      } 
     }, 

     modal: true, 
    minWidth: 250, 
    minHeight: 120 
    } 
    ); 


    $dialog_link_follow_confirm.dialog("open"); 
}); 
6

que escribió sobre la solución a este problema aquí: http://markmintoff.com/2011/03/asp-net-jquery-confirm-dialog/

A pesar de que la el artículo está orientado a ASP.Net, se puede adaptar fácilmente a php. Se basa en evitar el clic con un retorno falso y cuando el usuario hace clic en "Aceptar" o "SÍ" o lo que sea que tenga; el enlace o botón simplemente se vuelve a hacer clic.

var confirmed = false; 
function confirmDialog(obj) 
{ 
    if(!confirmed) 
    { 
     $("#dialog-confirm").dialog({ 
      resizable: false, 
      height:140, 
      modal: true, 
      buttons: { 
       "Yes": function() 
       { 
        $(this).dialog("close"); 
        confirmed = true; obj.click(); 
       }, 
       "No": function() 
       { 
        $(this).dialog("close"); 
       } 
      } 
     }); 
    } 

    return confirmed; 
} 

Pruébalo y dejame saber lo que piensas. Espero que esto resuelva tu problema.

+0

Brillante, esta es la única respuesta que he visto que devuelve un booleano (como se le preguntó originalmente), pegue el código en Marcar? – deadcrab

+0

brillante. me ahorra algunos feos hacks. –

+0

este es interesante, vamos a intentarlo ... – OneNerd

0

Casi tres años después, estoy buscando algo similar. Como no he encontrado una solución "rápida" aceptable, escribí algo que se acerca mucho al criterio del OP. Me imagino que otros pueden encontrarlo útil en el futuro.

JavaScript está controlado por eventos y eso significa que no admite ningún tipo de bucle de "espera" o "suspensión" que podamos utilizar para pausar una función de confirmación de javascript puro. Las opciones implican grabar ciclos de procesador, usar un complemento de navegador o AJAX. En nuestro mundo cada vez más móvil, y con conexiones a Internet irregulares, ninguna de estas es una gran solución. Esto significa que tenemos que regresar de nuestra función "confirmar" de inmediato.

Sin embargo, como no hay una lógica "falsa" en el fragmento de código anterior (es decir, no se hace nada cuando el usuario hace clic en "Cancelar"), podemos activar el evento "hacer clic" o "enviar" cuando el usuario hace clic en "Aceptar". ¿Por qué no establecer una bandera y reaccionar en función de esa bandera dentro de nuestra función "confirmar"?

Para mi solución, opté por utilizar FastConfirm en lugar de un diálogo "modal". Usted puede modificar fácilmente el código para utilizar cualquier cosa que desee, pero mi ejemplo fue diseñado para utilizar esto:

https://github.com/pjparra/Fast-Confirm

Debido a la naturaleza de lo que esto, no veo una manera limpia de empaquetarlo. Si usted siente que esto tiene demasiados bordes ásperos, no dude en alisar hacia fuera o volver a escribir el código de la forma en que todo el mundo ha recomendado:

/* This version of $.fn.hasEvent is slightly modified to provide support for 
* the "onclick" or "onsubmit" tag attributes. I chose this because it was 
* short, even if it is cryptic. 
* 
* Learn more about the code by Sven Eisenschmidt, which is licensed under 
* the MIT and GPL at: 
*  http://github.com/fate/jquery-has-event 
*/ 
(function($) { 
    $.fn.hasEvent = function(A, F, E) { 
     var L = 0; 
     var T = typeof A; 
     E = E ? E : this; 
     var V = (E.attr('on'+A) != undefined); 
     A = (T == 'string') ? $.trim(A) : A; 
     if (T == 'function') 
      F = A, A = null; 
     if (F == E) 
      delete(F); 
     var S = E.data('events'); 
     for (e in S) 
      if (S.hasOwnProperty(e)) 
       L++; 
     if (L < 1) 
      return V; // = false; 
     if (A && !F) { 
      return V = S.hasOwnProperty(A); 
     } else if(A && S.hasOwnProperty(A) && F) { 
      $.each(S[A], function(i, r) { 
       if(V == false && r.handler == F) V = true; 
      }); 
      return V; 
     } else if(!A && F) { 
      $.each(S, function(i, s) { 
       if (V == false) { 
        $.each(s, function(k, r) { 
         if (V == false && r.handler == F) 
          V = true; 
        }); 
       } 
      }); 
     } 
     return V; 
    } 
    $.extend($, {hasEvent: $.fn.hasEvent}); 
}) (jQuery); 

/* Nearly a drop-in replacement for JavaScript's confirm() dialog. 
* Syntax: 
* onclick="return jq_confirm(this, 'Are you sure that you want this?', 'right');" 
* 
* NOTE: Do not implement "false" logic when using this function. Find another way. 
*/ 
var jq_confirm_bypass = false; 
function jq_confirm(el, question, pos) { 
    var override = false; 
    var elem = $(el); 

    if ($.fn.fastConfirm == undefined) { 
     override = confirm(question); 
    } else if (!jq_confirm_bypass) { 
     if (pos == undefined) { 
      pos = 'right'; 
     } 

     elem.fastConfirm({ 
      position: pos, 
      questionText: question, 
      onProceed: function(trigger) { 
       var elem = $(trigger); 
       elem.fastConfirm('close'); 

       if (elem.hasEvent('click')) { 
        jq_confirm_bypass = true; 
        elem.click(); 
        jq_confirm_bypass = false; 
       } 
       if (elem.hasEvent('submit')) { 
        jq_confirm_bypass = true; 
        elem.submit(); 
        jq_confirm_bypass = false; 
       } 
       // TODO: ??? 
      }, 
      onCancel: function(trigger) { 
       $(trigger).fastConfirm('close'); 
      } 
     }); 
    } 

    return override ? override : jq_confirm_bypass; 
} 

Entonces ... onclick = "confirmar retorno (" ¿Quieres para probar esto? '); " se volvería onclick = "return jq_confirm (esto, '¿Quieres probar esto?');" El parámetro pos/"right" es opcional y es específicamente para Fast-Confirm.

Al hacer clic, la función jq_confirm() generará el cuadro de diálogo jQuery y devolverá "false". Cuando el usuario hace clic en "Aceptar", jq_confirm() establece un indicador, llama al evento original de hacer clic (o enviar), devuelve "verdadero" y luego lo desactiva en caso de que quiera permanecer en la misma página.

1

Tengo una solución que se puede usar para reemplazar la función predeterminada window.confirm. No requiere que anule la ventana. Confirme que eso no es completamente posible.

Mi solución le permite tener una clase general como yo, digamos 'confirmar-acción' que coloca en cualquier elemento que requiera confirmación antes de ser procesada. El script es muy simple y utiliza jQuery, jQuery UI Dialog y ningún otro complemento.

Puede encontrar la demostración completa de la implementación en jsFiddle, http://jsfiddle.net/74NDD/39/.

Uso:

  • añadir este código Javascript en su cabeza html o antes de cualquier otro clic vinculante que tiene en su Javascript.

    $("#dialog:ui-dialog").dialog("destroy"); 
    
    $('.confirm-action').live('click', function(e) { 
        $self = $(this); 
    
        if (e && e.stopImmediatePropagation && $self.data('confirmed') !== true) { 
         e.stopImmediatePropagation(); 
    
         $('#confirm-action-dialog').dialog({ 
          height: 110, 
          modal: true, 
          resizable: false, 
          draggable: false, 
          buttons: { 
           'Yes': function() { 
            $(this).dialog('close'); 
            $self.data('confirmed', true); 
            $self.click(); 
           }, 
           'No': function() { 
            $self.data('confirmed', false); 
            $(this).dialog('close'); 
           } 
          } 
         }); 
        } else if ($self.data('confirmed') === true) { 
         e = window.event; 
         e.cancelBubble = false; 
         $self.data('confirmed', false); 
        } 
    
        return false; 
    }); 
    
  • Coloque este código HTML en alguna parte del cuerpo (está oculto por defecto).

     
    <div style="display:none;" id="confirm-action-dialog" title="Confirm Action?"> 
        <p> 
         <span class="ui-icon ui-icon-alert"></span> 
         Are you sure you want to continue? 
        </p> 
    </div> 
    
  • Ponga la clase 'confirmar la acción' en cualquier elemento que requiere confirmación.

    confirm-action

Esta solución funciona perfecto, ya que no altera evento jQuery burbujeante, simplemente se detiene (paradas) Todos los demás eventos hasta que el usuario decide lo que quiere hacer.

Espero que esto sea útil para otra persona, ya que no pude encontrar ninguna otra solución que no requiera la instalación de otro plugin de jQuery o algún otro hackeo.

2

Dado que esta cuestión parece que falta la respuesta canónica: no hay manera de hacer una pausa programáticamente (y reanudar) Javascript ejecución como alert o confirm hacer.

Dicho esto, depender de este comportamiento hoy en día generalmente se considera una mala práctica dada la naturaleza de un solo subproceso de javascript, y la razón por la cual las funciones mencionadas pausan la ejecución es probablemente porque fueron diseñados cuando la web todavía estaba en un etapa inicial, y luego dejó sin cambios para garantizar la compatibilidad. Dado que el enfoque actual es escribir tanto código js no bloqueante como sea posible, es poco probable que la funcionalidad para detener js programáticamente llegue a alguna especificación futura de ECMAScript, por lo que su mejor opción es volver a trabajar en su sitio para asegurarse de confirmar y los diálogos de alerta pueden coexistir con otro código JavaScript que se ejecuta en segundo plano.

Cuestiones relacionadas