web-dev-qa-db-fra.com

Construire dynamiquement Twitter Bootstrap modal

Je construis une application Rails et je souhaite placer le contenu d'un partiel de Rails dans le modal via AJAX.

Dans un modal Twitter Bootstrap 2.3.2, j'ai lu dans la documentation que vous pouvez charger du contenu via ajax à l'aide de la clé distante. 

http://getbootstrap.com/2.3.2/javascript.html#modals

Cependant, cela permet uniquement d'injecter du contenu dans le .modal-body, plutôt que de construire le modal entier de manière dynamique. 

Existe-t-il un moyen de construire l'ensemble du modal, y compris .modal-header, .modal-footer, de manière dynamique avec JS? 

Cela semble très difficile à faire avec une chaîne, comme suit:

partial = render_to_string(:partial => 'some-partial').gsub(%{"}, %{'}).gsub(/'/,"\\\\'").gsub("\n", "")
27

Mettre à jour:

Depuis que j'ai posté ceci, j'ai trouvé une élégante fonction wrapper de bootstrap 3 ici , qui ne nécessite pas l'ajout d'un div au code html.


Voici un exemple de code qui montre cela. Pour l'utiliser, ajoutez simplement un div dans votre <body> (à l'intérieur de <div class = "container"> de bootstrap), par exemple:

<div id="idMyModal"></div>

et ensuite vous pouvez l'utiliser via:

var header = "This is my dynamic header";
var content = "This is my dynamic content";
var strSubmitFunc = "applyButtonFunc()";
var btnText = "Just do it!";
doModal('idMyModal', header, content, strSubmitFunc, btnText);

Pour fermer le modal, lancez un appel à hideModal, également défini ci-dessous:

function doModal(placementId, heading, formContent, strSubmitFunc, btnText)
{
    var html =  '<div id="modalWindow" class="modal hide fade in" style="display:none;">';
    html += '<div class="modal-header">';
    html += '<a class="close" data-dismiss="modal">×</a>';
    html += '<h4>'+heading+'</h4>'
    html += '</div>';
    html += '<div class="modal-body">';
    html += '<p>';
    html += formContent;
    html += '</div>';
    html += '<div class="modal-footer">';
    if (btnText!='') {
        html += '<span class="btn btn-success"';
        html += ' onClick="'+strSubmitFunc+'">'+btnText;
        html += '</span>';
    }
    html += '<span class="btn" data-dismiss="modal">';
    html += 'Close';
    html += '</span>'; // close button
    html += '</div>';  // footer
    html += '</div>';  // modalWindow
    $("#"+placementId).html(html);
    $("#modalWindow").modal();
}


function hideModal()
{
    // Using a very general selector - this is because $('#modalDiv').hide
    // will remove the modal window but not the mask
    $('.modal.in').modal('hide');
}
32
Amnon

Mettre à jour

Je suis récemment tombé sur bootbox.js , une bibliothèque complète dédiée à la création dynamique de modaux bootstrap et à la réaction des utilisateurs avec leurs interactions. Bien que différente de la méthode ci-dessous, bootbox accepte les rappels plutôt que le nom d'une fonction. Personnellement, je ne l'ai pas encore utilisé car je ne peux pas justifier qu'une bibliothèque de 26 Ko fasse essentiellement ce que la fonction ci-dessous fait. Mais j'ai pensé que quelqu'un pourrait le trouver utile.

Mise à jour du 17/08/2016

J'utilise maintenant bootbox pour à peu près tous les projets pour lesquels j'ai besoin de modaux dynamiques. Fonctionne très bien et je le recommande vivement.

Mise à jour 10/1/2018

Bootbox ne prend pas encore officiellement en charge bootstrap 4, mais il existe une branche bootbox v5.x où ils travaillent sur le support de bootstrap 4. Selon la feuille de route 5.0.0 et Liste de distribution de Bootbox 5.0 ticket, on dirait que la branche est pratiquement prête à fonctionner mais ils ne l’ont pas encore publiée. Mais il y a quelques instructions sur la façon de l'utiliser. Déni de responsabilité: Je n'ai pas encore utilisé la branche v5.x et je ne peux pas en garantir l'exhaustivité. 

Message original

Le code provient de la réponse d'Ammon ci-dessus. Mise à jour pour bootstrap 3.0

function doModal(placementId, heading, formContent, strSubmitFunc, btnText)
{
    html =  '<div id="modalWindow" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="confirm-modal" aria-hidden="true">';
    html += '<div class="modal-dialog">';
    html += '<div class="modal-content">';
    html += '<div class="modal-header">';
    html += '<a class="close" data-dismiss="modal">×</a>';
    html += '<h4>'+heading+'</h4>'
    html += '</div>';
    html += '<div class="modal-body">';
    html += formContent;
    html += '</div>';
    html += '<div class="modal-footer">';
    if (btnText!='') {
        html += '<span class="btn btn-success"';
        html += ' onClick="'+strSubmitFunc+'">'+btnText;
        html += '</span>';
    }
    html += '<span class="btn" data-dismiss="modal">';
    html += <?php echo "'".__t("Close")."'"; ?>;
    html += '</span>'; // close button
    html += '</div>';  // footer
    html += '</div>';  // content
    html += '</div>';  // dialog
    html += '</div>';  // modalWindow
    $("#"+placementId).html(html);
    $("#modalWindow").modal();
    $("#dynamicModal").modal('show');
}

C'est ce que j'ai fini par utiliser pour mes besoins. Inclut également un gestionnaire d’événements pour supprimer le modal du DOM une fois celui-ci fermé. J'avais juste besoin d'un modal info, alors j'ai sorti les arguments de la fonction d'envoi et du texte du bouton.

function doModal(heading, formContent) {
    html =  '<div id="dynamicModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="confirm-modal" aria-hidden="true">';
    html += '<div class="modal-dialog">';
    html += '<div class="modal-content">';
    html += '<div class="modal-header">';
    html += '<a class="close" data-dismiss="modal">×</a>';
    html += '<h4>'+heading+'</h4>'
    html += '</div>';
    html += '<div class="modal-body">';
    html += formContent;
    html += '</div>';
    html += '<div class="modal-footer">';
    html += '<span class="btn btn-primary" data-dismiss="modal">Close</span>';
    html += '</div>';  // content
    html += '</div>';  // dialog
    html += '</div>';  // footer
    html += '</div>';  // modalWindow
    $('body').append(html);
    $("#dynamicModal").modal();
    $("#dynamicModal").modal('show');

    $('#dynamicModal').on('hidden.bs.modal', function (e) {
        $(this).remove();
    });

}
24
Craig Harshbarger

En utilisant DOM, j'ai créé le bouton ainsi que le modal Bootstrap qui apparaît dès que le bouton est cliqué.

Incluez également ces éléments dans la section head de la page HTML:

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href=      
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script  
src= "https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js">
</script>
<script  
src= "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">     
</script>

L'ensemble de ce code doit être écrit dans un fichier JS.

// Tout d’abord, créer un bouton qui affiche le Bootstrap Modal 

var button = document.createElement("input");
button.className = 'btn btn-info btn-lg';
button.setAttribute("type", "button");
button.setAttribute("data-toggle", "modal");
button.setAttribute("data-target", "#myModal");              
button.setAttribute("value", "More Information...");
document.getElementsByTagName('body')[0].appendChild(button);   

// CREATION MODALE:

var div1 = document.createElement('div');
div1.id = 'myModal';
div1.className = 'modal fade';
div1.setAttribute("role", "dialog");     

var innerDiv1m = document.createElement('div');
innerDiv1m.className = 'modal-dialog modal-sm';
div1.appendChild(innerDiv1m);              

var innerDiv2m = document.createElement('div');
innerDiv2m.className = 'modal-content';
innerDiv1m.appendChild(innerDiv2m);

var innerDiv3 = document.createElement('div');
innerDiv3.className = 'modal-header';
innerDiv2m.appendChild(innerDiv3);

var buttonM = document.createElement("button");
buttonM.className = 'close';
buttonM.setAttribute("data-dismiss", "modal");
buttonM.setAttribute("aria-hidden", "true");
buttonM.setAttribute("value", "Close");
innerDiv3.appendChild(buttonM); 

var headerM = document.createElement("H4");
headerM.className = 'modal-title';
innerDiv3.appendChild(headerM);

var innerDiv31 =  document.createElement('div');
innerDiv31.className = 'modal-body';
innerDiv2m.appendChild(innerDiv31);

var para =  document.createElement('p'); 
innerDiv31.appendChild(para);
para.innerHTML = "paragraph";

var innerDiv32 =  document.createElement('div');
innerDiv32.className = 'modal-footer';
innerDiv2m.appendChild(innerDiv32);

var closeButton = document.createElement("input");
closeButton.className = 'btn btn-default';
closeButton.setAttribute("data-dismiss", "modal");
closeButton.setAttribute("type", "button");
closeButton.setAttribute("value", "Close");
innerDiv32.appendChild(closeButton);

document.getElementsByTagName('body')[0].appendChild(div1); 

// Par conséquent, en cliquant sur le bouton créé, le modal apparaît à l'écran.

5
Khushboo Mulani

Thème très similaire à la réponse acceptée mais écrit comme un plugin jQuery. Je cherchais une certaine logique à intégrer dans une boîte à outils. Je suis en train de travailler mais je n’en ai pas trouvé qui me soit parvenue.

Il y a beaucoup de code ci-dessous, mais il est conçu pour être écrit une fois, puis appelé facilement ensuite. Ainsi, en tant que spoiler, une fois que vous avez tout configuré, il est aussi facile à utiliser que:

$.fn.alert("utils.js makes this so easy!");

Et comme exemple de travail complet:

https://jsfiddle.net/63zvqeff/

Il n’est pas nécessaire que le <div /> existant soit présent sur la page, et cela fonctionne avec les dialogues imbriqués, tirés d’une trousse à outils que j’ai construite, j’ai donc inclus tous les bits pertinents pour qu’il s’agisse d’un exemple de copier/coller de travail.

(function ($)
{
    $.utils = {
        // http://stackoverflow.com/a/8809472
        createUUID: function ()
        {
            var d = new Date().getTime();
            if (window.performance && typeof window.performance.now === "function")
            {
                d += performance.now(); //use high-precision timer if available
            }
            var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c)
            {
                var r = (d + Math.random() * 16) % 16 | 0;
                d = Math.floor(d / 16);
                return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
            });
            return uuid;
        }
    }

    $.fn.dialogue = function (options)
    {
        var defaults = {
            title: "", content: $("<p />"),
            closeIcon: false, id: $.utils.createUUID(), open: function () { }, buttons: []
        };
        var settings = $.extend(true, {}, defaults, options);

        // create the DOM structure
        var $modal = $("<div />").attr("id", settings.id).attr("role", "dialog").addClass("modal fade")
                        .append($("<div />").addClass("modal-dialog")
                            .append($("<div />").addClass("modal-content")
                                .append($("<div />").addClass("modal-header")
                                    .append($("<h4 />").addClass("modal-title").text(settings.title)))
                                .append($("<div />").addClass("modal-body")
                                    .append(settings.content))
                                .append($("<div />").addClass("modal-footer")
                                )
                            )
                        );
        $modal.shown = false;
        $modal.dismiss = function ()
        {
            // loop until its shown
            // this is only because you can do $.fn.alert("utils.js makes this so easy!").dismiss(); in which case it will try to remove it before its finished rendering
            if (!$modal.shown)
            {
                window.setTimeout(function ()
                {
                    $modal.dismiss();
                }, 50);
                return;
            }

            // hide the dialogue
            $modal.modal("hide");
            // remove the blanking
            $modal.prev().remove();
            // remove the dialogue
            $modal.empty().remove();

            $("body").removeClass("modal-open");
        }

        if (settings.closeIcon)
            $modal.find(".modal-header").prepend($("<button />").attr("type", "button").addClass("close").html("&times;").click(function () { $modal.dismiss() }));

        // add the buttons
        var $footer = $modal.find(".modal-footer");
        for(var i=0; i < settings.buttons.length; i++)
        {
            (function (btn)
            {
                $footer.prepend($("<button />").addClass("btn btn-default")
                    .attr("id", btn.id)
                    .attr("type", "button")
                    .text(btn.text)
                    .click(function ()
                    {
                        btn.click($modal)
                    }))
            })(settings.buttons[i]);
        }

        settings.open($modal);

        $modal.on('shown.bs.modal', function (e) {
            $modal.shown = true;
        });
        // show the dialogue
        $modal.modal("show");

        return $modal;
    };
})(jQuery);

J'ai ensuite écrit une fonction d'assistance pour les moments où vous vouliez juste une alerte de base ()

(function ($)
{
    $.fn.alert = function (message)
    {
        return $.fn.dialogue({
            title: "Alert", 
            content: $("<p />").text(message),
            closeIcon: true,
            buttons: [
                { text: "Close", id: $.utils.createUUID(), click: function ($modal) { $modal.dismiss(); } }
            ]
        });
    };

})(jQuery);

Sinon, vous devez créer votre contenu en tant qu’objet jQuery, puis le transmettre sous la forme d’un objet tel que:

{
    title: "", // what ever you want in the title bar
    content: $("<p />"), // any DOM structure you can build as a jQuery object
    closeIcon: false, // does the dialogue have a X in the tilte bar to close it
    id: $.utils.createUUID(), // a reference id 
    open: function () { }, // a function called after the DOM structure is built but BEFORE rendering
    buttons: [ // an array of buttons to include in the footer
        // example "close" button, all buttons get a reference to $modal passed into them 
        // .dismiss() is a function attached to $modal to revert the DOM changes
        { text: "Close", click: function ($modal) { $modal.dismiss(); } }
    ]
};
4
Morvael

J'ai eu le même problème, après des recherches approfondies, j'ai finalement créé une fonction js pour créer des modaux de manière dynamique en fonction de mes besoins. En utilisant cette fonction, vous pouvez créer des popups sur une ligne tels que:

puyModal({title:'Test Title',heading:'Heading',message:'This is sample message.'})

Ou vous pouvez utiliser d'autres fonctionnalités complexes telles que les iframes, les popups vidéo, etc.

Trouvez-le sur https://github.com/aybhalala/puymodals Pour une démonstration, visitez http://pateladitya.com/puymodals/

0
Adi.P