[D3.js] Tests difficiles avec l’arbre de D3.js (Customisation…)

d3js

Introduction


La librairie D3.js propose des solutions de visualisation de données innovantes, à intégrer dans les applications WEB de demain. C’est une librairie open source et donc gratuite.

Lorsque l’on suit les exemples des codes exemples, et que l’on y intègre ses propres modèles de données JSON, c’est relativement accessible.

Les problèmes commencent lorsque l’on veut ajouter des fonctionnalités inexistantes à un graphique D3.js, ouch , et que l’on ne connait pas l’API!

Là, je décide de customiser l’arbre de D3.JS (Qui n’est même pas celui de base !) en y ajoutant la faculté de supprimer un node, de le renommer et de faire d’autres choses comme ajouter des images… Je débute, donc je glane des portions de codes D3.Js associés à l’arbre sur internet, puis je les colle dans le code en essayant de réflechir…

J’ai aussi besoin de créer un menu contextuel avec un click droit, autant dire que ce n’est pas de la tarte au début !

Le but final est de pouvoir intégrer cet arbre à une application permettant de gérer des projets .

Pour tester, c’est ici:  http://nicolash.org/d3/

Photo de l’arbre à customiser :


d3.jpg

Ce que j’ai réussi à ajouter au jour 1:



  • Intégration dans AngularJs (Pas très beau, le code JS est directement dans une fonction Js)…
  • Ajout d’un node sur double clic (Il faudra le mettre dans un menu contextuel, en plus ca buggote au niveau des cercles)
  • Edition du nom d’un node
  • Suppression du behavior sur clic Droit.

 

Liens utiles


  • http://bl.ocks.org/robschmuecker/7880033
  • http://fiddle.jshell.net/mattsrinc/g8wfegyb/3/light/
  • http://plnkr.co/edit/bDBe0xGX1mCLzqYGOqOS?p=preview
  • http://bl.ocks.org/d3noob/9662ab6d5ac823c0e444
  • https://github.com/patorjk/d3-context-menu
  • http://plnkr.co/edit/bDBe0xGX1mCLzqYGOqOS?p=preview
  • http://jsfiddle.net/mnk/vfro9tkz/
  • http://www.d3noob.org/2014/01/tree-diagrams-in-d3js_11.html

 

 

Lire la suite

Publicités

Exercice 20 : Elaboration des Statistiques.

Introduction :


La partie la plus excitante de la programmation dans Supercours va être les statistiques(Ou en Anglais, Reporting). Dans un premier temps, on va assurer les statistiques générales, décomposées en :

1. Enumérations génériques, des infos simples mais toujours très utiles pour les décisionnaires.

2. Moyennes générales les plus utiles (Moyenne de Notes des élèves, Moyenne de présence en Cours, Moyenne des notes des élèves d’un professeur donné; et bien d’autres…

3. Pourcentages de remplissage des cours, pourcentages d’évolution d’inscriptions par dates. (Tout cela en graphiques fromages, ou en barres, avec des graphes en 3 dimension et j’en passe, le but est que ça pête visuellement !)

4. Ensuite on pourra commencer à penser à des choses plus compliquées du style : Stats prévisionnelles, Optimisation de remplissage des cours par algorithmes, Evaluations de Rentabilité d’un cours, etc … (Vu que je ne suis pas spécialiste, il faudra étudier un peu… Voir beaucoup…)

st1

Introduction au code:


Le but est d’effectuer des requêtes dans la base de données, puis de présenter les données à l’utilisateur. Ordonnancement : ->AFFICHAGE DE HTML

->JQUERY AJAX EXECUTE UN FICHIER PHP

->PHP LIT UNE REQUETE SQL

->JQUERY AJAX RECUPERE LE CONTENU DE LA REQUETE AU FORMAT JSON DANS SUCCESS(){}

-> JQUERY AFFICHE LES DONNEES EN HTML.

Description : Il y a le fichier HTML, le fichier JAVASCRIPT, et les fichiers PHP.

  • Le fichier HTML contient 2 DIV :La div du menu appelée « men1 » et la div destinée à recevoir les données et les graphiques appelée « infovue« .Chaque click sur un élément du menu HTML lance une fonction Javascript à l’aide de onclick= »Gx() » ou onclick= »Nx() », qui remets à jours en tous les cas la div « infovue« . Si c’est une fonction Gx(), le résultat sera un graphe; si c’est une fonction Nx() le résultat sera des chiffres.
  • Le fichier Javascript contient toutes les fonctions javascript AJAX tel que Gx() soit une fonction de génération de graphe, et Nx() une fonction de génération de chiffres.(avec x<n pour n= nombre de fonctions). (Note:La fonction Jquery Ajax peut aussi bien récupérer les données d’un fichier Json mais peut aussi afficher directement le contenu d’un fichier PHP directement dans le HTML)
  • Les fichiers PHP vont requêter la base de données avec les requêtes SQL appropriées, puis créent un objet JSON qui est récupéré dans la fonction de rappel de chaque fonction Javascript tel que Gx.php soit un fichier de génération de graphe, et Nx.php soit un fichier de génération de chiffres.( avec x<n pour n = nombre de fichiers)

Le code :

Voici le fichier HTML statsGen.html

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=iso-8859-15" />
</head>
<body>

<div id="men1" > 
        
        <ul class="sf-menu" id="example">
            <li class="current">
                <a href="">Enumérations<span class="ui-icon ui-icon-person"></a>
                <ul>
                    <li>
                        <a href="#" onclick="N1()">Chiffres</a>
                    </li>
                        <li class="current">
                            <a href="#">Graphiques</a>
                            <ul>
                                <li><a href="#"     onclick="G1()"    >Nombre de Professeurs par Catégories</a></li>
                                <li><a href="#"                    >Graphe 2</a></li>
                                <li><a href="#"                    >Graphe 3</a></li>
                                <li><a href="#"                    >Graphe 4</a></li> 
                            </ul>
                        </li>
                </ul>
            </li>
                
                <li class="current">
                <a href="">Moyennes<span class="ui-icon ui-icon-person"></a>
                <ul>
                    <li>
                        <a href="#" onclick="N2()">Chiffres</a>
                    </li>
                        <li class="current">
                            <a href="#">Graphiques</a>
                            <ul>
                                <li><a href="#"     onclick=""    >Graphe 1</a></li>
                                <li><a href="#"                    >Graphe 2</a></li>
                                <li><a href="#"                    >Graphe 3</a></li>
                                <li><a href="#"                    >Graphe 4</a></li> 
                            </ul>
                        </li>
                </ul>
            </li>
            
            <li>
                <a href="">Pourcentages<span class="ui-icon ui-icon-person"></a>
                <ul>
                    <li>
                        <a href=""></a>
                        <ul>
                            <li><a href="#"                     >Graphe 1</a></li>
                            <li><a href="#"                    >Graphe 2</a></li>
                            <li><a href="#"                    >Graphe 3</a></li>
                            <li><a href="#"                    >Graphe 4</a></li> 
                        </ul>
                    </li>
                    <li>
                        <a href="">menu item</a>
                        <ul>
                            <li><a href="#"                     >Graphe 1</a></li>
                            <li><a href="#"                    >Graphe 2</a></li>
                            <li><a href="#"                    >Graphe 3</a></li>
                            <li><a href="#"                    >Graphe 4</a></li> 
                        </ul>
                    </li>
                    <li>
                        <a href="">menu item</a>
                        <ul>
                            <li><a href="#"                     >Graphe 1</a></li>
                            <li><a href="#"                    >Graphe 2</a></li>
                            <li><a href="#"                    >Graphe 3</a></li>
                            <li><a href="#"                    >Graphe 4</a></li> 
                        </ul>
                    </li>
                
                </ul>
            </li>
            <li>
                <a href="">Optimisations<span class="ui-icon ui-icon-person"></a>
            </li>    
            <li>
                <a href="">Stats Dynamiques<span class="ui-icon ui-icon-person"></a>
            </li>    
        </ul>
</div> 

<div id='infovue'></div>

</body>




Le fichier Javascript classeStatsGen.js comprends les fonctions de type Nx() ou Gx(), elles contiennent des appels AJAX de type $.ajax() et traitent les données reçues grâce à leurs fonctions de rappel success().

function statsGen(){
    $( "#statsGen" ).dialog( "open" );// Ouverture de la fenetre des stats générales
    $("#statsGen").load('statsGen.html'); 
    var example = $('#example').superfish({
                //add options here if required
                });
 
}

 
 // Decomptes 
function N1(){

document.getElementById("charge").style.visibility="visible";
    $.ajax({
        type: "POST",
        url: "N1.php",
        dataType: "json", 
        success: function (dataStats) {
            window.dataStats = dataStats;
            $("#infovue").empty();
            $("#infovue").append('\
                                <b>Nombre de Cours :                </b>\
                                <span id="nbcours">                    </span><br>\
                            \
                                <b>Nombre d\'étudiants :            </b>\
                                <span id="nbetudiants">                </span><br>\
                            \
                                <b>Nombre de professeurs :            </b>\
                                <span id="nbprofs">                    </span><br>\
                            \
                                <b>Nombre de documents hébergés :    </b>\
                                <span id="nbdocsheb">                </span><br>\
                            \
                                <b>Nombre d\'inscrits dans les cours:</b>\
                                <span id="nbinscrits">                </span><br>\
                                ');
            $("#nbcours").html        (dataStats[0].nbCours);
            $("#nbetudiants").html    (dataStats[1].nbEtudiants);
            $("#nbprofs").html        (dataStats[2].nbProfesseurs);
            $("#nbdocsheb").html    (dataStats[3].nbDocumentsCours); 
            $("#nbinscrits").html    (dataStats[4].nbInscrits); 
            document.getElementById("charge").style.visibility="hidden";
        }
    });

}

// Moyennes
function N2(){

document.getElementById("charge").style.visibility="visible";
    $.ajax({
        type: "POST",
        url: "N2.php",
        dataType: "json", 
        success: function (dataStats) {
            window.dataStats = dataStats;
            $("#infovue").empty();
            //Age Moyen des étudiants:
            $("#infovue").append('<b>Age Moyen des étudiants: </b>');
            $("#infovue").append(dataStats[0].ageMoyen);
            $("#infovue").append('<br>');
            //Paiement Moyen des étudiants: 
            $("#infovue").append('<b>Paiement Moyen des étudiants: </b>');
            $("#infovue").append(dataStats[1].paiementMoyen);
            $("#infovue").append(' Euros');
            $("#infovue").append('<br>');
            //Moyenne Etudiants Max par Cours
            $("#infovue").append('<b>Moyenne du nombre d\'Etudiants Max par Cours: </b>');
            $("#infovue").append(dataStats[2].nbemaxMoyen);
            $("#infovue").append(' Etudiants au maximum par Cours');
            $("#infovue").append('<br>');
            
            document.getElementById("charge").style.visibility="hidden";
        }
    });

}


function G1(){
$("#infovue").empty();
document.getElementById("charge").style.visibility="visible";
    $.ajax({    
            type: "POST",
            url: "G1.php",
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            success: function (response){
                                        plot = $.jqplot('infovue',response, {// La librairie Jqplot se sert de l'objet JSON response pour créer le graphique,celui-ci a été généré par G1.php.
                                             async: false,
                                            title:'Nombre de professeurs par Catégories :',
                                            seriesDefaults:{
                                            renderer:$.jqplot.BarRenderer,pointLabels: { show: true },
                                            rendererOptions: { varyBarColor: true }},    
                                            axes: {xaxis: {renderer: $.jqplot.CategoryAxisRenderer,}},
                                            });

            document.getElementById("charge").style.visibility="hidden";
            },
            failure: function (errMsg){
                                    $('#errorMessage').text(errMsg);  //errorMessage is id of the div
            }        
    })

};


Voici maintenant les fichiers PHP dont le nom correspond au nom de la fonction Javascript. Par Exemple, le fichier qui requête pour la génération du graphe Nombre de professeurs par Catégorie de Cours, il s’appelle G1.php et sa fonction Js associée est G1().


<?php
// Connexion à la BDD
include('connexionSql.php');
connexionSql();

/* --------------------------------------------------------Stat 6 : Nombre de professeurs par Catégorie de Cours----------------------------------------------------- */
$lectureSql5="SELECT distinct count(professeur.idcategcours) as decompte,categcours.nom as nom FROM professeur INNER JOIN categcours ON professeur.idcategcours=categcours.idcategcours group by professeur.idcategcours";
$lecture5 = mysql_query($lectureSql5) or die(mysql_error());

while ($col=mysql_fetch_array($lecture5)){ 
        $col[0]=intval($col[0]); 
        $tabGen[]=array($col[1],$col[0]);
};    

$tabAdded=json_encode($tabGen);
echo('['.$tabAdded.']');




Voici l’objet Json qu’on voit passer dans Firebug à la suite de l’exécution du script précédent : json1 Voici un autre exemple : N1.php est le fichier qui comprends des requêtes SQL de type count(), qui servent pour générer les Enumérations.

Sa fonction javascript relative est N1() dans le fichier Javascript: Le résultat de ces requêtes est placé dans un tableau PHP qui est converti en JSON à la fin du fichier PHP, pour être traité par la fonction de rappel de jquery.ajax() qui s’appelle success(dataStats). dataStats contient alors l’objet JSON, et donc toutes ses variables, qui deviennent accessibles dans la fonction success de jquery.ajax().


<?php
// Connexion à la BDD
include('connexionSql.php');
connexionSql();

// Initialisation du tableau
/* $tabGen = []; */


/* --------------------------------------------------------Stat 1 : Nombre de Cours----------------------------------------------------- */
$lectureSql="SELECT count(*) from cours  ";
$lecture = mysql_query($lectureSql) or die(mysql_error());
$row    = mysql_fetch_assoc($lecture);

// On remplit le tableau tabGen avec la Stat 1
foreach ($row as $value){
 $tabGen[]=array(
    "nbCours"        =>$value,
    );
}

/* --------------------------------------------------------Stat 2 : Nombre d'étudiants----------------------------------------------------- */

$lectureSql="SELECT count(*) from etudiant  ";
$lecture = mysql_query($lectureSql) or die(mysql_error());
$row    = mysql_fetch_assoc($lecture);

// On remplit le tableau tabGen avec la Stat 2
foreach ($row as $value){
 $tabGen[]=array(
    "nbEtudiants"        =>$value,
    );
}

/* --------------------------------------------------------Stat 3 : Nombre de professeurs----------------------------------------------------- */

$lectureSql="SELECT count(*) from professeur  ";
$lecture = mysql_query($lectureSql) or die(mysql_error());
$row    = mysql_fetch_assoc($lecture);

// On remplit le tableau tabGen avec la Stat 3
foreach ($row as $value){

 $tabGen[]=array(
    "nbProfesseurs"        =>$value,
    );
}

/* --------------------------------------------------------Stat 4 : Nombre de documents hébergés----------------------------------------------------- */

$lectureSql="SELECT count(*) from documentscours  ";
$lecture = mysql_query($lectureSql) or die(mysql_error());
$row    = mysql_fetch_assoc($lecture);

// On remplit le tableau tabGen avec la Stat 4
foreach ($row as $value){

 $tabGen[]=array(
    "nbDocumentsCours"        =>$value,
    );
}

/* --------------------------------------------------------Stat 5 : Nombre d'élèves inscrits----------------------------------------------------- */

$lectureSql="SELECT count(idetudiant) from listeetudiant";
$lecture = mysql_query($lectureSql) or die(mysql_error());
$row    = mysql_fetch_assoc($lecture);

// On remplit le tableau tabGen avec la Stat 5
foreach ($row as $value){

 $tabGen[]=array(
    "nbInscrits"        =>$value,
    );
}





echo json_encode($tabGen);

exit();


Voici l’objet Json qu’on voit passer dans Firebug à la suite de l’exécution du script précédent : json2 CONCLUSION :


Une fois que l’on a compris la logique de la génération des graphiques à l’aide de JSON, on peut envisager de créer des appllcations Sympas.

Les autres graphes -Google code- étant trèèèès esthétiques mais pas toujours faciles à créer et à gérer. La méthode énoncée ici va me permettre d’exploiter d’autres librairies de génération de graphes telles que D3.js, et cela avec une méthode structurée.

La méthode $.ajax() de Jquery: Avec la méthode jquery $.ajax(), on 2 choix

1. Afficher directement le contenu d’un fichier PHP dans le HTML avec un $.load(), ce qui est bien si un dév PHP a créé un super script.

2. Mais on peut aussi récupérer les variables du script PHP au format JSON et les traiter avec Javascript dans la fonction de rappel de $.ajax() success(reponse){]. En ce cas, reponse est un objet JSON qui comprends toutes les données récupérées par notre fichier PHP, et en ce cas on travaille en mémoire VIVE, avec toutes la vivacité de Javascript.

Note personelle : Contrairement à Commandis, les graphiques en barres ne sont plus générés à partir de fichiers en dur JSON, mais directement à partir de conversion à l’aide de la fonction php json_encode(), ça va bien plus vite.

Samedi 21 Février


Aujourd’hui, je vais créer un camembert de pourcentages statistiques avec la librairie Jqplot.js: cm Demain, j’en ferais d’autres avec Highcharts.js puis, plus tard, avec D3.js. On s’y prends la même manière que décrit précédemment, sauf que la requête SQL est naturellement différente, ainsi que la méthode Jqplot, qui, cette fois-ci, utilise $.jqplot.PieRenderer pour générer le graphique. La difficulté principale est la création de la requête SQL, qui fait appel à la logique. Le reste n’est que répétition. Je vais élaborer la requête Pourcentage d’étudiants inscrits par catégories :

Phase 1 : Créer le lien de menu qui appelle la méthode Ajax G7() : Fichier concerné :statsGen.html


 <li><a href="#" onclick="G7()" >Pourcentage d'étudiants inscrits par catégories</a></li>

Phase 2 : Elaborer la requête SQL puis, récupérer son résultat à l’aide du langage PHP, puis créer un objet JSON. Fichier concerné : G7.php

<?php
// Connexion à la BDD
include('connexionSql.php');
connexionSql();
/* --------------------------------------------------------Pourcentage etudiants par catégories------------------------------ */
$lectureSql="SELECT Distinct COUNT( idetudiant ) AS nbinscrits,categcours.nom,ROUND(COUNT(idetudiant)/(SELECT COUNT(*) FROM listeetudiant )*100)FROM listeetudiant LEFT JOIN cours ON listeetudiant.idcours=cours.idcours LEFT JOIN categcours ON cours.idcategcours=categcours.idcategcours GROUP BY cours.idcategcours ";
$lecture = mysql_query($lectureSql) or die(mysql_error());

while ($col=mysql_fetch_array($lecture)){ 
 
 $col[0]=intval($col[0]); 
 $tabGen[]=array($col[1],$col[0]);
};
echo json_encode($tabGen); 
exit();


Note : Lors de l’élaboration de la Rqt, je récupère 3 champs, mais ensuite, finalement, je n’en récupère que 2 lors de la boucle PHP. Lorsque je conçois les rqts, je les teste dans Mysql, ce qui fait que parfois, c’est utilise de garder quelques champs dans le SQL, mais j’aurais du l’enlever. 2ème note, dans la boucle PHP, il y a une conversion INT, sans cela Json mets les nombres entre guillemets, bien sur.

Phase 3: Le contenu de l’objet JSON est récupéré dans la méthode success de Jquery, et c’est dans cette méthode de rappel que j’exécute la librairie Jqplot.(Note : L’indendation n’a pas été reprise par wordpress) Fichier concerné : ClasseStatsGen.js


// Pourcentages
function G7(){
$("#infovue").empty();
document.getElementById("charge").style.visibility="visible";
$.ajax({
type: "POST",
url: "G7.php",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (response){
var plot2 = jQuery.jqplot ('infovue', [response],
{
seriesDefaults: {
renderer: jQuery.jqplot.PieRenderer,
rendererOptions: {
// Turn off filling of slices.
fill: false,
showDataLabels: true,
// Add a margin to seperate the slices.
sliceMargin: 4,
// stroke the slices with a little thicker line.
lineWidth: 5
}
},
legend: { show:true, location: 's' }
}
);
document.getElementById("charge").style.visibility="hidden";
},
failure: function (errMsg){
$('#infovue').append(errMsg); //infovue is id of the div
}
})
};

 

 

Mercredi 25 Février

 

Aujourd’hui, je vais élaborer une statistique avec un premier graphique HighCharts.js:

hc

 

C’est la somme des paiements des étudiants par mois (en Euros) pour une année donnée.

 

Comme d’hab, en PHASE 1, je crée un lien dans le menu qui pointe sur ma méthode Javascript G8() :


 <li><a href="#"  onclick="G8()" >Somme des Paiements par mois </a></li> 

 

Phase 2 : Je crée la requête SQL qui retourne la somme des paiements par mois :


SELECT sum( paiement ) , monthname( dateentree ) FROM etudiant WHERE year( dateentree ) =2014 GROUP BY month( dateentree )

A remarquer que cette requête retourne un tableau comme ceci :
tb1

 

On remarque donc que les mois ne sont pas cités lorsqu’il n’y a pas eu de paiement.

Par contrainte de temps, je m’en contente et adapte le graphique à cela , en Phase 3, en créant un premier appel ajax qui récupère les mois pour les nommer les colonnes.

Donc, toujours  pour la phase 2, comme d’hab je crée mon fichier PHP G8.php :


<?php
// Connexion à la BDD
include('connexionSql.php');
connexionSql();
/* --------------------------------------------------------Somme des Paiement par mois ----------------------------------------------------- */
$lectureSql="SELECT sum( paiement ) , monthname( dateentree ) FROM etudiant WHERE year( dateentree ) =2014 GROUP BY month( dateentree )";

$lecture = mysql_query($lectureSql) or die(mysql_error());

while ($col=mysql_fetch_array($lecture)){ 
 
 $col[0]=intval($col[0]); 

 $tabGen[]=array($col[1],$col[0]);
};


echo json_encode($tabGen);

exit();

sauf qu’en plus j’en crée un annexe G8mois.php pour récupérer facilement les titres des colonnes:


<?php

<?php
// Connexion à la BDD
include('connexionSql.php');
connexionSql();
/* --------------------------------------------------------Somme des Paiement par mois ----------------------------------------------------- */
$lectureSql="SELECT sum(paiement),monthname(dateentree) from etudiant group by month(dateentree)";
$lecture = mysql_query($lectureSql) or die(mysql_error());

while ($col=mysql_fetch_array($lecture)){ 
 
 

 $tabGen[]=array($col[1]);
};



echo json_encode($tabGen); 
exit();

 

En Phase 3, Je récupère le contenu des 2 fichiers PHP dans la fonction de rappel de Jquery Ajax, puis crée le graphe( Comme d’hab, wordpress ne reprends pas l’indentation, on ne comprends rien…) :


function G8(){
$("#infovue").empty();
document.getElementById("charge").style.visibility="visible";
$.ajax({ 
 type: "POST",
 url: "G8mois.php",
 dataType: "json",
 contentType: "application/json; charset=utf-8",
 success: function (mois){
 $.ajax({ 
 type: "POST",
 url: "G8.php",
 dataType: "json",
 contentType: "application/json; charset=utf-8",
 success: function (response){
 $(function () {
 $('#infovue').highcharts({
 chart: {
 type: 'column',
 margin: 75,
 options3d: {
 enabled: true,
 alpha: 10,
 beta: 25,
 depth: 70
 }
 },
 title: {
 text: 'Paiements par mois'
 },
 tooltip: {
 headerFormat: '<b>{point.key}</b><br>',
 pointFormat: '<span style="color:{series.color}">\u25CF</span> {series.name}: {point.y} / {point.stackTotal}'
 },
 
 subtitle: {
 text: 'Somme des paiements des étudiants par mois'
 },
 plotOptions: {
 column: {
 depth: 25
 }
 },
 xAxis: {
 categories: mois/* ['January', 'February', 'March', 'June', 'August','September','October','November'] */
 
 },
 yAxis: {
 title: {
 text: "Euros"
 }
 },
 series: [{
 name: 'Ventes',
 data: response,
 stack: 'Euros'
 
 }]
 });
 });

 document.getElementById("charge").style.visibility="hidden";
 },
 failure: function (errMsg){
 $('#infovue').append(errMsg); //infovue is id of the div
 } 
 })


 }
 });
};

pour conlure, on constate que les noms des mois sont en Anglais, pour les traduire, une solution est utiliser month( dateentree ) à la place de monthname( dateentree ) dans le sql, cela retourne des vars « int », de cette façon, on peut affecter chaque int à un nom en français en javascript.

Exercice 18 : « Classe » de Modification d’objets graphiques Javascripts live + Drag And Drop dans les objets

Introduction.

Aujourd’hui, je vais continuer mes expérimentations en matière de création d’objets Javascript.
J’ai eu une « vision » ah ah, d’un écran, comportant de multiples sous-objets dans des cases de même taille, qui seraient pour chacun modifiables par Drag and Drop, à l’aide de banques de données graphiques A tester ici

exo18-1

Tous les objets sont chargés en Mémoire vive sur une lecture ajax en BDD.

Chaque objet dispose alors de sa photo, d’un petit graphe, et de 3 ou 4 champs modifiables. Suite à la modification d’un objet, l’enregistrement modifie les variables de l’objet directement en mémoire, mais pas en base de données.

Enfin, une fois que l’utilisateur est satisfait de la modification de tous ces objets, il clique sur un bouton, qui enregistre le tout dans la base de donnée, en Ajax.

Cet organisation pourrait être très esthétique, pour un utilisateur qui voudrait par exemple contrôler l’état en temps réel des ventes d’un groupe d’objets, ou alors, dans une industrie par exemple, pouvoir changer à la volée les caractéristiques d’un élément particulier d’une machine, j’ajouterais que le fait de modifier un seul objet aura éventuellement une répercution immédiate sur les caractéristiques des autres objets.

Au sujet du code, cela va être un très bon exercice pour travailler la prog objet en Javascript qui ne comporte pas de classes.

Je vais donc finaliser cet exercice, avant de finaliser mes deux autres exercices du moment : l’exercice 11 (Commandis) et l’autre.

Je pense à créer les objets d’une Voiture.

Liens : 

http://t-templier.developpez.com/tutoriel/javascript/javascript-poo1/

https://developer.mozilla.org/fr/docs/Web/JavaScript/Guide/Le_mod%C3%A8le_objet_JavaScript_en_d%C3%A9tails

http://fr.wikipedia.org/wiki/Programmation_orient%C3%A9e_prototype

Modélisation UML2.0:

Pour cet exercice, je vais faire une prémodélisation UML que je vais afficher dans cet article.

J’adore UML2.0.

Mais tout d’abord, voici une petite description de ce qui va se passer lors du premier affichage des objets:

exo18

Prog en cours, jour par jour ….

Jour 1:

Finalement ça va assez vite : j’ai déjà fait le code pour l’affichage (une classe et Une méthode),et le style objet couplé à Jquery rends les choses vachement plus rapide :

A tester ce soir sur http://nicolash.org/exercice18Modificationobjet/

Index.html : Appelle les libs, et contient la seule DIV de l’exercice, qu’un APPEND JQUERY va remplir avec les formulaires. (Code Remis à jour le jour 5

<!DOCTYPE html>
<meta http-equiv="X-UA-Compatible" content="IE=edge" >	<meta charset="utf-8">
<html> 
<head>
<!-- -----------------------------------------------DEBUT DU CHARGEMENT DES LIBRAIRIES------------------------ -->
		<!--	APPEL LIB JQUERY -->
		<script	 type="text/javascript" src="librairies/jquery.js"></script>
		
		<!--	APPEL LIB JQUERY UI ( look sympa du programme) -->
		<script type="text/javascript" src="librairies/jquery-ui.js"></script>
		<link href="librairies/jquery-ui.css" rel="stylesheet" type="text/css" />
		<script type="text/javascript" src="librairies/jquery.dialogextend.js"></script>
		
		<!-- 	TOUCH Pour les tablettes Android-->
		<script src="librairies/jquery.ui.touch-punch.js" language="javascript"></script>

		<!--	CSS DU PROGRAMME -->
		<link rel="stylesheet" type="text/css" href="style.css" />

		<!-- 	FONCTIONS PERSONNELLES-->
		<script src="fonctionsMachines.js" language="javascript"></script>
		<script src="images.js" language="javascript"></script>
<!-- ----------------------------------------------FIN DU CHARGEMENT DES LIBRAIRIES------------------------ -->
</head>

<body>
<!--zone du petit gif animé AJAX-->
<img id="charge" src="chargeur.gif" width=100px  />
<div id="objet" title="Ma Liste d'Objets" >
<div id="total"></div>
<div id="share"></div>
<div id="images" title="Ma Banque d'Images" ></div>
</body>
</html>

lectureBdd.php. Les données sont le fichier JSON qui ont été générées par le fichier suivant :

<?php
// Ce tableau est censé être le résultat d'une requête SQL :
$employe = array(
    array(
        "nom" => "jante",
        "type" => "piece",
		"photo" => "jante.jpg",
		"taille" => "16",
		"prix" => "121"
    ),
    array(
        "nom" => "capot",
        "type" => "piece",
		"photo" => "capot.jpg",
		"taille" => "na",
		"prix" => "200"
    ),
   array(
        "nom" => "Pare Brise",
        "type" => "piece",
		"photo" => "parebrise.jpg",
		"taille" => "na",
		"prix" => "320"
    ),
);

// On encode en JSON,le format compréhensible par Javascript et par d'autres langages...
echo json_encode($employe); 
exit();

fonctionsMachines.js : EDIT JOUR 5
Et enfin le plus gros du travail, le fichier Moteur qui contient des « classes » javascript (oui je sais, les classes javascripts n’existent pas…). C’est le fichier qui crée les objets, et les manipule avec de méthodes, un peu comme PHp OBJET ou Java sauf que c’est du Javascript-JQUERY.

/* ------------------------------------------------------------------------------------------------------- */
/*  LECTURE EN BDD ET RECUPERATION DES VARIABLES DE CHAQUE OBJET DANS LE  FICHIER JSON */
$.ajax({
    type: "POST",
    url: "lectureBdd.php",
    dataType: "json", 
    success: function (data) {
	creerObjets(data);
	}
});
/* -------------------------------------------------------------------------------------------------------	 */




function creerObjets(data){
	
	//CREATION DES OBJETS JAVASCRIPT A PARTIR DES DATAS DU FICHIER JSON
	window.objet = 0;
	window.objet = [];
	for (var id=0; id < data.length; id++){
	objet[id] = new Objet([id],data[id].nom,data[id].type,data[id].photo,data[id].taille,data[id].prix); 
	}	
	window.objet=objet; // Rends les objets globaux sur le scope mais seulement dans les fonctions à cause de l'asynchronicité d'ajax
	//AFFICHAGE DES OBJETS JAVASCRIPT : ILS SONT PASSES EN PARAMETRE A LA FONCTION AFFICHEOBJETS() QUI LES AFFICHE
	afficherObjets(objet);
	afficherBanqueImage();
}




function afficherObjets(objet){
	$("#total").empty();
	$("#total").append('<b>Nom de la Liste : </b>');
	$("#total").append('<br>');
	$("#total").append('Liste 1');
	$("#total").append('<br>');
	$("#total").append('<br>');
	$("#total").append('<b>Liste des Objets : </b>');
	prixGeneral=0;
    // BOUCLE QUI TOUS AFFICHE LES OBJETS EN HTML A LAIDE DE LA METHODE PRINT DE LOBJET Objet
	for (var id=0; id < objet.length; id++){
	objet[id].print(); 
	//Total Prix
	prix=objet[id].prix;
	window.prixGeneral=Number(prixGeneral)+Number(prix);
	nom=objet[id].nom;
	$("#total").append('<br>');
	$("#total").append(nom);
	}	
	$("#total").append('<br>');
	$("#total").append('<br>');
	$("#total").append('<b>Cout total des objets :</b>');
	$("#total").append('<br>');
	$("#total").append(''+prixGeneral+' Euros<br>');




}




function ajouterObjet(){
	var nbObjets = objet.length;
	var nouvelObjet = nbObjets;
	/* alert (nouvelObjet); */
	objet[nouvelObjet]= new Objet(nouvelObjet,"nouveau","nouveau","nouveau.jpg",0,0);




	$("#share").empty();
	afficherObjets(objet);
	$("#images").empty();
	afficherBanqueImage();
}








/* 
-----------------------------------------CLASSE CREATION -------------------------------------------------- */
/* ON TRANSMETS LES VARIABLES A LA "CLASSE" CREATION QUI VA CREER LES FORMULAIRES(oui je sais en javascript cela n'existe pas officiellement, mais c'est similaire)*/




/* CONSTRUCTEUR DE LA CLASSE CREATION */
function Objet(id,txtNom,txtType,txtPhoto,txtTaille,txtPrix){
	this.id=id;
	this.nom=txtNom;
	this.type=txtType;
	this.photo=txtPhoto;
	this.taille=txtTaille;
	this.prix=txtPrix;
	this.print=affForm;
	}




/* Méthode de la classe creation qui créée automatiquement un formulaire HTML avec JQUERY APPEND */
/* On ré-injecte les variables objet dedans et on crée à la volée un formulaire dynamique! */
/* Chaque formulaire dispose de son ID qui correspond à l'id de l'objet */




function affForm(){
	var id=this.id;
	var nom=this.nom;
	var prix=this.prix;
	var taille=this.taille;
	var divid = 'div'+id;
	var divModifId = 'divModif'+id;
	var savebutton= 'savebutton'+id;
	var formulaire='formulaire'+id;
	var modifierObjetId='modifierObjet'+id;




	/* LES INPUTS TEXT*/
	var inputNom='nom'+id;
	var inputTaille='taille'+id;
	var inputPrix='prix'+id;
	/* var importPhoto='importPhoto'+id; 








/* CREATION DU FORMULAIRE: */
/* http://stackoverflow.com/questions/17431760/create-a-form-dynamically-with-jquery-and-submit */
	$("#share").append('<form action="upload.php" method="POST" enctype="multipart/form-data" id="'+formulaire+'">');
	$("#share").append('<div style="font-size:1em; border-top: medium solid grey;border-bottom: medium solid grey;border-left: medium solid grey;border-right: medium solid grey;background-color:white;"class="presentation"><img src="images/'+this.photo+'" title="'+this.photo+'" height=70px width=70px><b>Objet numero : </b>'+this.id+'<b> Nom:</b> '+nom+   '     <b>  Taille:</b>'+this.taille+   '  <b>   Prix=</b>'+this.prix+ ' Euros  <br><input type="submit" id="'+modifierObjetId+'" value="Modifier l\'objet " " /></div>');
	
	$("#share").append('<div id="'+divModifId+'" style="font-size:1em; border-top: medium solid grey;border-bottom: medium solid grey;border-left: medium solid grey;border-right: medium solid grey;background-color:white;">');
	$("#"+divModifId+"").append('<br><br><br><b>Modifier L\'Objet:</b><br><br>');
	$("#"+divModifId+"").append('Nom : <input class="input" type="text" placeholder="'+this.nom+'"  id="'+inputNom+'" name="'+inputNom+'" /></br>');
	$("#"+divModifId+"").append('Taille :<input class="input" type="text" placeholder="'+this.taille+'"  id="'+inputTaille+'" /></br>');
	$("#"+divModifId+"").append('Prix   :<input class="input" type="text" placeholder="'+this.prix+'" Euros" id="'+inputPrix+'"  /></br>');
	$("#"+divModifId+"").append('<br>Faire glisser la nouvelle photo:');
	$("#"+divModifId+"").append('<div id='+divid+' style="height:90px;width:100px;background-color:white" class="ui-widget-header" >');
	$("#"+divModifId+"").append('<br><input type="submit" id="'+savebutton+'" value="Modifier" />');
	$("#share").append('</div><br><br></div>'); 
	$("#share").append('--------------------------------------------------------------------------------------------'); 




	// ON CACHE LA DIV DE MODIFICATION DE LOBJET 
	$("#"+divModifId+"").hide();
	$( "#"+modifierObjetId+"").click(function() {
	$("#"+divModifId+"").show();
	});
	
	// ON CONTROLE LES CHAMPS DU FORMULAIRE
	$("#"+savebutton+"").prop('disabled', true); 
	$(document).ready(function(){
	$('input[name='+inputNom+']').blur(function(){
		if($(this).val().length == 0){
		$("#"+savebutton+"").prop('disabled', true);
		}
		else {
			$("#"+savebutton+"").prop('disabled', false);
		}
	});
	});
  
   /* ON RECUPERE LES VARIABLES DES DIFFERENTS FORMS SUR EVENEMENT CLICK  */
	$( "#"+savebutton+"").click(function() {
	
	var nom = $("#"+inputNom+"").val();
	var taille = $("#"+inputTaille+"").val();
	var prix = $("#"+inputPrix+"").val();




	/* MODIFIER LES VALEURS DES OBJETS */
	objet[id].nom=nom; 
	objet[id].taille=taille; 
	objet[id].prix=prix; 
	
	/* RESSETTER LES OBJETS GRAPHIQUEMENT */
	$("#share").empty();
	afficherObjets(objet);
	$("#images").empty();
	afficherBanqueImage();
	
	});
}




 
function afficherBanqueImage(){
 document.getElementById("charge").style.visibility="visible";
/* ------------------------------------------------------------------------------------------------------- */
/* RECUPERATION DE LA BANQUE DIMAGE POUR LE DRAG AND DROP */
$.ajax({
	
    type: "POST",
    url: "banqueImages.php",
    dataType: "json", 
    success: function (data) {
		 
		image=[];
		for (var id=0; id < data.length; id++){
			image = data[id].photo;
			$("#images").append('<img src="images/'+image+'" id="'+id+'" class="ui-widget-content" title="Faites un Glisser-Deposer de  '+image+' vers votre objet" height=70px width=70px /></div>');// Fait apparaitre chaque image dans la fenêtre et attribue un id à chaque image
			$("#"+id+"").draggable( {helper:'clone',appendTo: '#share',scroll: false}); // Rends chaque image draggable
			$("#div"+id+"").droppable({ // Permet de pouvoir dropper chaque image dans l'objet voulu.
							hoverClass: "ui-state-active",
							tolerance: 'fit',
							drop: function(event, ui) {
							$( this )
								.addClass( "ui-state-highlight" )
								.find( "p" )
								.html( "Dropped!" );
								var id = ui.draggable.attr("id");
								// On récupère l'url de la photo que lon a droppé.
								url=data[id].photo;
								alert(url);
								var thisDiv = ($(event.target).attr('id'));
								$("#"+thisDiv+"").empty();
								$("#"+thisDiv+"").append('<img src="images/'+url+'" title="'+url+'" height=70px width=70px />');
								numeroObjet=thisDiv.replace(/div/, ""); // retrouve le numéro de l'objet pour le modifier
								objet[numeroObjet].photo=url; // Modifie l'url de la photo de l'objet
								
								}
							
			}); 
			document.getElementById("charge").style.visibility="hidden";	
		}		
	}
});




}












/* ----------------------------------------------------------- FENETRAGE--------------------------------------------*/








$(document).ready(function() {
















	$(function() {
		$( "#objet" ).dialog({width:500,autoOpen: true,draggable: true,appendTo: 'body'}).dialogExtend({
				"closable" : false,
				"maximizable" : true,
				"minimizable" : true,
				"collapsable" : true,
				"dblclick" : "collapse",
				"minimizeLocation" : "right",
				});
	});












	$(function() {
		$( "#images" ).dialog({width:300,height:400,autoOpen: true,draggable: true,appendTo: 'body'}).dialogExtend({
				"closable" : false,
				"maximizable" : true,
				"minimizable" : true,
				"collapsable" : true,
				"dblclick" : "collapse",
				"minimizeLocation" : "right",
				});
	});




});

Jour 3 :

J’ai revu un peu le CSS:
http://nicolash.org/exercice18Modificationobjet/

Aujourd’hui, je vais essayer d’ajouter la possibilité de modifier la photo des sous objets,
et d’ajouter un sous objet.

Je dois avouer que la prog est assez rude, car je n’ai pas réussi à passer les objets dans le scope de base, c’est à dire que les vars des objets ne sont pas accessibles de l’extérieur des fonctions concernées, ce qui complique beaucoup la simplification du code et la clarification du code. Je n’arrive pas à créer des fonctions explicites et bien claires, afin qu’il soit simple de comprendre et débugger le code. Lacunes de théorie, sans doute.

Par contre, ça va être très sympa à la fin, car on va pouvoir se créer ses propres objets en cliquant sur un icône ‘créer mon objet’, y inclure ses sous objets et leurs caractéristiques, puis stocker l’objet dans la base de donnée. Ensuite, il y aura un icone « Visionner la liste des objets…

Mais cela devient de plus en plus difficile, bon… continuons déjà avec la possiblité de changer la photo, ce qui ne va pas être de la tarte ! Je pense que je vais essayer de placer du plug dropzone… Il va aussi falloir ajouter le contrôle sur les champs … Bref, ça porte plus loin que prévu…

Ah et dernière idée : Lors de l’actualisation de la liste des objets, une copie de l’objet originel devrait être faite, afin d’avoir un historique, dont je me servirais pour incrémenter les futurs graphes…

En réalisant ces exercices, je conçois que JQUERY permet de créer des DIVS à la volée, dans le DOM, ce qui est très pratique !! En insérant cette fonctionnalité dans une boucle, je crée les noms des divs dynamiquement !

Jour 4:

Hier, j’ai bien avancé, chaque objet a désormais un bouton qui permet la mise à jour de sa photo en live, + MAJ de la var objet. Cela ne fonctionne pas encore en ligne à cause du CHMOD de l’image téléchargée sur le ftp. Je n’utilise pas de plug in, mais Jquery couplé à HTML 5, une fois que l’on a pigé le truc c’est assez simple… Mais cela a pris du temps!

Par contre, entre temps, je me suis rendu compte que c’était très lourd et un peu archaïque, du coup je me suis dit  » Et si les objets pouvaient être modifiés à l’aide de DRAG AND DROP, à la façon des jeux vidéos ? Du coup j’ai commencé à créer une banque d’image, que l’on va pouvoir « Dragger » vers les objets afin de les modifier… Ce qui va être très moderne ! Bien sur la banque d’image sera elle aussi modifiable à volonté.

C’est là que je commence à ressentir un peu les effets de la prog objet en Javascript, même si elle est balbutiante.

Car à terme, ce ne sera pas qu’une banque d’image que l’on pourra dragger et dropper, mais aussi des modèle de graphes ! On se rends compte alors de la puissance du truc… Mais aussi de sa complexité, car il faut garder un code le plus clair possible, et sans la possibilité d’établir des classes bien déterminée, c’est assez difficile.

Bref, aujourd’hui, je vais donc essayer de faire fonctionner le Drag And Drop d’image dans les objets, ainsi que le fait de pouvoir incrémenter la banque de données d’image, la seconde étape est également de pouvoir incrémenter le nombre d’objets dans un objet général.

Jour 5:
Comme d’hab, wordpress a buggué et m’a inséré des caractères erronés dans le code de base que j’avais publié le jour 1, j’ai la haine, d’autant plus que je n’historise pas.

Bref tant pis je remets à jour avec la version en cours… C’est vraiment de l’expérimental, avec des accés ajax pas triés ni rien… Donc, pas à prendre en exemple mais cela marche. C’est pour ça que le code de base était bien car il n’y avait que la base.

j’ai trouvé un plug in pour faire marcher le drag and drop sur les navigateurs Android ! Ca va vraiment péter à la fin parce que ce sera super dynamique! Merci à jakecigar sur le forum Jquery. https://github.com/furf/jquery-ui-touch-punch

Ca ne marche toujours pas sur firefox user Agent I.E 8, mais cela fonctionne sur Android !
Par contre, ça rame pas mal sur ma tablette mais cela reste utilisable ! Pour les prochains exercices, je vais abandonner Jquery Dialog comme fenêtrage…

Je vais d’abord faire marcher le système, puis ensuite, je réfléchirai à comment organiser le code pour le rendre le plus clair et organisé possible, et à le compresser.

J’aimerais savoir si il est possible de faire de l’héritage comme en Java, car pour l’instant je vois pas comment faire. C’est super embétant de pas pouvoir écrire class machin {} !

y’a des trucs vraiment pas beaux dans le code par exemple à la ligne 36 : Prix total ah ah, on se demande ce que ça fout là ! Mais c’est juste pour tester.

Jour 6 :

J’ai revu le code aujourd’hui au menu :
-> Affectation des variables de la banque d’image aux objets, après un glissé déposé = OK
-> Contrôle basique d’entrées utilisateur sur les Inputs = OK.
-> Possibilité d’ajout d’un objet en mémoire RAM= OK. (Super bien! C’est là qu’on voit que c’est de la prog Objet, car il n’y a pas de limite , on peut cliquer 10 fois sur le bouton si on veut !)
– Fonction JQUERY HIDE et SHOW qui permet de cacher/monter la div de modification d’un objet.

Ensuite, j’ai eu l’idée de faire du drag and drop sur des éléments de base de données comme par exemple une liste de producteurs que l’on peut associer à un objet en faisant un glissé déposé.Je vais aussi essayer de faire du drag and drop de graphes après… Je ne sais pas encore trop comment.

Le but final est d’obtenir un logiciel très moderne pouvant fonctionner sur tablette, basé sur le drag and drop, mais un logiciel de bureautique.

A la fin, il faudra être en mesure de sauvegarder la liste de l’objet en BDD, bien sur.
J’ai essayé de mettre un JQUERY ACCORDION à l’endroit ou on modifie l’objet, mais j’ai aps encore réussi,cela sera plus esthétique.
L’utilisateur cliquera sur un liste, puis pourra la modifier à loisir à l’aide du drag and drop, y ajouter des objets, puis la sauvegarder.

Ce que je trouve super cool, c’est de travailler uniquement en mémoire vive, comme si c’était un vrai programme, c’est clair que cela n’a plus rien à voir avec de simples pages HTML, d’ailleurs la complexité au niveau des variables est parfois réelle. Car on ne travaille qu’avec des variables dynamiques

Pour conclure; il y a quand même un big pb, pour l’instant, lorsque l’on sauvegarde un objet en RAM, cela relance l’appel ajax de la banque d’images. C’est à modifier.

Pour la Banque d’image, il va falloir rajouter l’uploader, et une possibilité de tri, mais cela ne devrait pas être très dur, seulement il va falloir se taper toute la création de la BDD …

Pour conclure pour aujourd’hui, je vais « transmuter » l’exercice 18 en un exercice de réservation de salle de Cours, ça va être top avec le drag and drop.

Jour 7 :

Petit passage une heure aujourd’hui sur le prog. J’ai regroupé tous les accès AJAX en début de script, j’ai ainsi éliminé le problème d’accès AJAX permanent sur la banque de photos qui était un non sense.
J’ai enfin trouvé comment facilement créer des tableaux accessibles sur le scope Global, en utilisant PUSH … ça m’ouvre de grandes perspectives !
Car je vais pouvoir créer des applications objets très dynamiques et facilement, avec des objets possédant un très grand nombre de variable, et pas mal d’intéractions.
Une fois qu’on a compris comment gérer l’asynchronicité d’AJAX, et que l’on peut créer des objets et des tableaux en RAM, on peut envisager la création d’applications de style OBJET robustes. je me demande comment un jour je pourrais en plus tirer partie de JAVA la dedans ? Car on pourrait très bien ne faire que du JAVASCRIPT-NODES.


/* Déclaration des tableaux de variables sur le scope Global : */
window.bqImages=[];

/* -------------------------------------CONNEXIONS AJAX          ----------------------------------------- */
/*  LECTURE EN BDD ET RECUPERATION DES VARIABLES DE CHAQUE OBJET DANS LE  FICHIER JSON */
$.ajax({
    type: "POST",
    url: "lectureBdd.php",
    dataType: "json", 
    success: function (data) {
	creerObjets(data);
	}
});
/* ------------------------------------------------------------------------------------------------------- */
/* RECUPERATION DE LA BANQUE DIMAGE POUR LE DRAG AND DROP */
$.ajax({
	type: "POST",
    url: "banqueImages.php",
    dataType: "json", 
    success: function (data) {
	for (var id=0; id < data.length; id++){
	bqImages.push(data[id].photo);// Création du tableau des urls des images sur le scope global, marche bien avec PUSH, pas avec les []
	}
	maintienImages(bqImages)	;
	}
});
/* -------------------------------------------------------------------------------------------------------	 */


function creerObjets(data){
	
	//CREATION DES OBJETS JAVASCRIPT A PARTIR DES DATAS DU FICHIER JSON
	window.objet = 0;
	window.objet = [];
	for (var id=0; id < data.length; id++){
	objet[id] = new Objet([id],data[id].nom,data[id].type,data[id].photo,data[id].taille,data[id].prix); 
	}	
	window.objet=objet; // Rends les objets globaux sur le scope mais seulement dans les fonctions à cause de l'asynchronicité d'ajax
	//AFFICHAGE DES OBJETS JAVASCRIPT : ILS SONT PASSES EN PARAMETRE A LA FONCTION AFFICHEOBJETS() QUI LES AFFICHE
	afficherObjets(objet);
}

function afficherObjets(objet){
	$("#total").empty();
	$("#total").append('<b>Nom de la Liste : </b>');
	$("#total").append('<br>');
	$("#total").append('Liste 1');
	$("#total").append('<br>');
	$("#total").append('<br>');
	$("#total").append('<b>Liste des Objets : </b>');
	prixGeneral=0;
    // BOUCLE QUI TOUS AFFICHE LES OBJETS EN HTML A LAIDE DE LA METHODE PRINT DE LOBJET Objet
	for (var id=0; id < objet.length; id++){
	objet[id].print(); 
	//Total Prix
	prix=objet[id].prix;
	window.prixGeneral=Number(prixGeneral)+Number(prix);
	nom=objet[id].nom;
	$("#total").append('<br>');
	$("#total").append(nom);
	}	
	$("#total").append('<br>');
	$("#total").append('<br>');
	$("#total").append('<b>Cout total des objets :</b>');
	$("#total").append('<br>');
	$("#total").append(''+prixGeneral+' Euros<br>');

}

function ajouterObjet(){
	var nbObjets = objet.length;
	var nouvelObjet = nbObjets;
	/* alert (nouvelObjet); */
	objet[nouvelObjet]= new Objet(nouvelObjet,"nouveau","nouveau","nouveau.jpg",0,0);

	$("#share").empty();
	afficherObjets(objet);
	$("#images").empty();
	maintienImages(bqImages);
}


/* 
-----------------------------------------CLASSE CREATION -------------------------------------------------- */
/* ON TRANSMETS LES VARIABLES A LA "CLASSE" CREATION QUI VA CREER LES FORMULAIRES(oui je sais en javascript cela n'existe pas officiellement, mais c'est similaire)*/

/* CONSTRUCTEUR DE LA CLASSE CREATION */
function Objet(id,txtNom,txtType,txtPhoto,txtTaille,txtPrix){
	this.id=id;
	this.nom=txtNom;
	this.type=txtType;
	this.photo=txtPhoto;
	this.taille=txtTaille;
	this.prix=txtPrix;
	this.print=affForm;
	}

/* Méthode de la classe creation qui créée automatiquement un formulaire HTML avec JQUERY APPEND */
/* On ré-injecte les variables objet dedans et on crée à la volée un formulaire dynamique! */
/* Chaque formulaire dispose de son ID qui correspond à l'id de l'objet */

function affForm(){
	var id=this.id;
	var nom=this.nom;
	var prix=this.prix;
	var taille=this.taille;
	var divid = 'div'+id;
	var divModifId = 'divModif'+id;
	var savebutton= 'savebutton'+id;
	var formulaire='formulaire'+id;
	var modifierObjetId='modifierObjet'+id;

	/* LES INPUTS TEXT*/
	var inputNom='nom'+id;
	var inputTaille='taille'+id;
	var inputPrix='prix'+id;
	/* var importPhoto='importPhoto'+id; 


/* CREATION DU FORMULAIRE: */
/* http://stackoverflow.com/questions/17431760/create-a-form-dynamically-with-jquery-and-submit */
	$("#share").append('<form action="upload.php" method="POST" enctype="multipart/form-data" id="'+formulaire+'">');
	$("#share").append('<div style="font-size:1em; border-top: medium solid grey;border-bottom: medium solid grey;border-left: medium solid grey;border-right: medium solid grey;background-color:white;"class="presentation"><img src="images/'+this.photo+'" title="'+this.photo+'" height=70px width=70px><b>Objet numero : </b>'+this.id+'<b> Nom:</b> '+nom+   '     <b>  Taille:</b>'+this.taille+   '  <b>   Prix=</b>'+this.prix+ ' Euros  <br><input type="submit" id="'+modifierObjetId+'" value="Modifier l\'objet " " /></div>');
	
	$("#share").append('<div id="'+divModifId+'" style="font-size:1em; border-top: medium solid grey;border-bottom: medium solid grey;border-left: medium solid grey;border-right: medium solid grey;background-color:white;">');
	$("#"+divModifId+"").append('<br><br><br><b>Modifier L\'Objet:</b><br><br>');
	$("#"+divModifId+"").append('Nom : <input class="input" type="text" placeholder="'+this.nom+'"  id="'+inputNom+'" name="'+inputNom+'" /></br>');
	$("#"+divModifId+"").append('Taille :<input class="input" type="text" placeholder="'+this.taille+'"  id="'+inputTaille+'" /></br>');
	$("#"+divModifId+"").append('Prix   :<input class="input" type="text" placeholder="'+this.prix+'" Euros" id="'+inputPrix+'"  /></br>');
	$("#"+divModifId+"").append('<br>Faire glisser la nouvelle photo:');
	$("#"+divModifId+"").append('<div id='+divid+' style="height:90px;width:100px;background-color:white" class="ui-widget-header" >');
	$("#"+divModifId+"").append('<br><input type="submit" id="'+savebutton+'" value="Modifier" />');
	$("#share").append('</div><br><br></div>'); 
	$("#share").append('--------------------------------------------------------------------------------------------'); 

	// ON CACHE LA DIV DE MODIFICATION DE LOBJET 
	$("#"+divModifId+"").hide();
	$( "#"+modifierObjetId+"").click(function() {
	$("#"+divModifId+"").show();
	});
	
	// ON CONTROLE LES CHAMPS DU FORMULAIRE
	$("#"+savebutton+"").prop('disabled', true); 
	$(document).ready(function(){
	$('input[name='+inputNom+']').blur(function(){
		if($(this).val().length == 0){
		$("#"+savebutton+"").prop('disabled', true);
		}
		else {
		$("#"+savebutton+"").prop('disabled', false);
		}
	});
	});
  
   /* ON RECUPERE LES VARIABLES DES DIFFERENTS FORMS SUR EVENEMENT CLICK  */
	$( "#"+savebutton+"").click(function() {
	
	var nom = $("#"+inputNom+"").val();
	var taille = $("#"+inputTaille+"").val();
	var prix = $("#"+inputPrix+"").val();

	/* MODIFIER LES VALEURS DES OBJETS */
	objet[id].nom=nom; 
	objet[id].taille=taille; 
	objet[id].prix=prix; 
	
	/* RESSETTER LES OBJETS GRAPHIQUEMENT */
	$("#share").empty();
	afficherObjets(objet);
	$("#images").empty();
	maintienImages(bqImages);
	
	});
}


function maintienImages(data){
	 document.getElementById("charge").style.visibility="visible";
	console.log(data);
	for (var id=0; id < data.length; id++){
	image = data[id];
		$("#images").append('<img src="images/'+image+'" id="'+id+'" class="ui-widget-content" title="Faites un Glisser-Deposer de  '+image+' vers votre objet" height=70px width=70px /></div>');// Fait apparaitre chaque image dans la fenêtre et attribue un id à chaque image
		$("#"+id+"").draggable( {helper:'clone',appendTo: '#share',scroll: false}); // Rends chaque image draggable
		$("#div"+id+"").droppable({ // Permet de pouvoir dropper chaque image dans l'objet voulu.
							hoverClass: "ui-state-active",
							tolerance: 'fit',
							drop: function(event, ui) {
							$( this )
								.addClass( "ui-state-highlight" )
								.find( "p" )
								.html( "Dropped!" );
								var id = ui.draggable.attr("id");
								// On récupère l'url de la photo que lon a droppé.
								url=data[id];
								alert(url);
								var thisDiv = ($(event.target).attr('id'));
								$("#"+thisDiv+"").empty();
								$("#"+thisDiv+"").append('<img src="images/'+url+'" title="'+url+'" height=70px width=70px />');
								numeroObjet=thisDiv.replace(/div/, ""); // retrouve le numéro de l'objet pour le modifier
								objet[numeroObjet].photo=url; // Modifie l'url de la photo de l'objet
								
								}
							
			});
		document.getElementById("charge").style.visibility="hidden";	
		}		
}

/* ----------------------------------------------------------- FENETRAGE--------------------------------------------*/

$(document).ready(function() {
$(function() {
		$( "#objet" ).dialog({width:500,autoOpen: true,draggable: true,appendTo: 'body'}).dialogExtend({
				"closable" : false,
				"maximizable" : true,
				"minimizable" : true,
				"collapsable" : true,
				"dblclick" : "collapse",
				"minimizeLocation" : "right",
				});
	});
$(function() {
		$( "#images" ).dialog({width:300,height:400,autoOpen: true,draggable: true,appendTo: 'body'}).dialogExtend({
				"closable" : false,
				"maximizable" : true,
				"minimizable" : true,
				"collapsable" : true,
				"dblclick" : "collapse",
				"minimizeLocation" : "right",
				});
	});
});

Exercice 17 : Création de la vue  » Pourcentages d’Evolutions  » de l’exercice 11 avec une boucle FOR.

Introduction

Il faut donc que l’utilisateur de l’exercice 11(Commandis) soit capable de visualiser les Pourcentages d’évolution du prix d’un objet quelconque en tapant sa référence. (Il est aidé pour cela par un JQUERY AUTOCOMPLETE, lorsqu’il tape dans le champs.). Il doit aussi visualiser la date de changement du pourcentage d’évolution du prix dans le graphe qui va se générer. Comme d’hab, il s’agit d’un pseudo MVC avec AJAX->VUE->GENEREJSON-GENEREGRAPHE

Ma méthode pour y arriver :

Tout d’abord, je lis le théorème des pourcentages d’évolution dans un livre de PREBABAC 1ère ES de Nathan Copyright 2008:

maths1

Ensuite, vu qu’il n’y a pas d’UML2.0, je pense les variables mathématiques dans le contexte de l’exercice 11, un peu à l' »arrache ». Comme d’hab, faut remplacer les var mathématiques par des vars « informatiques »… La difficulté ici, est que nous n’avons pas qu’un seul pourcentage d’évolution à calculer, mais un tableau …D’ou l’idée de la boucle For.

L' »ordonnancement » du traitement dans la vue sera donc celui-ci (J’ai choisi cela) :

1. Une Requête SQL en Lecture sous le critère référence de l’objet, qui va donc chercher tous les prix d’un objet puis les trie par date.

2. Création de 3 tableaux
-Les dates
-les Prix
-Et une copie du tableau prix.
Ceux ci sont en quelque sorte « synchronisés  » de par leur ids qui sont identiques, ce qui va permettre de réassembler le tableau des dates et celui des pourcentages $Pe qui aura été généré.

3. L’idée est d’avoir 2 tableaux des prix identiques afin de pouvoir traiter à l’aide d’une boucle for les variables PRIX  » de départ » et PRIX « d’arrivée ». Ensuite, je crée mon pourcentage et l’injecte dans un nouveau tableau de pourcentage $Pe dans la boucle for qui sera ensuite collé à mon tableau de date $tabDates. C’est la solution que j’ai trouvé. L’index du prix dans ma première boucle for sera $x, et je vais me servir de cet index de cette façon $x-1 ou $x+1 afin de me déplacer dans mon tableau pour faire les calculs conformément au théorème du livre prépabac puis les injecter dans $Pe.

4. Au final, le tableau $tabF qui comprends les dates et les pourcentages est converti au format JSON et nous obtenons une vue très importante suceptible d’être utilisée dans un Graphe !
En l’occurrence, c’est JQPLOT qui va devoir être également paramétré pour les dates et les pourcentages(C’est assez difficile).

Le code :

C’est une vue, il n’y a donc qu’un fichier:
afficherPourcentages.php

<?php
include('connexionSql.php');
indique que le type de la réponse renvoyée au client sera du Texte
header(&quot;Content-Type: text/plain&quot;);
//anti Cache pour HTTP/1.1
header(&quot;Cache-Control: no-cache , private&quot;);
//anti Cache pour HTTP/1.0
header(&quot;Pragma: no-cache&quot;);

// Transmission des var qui arrivent en mode get en variables classique PHP
$referenceP= $_GET['referenceP'];

connexionSql();
$lectureSql=&quot;Select date,prix from livraison where reference like ".$referenceP." order by livraison.date;&quot;;
$lecture = mysql_query($lectureSql) or die(mysql_error());

/* REQUETE SQL pour GRAPHE 1 */
/* POURCENTAGE DEVOLUTION DES PRIX PAR DATES*/
/* -----------------------------------------------------------------------------------------------------	 */	
while ($col=mysql_fetch_array($lecture)){
		$col[prix]=intval($col[prix]); 
		$tabPrix[] = $col[prix];
		$tabDates[] = $col['date'];
		$tabCopie[]=$col[prix];
}
/* -------------------------------------------------------------------------------------------------------- */

 // CALCUL ET POSITIONNEMENT DES POURCENTAGES D EVOLUTION des prix dans le tableau $Pe
for ($x=0;$x<sizeof($tabPrix);$x++){
	$Pe[$x]=$tabCopie[$x+1]-$tabPrix[$x];// IDEM LIVRE MATHSPREPABAC
	$Pe[$x]=$Pe[$x]/$tabPrix[$x]*100; // FORMULE DU LIVRE PREPABAC
	};

// ENLEVE LE DERNIER POURCENTAGE DU TABLEAU PE QUI EST forcement a zero et ne sert à rien
$size=sizeof($Pe)-1;
unset($Pe[$size]);

// INJECTION DES POURCENTAGES DEVOLUTION DANS LE TABLEAU DES DATES
for ($z=0;$z<sizeof($Pe);$z++){
	$tabF[]=array($tabDates[$z+1],$Pe[$z]);
	}

echo json_encode($tabF);

Voici les données JSON générées, Je n’ai pas encore arrondi les pourcentages à x.xx%, parce que certains moteurs de graphes le font par défaut. On voit donc que le 17 Septembre 2014, prix de notre article a bondi de 175.9 pour cent:

[["2014-09-17",175.86206896552],["2014-09-17",400],["2014-09-17",5.2],["2014-09-20",-87.690114068441],["2014-09-20",33.204633204633]]

Pour contrôle, on voit bien que ces pourcentages d’évolution correspondent bien aux données de PRIX de la requête SQL concernant l’article de référence gh2012 :

exercice17-1

Note : Ces données ne sont pas réalistes, car généralement, le prix d’un article ne peux bondir de 400 pour cent en une journée, ce qui nous donne des pourcentages d’évolution grotesques du style +400% ou -87.7% …

Note:
Jqplot a besoin de placer ces donnnées entre deux crochets additionels, ce qui donne (J’lai pas encore fait dans le code):

[[["2014-09-17",175.86206896552],["2014-09-17",400],["2014-09-17",5.2],["2014-09-20",-87.690114068441],["2014-09-20",33.204633204633]]]

Exercice 16 : Créer des objets Javascript sur appel Jquery Ajax.

Introduction :

Dans cet exercice, je crée deux objets Javascripts, EMPLOYE et EMPLOYEUR, qui ont des sous fonctions qui permettent de les imprimer à l’écran (Très basiquement, pour faire court pour l’instant..)

L’acquisition des variables est soumise à un critère ID, puis se fait sur un fichier JSON qui aura été généré au préalable à l’aide d’une requête SQL, puis affiché à l’aide d’un langage quelconque (Php en l’occurence, mais ça aurait pu être du JAVA ou fait avec NODE.JS.).

L’acquisition et le parsing des variables du fichier JSON est faite à l’aide de la fameuse fonction Jquery $.ajax. cela se passe dans la fonction success: (de rappel ).

Ordonnancement :

Appel AJAX ->
Requête SQL ->
Conversion en JSON ->
Récupération et Parsing des Variables ->

Injection dans les objets Javascript ->
Affichage des objets Javascript.

Le code :

Index.html : Ne sert qu’à charger la lib jquery ;

<meta http-equiv="content-type" content="text/html;charset=iso-8859-15" />
<head>
<!-- -----------------------------------------------DEBUT DU CHARGEMENTDES LIBRAIRIES------------------------ -->
		<!--	APPEL LIB JQUERY -->
		<script	 type="text/javascript" src="librairies/jquery.js"></script>

		<!--	CSS DU PROGRAMME -->
		<link rel="stylesheet" type="text/css" href="style.css" />
		
		<!-- Fonction Machine-->
		<script src="fonctionsMachines.js" language="javascript"></script>

<!-- ----------------------------------------------FIN DU CHARGEMENT DES LIBRAIRIES------------------------ -->
</head>
<html> 
<body>

</body>
</html>

fonctionsMachines.js : Le moteur qui va chercher les données JSON puis les injecter dans les objets …


/* CONSTRUCTEUR DE L'OBJET "EMPLOYE" */
function Employe(txtNom,txtPrenom,txtAge,txtDateNaissance,txtEmploi,txtSalaire,objEmployeur){
	this.nom=txtNom;
	this.prenom=txtPrenom;
	this.age=txtAge;
	this.datenaissance=txtDateNaissance;
	this.emploi=txtEmploi;
	this.salaire=txtSalaire;
	this.print=affEmploye;
	this.employeur=objEmployeur;
}

/* Fonction additionnelle de l'objet EMPLOYE qui affiche  les données */
function affEmploye(){
	document.write("Cet employé s'appelle ",this.prenom," ",this.nom," Il a  ",this.age," ans, son emploi :  ",this.emploi," son salaire est :",this.salaire," son employeur est :  <br/>");
	this.employeur.print();
}

/* CONSTRUCTEUR DUN OBJET SECONDAIRE  : EMPLOYEUR; CELUI-CI SERA IMBRIQUE AU PREMIER*/
function Employeur(txtNom,txtAdresse){
	this.nom=txtNom;
	this.adresse=txtAdresse;
	this.print=affEmployeur;
}
function affEmployeur(){
	document.write(this.nom," est a l'adresse ",this.adresse,".<br/>");
}

/* var id = 2; FACULTATIF Cet Id sera récupéré par le biais d'un formulaire ... */

/* CREATION DOBJET JAVASCRIPTS A PARTIR DE FICHIERS JSON */
/* PHASE 1 LECTURE EN BDD ET RECUPERATION DE VARIABLES AU FORMAT JSON */
$.ajax({
    type: "POST",
    url: "lectureBdd.php",
   /*  data: 'id=' + userid,  On peut transmettre l'id au fichier PHP pour choisir la personne appropriée dans la BDD... */
    dataType: "json", // Set the data type so jQuery can parse it for you
    success: function (data) {
							
							/* PHASE 2 CREATION DOBJETS JAVASCRIPT AVEC LES VAR PROVENANT DU FICHIER JSON */
							var employeur1 = new Employeur(data[7],data[8]);
							var employe1= new Employe(data[0],data[1],data[2],data[3],data[4],data[5],employeur1); 
							
							/* PHASE 3  AFFICHAGE DOBJETS AVEC LA METHODE PRINT DE LOBJET EMPLOYE */
							employe1.print();
							
							/*  document.getElementById("nom").innerHTML = data[0]; Autre solution pour remplir directement la page en HTML. */
    }
});




/* FACULTATIF : EXEMPLE DE CREATION DOBJETS IMBRIQUES MANUELLE REMARQUER LOBJET SECONDAIRE CITE EN DERNIERE POSITION   */
/* var employeur1 = new Employeur("BP","12 rue de Lilas 75016 Paris");
var employeur2 = new Employeur("Shell","44 Avenue de Picpus 75015 Paris");
var employe1= new Employe("Dupont","Nicolas","35","03021980","ingenieur","350000",employeur1);
var employe2= new Employe("Durant","philbert","40","03021976","employé","320000",employeur2);  */


lectureBdd.php qui retourne un tableau qui sera converti au format JSON, je n’ai pas mis la requête SQL cela ne sert à rien …

<?php
// Ce tableau est censé être le résultat d'une requête SQL ** sur deux tables différentes** :
$employe = array();
$employe[0] = "Dupont";
$employe[1] = "Pierre";
$employe[2] = "42";
$employe[3] = "03021973";
$employe[4] = "Ingenieur";
$employe[5] = "42003";
$employe[6] = "employeur1";
$employe[7] = "BP";
$employe[8] = "12 rue de Lilas 75016 Paris";

// On encode en JSON,le format compréhensible par Javascript et par d'autres langages...
echo json_encode($employe);
exit();


// Autre méthode de création de tableaux possible ...
/* 'nom'=>"Dupont",
'prenom'=>"Pierre" */

lectureBdd.php retourne les données Json suivantes directement à l’écran:

["Dupont","Pierre","42","03021973","Ingenieur","42003","employeur1","BP","12 rue de Lilas 75016 Paris"]

Finalement, l’aspect HTML du résultat est celui-ci :

Cet employé s'appelle Pierre Dupont Il a 42 ans, son emploi : Ingenieur son salaire est :42003 son employeur est :
BP est a l'adresse 12 rue de Lilas 75016 Paris.

Exercice 15 : Uploader 1 fichier avec JQuery Upload File, puis parser avec PAPAPARSE

Introduction

Voici comment importer un fichier CSV dans une application, puis le parser( décomposer) en un tableau javascript.
J’utilise pour ceci 2 librairies JQuery/Javascript :

1. http://hayageek.com/docs/jquery-upload-file.php

et

2. http://papaparse.com/

exo15

Tester en ligne :
http://nicolash.org/exercice15/

Le Code :

index.html


<meta http-equiv="content-type" content="text/html;charset=utf8" />

							<!-- 		DEBUT DU CHARGEMENT DES LIBRAIRIES -->
<!--	APPEL LIB JQUERY -->
	<script	 type="text/javascript" src="librairies/jquery.js"></script>

<!--	APPEL LIB JQUERY UI ( look sympa du programme) -->
<!--	<link href="http://code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css" rel="stylesheet" type="text/css" /> -->
	<script type="text/javascript" src="librairies/jquery-ui.js"></script>
	<link href="librairies/jquery-ui.css" rel="stylesheet" type="text/css" />
	<script type="text/javascript" src="librairies/jquery.dialogextend.js"></script>

<!-- 	CHARGEMENT LIB UPLOADFILE -->
		<link rel="stylesheet" href="librairies/jquery-upload-file-master/css/uploadfile.min.css" type="text/css"/>
	<script src="librairies/jquery-upload-file-master/js/jquery.uploadfile.min.js" type="text/javascript" charset="utf-8"></script>

<!--	FONCTIONS AJAX DU PROGRAMME -->
	<script type="text/javascript" src="fonctionsMachine.js"></script>

<!--	CSS DU PROGRAMME -->
	<link rel="stylesheet" type="text/css" href="style.css" />

<!-- 	PAPAPARSE CSV TO JSON -->
	<script src="librairies/papaparse.js" type="text/javascript" ></script>
<!-- 		FIN DU CHARGEMENT DES LIBRAIRIES -->

<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>Exercice 15</title>
	<body BGCOLOR=white>
	<img src="COMMANDIS.jpg" height=30px width=150px /> 

<!-- PAGE PRINCIPALE -->
<div id="page" >
<div id="info" >Les données vont apparaitre ici</div>

<!-- ICONES -->
<h3 id="clickMe2" id="draggable" class="icone" style="width:130px; background:tan; border:4px outset black;border-radius:5px;left: 400px; top:200px ">
<img src="photoscommandis/exercice.jpg" height=100px width=100px />Parser un fichier CSV</h3>

<!-- FENETRES -->
<div id="dialog2" title="Lancer 1 lecture jquery ajax">
<div id="fileuploader">Télécharger votre fichier Csv</div>
<div id="eventsmessage">debug</div>

<!--zone du petit gif animé AJAX-->
<img id="charge" src="chargeur.gif" width=50px  />

<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>
<!-- <button class="submit" type="submit" id="tbutton" >Requête Jquery Ajax</button> -->
</div> 

<!-- FIN DE PAGE -->
</body>
</html>

fonctionMachines.js


// JavaScript Document

// --------------------------------------------------- RECEPTION DES REQUETES AJAX ------------------------------------------------------

/* Requete En lecture Ajax JQUERY*/
 $(function() {
     $("#tbutton").click(function(){
	//gestion du bouton et du gif animé chargeur Ajax
	document.getElementById("tbutton").disabled= true;
	document.getElementById("charge").style.visibility="visible";

	$.ajax({
            url: 'afficher.php',
            type: "GET",
			 data: "",
				success: function(data) {
				/* 	//code to execute */
				document.getElementById("info").innerHTML=data;
				//affiche la zone info
				document.getElementById("info").style.visibility="visible";
				alert('Requete ajax Jquery ok');
				/* 	Fait disparaitre l'image du chargeur Ajax et réactive le button ! */
				document.getElementById("tbutton").disabled= false;
				document.getElementById("charge").style.visibility="hidden";
				}
            });	

		});
 });
/*
-----------------------------------------------RECEPTION DE FICHIER ET PARSING----------------------  */

 /*Téléchargement du Fichier CSV */
 /* http://hayageek.com/docs/jquery-upload-file.php */

$(document).ready(function()
{
	$("#fileuploader").uploadFile({
	url:"upload.php",
	fileName:"myfile",
	allowedTypes:"csv",
	/* 	Traduction */
	dragDropStr: "<span><b>Faites glisser et deposez les fichiers</b></span>",
	abortStr:"abandonner",
	cancelStr:"resilier",
	doneStr:"fait",
	multiDragErrorStr: "Plusieurs Drag & Drop de fichiers ne sont pas autorises.",
	extErrorStr:"n'est pas autorisé. Extensions autorisees:",
	sizeErrorStr:"n'est pas autorisé. Admis taille max:",
	uploadErrorStr:"Upload n'est pas autorise",
	extErrorStr:"n'est pas autorise. Extensions autorisees:",

onSubmit:function(files)
{
	$("#eventsmessage").html($("#eventsmessage").html()+"<br/>Soumission:"+JSON.stringify(files));
},
onSuccess:function(files,data,xhr)
{
	$("#eventsmessage").html($("#eventsmessage").html()+"<br/>Succes pour : "+JSON.stringify(data));
	var nomFichier= JSON.stringify(files);

	/* PARSING CSV->JSON AVEC PAPAPARSE */
	var nomFichier= nomFichier.replace('"','');
	var nomFichier= nomFichier.replace('"','');
	var nomFichier= nomFichier.replace('[','');
	var nomFichier= nomFichier.replace(']','');
	var nomFichier= "/exercice15/uploads/"+nomFichier;
	alert(nomFichier);
	Papa.parse(nomFichier, {
	download: true,
	complete: function(results) {
		console.log("Le fichier CSV a ete parse en un tableau javascript JSON", results);
		var tableau = results.data;
/* 		document.write(results.data); */
		$("#eventsmessage").html($("#eventsmessage").html()+"<br/>Voici les donnees parsees: "+results.data);
		}
});

},
afterUploadAll:function(files)
{
	$("#eventsmessage").html($("#eventsmessage").html()+"<br/>Tous les fichiers sont uploades");

},
onError: function(files,status,errMsg)
{
	$("#eventsmessage").html($("#eventsmessage").html()+"<br/>Erreur pour: "+JSON.stringify(files));
}
});
	});

/*  ----------------------------------------GENERATION DE TABLES ------------------------------------------------------------ */

/*   ---------------------------------PLUGS IN DE FORMULAIRES --------------------------------------------------------------- */

/*  --------------------------------------FENETRAGE et ICONES-----------------------------------------------------------------------------  */

  // Ouvre les fenetres sur clic d'icone
$(function() {
$('#clickMe2').click(function(event) {
   /*  var mytext = $('#myText').val(); */

/* ligne dorigine tres inteeressante qui affiche une var supplemenaire dans la page (mytext)
   $('<div id="dialog2">'+mytext+'</div>').appendTo('body');
 */

  $('<div id="dialog2"></div>').appendTo('body');
	event.preventDefault();

		 var dialog2Opts = {width:600, height:600, maxWidth: 800, maxHeight: 800, minWidth: 300, minHeight: 200,left: 100, top:10 ,autoOpen: true};
		 $( "#dialog2" ).dialog(dialog2Opts).dialogExtend({
        "closable" : true,
        "maximizable" : true,
        "minimizable" : true,
        "collapsable" : true,
        "dblclick" : "collapse",

        "minimizeLocation" : "right",

      });
    }); //close click
});

$(function() {
var dialogOpts = {width:400, height:400, maxWidth: 800, maxHeight: 800, minWidth: 300, minHeight: 200,left: 100, top:10 , autoOpen: false} ;
$( "#dialog2" ).dialog(dialogOpts).dialogExtend({
        "closable" : true,
        "maximizable" : true,
        "minimizable" : true,
        "collapsable" : true,
        "dblclick" : "collapse",

        "minimizeLocation" : "right",

      });
  });

   // Rends draggable les icones avec JQUERY
$(function() {
$( "#clickMe2" ).draggable();
});

essai.csv

paul;12345
pierre;45121
jacques ;467874

upload.php


<?php
$output_dir = "uploads/";
if(isset($_FILES["myfile"]))
{
	$ret = array();

//	This is for custom errors;
/*	$custom_error= array();
	$custom_error['jquery-upload-file-error']="File already exists";
	echo json_encode($custom_error);
	die();
*/
	$error =$_FILES["myfile"]["error"];
	//You need to handle  both cases
	//If Any browser does not support serializing of multiple files using FormData()
	if(!is_array($_FILES["myfile"]["name"])) //single file
	{
 	 	$fileName = $_FILES["myfile"]["name"];
 		move_uploaded_file($_FILES["myfile"]["tmp_name"],$output_dir.$fileName);
    	$ret[]= $fileName;
	}
	else  //Multiple files, file[]
	{
	  $fileCount = count($_FILES["myfile"]["name"]);
	  for($i=0; $i < $fileCount; $i++)
	  {
	  	$fileName = $_FILES["myfile"]["name"][$i];
		move_uploaded_file($_FILES["myfile"]["tmp_name"][$i],$output_dir.$fileName);
	  	$ret[]= $fileName;
	  }

	}
    echo json_encode($ret);
 }
 ?>

Exercice 14 : Comparaison AJAX Jquery VS AJAX Xhr de base + framework Jquery UI de base

Introduction :

C’est la comparaison entre une requête Ajax XHR et une requête Ajax Jquery.
les deux requêtes sont identiques, et lancent un appel(query) à afficher.php, avec une fonction(une action) de retour qui affiche le résultat dans la Div concernée.
Le resultat de afficher.php est un var_dump() d’un tableau.

Le tout dans un framework Jquery UI de base.

Pour le tester, voici le lien :
http://nicolash.org/exercice14/

Le code :

Index.html :
Appel aux librairies + affichage ou pas des DIVS


<!-- 		DEBUT DU CHARGEMENT DES LIBRAIRIES -->

<!--	APPEL LIB GOOGGLE -->
<!--  <script type='text/javascript' src='https://www.google.com/jsapi'></script>  --> <!--	LA FONCTION XHR POUR LES APPELS AJAX--><script src="fonctionsAjax.js" type="text/javascript"></script>

<!--	APPEL LIB JQUERY -->
<script src="librairies/jquery.js" type="text/javascript"></script><!--	APPEL LIB JQUERY UI ( look sympa du programme) --> <!--		<link href="http://code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css" rel="stylesheet" type="text/css" /> --><script src="librairies/jquery-ui.js" type="text/javascript"></script>
<script src="librairies/jquery.dialogextend.js" type="text/javascript"></script><!--   APPEL LIB DATATABLE --><script src="librairies/jquery.dataTables.js" type="text/javascript"></script>

<!--	APPEL LIB JQPLOT -->
<script src="librairies/jquery.jqplot.js" type="text/javascript"></script><!-- 	Plug ins --><script src="librairies/plugins/jqplot.barRenderer.min.js" type="text/javascript"></script>
<script src="librairies/plugins/jqplot.pieRenderer.min.js" type="text/javascript"></script><script src="librairies/plugins/jqplot.categoryAxisRenderer.min.js" type="text/javascript"></script>
<script src="librairies/plugins/jqplot.pointLabels.min.js" type="text/javascript"></script><script src="librairies/plugins/jqplot.json2.min.js" type="text/javascript"></script>

<!--	APPEL LIB DROPZONE -->
<script src="librairies/dropzone.js"></script><!-- Chargement de jQuery-Validation-Engine (fichier de langue + script) --><script src="librairies/validation-engine/js/languages/jquery.validationEngine-fr.js" type="text/javascript" charset="utf-8"></script>
<script src="librairies/validation-engine/js/jquery.validationEngine.js" type="text/javascript" charset="utf-8"></script><!-- Chargement du CSS de jQuery-Validation-Engine --> <!--	FONCTIONS AJAX DU PROGRAMME --><script src="fonctionsMachine.js" type="text/javascript"></script>

<!--	CSS DU PROGRAMME -->

<!-- 		FIN DU CHARGEMENT DES LIBRAIRIES -->

Exercice 14

<img src="COMMANDIS.jpg" alt="" width="150px" height="30px" />

<!-- PAGE PRINCIPALE -->
<div id="page">
<div id="info">Les données vont apparaitre ici</div>
<!-- ICONES -->
<h3 id="draggable" class="icone" style="width: 130px; background: tan; border: 4px outset black; border-radius: 5px; left: 400px; top: 200px;"><img src="photoscommandis/historique.png" alt="" width="100px" height="100px" />Requetes</h3>
<!-- FENETRES -->
<div id="dialog2" title="Lancer 1 lecture jquery ajax"><!--zone du petit gif animé AJAX-->
<img id="charge" src="chargeur.gif" alt="" width="50px" />
<input id="button" name="button" type="button" value="Requete Xhr Ajax" />


<button id="tbutton" class="submit" type="submit">Requête Jquery Ajax</button></div>
</div>
<!-- FIN DE PAGE -->


fonctionMachine.js contient le code Javascript qui lance les appels sur afficher.php, on voit que la fonction jquery est bien plus simple que l’ancienne fonction Xhr, et encore y’a pas le serialise des variables… qui est l’avantage Majeur de Jquery, puisque cela permet de répupérer toutes les variables provenant d’un formulaire dans la vue php, sans rien écrire en javascript:


// JavaScript Document

// --------------------------------------------------- RECEPTION DES REQUETES AJAX ------------------------------------------------------


/* ANCIENNE METHODE AVEC XHR*/

 function afficher() {   
	 /*-----------------------------Config et envoi de la requete ASYNCHRONE : */
	 objetXHR = creationXHR();//création d'un objet XHR multi-navigateurs 	 
	// acquisition des variables JAVASCRIPT provenant du formulaire 
/* 	var categorie = document.getElementById('scategorie').selectedIndex; */
	temps = new Date().getTime();//création d'une variable temps pour l'anti-cache
	// transmission des variables acquises avec javascript au fichier PHP
	objetXHR.open("get",'afficher.php', true); //Config. objet XHR
/* 	objetXHR.open("get",'afficher.php?categorie='+categorie+'&primal='+primal+'&marque='+marque+'&anticache='+temps, true); //Config. objet XHR */
	objetXHR.onreadystatechange = actualiserPage;//désignation de la fonction de rappel
	//gestion du bouton et du chargeur
	document.getElementById("button").disabled= true;
	 document.getElementById("charge").style.visibility="visible";
	objetXHR.send(null);//envoi de la requete
	 /*---------------------------------------- */
 }
  
  function actualiserPage() {
	if (objetXHR.readyState == 4) {//test si le résultat est disponible
	 if (objetXHR.status == 200) {
	 var reponsePhp = objetXHR.responseText;//recup du résulat renvoyé par le serveur 
       //actualisation du résultat
	  document.getElementById("info").innerHTML=reponsePhp;
	  //affiche la zone info
	 document.getElementById("info").style.visibility="visible"; 
	  //gestion du bouton et du chargeur
	   document.getElementById("button").disabled= false;
	   document.getElementById("charge").style.visibility="hidden";
	 }
	else{
	   //message d'erreur serveur
	   var erreurServeur="Erreur serveur : "+objetXHR.status+" – "+ objetXHR.statusText;
	   remplacerContenu("info", erreurServeur);

	   //gestion du bouton et du chargeur
	  document.getElementById("button").disabled= false; 
	   document.getElementById("charge").style.visibility="hidden";
	   //annule la requete en cours
	   objetXHR.abort();
	   objetXHR=null;
	   }
	 }
  }

  
/* NOUVELLE METHODE AVEC JQUERY */
 $(function() {
     $("#tbutton").click(function(){
	//gestion du bouton et du gif animé chargeur Ajax
	document.getElementById("tbutton").disabled= true;
	document.getElementById("charge").style.visibility="visible";

	$.ajax({
            url: 'afficher.php',
            type: "GET",
			 data: "",
				success: function(data) {
				/* 	//code to execute */
				document.getElementById("info").innerHTML=data;
				//affiche la zone info
				document.getElementById("info").style.visibility="visible"; 
				alert('Requete ajax Jquery ok');
				/* 	Fait disparaitre l'image du chargeur Ajax et réactive le button ! */
				document.getElementById("tbutton").disabled= false;
				document.getElementById("charge").style.visibility="hidden";
				}
            });	
		
		});
 });


/*  ----------------------------------------GENERATION DE TABLES ------------------------------------------------------------ */
 
/*   ---------------------------------PLUGS IN DE FORMULAIRES --------------------------------------------------------------- */
 
/*  --------------------------------------FENETRAGE et ICONES-----------------------------------------------------------------------------  */
  
 
  // Ouvre les fenetres sur clic d'icone
$(function() {
$('#clickMe2').click(function(event) {
   /*  var mytext = $('#myText').val(); */

/* ligne dorigine tres inteeressante qui affiche une var supplemenaire dans la page (mytext)
   $('<div id="dialog2">'+mytext+'</div>').appendTo('body');   
 */


  $('<div id="dialog2"></div>').appendTo('body');    	
	event.preventDefault();

		 var dialog2Opts = {width:400, height:400, maxWidth: 800, maxHeight: 800, minWidth: 300, minHeight: 200,left: 100, top:10 ,autoOpen: true};
		 $( "#dialog2" ).dialog(dialog2Opts).dialogExtend({
        "closable" : true,
        "maximizable" : true,
        "minimizable" : true,
        "collapsable" : true,
        "dblclick" : "collapse",
  
        "minimizeLocation" : "right",
        
		
		
      });
    }); //close click
});
 

$(function() {
var dialogOpts = {width:400, height:400, maxWidth: 800, maxHeight: 800, minWidth: 300, minHeight: 200,left: 100, top:10 , autoOpen: false} ;
$( "#dialog2" ).dialog(dialogOpts).dialogExtend({
        "closable" : true,
        "maximizable" : true,
        "minimizable" : true,
        "collapsable" : true,
        "dblclick" : "collapse",
  
        "minimizeLocation" : "right",
        
      });
  });
   
   
   
   // Rends draggable les icones avec JQUERY
$(function() {
$( "#clickMe2" ).draggable();
});

En plus, les anciennes fonctions utilisant XHR ont besoin de ce fichier supplémentaire fonctionAjax.js pour fonctionner avec l’objet Xhr:

// JavaScript Document
 function creationXHR() {
   var resultat=null;
   try {//test pour les navigateurs : Mozilla, Opéra, ...
	    resultat= new XMLHttpRequest();
     } 
     catch (Error) {
     try {//test pour les navigateurs Internet Explorer > 5.0
     resultat= new ActiveXObject("Msxml2.XMLHTTP");
     }
     catch (Error) {
         try {//test pour le navigateur Internet Explorer 5.0
         resultat= new ActiveXObject("Microsoft.XMLHTTP");
         }
         catch (Error) {
            resultat= null;
         }
     }
  }
return resultat;
}

afficher.php est la « vue » qui lit la requête SQL grâce à PHP :


<?php
 error_reporting(0);
 require 'jsonwrapper.php';
include('connexionSql.php');
//indique que le type de la réponse renvoyée au client sera du Texte
header("Content-Type: text/plain");
//anti Cache pour HTTP/1.1
header("Cache-Control: no-cache , private");
//anti Cache pour HTTP/1.0
header("Pragma: no-cache");
//simulation du  temps d'attente du serveur (2 secondes)
sleep(1);


connexionSql();

$lectureSql="select * from livraison;";

$lecture = mysql_query($lectureSql) or die(mysql_error());
while ($col=mysql_fetch_array($lecture))
	{

	// possiblite de création du tableau avec les données de la BDD, dans l'ordre de la requête SQL
	/* $tab=array(
	"Primaire"=>$col[primal.nom],
	"Categorie"=>$col[1],
	"Marque"=>$col[2],
	"Prix"=>$col[prix],
	"Nombre"=>$col[nombre],
	"date"=>$col[date]
	); */
	
	$tab=array(
	$col[id],
	$col[1],
	$col[2],
	$col[3],
	$col[reference],
	$col[prix],
	$col[nombre],
	$col[coutlivraison],
	$col[heure],
	$col[date], 
	$col[dateperime],
	$col[fichier1]
	
	); 

	

	}
var_dump($tab);
	

?>

style.css est le fichier de css de l’exercice 14 :


@charset "utf-8";
/* CSS Document */
body, h1, h2, p { font-size: 1em; margin: 0; padding: 0; }
body {
  font-family: Verdana, Geneva, Arial, sans-serif;
  text-align: center;
}

#page {
   position: relative;
   margin: 0 auto;
   width:1200px;
   height:700px;
   border-top: medium solid grey;
   border-bottom: medium solid grey;
   border-left: medium solid grey;
   border-right: medium solid grey;
   	background-color:wheat;
   
}
#info {
	position: absolute;
  
  
	visibility:hidden;
	background-color:white;
	color:black;
	border:4px;
	   border-top: medium solid grey;
   border-bottom: medium solid grey;
   border-left: medium solid grey;
   border-right: medium solid grey;
 
	background-color:white;
}
#resultat {   
	font-weight:bold;
	   border-top: medium solid grey;
   border-bottom: medium solid grey;
 
}
#formulaire {
    position: absolute;
    left: 10px;
    top: 20px;
	width:200px;
	background-color:white;
	height:900px;
	 left: 10px;
	 	    border-top: medium solid grey;
   border-bottom: medium solid grey;
   border-left: medium solid grey;
   border-right: medium solid grey;
   
}
#stock {
    position: absolute;
    left: 700px;
    top: 50px;
	width:200px;
	background-color:white;
	height:400px;
		     border-top: medium solid grey;
   border-bottom: medium solid grey;
   border-left: medium solid grey;
   border-right: medium solid grey;
}



#charge {
    position: absolute;
    left: 10px;
    top: 10px;
	visibility:hidden
}

#dialog2{
	   font-size: 0.8em;
	 top: 30px;
left:10px;
}	

#display{
visibility:hidden;
}

	
#draggable { width: 130px; height: 50px; padding: 0.5em; background:white;}
	 
	 
#icone {width:130px;background:white;}