Bonjour,

J'ai une page web classique, et je veux laissez à l'utilisateur la liverté de n'afficher que certains panels (bootstrap). Je fais donc des test avec un seul panel.
Pour ce faire, j'ai mis toute ma page dans une div et lui donnant l'idée "#full". Quand je clique sur le bouton pour n'afficher que le panel "boite à outils", voilà ce qui s'exécute :

$(document).ready(function(){
    $("#boiteOutil").click(function(){
        var cloneText = $("#A11").html();
        $(".oneBox").html(cloneText);
        $("#full").hide();
    });
});

Tout se passe bien : la page complète ce cache et le contenu du panel s'affiche correctement là dedans (la colonne vide sert uniquement à recenter l'élément car il y a un menu de deux colonnes qui reste systématiquement sur la page) :

<div class="row" stlye="visibility: hidden">
    <div class="hidden-xs hidden-sm col-md-2 col-lg-2"></div>
    <div class="col-xs-12 col-sm-12 col-md-5 col-lg-5 oneBox"></div>                
</div>

Le soucis, c'est que la div copiée et insérée ci dessus possède des icônes cliquables qui fonctionnent avec du javascript : réduire/agrandir la fenêtre et ouvrir une fenêtre modale qui reprend le conteu. En effet, pour eviter de dupliquer le code dans la fenêtre modale et en dehors (pour qu'il soit affiché dans tout les cas car la modale ne sert qu'à agrandir le contenu, à l'image d'une galerie photo), j'utilise le clone comme je le fais dans le JS montré si dessus.

$(document).ready(function(){

    $("#ZA1").click(function(){
        var cloneText = $("#A1").html();
        $("#content-modal-A1").html(cloneText);
    });
<div class="modal fade" id="modalA1" tabindex="-1" role="dialog" aria-hidden="true">
                    <div class="modal-dialog">
                            <div class="modal-content">
                                    <div class="modal-header">
                                            <h4 class="modal-title">Boite à outils</h4>
                                    </div>
                                <div class="modal-body" id="content-modal-A1">

                        </div>
                </div>
        </div>

Tout fonctionne très bien en affichage normal, mais la réduction du panel et l'affichage de la modale ne fonctionne plus lorsque je veux l'exécuter sur un panel qui s'affiche seul (comme au début de l'explication). J'ai beau cherché, je ne vois pas pourquoi ca ne fonctionne pas. J'ai simplement ajouté un id "#A11" sur l'ensemble du panel pour avoir le header et le body sur l'affichage seul, là ou l'id "#A1" est attribué uniquement au panel-body car je n'affiche que lui dans la modale.

Merci d'avance, et désolé pour la pavé ;)

11 réponses


Je n'ai pas tout compris à tes explications, mais le soucis que je comprends est assez connu et répandu.

En gros, ton JS fonctionne sur le DOM à instant T, si tu changes le DOM (le HTML donc) le javascript n'est pas relancé sur cette nouvelle partie du DOM. Par conséquent, ton JS qui est sensé marché pour tel ou tel id/class n'aura aucun effet car le JS n'a pas été lancé pour ce nouveau code HTML.

Tu as donc 2 solutions.

Soit tu relances le code JS spécifique au contenu que tu as ajouté.
Soit tu fais un "click live" (la fonction "live" n'existe plus).

Pour le premier cas, on suppose que ton click() se trouve dans une extension jQuery ($.fn.mesActions = function() { $(this).click(....); })
Et donc sur ton nouveau HTML, il te suffit de faire $variableDuDomHtml.mesActions();

Pour le second cas, plus simple, mais moins optimisé, il faut remplacer tes
$('monSelector').click(function() { .... });
par
$(document).on('click', 'monSelector', function() { .... });

sytrys59
Auteur

Et comment je fais pour relancer le code JS (en gros mon fichier, ici en locurrence "duplicate.js") ? Il faut recharger la page forcemment ?

EDIT :
Laisse tomber la première méthode, j'ai un petit niveau en JS/JQuery donc ça risque de devenir rapidement compliqué pour le moment :p

Non, c'est ce que je dis en solution 1 :

Il faut que tu te créés des "plugins" jQuery via $.fn.mesActionsAMoi = function....
De sorte qu'au premier lancement, tu fais $(document).mesActionsAMoi();

Et lorsque tu charges dynamiquement du contenu (ajax notamment), tu n'aies plus qu'à faire $('.monNouveauContenu').mesActionsAMoi();

Pour relancer ton script pour ce nouveau contenu.

Maintenant, selon tes connaissances, utilise plutôt la seconde solution, beaucoup plus simple à mettre en oeuvre.

A partir de ton seul fichier, sans modification, tu n'a pas solution.

sytrys59
Auteur

J'ai essayé de modifier la fonction qui me permet d'afficher ma modale ou encore de réduire mon panel, mais ca ne fonctionne pas :/ La solution serait de garder en cache l'affichage choisis par l'utilisateur et de reload la page :/

Copie/colle par exemple le script pour réduire le panel (avant ta modif et après ta modif), histoire de verif que tout est ok.

sytrys59
Auteur
    $("#RA1, #PA1").click(function(){
        $("#A1").toggle();
        $("#RA1").toggle();
        $("#PA1").toggle();
    }); 

    $(document).on("click", "#RA1, #PA1", function(){
        $("#A1").toggle();
        $("#RA1").toggle();
        $("#PA1").toggle();
    });

En sachant que R correspond à l'icone "-" qui s'affiche et P correspond à l'icon "+" qui s'affiche (et qui est masquée au début), d'où l'utilisation du toogle().

Sur le papier, ça me parait bon, sauf à mettre ton code en ligne, je ne vois pas comment t'aider plus.
Pense à mettre des noms de id/class plus parlante à l'avenir ;)

sytrys59
Auteur

Je les comprends :) A = la colonne et le numéro = sa position dans la colonne.

sytrys59
Auteur

En gros au chargement de ma page, j'ai un DOM précis, et l'utilisateur à la possibilité de le modifier (ajout/suppression de div, en fait elle sont simplement hide() ). Mais le soucis c'est que les nouveau ne sont pas connus par js, donc les fonctions ne peuvent pas s'exécuter ...

UP ? Des idées ? Pourtant j'ai changé mon code js :

$(document).ready(function(){

    $(document).on('click', "#ZA1", function(){
        var cloneText = $("#A1").html();
        $("#content-modal-A1").html(cloneText);
    });

    $(document).on('click',"#ZA2", function(){
        var cloneText = $("#A2").html();
        $("#content-modal-A2").html(cloneText);
    });

    $(document).on('click',"#ZA3", function(){
        var cloneText = $("#A3").html();
        $("#content-modal-A3").html(cloneText);
    });

    $(document).on('click',"#ZB1", function(){
        var cloneText = $("#B1").html();
        $("#content-modal-B1").html(cloneText);
    });

    $(document).on('click',"#ZC1", function(){
        var cloneText = $("#C1").html();
        $("#content-modal-C1").html(cloneText);
    });

    $(document).on('click',"#ZC2", function(){
        var cloneText = $("#C2").html();
        $("#content-modal-C2").html(cloneText);
    });
});

Tout mon js est maintenant sous cette forme.

il ressemble à quoi #A1 pour info ?

(un pb à la fois, mais il faudra que tu fasses en sorte de ne pas dupliquer ton code comme tu le fais, les variables, ça sert à quelque chose :))

sytrys59
Auteur

A1 c'est un panel.

<div class="panel panel-default"> 
                            <div class="panel-heading header">
                                <span class="pull-right">
                                    <i class="fa fa-search-plus box-icon" data-toggle="modal" data-target="#modalA1" id="ZA1" title="" style="margin-right:10px;"></i>
                                    <i class="fa fa-minus box-icon reduce" id="RA1" title="Réduire la boîte"></i>
                                    <i class="fa fa-plus box-icon PA" id="PA1" title="Agrandir la boîte"></i>
                                </span>
                                <span class="pull-left">
                                    <i class="fa fa-briefcase"></i>
                                </span>
                                <h4 class="panel-title">Boite à outils</h4>                             
                            </div>
                            <div class="panel-body" id="A1">
                                <p>- Liens internes</p>
                                <p>- Liens notes</p>
                                <p>- LDA</p>    
                            </div>

                            <!-- Le modal -->

                            <div class="modal fade" id="modalA1" tabindex="-1" role="dialog" aria-hidden="true">
                                <div class="modal-dialog">
                                    <div class="modal-content">
                                        <div class="modal-header">
                                            <h4 class="modal-title">Boite à outils</h4>
                                        </div>
                                        <div class="modal-body" id="content-modal-A1">

                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>