11525 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous
J'ai un programme qui crée un objet JSON relativement complexe.
Avant d'envoyer cet objet à une routine du serveur qui écrira cet objet dans un fichier .json sur le site, je voudrais afficher l'objet sous la même forme qu'utilisent les navigateurs pour afficher un fichier .json et demander l'accord de l'utilisateur.
Ce ne sont pas les solutions qui manquent mais j'aimerais vos conseils sur la façon la plus économique de faire ça.
Merci pour votre aide.
Modérateur
Bonjour,

La question porte-t-elle plutôt sur la manière de formater le json ou bien de recueillir le consentement de l'utilisateur ?

Amicalement,
La question porte sur l’affichage du json dans une popup dans laquelle je mettrai un couple de boutons ok/cancel
Après avoir dormi dessus, je pense je vais faire une procédure récursive en js qui affiche le json.
J’étais parti sur des trucs du genre ouvrir un <iframe> avec un src ad-hoc pour bénéficier de l’affichage du json par le navigateur mais c’est finalement le marteau-pilon pour écraser un bug Smiley cligne
Modérateur
Bonjour,

Je n'ai vu que firefox faire une mise en page élaborée des json. Il y en a peut-être d'autres, mais chrome et safari, eux, me semblent ne rien faire de spécial et affichent juste le contenu des json comme s'il s'agissait d'un texte.

Amicalement,
OK
J'ai bien fait d'écrire ma procédure récursive.
Elle ne fait que 25 lignes mais j'ai pas mal bavé pour la mettre au point.
Salut,

je ne suis pas bien sur de comprendre ce que tu voulais faire (et vu qu'on a pas les 25 lignes de code de réponses je peux pas deviner Smiley ohwell ). Tu veux juste l'afficher sous forme d'arborescence dans une popup ?

Si tu as déjà un objet json a priori tu dois pouvoir l'afficher dans une balise pre avec cette fonction la :
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#using_the_space_parameter

Exemple (dans la console du navigateur directement sur leur page d'exemple) :
document.getElementById("using_the_space_parameter").innerHTML="<pre>"+JSON.stringify({ uno: 1, dos: 2 }, null, "\t")+"</pre>";

function ObjectToNode(data) {
	let dataNode;
	if(typeof data === 'object') {
		if(Array.isArray(data)) {
			dataNode = newNode('ul', '.array');
			for(const item in data) {
				const itemNode = ObjectToNode(item);
				itemNode.classList.add('item');
				dataNode.appendChild(newNode('li', itemNode));
			}
		}
		else {
			dataNode = newNode('ul', '.object');
			for(const [name, value] of Object.entries(data)) {
				const nameNode = newNode('p', '.objectName', name);
				const valueNode = ObjectToNode(value);
				valueNode.classList.add('objectValue');
				const namedNode = newNode('div', '.object', nameNode, valueNode);
				dataNode.appendChild(newNode('li', namedNode));
			}
		}
	}
	else dataNode = newNode('p', data);
	return dataNode;
}

newNode() est une fonction qui simplement fait un document.create() et y ajoute les attributs et le contenu.
Je suppose que toutes les librairies js contiennent une fonction de ce genre, simplement j'ai créé cette fonction avant qu'il existe de telles librairies et je n'ai pas envie de les utiliser.

Voici ce que ça donne :
upload/1683641902-48769-bjecttonode.png

La difficulté que j'ai rencontrée est que si au lieu d'écrire

let dataNode;
if(...) dataNode = ...;
else dataNode = ...;

on écrit

if(...) const dataNode = ...;
else const dataNode = ...;

ça ne marche pas sans message d'erreur apparent. Simplement ça ne génère pas ce que l'on veut.
Je pensais que, comme un seul des const dataNode est exécuté ça ne posait pas de problème, mais ce n'est pas comme ça que ça marche.
Modifié par PapyJP (09 May 2023 - 16:24)
Salut

Cela ne répondra pas à tes questions, mais peut être cela pourra te faire avoir une idée surprise
Smiley smile :

J'utilise une petite fonction pour afficher toutes les clés valeurs d'un json multidimensionnel :

function afficherClesValeurs(obj) {
  for (let cle in obj) {
    if (typeof obj[cle] === "object") {
      afficherClesValeurs(obj[cle]); // appel récursif pour les objets imbriqués
    } else {
      console.log(`${cle} => ${obj[cle]}`);
    }
  }
}


mais c'est très basique.
Ce code va parcourir l'objet JSON obj et pour chaque clé, afficher la clé et sa valeur sous la forme "clé => valeur". Si la valeur de la clé est un objet JSON, la fonction afficherClesValeurs est appelée de manière récursive pour afficher les clés et les valeurs de l'objet imbriqué.
Modifié par JENCAL (09 May 2023 - 17:15)
Oui c’est à peu près ce que je fais, sauf que ce n’est pas pour afficher sur la console. On peut très bien faire un console.log d’un objet je le faits très souvent pour debugger mes scripts.
PapyJP a écrit :

Voici ce que ça donne :
upload/1683641902-48769-bjecttonode.png


Ah ok, tu fais un rendu un peu plus jolie que juste l'affichage du json en fait Smiley lol , je pensais que tu voulais juste afficher le json sur plusieurs lignes au lieu d'une seul pour qu'il soit un peu plus lisible.

PapyJP a écrit :

La difficulté que j'ai rencontrée est que si au lieu d'écrire

let dataNode;
if(...) dataNode = ...;
else dataNode = ...;

on écrit

if(...) const dataNode = ...;
else const dataNode = ...;

ça ne marche pas sans message d'erreur apparent. Simplement ça ne génère pas ce que l'on veut.
Je pensais que, comme un seul des const dataNode est exécuté ça ne posait pas de problème, mais ce n'est pas comme ça que ça marche.


Pour ce problème je suppose que cela devait être lié à un problème de portée de variable, let et const n'existent qu'au sein du sous bloc mais généralement cela retourne un message d'erreur pour indiqué que l'on accède à un element non déclare si on essaye de s'en servir en dehors ..
Désolé de répondre aussi tard.
Si, au lieu de
[if(…) const dataNode =….,

On écrivait
if(…) {const dataNode = …}

on prendrait mieux conscience que const dataNode n’a comme portée que le bloc que constitue à elle seule cette instruction.
Donc utiliser dataNode plus loin n’a pas de sens.
CQFD Smiley cligne
Modifié par PapyJP (13 May 2023 - 08:10)
Modérateur
Bonjour,

Dans le code :
let a=true, b=1;
if(a) const c = b;
en plus du fait que c ne sera pas utilisable après pour une question de visibilité de variable, il y aura une erreur de syntaxe, car il n'est pas permis d'utiliser un const (ou un let) dans un bloc ne contenant qu'une seule ligne non entourée par des accolades.

Et même si cela avait été permis syntaxiquement, cela aurait été probablement inutile, puisque la variable ne pourrait pas être ensuite utilisée ni dans le bloc où elle est déclaré puisqu'un tel bloc sans accolades ne peut avoir qu'une seule ligne, ni ailleurs pour des raisons de portée de variable. Et c'est probablement pour ça qu'il est interdit du point de vue syntaxique de mettre un const dans un bloc n'ayant qu'une seule ligne non entourée d'accolades.

Amicalement,
Modifié par parsimonhi (13 May 2023 - 12:48)
Pour une fois qu’il y a une bonne raison pour une interdiction ! Smiley cligne
Ce qui me gêne c’est que je n’ai eu aucune alerte de la machine js de mon navigateur
Modérateur
Bonjour,

Le code ci-dessous génère une erreur Uncaught SyntaxError: Unexpected token 'const' avec Chrome, Firefox et Safari.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Const syntax error</title>
<style>
</style>
</head>
<body>
<h1>Const syntax error</h1>
<script>
let a=true, b=1;
if(a) const c = b;
</script>
</body>
</html>

Dans un code plus complexe, il se peut qu'une autre erreur empêche cette erreur de survenir. Mais si tout est en ordre avant d'arriver à ce bout de code, l'erreur de syntaxe sera présente dans la console.

Amicalement,