web-dev-qa-db-fra.com

Une boîte de confirmation modale utilisant JQuery est-elle possible?

J'ai regardé un peu et je n'arrive pas à trouver une solution JQuery ( c'est peut-être juste une limitation de JavaScript ) pour cela:

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

Dans l'exemple ci-dessus, lorsqu'un utilisateur clique sur le lien, il ne se rendra à son href que si l'utilisateur clique sur OK dans la boîte de confirmation.

Ce que j'essaie de faire est d'obtenir un look plus moderne en utilisant une div popup. Peut-être quelque chose comme ça:

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

(Où jq_confirm est une fonction de confirmation JQuery personnalisée qui affiche une div Nice avec une paire de boutons YES/NO ou OK/CANCEL).

Cependant, je n'arrive pas à trouver une telle chose.

J'ai regardé certaines bibliothèques de widgets JQuery, etc. qui offrent des fonctionnalités similaires, mais aucune n'attendra la réponse de l'utilisateur ( au moins, pas dans le scénario décrit ci-dessus ), mais au lieu de cela, ils procèdent simplement et amènent l'utilisateur au lien ( ou exécutent tout JavaScript intégré dans la partie href = '' du lien ). Je soupçonne que c'est parce que si vous pouvez attacher une fonction de rappel à plusieurs de ces widgets pour renvoyer une valeur vraie/fausse, l'événement onclick n'attend pas de réponse ( les rappels sont asynchrones ), ce qui va à l'encontre de l'objectif de la boîte de confirmation.

Ce dont j'ai besoin, c'est du même type de fonctionnalité stop-all-javascript (modal) que la commande par défaut confirm () fournit. Est-ce possible en JQuery ( ou même en JavaScript )?

Comme je ne suis pas un expert en JavaScript ni en JQuery, je m'en remets à vous gourous là-bas. Toute solution JQuery ( ou même pure JavaScript ) est la bienvenue ( si possible ).

Merci -

32
OneNerd

Je devais juste résoudre le même problème. J'ai fini par utiliser le widget dialog de JQuery UI . J'ai pu l'implémenter sans utiliser de rappels avec la mise en garde que le dialog doit être partiellement initialisé dans le gestionnaire d'événements click pour le lien avec lequel vous souhaitez utiliser la fonctionnalité de confirmation (si vous voulez utilisez-le pour plus d'un lien). En effet, l'URL cible du lien doit être injectée dans le gestionnaire d'événements pour le clic du bouton de confirmation.

Voici ma solution, résumée pour convenir à un exemple. J'utilise une classe CSS pour indiquer quels liens doivent avoir le comportement de confirmation.

<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>
21
Paul Morie

Découvrez http://www.84bytes.com/2008/06/02/jquery-modal-dialog-boxes/

Ils ont une bonne variété de boîtes modales pour JQuery.

Je pense que vous devriez voir http://www.ericmmartin.com/simplemodal/

Une boîte de dialogue modale remplace la fonction de confirmation JavaScript. Montre l'utilisation d'OnShow ainsi que la façon d'afficher une confirmation de boîte de dialogue modale au lieu de la boîte de dialogue de confirmation JavaScript par défaut.

8
janhartmann
7
Russ Cam

J'ai blogué sur la solution à ce problème ici: http://markmintoff.com/2011/03/asp-net-jquery-confirm-dialog/

Même si l'article est orienté vers ASP.Net, il peut être facilement adapté au php. Il repose sur la prévention du clic avec un retour faux et lorsque l'utilisateur clique sur "OK" ou "OUI" ou ce que vous avez; le lien ou le bouton est simplement cliqué à nouveau.

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

Essayez-le et faites-moi savoir ce que vous en pensez. J'espère que cela résoudra votre problème.

6
Mark Mintoff

Comme cette question semble manquer la réponse canonique: il n'y a aucun moyen de suspendre (et de reprendre) par programme l'exécution javascript comme alert ou confirm do.

Cela étant dit, s'appuyer sur ce comportement aujourd'hui est généralement considéré comme une mauvaise pratique compte tenu de la nature unique du javascript, et la raison pour laquelle les fonctions susmentionnées interrompent l'exécution est probablement parce qu'elles ont été conçues lorsque le Web était encore à un stade très précoce, et laissé plus tard inchangé pour assurer la compatibilité. Étant donné que l'accent est mis aujourd'hui sur l'écriture d'autant de code js non bloquant que possible, il est peu probable que la fonctionnalité pour arrêter par programme js atteindra jamais les futures spécifications d'ECMAScript, donc votre meilleur pari est de retravailler votre site pour vous assurer de confirmer et les boîtes de dialogue d'alerte peuvent coexister avec d'autres codes javascript exécutés en arrière-plan.

2
Mahn

Vous devriez pouvoir remplacer la fonction standard window.confirm en écrivant le code suivant.

window.confirm = modalConfirm

alors vous devrez créer une fonction comme celle-ci

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

Cela devrait fonctionner, même si je ne l'ai pas encore testé. Je vais faire exactement cela maintenant et je vous ferai savoir comment cela a fonctionné.

Edit: J'ai testé mon exemple ci-dessus maintenant et ce n'était pas possible, vous devrez passer une fonction de rappel à votre fonction de confirmation écrasée comme ceci:

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

..pour que votre appel à la fonction ressemble à ceci:

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

En d'autres termes, il n'est pas possible de remplacer complètement la fonction window.confirm par défaut sans provoquer une boucle désagréable qui provoque le blocage du navigateur. Je pense que vous devrez modifier vos appels de confirmation comme ci-dessus.

2
Torbjorn

Mon moyen de contourner ce problème était d'ajouter des données arbitraires à l'objet et de vérifier ces données en cliquant. Si elle existait, continuez avec la fonction normalement, sinon confirmez par oui/non (dans mon cas en utilisant une superposition jqtools). Si l'utilisateur clique sur Oui - insérez les données dans l'objet, simulez un autre clic et effacez les données. S'ils cliquent sur non, fermez simplement la superposition.

Voici mon exemple:

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

Et voici ce que j'ai fait pour remplacer la fonction de confirmation (en utilisant une superposition d'outils 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
Steve

Mettez la redirection à l'intérieur de la fonction comme:

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

Et appelez-le comme ceci:

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

S'appuyer sur la solution de Banu (merci une tonne!) Pour en faire une solution à une touche en haut de chaque page. Collez ce code à l'intérieur:

$(document).ready

Et ajoutez la classe "confirmLinkFollow" à tous les liens que vous souhaitez confirmer:

$(".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");
});
1
cii

J'ai une solution qui peut être utilisée pour remplacer la fonction window.confirm par défaut. Cela ne vous oblige pas à remplacer window.confirm car cela n'est pas entièrement possible.

Ma solution vous permet d'avoir une classe générale comme moi, disons 'confirm-action' que vous placez sur tout élément qui nécessite une confirmation avant d'être traité. Le script est très simple et utilise jQuery, jQuery UI Dialog et aucun autre plugin.

Vous pouvez trouver la démo complète de l'implémentation sur jsFiddle, http://jsfiddle.net/74NDD/39/ .

Usage:

  • Ajoutez ce code javascript dans votre tête html ou avant toute autre liaison de clic que vous avez dans votre 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;
    });
    
  • Placez ce html quelque part dans le corps (il est caché par défaut).

     <div style = "display: none;" id = "confirm-action-dialog" title = "Confirmer l'action?"> 
     <p> 
     <span class = "ui-icon ui-icon-alert"> </span> 
     Voulez-vous vraiment continuer? 
     </p> 
     </div> 
    
  • Mettez la classe 'confirm-action' sur tout élément qui nécessite une confirmation.

    confirmer-action

Cette solution fonctionne parfaitement car elle ne modifie pas le bouillonnement des événements jQuery, elle suspend simplement (arrête) tous les autres événements jusqu'à ce que l'utilisateur décide ce qu'il veut faire.

J'espère que cela est utile pour quelqu'un d'autre car je n'ai pas pu trouver d'autre solution qui ne nécessite pas l'installation d'un autre plugin jQuery ou un autre hack.

1
Jamalah Bryan

Près de trois ans plus tard, je recherche quelque chose de similaire. Comme je n'ai pas trouvé de solution "rapide" acceptable, j'ai écrit quelque chose qui se rapproche beaucoup des critères du PO. Je pense que d'autres pourraient le trouver utile à l'avenir.

JavaScript est piloté par les événements, ce qui signifie qu'il ne prend en charge aucune sorte de boucle "d'attente" ou de "sommeil" que nous pouvons utiliser pour suspendre une fonction de confirmation en pur javascript. Les options impliquent de graver des cycles de processeur, en utilisant un plugin de navigateur ou AJAX. Dans notre monde de plus en plus mobile et avec des connexions Internet parfois irrégulières, aucune de ces solutions n'est excellente. Cela signifie que nous devons immédiatement revenir de notre fonction "confirmer".

Cependant, comme il n'y a pas de logique "fausse" dans l'extrait de code ci-dessus (c'est-à-dire que rien n'est fait lorsque l'utilisateur clique sur "Annuler"), nous pouvons déclencher à nouveau l'événement "clic" ou "soumettre" lorsque l'utilisateur clique sur "OK". " Pourquoi ne pas définir un indicateur et réagir en fonction de cet indicateur dans notre fonction "confirmer"?

Pour ma solution, j'ai choisi d'utiliser FastConfirm plutôt qu'une boîte de dialogue "modale". Vous pouvez facilement modifier le code pour utiliser tout ce que vous voulez, mais mon exemple a été conçu pour utiliser ceci:

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

En raison de la nature de ce que cela fait, je ne vois pas de moyen propre de le conditionner. Si vous pensez que cela a trop de bords rugueux, n'hésitez pas à les lisser ou à réécrire votre code de la manière recommandée par tout le monde:

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

Donc ... onclick = "return confirm ('Voulez-vous tester cela?');" deviendrait onclick = "return jq_confirm (this, 'Voulez-vous tester cela?');" Le paramètre pos/"right" est facultatif et concerne spécifiquement la confirmation rapide.

Lorsque vous cliquez sur, la fonction jq_confirm () fera apparaître la boîte de dialogue jQuery et retournera "false". Lorsque l'utilisateur clique sur "OK", jq_confirm () définit un indicateur, appelle l'événement click (ou submit) d'origine, renvoie "true", puis désactive l'indicateur au cas où vous souhaiteriez rester sur la même page.

0
EpicVoyage

Le lien suivant a un plugin jQuery pour les boîtes de confirmation similaire à la construction comme confirm ("quelque chose") en JavaScript

http://labs.abeautifulsite.net/archived/jquery-alerts/demo/

0
Sathesh