web-dev-qa-db-fra.com

Bootstrap modal - cache un puis montre un autre

J'utilise jQueryUI depuis longtemps, mais je suis récemment passé à Bootstrap pour des raisons esthétiques. Je suis maintenant aux prises avec ce que je pense être un problème simple et je me suis demandé si c'était quelque chose que d'autres personnes plus familiers avec Bootstrap peuvent m'aider.

J'ai une fonction générique pour créer des boîtes de dialogue à la volée. Il arrive parfois que je montre une boîte de dialogue sans boutons (lors du traitement de quelque chose), puis que je la remplace par une boîte de dialogue comportant des boutons Exemple). Je n'essaie pas de définir un processus défini ici, donc je dis fondamentalement que je veux pouvoir fermer un dialogue et en ouvrir un autre à tout moment. C'est là que le problème entre en jeu.

Avec Bootstrap, les dialogues s'animent et s'animent, et j'aime ça et je veux le garder. Je ne veux pas le faire quand permuter des dialogues. Je peux le faire en supprimant la classe fade de la première boîte de dialogue lorsqu'elle s'affiche et de la deuxième boîte de dialogue avant qu'elle ne s'affiche, et cela fonctionne très bien. J'ajoute ensuite la classe à la deuxième boîte de dialogue afin qu'elle s'anime. Cependant, l'animation se passe mal quand je fais cela et il y a un flash moche où la scène d'arrière-plan devrait s'estomper doucement.

J'ai mis en place un clavier pour illustrer le problème. Vous pouvez cliquer sur le bouton de fermeture de la première boîte de dialogue pour voir à quoi l’animation de fondu sortant devrait.

Toute aide serait la bienvenue avant de commencer à fouiller dans les fichiers source Bootstrap.

http://jsfiddle.net/ArchersFiddle/0302gLav/1/

tl; dr

Regardez le jsfiddle - cliquez sur "show dialog 2" - cliquez sur "ok". Je veux me débarrasser du flash noir à la fin.

CSS

@import url("//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css");
.modal {
    display: none;
}

HTML

<div id="dialog1" class="modal fade">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title">Modal Dialog 1</h4>
      </div>
      <div class="modal-body">This is the first modal dialog</div>
      <div class="modal-footer">
        <button type="button" id="dialog-ok" class="btn btn-default">Show dialog 2</button>          
        <button type="button" id="dialog-close" class="btn btn-default" data-dismiss="modal">Close</button>          
      </div>
    </div>
  </div>
</div>

<div id="dialog2" class="modal">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title">Modal Dialog 2</h4>
      </div>
      <div class="modal-body">This is the second modal dialog</div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">OK</button>          
      </div>
    </div>
  </div>
</div>

JavaScript

function showDialog2() {
    $("#dialog1").removeClass("fade").modal("hide");
    $("#dialog2").modal("show").addClass("fade");
}

$("#dialog1").modal("show");

$("#dialog-ok").on("click", function() {
    showDialog2();
});
6
Archer

D'accord, je n'aime pas répondre à ma propre question, mais j'ai une solution à 100% infaillible (autant que je sache). J'ai finalement opté pour une solution qui vérifie la présence d'un dialogue et le modifie, plutôt que de le masquer et d'en afficher un nouveau.

Voici un jsfiddle qui fonctionne (en utilisant echo dans l'appel ajax où il charge normalement un modèle html) ...

http://jsfiddle.net/ArchersFiddle/0302gLav/9/

Le code fait partie d'une plus grande bibliothèque sur laquelle je travaille, mais je le posterai ici car il pourrait s'avérer utile pour d'autres.

Bibliothèque JavaScript

(function () {

    var _defaultOptions = {
        backdrop: "static",
        close: true,
        keyboard: true
    };

    window.bootstrap = {
        modal: {
            show: function (options) {

                options = $.extend(_defaultOptions, options);

                var buttonText = "";

                for (var key in options.buttons) {

                    options.buttons[key].id = "button_" + key.split(" ").join("");

                    var button = options.buttons[key];

                    buttonText += "<button type=\"button\" " +
                        "id=\"" + button.id + "\" " +
                        "class=\"btn " +
                        (typeof (button.class) == "undefined" ? "btn-default" : button.class) + "\" " +
                        (typeof (button.dismiss) == "undefined" ? "" : "data-dismiss=\"modal\" ") + ">" +
                        key + "</button>";
                }

                $.ajax({
                    url: "templates/bootstrap-modal.html"
                })
                .done(function (data) {
                    data = data
                        .replace("{:Title}", options.title)
                        .replace("{:Body}", options.body)
                        .replace("{:Buttons}", buttonText);

                    var $modal = $("#bootstrap-modal");
                    var existing = $modal.length;

                    if (existing) {
                        $modal.html($(data).find(".modal-dialog"));
                    }
                    else {
                        $modal = $(data).appendTo("body");
                    }

                    for (var key in options.buttons) {
                        var button = options.buttons[key];
                        if (typeof (button.callback) !== undefined) {
                            $("#" + button.id).on("click", button.callback);
                        }
                    }

                    $modal.off("shown.bs.modal").on("shown.bs.modal", function(e) {
                        if (typeof(options.onshow) === "function") {
                            options.onshow(e);
                        }
                    });

                    if (!existing) {
                        $modal.modal(options);
                    }

                    if (options.large === true) {
                        $modal.find(".modal-dialog").addClass("modal-lg");
                    }

                    if (options.close === false) {
                        $modal.find("button.close").remove();
                    }
                });
            },
            hide: function (callback) {
                var $modal = $("#bootstrap-modal");

                if (!$modal.length) return;

                $modal.on("hidden.bs.modal", function(e) {
                    $modal.remove();
                    if (typeof(callback) === "function") {
                        callback(e);
                    }
                });

                $modal.modal("hide");
            }
        }
    };
})();

Modèle HTML

<div id="bootstrap-modal" class="modal fade">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
        <h4 class="modal-title">{:Title}</h4>
      </div>
      <div class="modal-body">{:Body}</div>
      <div class="modal-footer">
        {:Buttons}
      </div>
    </div>
  </div>
</div>

Exemple d'utilisation:

bootstrap.modal.show({
    title: "Dialog Title",
    body: "<p>This is the dialog body and can contain any old html rubbish.</p>",
    buttons: {
        Close: {
            dismiss: true
        }
    }
});

Autres options expliquées

bootstrap.modal.show({
    backdrop: true,                     // show the backdrop
    close: true,                        // show the close button
    keyboard: true,                     // allow the keyboard to close the dialog
    title: "Dialog Title",
    body: "<p>This is the dialog body and can contain any old html rubbish.</p>",
    buttons: {
        Button1: {
            class: "btn-primary",           // any class you want to add to the button
            dismiss: false,                 // does this button close the dialog?
            callback: function() {          // button click handler
                // the button was clicked - do something here
            }
        },
        Button2: {
            // options as defined as above.  You can have as many buttons as you want
        }
    },
    onshow: function(e) {
        // this will trigger when the dialog has completed the show animation
    }
});

et

bootstrap.modal.hide(function(e) {
    // this will trigger when the dialog has completed the hide animation
});

Toutes les options de la méthode show() sont facultatives, mais vous souhaiterez évidemment un titre et un corps.

3
Archer

MIS &AGRAVE; JOUR:

J'ai ajouté un gestionnaire click() pour votre dernier bouton avec un identifiant de test ajouté id="test" où la boîte de dialogue et l'arrière-plan sont estompés avec l'effet fadeOut() effect. L'important est de supprimer l'élément .modal-backdrop, qui encapsule à la fois le dialogue et l'arrière-plan:

$("#test").on("click", function () {
    $(".modal-backdrop").fadeOut("slow");
});

 

JsFiddle

4
urbz
function showDialog2() {
$("#dialog1").removeClass("fade").modal("hide");
$("#dialog2").addClass("fade").modal("show");

}

tu veux être ceci

2
esref

J'ai codé comment fermer un modal ouvert avant d'en ouvrir un autre.

$('[data-toggle="modal"]').on('click', function() { //On click a button which call a modal
    if(($(".modal").data('bs.modal') || {}).isShown){ //If a modal is shown
        var modal = $(".modal.in"); // Get the current element
        $(modal).modal('hide'); // Hide the current modal
    }
});

J'espère que ça a aidé!

0
Antony GUEDJ