11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous,

Je travaille en ce moment sur une page, appelons-la page1 dont je suis obligé de charger une partie dynamiquement à partir d'une autre page, disons page2.

page2 contient l'appel à un objet issu de la librairie jquery.ddslick.min.js, une magnifique liste déroulante.

Enfin, page1 contient l'appel à script.js, qui permet l'ajout de ligne d'option dans la liste déroulante de page2.

Le problème est simple, lors du $(document).ready de page1, page2 est chargée, mais son contenu n'est pas encore intégré, et l'ajout des lignes ne fonctionne donc pas.

Après avoir parcouru le forum, il se pourrait que la solution passe par la méthode .on(). Mais j'avoue ne pas y comprendre grand chose...

Voici page1, l'appel des librairie, un peu bizare est dû à l'utilisation d'un CMS propriétaire qui limite les appels de code.

<div id="mainCible"></div>
<script language="javascript" type="text/javascript">
        document.write(String.fromCharCode(60));
        document.write('script type="text/javascript" src="jquery-1.11.2.min.js"');
        document.write(String.fromCharCode(62));
        document.write(String.fromCharCode(60));
        document.write('/script');
        document.write(String.fromCharCode(62));  
                
        document.write(String.fromCharCode(60));
        document.write('script id="css-ddslick" type="text/javascript" src="jquery.ddslick.min.js"');
        document.write(String.fromCharCode(62));
        document.write(String.fromCharCode(60));
        document.write('/script');
        document.write(String.fromCharCode(62));                
                
        document.write(String.fromCharCode(60));
	document.write('script type="text/javascript" src="./script.js"');
        document.write(String.fromCharCode(62));
        document.write(String.fromCharCode(60));
        document.write('/script');
        document.write(String.fromCharCode(62));   

</script>


Voici page2

	<div id="ListeCB" class="dd-container" style="width: 397px">
	<div class="dd-select" style="WIDTH: 397px; BACKGROUND: #eee"><input class="dd-selected-value" type="hidden" /><a href="#" class="dd-selected">Choisissez votre carte bancaire</a></div>
	<ul class="dd-options dd-click-off-close" style="OVERFLOW: auto; HEIGHT: 300px; WIDTH: 397px">
	</ul>
	</div>


et voici script.js, appelé par page1

$(document).ready(function () {
	var ddData = [];

	
	        $("#mainCible").load('page2.html', function(responseTxt, statusTxt, xhr) {
            if(statusTxt == "success"){
					for (i = 0; i < cartes.length; i++) {
						ajoutOption (cartes[i]);
					}
						}
            if(statusTxt == "error")
                alert("Error: " + xhr.status + ": " + xhr.statusText);
        });	



J'espère que mes explications sont claires, merci par avance pour votre aide.
[/i]
Modifié par Arthur24 (24 Aug 2015 - 08:53)
Salut Arthur,

Pas mal de questions me viennent à l'esprit :
- pourquoi tu écris un énorme bloc comme ça :
<script language="javascript" type="text/javascript">
        document.write(String.fromCharCode(60));
        document.write('script type="text/javascript" src="jquery-1.11.2.min.js"');
        document.write(String.fromCharCode(62));
        document.write(String.fromCharCode(60));
        document.write('/script');
        document.write(String.fromCharCode(62));  
                
        document.write(String.fromCharCode(60));
        document.write('script id="css-ddslick" type="text/javascript" src="jquery.ddslick.min.js"');
        document.write(String.fromCharCode(62));
        document.write(String.fromCharCode(60));
        document.write('/script');
        document.write(String.fromCharCode(62));                
                
        document.write(String.fromCharCode(60));
	document.write('script type="text/javascript" src="./script.js"');
        document.write(String.fromCharCode(62));
        document.write(String.fromCharCode(60));
        document.write('/script');
        document.write(String.fromCharCode(62));   

</script>

au lieu d'écrire simplement ça ?
<script src="jquery-1.11.2.min.js"></script>
<script src="jquery.ddslick.min.js"></script>
<script src="script.js"></script>

- dans ta console de debug de ton navigateur, as-tu des messages d'erreurs de chargement des fichiers (genre 404...)
- à quoi sert ta variable ddData dans script.js ?
- où es déclaré ta variable cartes toujours dans script.js ?
- comment fonctionne ta fonction ajoutOption() dans script.js ?

Je ne connais pas ddslick.js, mais j'ai l'impression qu'il manque quelques trucs dans tes scripts...
Bonjour,

Comme je le disais, le tout sera inclus dans un CMS propriétaire, qui bride les appels à des fichiers externes. L'appel direct du style <script src="jquery-1.11.2.min.js"></script>
doit être remplacé par
document.write(String.fromCharCode(60));
document.write('script type="text/javascript" src="jquery-1.11.2.min.js"');
document.write(String.fromCharCode(62));
document.write(String.fromCharCode(60));
document.write('/script');
document.write(String.fromCharCode(62));


ddData est une variable utilisée par ddslick.

cartes est déclaré en en-tete de script.js
var cartes = new Array (
["983-248773", "00520", "XXXXXXXX" , "YYYYYYYYYY" ,"ZZZZZZZZZ"],
["983-248773", "00519", "XXXXXXXX" , "YYYYYYYYYY" ,"ZZZZZZZZZ"],
["983-248272", "00514", "XXXXXXXX" , "YYYYYYYYYY" ,"ZZZZZZZZZ"],
["983-248272", "00509", "XXXXXXXX" , "YYYYYYYYYY" ,"ZZZZZZZZZ"],
["983-99583" , "00526", "XXXXXXXX" , "YYYYYYYYYY" ,"ZZZZZZZZZ"],
["983-99583" , "00525", "XXXXXXXX" , "YYYYYYYYYY" ,"ZZZZZZZZZ"],
);


voici la fonction ajoutOption issues de script.js
function (nomSelect, idOption, valueOption, imageOption, libOption) {
code = "<option";
if (idOption!="") {code += " id='" + idOption+ "'"}
if (valueOption!="") {code += " value='" + valueOption + "'"}
if (imageOption !="") {code += " data-imagesrc='" + imageOption + "'"}
code +=">" + libOption + "</option>\n";
$('#'+nomSelect).append(code);
}




Tout cela fonctionnait parfaitement lorsque page1.html contenait le code maintenant déporté dans page2.html. page1.html était chargé avec la liste déroulante ddslick, et dans le $(document).ready(function () {} la fonction ajoutOption rajoutait des options à cette liste.

Mais le tristement célèbre CMS propriétaire que j'évoquais m’empêche d'utiliser du html avec des <a href="#">. Donc pour contourner le problème, je déporte le tag dans un fichier traité avec .load(). Et là, c'est le drame...

Du coup, le load() se passe bien, mais ajoutOption qui s’exécute ensuite ne trouve pas la liste car elle n'est pas contenue dans le html de départ de page1. Mon problème est de faire "voir" le contenu de page2 par ajoutOption.


J'espère que mes explications sont compréhensibles...
Arthur24 a écrit :

Comme je le disais, le tout sera inclus dans un CMS propriétaire, qui bride les appels à des fichiers externes.

Ah oui désolé, je n'avais pas bien lu...

As-tu essayé d'enlever la dernière virgule de ton tableau "cartes" ?

Tu ne passes à l'appel de ajoutOption que le tableau dans l'argument "nomSelect", c'est normal ?
Modifié par MatthieuR (20 Aug 2015 - 15:53)
Le passage de tes arguments à la fonction ajoutOption est incorrect, je pense que tu veux faire ça, non ? :
for (j = 0; j < cartes.length; j++) {
        ajoutOption(cartes[j][0], cartes[j][1], cartes[j][2], cartes[j][3], cartes[j][4]);
      }

Modifié par MatthieuR (20 Aug 2015 - 16:06)
Ok, mais du coup c'est pas simple d'identifier un problème si tu modifies des choses...

Où appelles-tu le plugin ?

Un dernier truc qui m'échappe : à la fin de ta fonction ajoutOption() tu append le code (correctement généré) à $('#'+nomSelect). Où est cet élément ? Ça doit être un select, non ?
Modifié par MatthieuR (20 Aug 2015 - 16:58)
Bon, ça me titillais et du coup je pense avoir trouvé ton problème :

Tu injectes le code déjà généré par ddslick au lieu de mettre ta liste classique. Voici donc un code à adapté selon tes contraintes...

page1.html : pas de changement

page2.html : juste une balise <select> vide (tu la remplis en JS par la suite...)

<select id="ListeCB"></select>


script.js : il faut que tu appelles ddslick() dans le success du .load() :

var cartes = new Array (
["983-248773", "00520", "XXXXXXXX" , "http://lorempixel.com/20/20/" ,"ZZZZZZZZZ"],
["983-248773", "00519", "XXXXXXXX" , "http://lorempixel.com/20/20/" ,"ZZZZZZZZZ"],
["983-248272", "00514", "XXXXXXXX" , "http://lorempixel.com/20/20/" ,"ZZZZZZZZZ"],
["983-248272", "00509", "XXXXXXXX" , "http://lorempixel.com/20/20/" ,"ZZZZZZZZZ"],
["983-99583" , "00526", "XXXXXXXX" , "http://lorempixel.com/20/20/" ,"ZZZZZZZZZ"], 
["983-99583" , "00525", "XXXXXXXX" , "http://lorempixel.com/20/20/" ,"ZZZZZZZZZ"]
);  

$(function() {
  var ddData = [];
  $("#mainCible").load('page2.php', function(responseTxt, statusTxt, xhr) {
    if(statusTxt == "success"){
      for (j = 0; j < cartes.length; j++) {
        ajoutOption(cartes[j][0], cartes[j][1], cartes[j][2], cartes[j][3], cartes[j][4]);
      }
      //tu adaptes ton appel
      $('#ListeCB').ddslick({
        onSelected: function(selectedData){
        //callback function: do something with selectedData;
    }   
  });
    }
    if(statusTxt == "error"){
      alert("Error: " + xhr.status + ": " + xhr.statusText);
    }
  });

  
});

function ajoutOption( nomSelect, idOption, valueOption, imageOption, libOption ) {

  var code = "<option";
  if (idOption != "") {code += " id='" + idOption+ "'"; }
  if (valueOption != "") {code += " value='" + valueOption + "'"; }
  if (imageOption != "") {code += " data-imagesrc='" + imageOption + "'"; }
  code +=">" + libOption + "</option>\n";
  $('#ListeCB').append(code);
}

Modifié par MatthieuR (20 Aug 2015 - 17:16)
Le plug-in ddslick est appelé dans page 1 :
document.write(String.fromCharCode(60));
document.write('script id="css-ddslick" type="text/javascript" src="https://www.ca-charente-perigord.fr/Vitrine/ObjCommun/Fic/CharentePerigord/vel/CB/jquery.ddslick.min.js"');
document.write(String.fromCharCode(62));
document.write(String.fromCharCode(60));
document.write('/script');
document.write(String.fromCharCode(62));


l'objet liste ddslick est appelé dans page2
<div id="ListeCB" class="dd-container" style="width: 397px">
<div class="dd-select" style="WIDTH: 397px; BACKGROUND: #eee"><input class="dd-selected-value" type="hidden" /><a href="#" class="dd-selected">Choisissez votre carte bancaire</a></div>
<ul class="dd-options dd-click-off-close" style="OVERFLOW: auto; HEIGHT: 300px; WIDTH: 397px">
</ul>
</div>


l'ajout des lignes dans la liste se fait dans script.js, lui-même appelé par page1
$(document).ready(function () {
var ddData = [];

//recupHtml(urlBase + 'ModuleLibre_vel_CB_contenu.html', '#main', "#mainCible" );

$("#mainCible").load(urlBase + 'ModuleLibre_vel_CB_contenu.html', function(responseTxt, statusTxt, xhr) {
if(statusTxt == "success"){
for (i = 0; i < cartes.length; i++) {
ajoutOption ("ListeCB", cartes[0], cartes[i][1], urlImgCB + cartes[i][2], cartes[i][3]);
}
}
if(statusTxt == "error")
alert("Error: " + xhr.status + ": " + xhr.statusText);
});
}


Ce n'est pas un select que l'on traite mais l'objet ListeCB qui est un ddslick et qui se trouve dans page2.

Le problème vient du fait que :
1°) Page1 se charge
2°) $(document).ready(function () s'execute
3°) page2 est load() dans page1
4°) ajoutOption s'applique à ListeCB loadé dans page1

Mais au moment d'ajoutOption, depuis script.js, le contenu modifié de page1 n'est pas accessible. cela fonctionnerait si je copiais/collais l'html de page2 dans page1. A ce moment-là, ListeCB ferait partie du DOM dès le $(document).ready(function () et je n'aurai aucun problème.

Mais je ne peux pas procéder comme cela à cause du CMS utilisé.

[/i][/i][/i]
Oui, j'ai bien compris que tu chargeais la librairie du plugin en page1, je te demandais à quel moment tu l'appelles, tu l'instancies, tu le fais travailler quoi... ($('#ListeCB').ddslick(});)

Le DOM est chargé dans la page1 et du coup, si tu appelles (instancies) ddslick() dans la fonction de callback du success de .load(), le contenu de page2 est bien chargé et est donc manipulable. Au moment de ajoutOption() ton contenu est bien manipulable, tu imagines, on pourrait pas faire beaucoup de choses si le DOM se chargeait une fois et puis c'est toit, plus d'accès : les callbacks (les fonctions anonymes que tu exécutes une fois le chargement effectué) sont là pour ça.

As-tu essayé le code que j'ai posté en dernier ? De mon côté ça fonctionne parfaitement !

Tu pourrais même ne pas manipuler le nouveau contenu chargé depuis page2, mais simplement générer ton tableau en JSON et le passer en option de ddslick au moment de son appel (la variable ddData)

Pour finir, il faut que tu n'aies qu'un select dans page2, c'est ddslick, lui tout seul, qui modifiera le contenu et le transformera en div.ddcontainer etc...
Modifié par MatthieuR (20 Aug 2015 - 17:41)
Rhaaaaaa ça marche !!!

Et je me rends compte que mes problèmes venaient de ce satané CMS qui avait, lors d'une reprise du code, substitué le select que j'avais jusque là utilisé par l'objet ddslick Smiley fache


Effectivement ton code fonctionne parfaitement, et le code fonctionne Smiley biggrin

Un grand merci pour ton aide, à la hauteur du ouf que je pousse !!!