IPB

Bienvenue invité ( Connexion | Inscription )

 
Reply to this topicStart new topic
> jQuery : intégration de plugins (dynamiquement)
Options
toluol
posté 12 Nov 2016, 18:32
Message #1


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



Bonsoir,

j'ai un problème récurrent lorsque je souhaite intégrer des plugins simples qui doivent à la fois fonctionner lorsque la page se charge, et lorsque, dynamiquement, ma page se recompose en ajax.

Par exemple un color Picker serait appelé ainsi :
Code
$(".monInput").colorpicker({
    parm1: "valeur",
        param2: "valeur",
        param3: "valeur"
});

Mais est-ton obligé de l'intégrer dans une fonction et d'y faire appel à chaque fois qu'on remplace du code html où il y a un "<div class="monInput">" ?

Généralement, quand je crée personnellement des choses, j'utilise la formule...
Code
$("body").on('click','.monInput',function(){
    //mon action ajax...
});

Ce type de code permet d'être toujours valide (au chargement et lorsque les élément sont créés "à la volée").
Peut-on imaginer la même chose avec un plugin ?

Ce message a été modifié par toluol - 12 Nov 2016, 18:33.
Go to the top of the page
 
+Quote Post
No6
posté 13 Nov 2016, 16:48
Message #2


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Whaoo...
J'ai l'impression que tu débute en Javascript...

Déjà, ce que tu considère comme une fonction est de base en JavaScript un objet. ( d'ailleurs en JavaScript tout est Objet, même une simple variable).


ensuite quand tu assigne une fonction ( ex ton "OnClick") cette instanciation ne se fait que sur les objets réellement présents sur la page HTML à ce moment la; ceux qui peuvent arriver par la suite ne seront pas instanciés par cette assignation.

Pour réaliser cette assignation sur des élément non encore existant 2 solutions:
- soit la faire 1 fois sur un élément parent qui reste toujours présent en lui indiquant la sous classe des éléments à considérer
- soit faire cette assignation après l'appel Ajax, mais c'est beaucoup plus contraignant.
il faut mieux utiliser les promesses, et ne pas oublier de faire une déassignation si l'élément est effacé de la page HTML, ben oui, JavaScript est un langage asynchrone, c'est ce qui fait sa force !

Et ne pas oublier non plus les problèmes de Hoisting

aller ; des tuto d'explication (indispensables à connaître) :
1-> https://www.grafikart.fr/formations/debuter.../scope-hoisting
2-> https://www.grafikart.fr/tutoriels/jquery/j...y-on-events-518

quand à passer par les promesses, ( https://api.jquery.com/deferred.promise/ ) c'est un peu plus compliqué à mettre en œuvre,, et selon les as on peut s'en tirer autrement...

Ce message a été modifié par No6 - 13 Nov 2016, 18:36.


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
toluol
posté 13 Nov 2016, 18:09
Message #3


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



En JS (enfin... plutôt jquery), je suis un débutant depuis 5 ans, oui... ^^ Mais on apprend toujours! tongue.gif (Et en apprenant sur le web, je dois dire qu'on ne commence pas toujours par les bons cours, les bons tutos)

Je sais bien ce qu'est un objet et une fonction. Je suis passé par de l'actionscript à un moment ou encore la création de classes en php... Je me suis sans doute mal exprimé.
Ta première solution (cibler un parent) est bien ce que je fais avec mon onClick $("body").on('click','.monInput' et celui-ci marche bien qu'on crée ou qu'efface les instances.

Par contre, je ne vois pas comment appliquer ce principe à un plugin... (sans devoir le rappeler à chaque fois)

Merci pour tes explications et tes liens. Je vais les regarder attentivement. Je connais Grafikart... Ils ont de bonnes explications. smile.gif
Go to the top of the page
 
+Quote Post
No6
posté 13 Nov 2016, 18:47
Message #4


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Ah oui, j'avais pas compris ta question.
Assigner un pluggin jQuery à un élément non présent....
ce qui revient à demander à jQuery de reprogrammer le navigateur web pour qu'il ajoute systématiquement des propriétés (fonctionnelles) à une classe d'éléments non encore présent....

Franchement je trouve pas cela très logique ou possible, mais bon, je me trompe peut-être, et moi aussi j'en apprends tous les jours...

Ce genre de chose est traité différemment dans les framesworks tels que AngularJs, ReactJs ou VueJS. Ills ont tous une sorte de gestionnaire d' évènements qui s'occupe de faire ces assignations au fur et à mesure des changements sur la page, ce qui forcement n'est pas toujours super rapide pour les gros sites, et même les petits car il il y a toute la machinerie du framework qui tourne....

Ce message a été modifié par No6 - 13 Nov 2016, 19:09.


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
Jaypee
posté 13 Nov 2016, 21:08
Message #5


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



C'est vrai qu'il est difficile de trouver un bon cours structuré de Javascript "moderne", je mets des guillemets car n'étant pas très vieux, on a du mal à parler de style classique ou de style moderne...

J'en ai suivi un sur SafariOnlineBooks.com auquel j'ai accès dans ma boîte. Le contenu tournait autour de la notion de privé/public, d'interface, qui aujourd'hui conditionne la programmation et l'usage des frameworks cités. Namespace et Module sont les notions importantes.

Je cite à tout hasard cette référence: https://addyosmani.com/resources/essentialj...tternjavascript

C'est un point de départ possible.

J-P

Ce message a été modifié par Jaypee - 13 Nov 2016, 21:11.
Go to the top of the page
 
+Quote Post
No6
posté 8 Aug 2017, 00:56
Message #6


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



petit déterrage, mais j'ai la solution !
tongue.gif

En fait, ce que tu veux faire est prévu dans jQuery ...

pour assigner une fonction "fct_x" à un élément id="theone", faut juste l'assigner dans le on("click ...
exemple :
Code
var fonc1 = function () {
      ....
      };
$("button#theone").on("click", fonc1);


tu peux aussi la dés-assigner
Code
$("#theone").off();


moins documenté, mais utile, si on a besoin de passer l'event:
Code
      var fonc2 = function (e) {
        e.stopPropagation();
....
      };
$("button#theone").on("click", {}, fonc2);


Le code complet de mes propres tests:
CODE
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>test affectation button</title>
<style>
button {
margin: 5px;
}
button#theone {
color: red;
background: yellow;
}
div {
border: 1px solid blue;
display: block;
width: 500px;
height: 50px;
padding: 10px;
}
</style>
</head>
<body>
<div id="GDIV">
<button id="theone">rien...</button>
<button id="fct_x">clear</button>
<button id="fct_0">no fct</button>
<button id="fct_1">fct_1</button>
<button id="fct_2">fct_2</button>
</div>
<div id="traceur">...!</div>
<div id="traceur2">...!</div>

<!-- <script src="jquery-3.2.1.min.js"></script> -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
var call_nb = 0;
var fonc1 = function () {
$("div#traceur").text("fonc1");
};

var fonc2 = function (e) {
$("div#traceur").text("fonc2");
e.stopPropagation();
};

$("#GDIV").on("click", function () {
call_nb++;
$("div#traceur2").text(call_nb);
});

$("#fct_x").on("click", function (e) {
$("div#traceur").text("...!");
e.stopPropagation();
});

$("#fct_0").on("click", function (e) {
$("div#traceur").text("no fct");
$("#theone").off();
$("#theone").text("rien");
$("body").off("click", "button#theone");
});

$("#fct_1").on("click", function () {
$("#theone").text("=> F1");
$("button#theone").on("click", fonc1);
});

$("#fct_2").on("click", function () {
$("#theone").text("=> F2");
$("button#theone").on("click", {}, fonc2);
});
});
</script>
</body>
</html>


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
toluol
posté 23 Dec 2017, 21:22
Message #7


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



Je te remercie beaucoup pour ta peine No6. Je redécouvre ce post quelques mois plus tard (après un petit éloignement de la plate-forme macbidouille rolleyes.gif )
Malheureusement, j'ai dû mal m'expliquer car je connais bien ce que tu me montres. Je l'utilise tout le temps. Mon problème est différent.

Je vais réexpliquer d'une autre façon... Tout d'abord essaie ce code parfaitement fonctionnel :
Code
<!doctype html>
<html lang="fr">
<head>
    <title>Colorpicker</title>  
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-colorpicker/2.5.1/css/bootstrap-colorpicker.min.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script>  
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-colorpicker/2.5.1/js/bootstrap-colorpicker.min.js"></script>  

    <style>
        h4{margin-top:50px;}
        .form-control{margin-bottom:10px;}
    </style>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-xs-12">
                <h4>Au chargement de la page</h4>
                <input class="form-control" type="text" id="colorpicker" value="#93bdab" style="background-color:#93bdab"/>
                <h4>A la volée</h4>
                <button id="add" type="button" class="btn btn-sm btn-outline-secondary">Ajouter des champs</button>
            </div>
        </div>
    </div>

    <script>
        $('#colorpicker').colorpicker().on('changeColor', function(e){
            $(this).css({'backgroundColor':e.color.toHex()});
        });
        var i=0;
        $('body').on('click','#add', function(e){
            $(this).before('<input class="form-control" type="text" id="colorpicker'+i+'" value="#93bdab" style="background-color:#93bdab"/>');
            $('#colorpicker'+i).colorpicker().on('changeColor', function(e){
                $(this).css({'backgroundColor':e.color.toHex()});
            });
            i++;
        });
    </script>
</body>
</html>


En regardant maintenant le code :
Le truc que je n'aime pas du tout, c'est qu'une même fonction est écrite et appelée plusieurs fois.
Et en plus, depuis cet essai, je n'arrive même plus à me passer du id pour faire fonctionner ce plugin et suis obliger d'incrémenter une valeur (i).

Idéalement, je souhaiterais pouvoir appliquer un plugin sur une classe (par ex. mycolorpicker):
Code
<input class="form-control" type="text" class="mycolorpicker" />

Puis, le faire fonctionner ainsi:
Code
$('body').on('click','.mycolorpicker', function(e){
    var input = $(this);
    input.colorpicker().on('changeColor', function(e){
        $(this).css({'backgroundColor':e.color.toHex()});
    });
});

...pour pouvoir ajouter mes input.mycolorpicker sans me soucier de redéclarer la fonction à chaque fois. Hélas, cette technique ne fonctionne pas.
(Et j'ai ce même problème pour tous les plugins...)

Revoici le code qui ne fonctionne pas:
Code
<!doctype html>
<html lang="fr">
<head>
    <title>Colorpicker</title>  
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-colorpicker/2.5.1/css/bootstrap-colorpicker.min.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script>  
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-colorpicker/2.5.1/js/bootstrap-colorpicker.min.js"></script>  

    <style>
        h4{margin-top:50px;}
        .form-control{margin-bottom:10px;}
    </style>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-xs-12">
                <h4>A la volée</h4>
                <button id="add" type="button" class="btn btn-sm btn-outline-secondary">Ajouter des champs</button>
            </div>
        </div>
    </div>

    <script>
$('body').on('click','.mycolorpicker', function(e){
    var input = $(this);
    input.colorpicker().on('changeColor', function(e){
        $(this).css({'backgroundColor':e.color.toHex()});
    });
});
        
        $('body').on('click','#add', function(e){
            $(this).before('<input class="form-control" type="text" class="mycolorpicker"/>');
        });
    </script>
</body>
</html>



Go to the top of the page
 
+Quote Post
No6
posté 24 Dec 2017, 01:54
Message #8


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Oki, cette fois, je pense avoir compris.... ohmy.gif laugh.gif

Mais...
dans ton exemple c'est le pluggin qui décide des evt à connecter l'élément auquel il est affecté.
Et il ne peut être affecté que sur un élément déjà présent sur la page html.

En gros, il est pas prévu pour l'usage que tu souhaite : une affectation de manière dynamique.

Soit tu le réécrit à ta sauce, en récupérant les sources par exemple, mais c'est un coton à coder, en tout cas pour moi.

Pour le type d'usage que tu souhaite, à titre perso, je laisserai un div caché dans un coin avec le color picker dedans, puis je le mettrai au premier plan sur la page en le positionnant à coté d'une de tes zone d'input-color.

Quelque chose du genre :
Code
$(document).on('click focus', '.ClassColorsPickers', function () {
    var elem = this;
    moveColorPickerTo($(this).position());
    theColorPicker.show().on('changeColor', function (e) {
    $(elem).css({
        'backgroundColor': e.color.toHex()
    }).hide();
});


bien sur il faut écrire les fonctions moveColorPickerTo et les suivantes...

PS : pour que ton colorPickerBootstrap soit afficher il faut lui mettre l'option { inline: true, ...} et sans doute d'autres trucs en plus.

Point de vue mémoire ce serait plus propre que le code que tu met en exemple, car celui ci multiplie les colorspicker


====

en fouillant un peu sur le site : https://farbelous.github.io/bootstrap-colorpicker/v2/

ce que je te propose est déjà plus ou moins prévu : avec les commandes (en version :
.colorpicker('show') --> Show the color picker
.colorpicker('hide') --> Hide the color picker
.colorpicker('reposition') --> Updates the color picker's position relative to the element

sinon en version 3
c'est par la https://farbelous.github.io/bootstrap-color...icker.html#show (enfin peut-être car j'ai survolé le texte)

Ce message a été modifié par No6 - 24 Dec 2017, 02:11.


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
toluol
posté 27 Dec 2017, 23:16
Message #9


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



Ok, je vois, oui !

Merci pour tes éclaircissements. J'imaginais bien que ces plugins n'avaient pas été conçu dans cet usage.
Le coup de mettre le plugin dans un coin et de l'afficher au besoin, ce n'est pas bête. Je n'y avais jamais songé.
Bon, cela marche pour le colopicker... Mais pas pour un plugin plus complexe comme ckeditor, par exemple.

En tout cas, j'essaierai ta solution pour les plugins "légers" ! Merci encore.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 utilisateur(s) sur ce sujet (1 invité(s) et 0 utilisateur(s) anonyme(s))
0 membre(s) :

 



Nous sommes le : 19th March 2024 - 06:22