1. #1
    Membre du Club
    Inscrit en
    novembre 2010
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : novembre 2010
    Messages : 123
    Points : 50
    Points
    50

    Par défaut Formater un formulaire au format JSON

    Bonjour,

    Je souhaiterai créer une fonction dynamique a fin de formater le résultat de mon formulaire dans un format spécifique JSON.

    Sur chacun de mes champs je possède un 'data-base' contenant le nom de la table, eventuellement de la jointure, et celui du champ.

    Imaginons que nous avons une table agent ayant les champs nom, prenom, enfants et coordonnees.
    où enfants correspond a une jointure oneToMany et coordonnes une jointure coordonnes

    Coté formulaire j'aurais :
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <input type="text" data-base="nom">
    <input type="text" data-base="prenom">
    <input type="text" data-base="enfants|0|nomEnfant">
    <input type="text" data-base="enfants|1|nomEnfant">
    <input type="text" data-base="coodonnees|codePostal">
    <input type="text" data-base="coodonnees|ville">


    Je souhaiterais donc récupérer le json suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    {"nom":"nom4","prenom":"prenom4","enfants":[{"nomEfant":"sonNom"},{"nomEfant":"sonNom"}],"coordonnees":{"codePostal":59300,"ville"
    :"maVille"}}
    Je sais que ca doit se faire en recursivité mais je n'y arrive pas.

    Serait il possible de m'orienter sur la facon de procéder svp?

    Merci

    Edit :
    Pour l'instant je suis en train d'essayer de créer une fonction qui me permetra de créer un objet sous la forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    niveau1 =>
                    niveau2 =>
                                    niveau3
    Mais je n'arrive pas à cella.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    function testObj(monTab, obj) {
        obj = obj || {};
        if(monTab.length > 0){
            obj[monTab[0]] = {};
            monTab.splice(0,1);
     
            obj = testObj(monTab, obj);
        }
     
        return obj;
     
    };
    Résultat obtenu:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    {niveau1, niveau2, niveau3}

  2. #2
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    février 2009
    Messages
    5 749
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : février 2009
    Messages : 5 749
    Points : 21 128
    Points
    21 128
    Billets dans le blog
    39

    Par défaut



    Exemple :

    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    <!DOCTYPE html>
    <html lang="fr" dir="ltr">
    <head>
    	<!-- cache-control avec max-age=60 pour le développement uniquement -->
      <meta http-equiv="cache-control" content="public, max-age=60">
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
      <meta name="author" content="Daniel Hagnoul">
      <title>test</title>
      <style>
                    *,
                    *:after,
                    *:before {
                            box-sizing: border-box;
                    }
                    
                    /* code du test */
                    
                    #dataIndividu {
                            width: 22rem;
                    }
                    
                    #dataIndividu > input {
                            display: block;
                            width: 18rem;
                    }
                    
                    /* fin code du test */
                    
            </style>
    	<script>
                    'use strict';
                                                    
                    document.addEventListener( "DOMContentLoaded", ev => {
                            // le DOM est construit, la page web n'est pas visible
                            // code du test
                            
                            
                            // fin code du test
                    
                    }, false );
                    
                    window.addEventListener( "load", ev => {
                            // le DOM est construit et la page web est visible
                            // code du test
     
                            document.querySelector( "#formIndividu" ).addEventListener( "submit", ev => {
                                    ev.stopPropagation();
                                    ev.preventDefault();
                                    
                                    const
                                            dataIndividu = {},
                                            inputs = Array.from( document.querySelectorAll( "#dataIndividu > input" ) );
                                            
                                    for ( const input of inputs ){
                                            dataIndividu[ input.getAttribute( "placeHolder" ) ] = input.getAttribute( "data-base" );
                                    }
                                    
                                    const strJSON = JSON.stringify( dataIndividu );
                            
                                    // debug, console, touche F12
                                    console.log( strJSON );
                                    
                            }, false );
                            
                            // fin code du test
                    
                    }, false );
      </script>
    </head>
    <body>
    	<main>
     
    		<form id="formIndividu">
    			<fieldset id="dataIndividu">
    				<legend>Individu</legend>
    				<input type="text" placeHolder="nom" data-base="Dupond">
    				<input type="text" placeHolder="prénom" data-base="Henri">
    				<input type="text" placeHolder="prénom enfant 1" data-base="Serge">
    				<input type="text" placeHolder="prénom enfant 2" data-base="Luc">
    				<input type="text" placeHolder="code postal" data-base="59300">
    				<input type="text" placeHolder="ville" data-base="Villerasée">
    			</fieldset>
    			<input type="submit">
    		</form>
     
    	</main>
    </body>
    </html>

    Blog



    Nota bene : si vous devez être compatible avec les navigateurs obsolètes (IE8 et plus), vous devez convertir les codes ES2015 en ES5 avec Babel.

    FAQ JS Tutoriels JS

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  3. #3
    Membre du Club
    Inscrit en
    novembre 2010
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : novembre 2010
    Messages : 123
    Points : 50
    Points
    50

    Par défaut

    Je te remercie pour ton aide daniel.

    Mais mon problème actuelle se situe plus au niveau de la récursivité et l'affectation des sous objet à l'objet parent.
    ex :
    niveau1
    |
    niveau2
    |
    niveau3

    Pour obtenir au final {"niveau1":{"niveau2":{"niveau3":""}}}

  4. #4
    Membre du Club
    Inscrit en
    novembre 2010
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : novembre 2010
    Messages : 123
    Points : 50
    Points
    50

    Par défaut

    J'avance un peu mais je n'obtiens toujours pas ce que je souhaite.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    function testObj(monTab,parent) {
        var obj = {};
        var objFinal = {};
        parent = parent || (monTab.length>0)?monTab[0]:"";
     
    console.debug('Dans la fonction => tab = ');
    console.debug(monTab);
     
        if(monTab.length > 0){
     
            obj[monTab[0]] = (monTab.length==1)?"test":{};
     
     
    console.debug("Dans le IF  longeur="+monTab.length);
    console.debug("Avant:");
    console.debug(obj);
     
     
            monTab.splice(0,1); //On supprime la premiere valeur du tableau
            obj = testObj(monTab,monTab[0]); //On rappelle la fonction recursive
            objFinal[parent] = obj;
     
     
    console.debug("Après:");
    console.debug("parent=>"+parent);
    console.debug(objFinal);
        }
     
        return objFinal;
     
    };
    Les LOG:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    Dans la fonction => tab = ["niveau1", "niveau2", "niveau3"]
     
    Dans le IF  longeur=3
     
    Avant:
    Object { niveau1={...}}
    Dans la fonction => tab = ["niveau2", "niveau3"]
     
    Dans le IF  longeur=2
     
    Avant:
    Object { niveau2={...}}
    Dans la fonction => tab = ["niveau3"]
     
    Dans le IF  longeur=1
    Avant:
    Object { niveau3="test"}
    Dans la fonction => tab = []
     
    Après:
    parent=>niveau3
    Object { niveau3={...}}
    Après:
    parent=>niveau2
    Object { niveau2={...}}
    Après:
    parent=>niveau1
    objFinal =>
    niveau1 Object { niveau2={...}}
            niveau2 Object { niveau3={...}}
                         niveau3 Object {}
    Cepandant dans l'objet niveau 3 je devrais avoir "niveau3":"test" et non object.
    Une idée svp?

  5. #5
    Membre éprouvé Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    septembre 2002
    Messages
    765
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : septembre 2002
    Messages : 765
    Points : 1 208
    Points
    1 208

    Par défaut

    Une question. Pourquoi as-tu besoin de la récursivité ?
    En fait je n'ai pas compris ta notion de niveau.
    Cela ne sert à rien d'optimiser quelque chose qui ne fonctionne pas.

    Mon site : www.emmella.fr

    Je recherche le manuel de l'Olivetti Logos 80B.

  6. #6
    Membre du Club
    Inscrit en
    novembre 2010
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : novembre 2010
    Messages : 123
    Points : 50
    Points
    50

    Par défaut

    @badaze, j'ai besoin de récursivité car je souhaiterais créer un script réutilisable dans mes prochains projets.
    Par conséquence, je ne connais pas d'avance ma base de donnée et le nombre de jointure qui peut y avoir.

    Par exemple, prenons un cas un peu tordu.
    J'ai une table agent qui possède une jointure oneToMany avec coordonnees, qui possède également une jointure OneToOne avec LesVilles (je sais c'est idiot comme relation mais bon, ca reste un exemple)

    Cela nous donne donc "agent" => (1 a n) "Coordonnees" => (1 a 1) "LesVilles"

    Lorsque je vais récupérer mes données au format JSON j'aurais : Je fait un select * from agent;
    {"nomAgent":"Polichon", "prenomAgent": "toto", "coordonnees":[{"numero": 12, "rue":"jean jaures", "ville":{"id":10,"nomVille":"Lille"}},{...},{...}] }

    Dans mon input coté html, j'aurais un champ data-chargementauto="coordonnes|0|ville|nomVille" ce qui signifie que ce champ correspond a mon champ nomVille de ma table ville. Le "0" correspond à la clé de mon tableau coordonnes car je pourrais récupérer plusieurs adresses pour un agent.

    Si je souhaite ajouter un champ input pour afficher le nom de l'agent je n'aurais que data-chargementauto="nomAgent"

    J'espère avoir été un peu plus clair dans mes explications.

  7. #7
    Membre éprouvé Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    septembre 2002
    Messages
    765
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : septembre 2002
    Messages : 765
    Points : 1 208
    Points
    1 208

    Par défaut

    Pour que la récursivité fonctionne, il faut être en mesure de déduire l'/les éléments de niveau n+1 à partir de l'élément de niveau n.
    Dans ton cas, j'ai l'impression qu'il manque des données. C'est pour ça que je t'ai posé ma question. Car tu n'as qu'un seul niveau en dessous du niveau le plus haut (enfants et coordonnées sont au même niveau logiquement parlant).

    En effet, comment fais-tu pour dire que enfant dépend de ce qu'il y a au-dessus ?
    Si c'est parce qu'il n'y a pas de caractère | censé indiquer que ce qui précède est une table comment sais-tu quelle est le nom de cette table de niveau supérieur ?

    Tout ça pour dire que si tu veux faire du code générique il faut que tu aies une structure qui se prête à la récursivité ce qui selon moi n'est pas entièrement le cas. De même si tu devais ajouter la table activités sachant qu'un enfant peut avoir de 0 à plusieurs comment t'y prendrais tu pour codifier tout cela ?

    De plus à ta place je codifierai tout selon le même "modèle". En effet pour enfants tu distingues le premier et le second par un n° d'indice (0 et 1). Pourquoi ne pas faire la même chose pour coordonnées même s'il n'y a qu'un seul enregistrement.
    En utilisant une structure identique tu te simplifies grandement le développement car tu appliqueras le même traitement tout le temps. En effet, tu n'auras pas à te demander si ce qui suit le nom de la table est un index ou un champ, tu auras toujours un index suivi d'un champ.

    Avant :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <input type="text" data-base="nom">
    <input type="text" data-base="prenom">
    <input type="text" data-base="enfants|0|nomEnfant">
    <input type="text" data-base="enfants|1|nomEnfant">
    <input type="text" data-base="coodonnees|codePostal">
    <input type="text" data-base="coodonnees|ville">

    Après :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <input type="text" data-base="nom">
    <input type="text" data-base="prenom">
    <input type="text" data-base="enfants|0|nomEnfant">
    <input type="text" data-base="enfants|1|nomEnfant">
    <input type="text" data-base="coodonnees|0|codePostal">
    <input type="text" data-base="coodonnees|0|ville">

    Ensuite tu peux encore te simplifier le développement en faisant en sorte de décoder les différentes valeurs en faisant le moins d'efforts possibles.
    Avec la structure ci-dessous je suis parti du principe que le nom de la table est suivi d'un tiret à qu'après le tiret il y a l'index. Je suis parti aussi du principe que ce qui suit # est un nom de champ.

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <input type="text" data-base="parent-0|#nom">
    <input type="text" data-base="parent-0|#prenom">
    <input type="text" data-base="parent-0|enfants-0|#nomEnfant">
    <input type="text" data-base="parent-0|enfants-1|#nomEnfant">
    <input type="text" data-base="parent-0|coodonnees-0|#codePostal">
    <input type="text" data-base="parent-0|coodonnees-0|#ville">

    De cette manière (mais il peut y en avoir d'autres) tu traites chaque élément de la même manière. tu fais un split('|'). Si un élément ne commence pas par # donc c'est une table. Tu fais un split('-') et le 1er poste te donne la table et le second son index. Si un élément commence par # alors tu sais que les caractères qui suivent correspondent au nom d'un champ.

    Voilà ce ne sont que quelques idées. Qu'en penses tu ?

    PS : Si j'ai un peu de temps ce soir j'essaierai de voir comment faire un algo récursif à partir de tout cela.
    Cela ne sert à rien d'optimiser quelque chose qui ne fonctionne pas.

    Mon site : www.emmella.fr

    Je recherche le manuel de l'Olivetti Logos 80B.

  8. #8
    Membre du Club
    Inscrit en
    novembre 2010
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : novembre 2010
    Messages : 123
    Points : 50
    Points
    50

    Par défaut

    Je te remercie de ton aide. C'est vrai que ce que tu me propose me parait bien plus structuré.

    Il faut que je vois si ca ne va pas engendrer trop de modification dans le reste de mon code JS car j'ai une fonction qui renseigne les champs inputs automatiquement en se basent sur ce data.

  9. #9
    Membre du Club
    Inscrit en
    novembre 2010
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : novembre 2010
    Messages : 123
    Points : 50
    Points
    50

    Par défaut

    Je pense avoir réussi a faire ce que je voulais sans ayant eu besoin de modifier mon data-chargementauto.
    Par contre je ne sais pas si mon code est très optimisé ou pas


    La fonction principale est parseJsonV2.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
     
     
    //Fonction recupere les valeurs des champs du formulaire
    function getValueChamp(monData){
        var valeur;
     
        if(monData != ""){
            var monChamp = $("[data-chargementauto='"+monData+"']");
            var id = monChamp.attr('id');
            var tagName = monChamp.tagName();
     
            if(tagName=="select"){
                valeur = $("#"+id+" option:selected").val();
            } else {
                var typeChamp = monChamp.attr('type');
                switch (typeChamp) {
                    case 'radio':
                        var name = $(monChamp).attr('name');
                        valeur = $('input[type=radio][name="' + name + '"]:checked').attr('value');
                        break;
                    case 'checkbox':
                        valeur = $(monChamp).val();
     
                        break;
                    default:
                        valeur = $(monChamp).val();
                        break;
                }
            }
        }
        if(typeof valeur != "undefined"){
            return valeur;
        }else{
            console.debug("Champ data-chargementauto="+monData+" => non trouvé");
            return "";
        }
    }
     
     
     
    function insertObject(object, tabData, maChaine) {
        var objectPrecedent = object;
     
        if(tabData.length >0) {
            //Si mon tableau n'est pas vide
            var objTempsPourRecherche = object; //Objet qui sera utilisé pour la recherche
            $.each(tabData, function (key, property) {
                if(!objTempsPourRecherche.hasOwnProperty(property)) { //Si on ne retrouve pas la propriété dans l'objet
                    if(key+1==tabData.length){ //Si je suis arrivé a la fin du tableau, j'ajoute la valeur avec ca clé
                        objTempsPourRecherche[tabData[key]] = getValueChamp(maChaine);
                    } else {
                        if (isNaN(tabData[key])) {//Je ne possède pas la propriété parent et c'est le premier ajout ex: key=enfants et non "0"
                            if (isNaN(tabData[key + 1])) { //Je suis dans le cas ou le la key suivant est de type texte => donc objet
                                var objAjout = {};
                                objAjout[tabData[key]] = {};
                                objectPrecedent[tabData[key]] = {};
     
                                objectPrecedent = objectPrecedent[tabData[key]];
                                objTempsPourRecherche = objTempsPourRecherche[tabData[key]];
                            } else { //dans le cas ou la clé suivant de type numéric => donc array
                                var arrayAjout = [];
                                objectPrecedent[tabData[key]] = arrayAjout;
                                objTempsPourRecherche =  objectPrecedent[tabData[key]];
                            }
                        } else { //Le cas ou la key = 1 ....
                            var arrayAjout = [];
                            arrayAjout.push({});
                            objectPrecedent[tabData[key-1]] = $.merge(objectPrecedent[tabData[key-1]], arrayAjout);
     
                            var monArray = objectPrecedent[tabData[key-1]];
                            objTempsPourRecherche =  monArray[tabData[key]];
                            objectPrecedent = monArray[tabData[key]];
                        }
                    }
                } else {
                    objectPrecedent = objTempsPourRecherche; //permet de recuperer la propriete precedente pour l'enregistrement de certain cas (tableaux)
                    objTempsPourRecherche = objTempsPourRecherche[property]; //La sous propriete existe, on affecte a l'objet de recherche le sous objet trouvé
                }
            });
     
        }
        return object;
    }
     
     
     
     
    $.fn.parseJsonV2 = function(mesChamps, object) {
        mesChamps = mesChamps || $(this).find('input, select, textarea');
        object = object || {};
        var objFinal = objFinal || {};
        var monJson = "";
     
        $.each(mesChamps, function(key, value) {
            var dataAutoChargement = $(this).data('chargementauto');
            if (typeof dataAutoChargement != "undefined" && dataAutoChargement != null) {
                var tabDataAutoChargement = dataAutoChargement.split('|');
     
                objFinal = insertObject(object, tabDataAutoChargement, dataAutoChargement);
     
            }
        });
     
        //console.debug(objFinal);
        monJson = JSON.stringify(objFinal);
        //console.debug(monJson);
     
        return monJson;
    };

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 23
    Dernier message: 24/08/2007, 10h53
  2. Export d'un formulaire au format pdf
    Par lebarbu45 dans le forum IHM
    Réponses: 1
    Dernier message: 23/05/2007, 15h38
  3. Format Contrôle Formulaire
    Par delcroixf dans le forum IHM
    Réponses: 5
    Dernier message: 11/03/2007, 16h58
  4. Export d'un formulaire en format jpeg
    Par Hélo2204 dans le forum IHM
    Réponses: 2
    Dernier message: 15/02/2007, 15h20
  5. formulaire et format de variable
    Par Mathieu72 dans le forum Formulaires
    Réponses: 2
    Dernier message: 18/01/2007, 16h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo