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]]]