Micro Application 7 : EvalEntretien avec Angular, Bootstrap, RestPhp

Introduction evalentretien2


Aujourd’hui, Je vais créer une application Web single page d’évaluation d’entretien avec Angular, Bootstrap pour  Angular, et avec un Rest en Php en partant de zéro. Peut être un peu de Jquery en plus …

Je suis sur cette appli en même temps que sur « Mon petit Stock ». A tester sur http://nicolash.org/angular/app7.html

Today, I’m going to create a pro evaluation meeting single page App, with Angular, Bootstrap, and a simple php Rest. I’ll work on this project at the same time than « Mon Petit Stock ».

Explication du principe fonctionnel du Programme :

Un DRH arrive le matin à son bureau, il ouvre le logiciel, clique sur la date du jour, puis découvre ses entretiens de la journée. Le candidat à l’emploi entre dans le bureau et l’évaluateur des ressources humaines clique sur « évaluer ». A la fin, l’entretien est enregistré, et on peut l’éditer à loisir. A la fin du processus de recrutement, les meilleurs candidats apparaissent dans l’ordre, en fonction des notes que l’évaluateur RH leur a attribué et de calculs mathématiques . Du coup, l’évaluateur peut envoyer automatiquement par EMAIL la décision de l’entreprise au candidat audité.

A terme, le DRH pourra paramétrer les emplois à pourvoir ainsi que leurs pré-requis.

Explication du principe de programmation :

Le but de cet exercice est de travailler le filtrage et la modification d’un modèle JSON, avec une programmation MVC avec angular.

Le modèle doit être unique et il faut éviter d’en créer des copies, Le modèle est l’objet dynamique JSON $scope.candidats qui contient tous les candidats à auditer par l’entreprise et leurs informations, ainsi que les notes données par la DRH. Pour savoir à quoi il ressemble, regarder le contenu de listePersonnes.json à la fin de post.

Ce modèle unique est filtré/et ou modifié à divers endroits du programme en temps réel, mais demeure unique, afin de faciliter l’enregistrement en Base de donnée, par la couche de persistance, qui viendra en conclusion de la modification du modèle.

Je tente donc de respecter une programmation Modèle Vue Controleur afin de simplifier  la compréhension du code par d’autres programmeurs.

A la fin d’un entretien, $scope.candidats[x].rdvEffectue passe du boleen 0 au boleen 1, de ce fait, on peut savoir si un rendez vous a été effectué ou non, et, de ce fait on peut filtrer dans la vue, en html par rendez vous effectué ou non. Bien cette modif sera également répercutée en base de données.

La vue( le code Html) est l’élèment qui filtre le modèle(l’objet Json), Le contrôleur est le controleur Angular.

(Note : au début j’ai du réaliser une copie du modèle à cause de la difficulté du filtrage du modèle par date picker. Je vais devoir essayer de modifier cela dans la mesure du possible, donc je continue à m’améliorer )

Le cahier des Charges :


  • Esthétique épurée, la plus moderne possible. Curated Design, as modern as possible.
  • Finalisation la plus rapide et précise possible. Fast rendering, concise stuff.
  • Etude sommaire des autres solutions et de leurs design. Others same spirit solutions short studies.
  • Durée approximative du projet 2 semaines . Approximate Programming Length : 2 weeks.

Le fonctionnement :

  • Choix d’un candidat dans un tableau et/ou un carroussel. Suite à un clic, le formulaire s’auto-remplit des données de l’utilisateur.
  • Les personnes sont chargées à l’aide de http de Angular, via un rest Php. (Pas de $.load Jquery)
  • Utilisation de l’évaluation par étoiles de Bootstrap.
  • Essayer d’intégrer l’agenda Angular, pour fixer un autre rendez-vous( Ca va être compliqué.)
  • Si il y a des fenêtres dialog, utiliser le css bootstrap.
  • Prise de notes avec un plug in wisiwig.
  • Tester un autre type de rest PHP que des fichiers de base..
  • Utilisation de directives Persos Angular, et de pratiques Angular Avancées.
  • Pour le design, s’inspirer de http://demos.telerik.com/kendo-ui/bootstrap/#schedule
  • Si il y a des curseurs, leir appliquer ce design :http://jsbin.com/bejiku/2/edit?html,css,js,output

Description


  • Type : Application front-end Web de type Saas.
  • Langage : Js, Angular, Bootstrap UI, Jquery U.I, Html 5.0, Css3.0
  • Format d’échanges de Données : JSON
  • Back-end : Php Rest .
  • Difficulté : ++++/+++++ (A cause de l’agenda)
  • Test avec jasmine : Non.
  • Durée de codage : 1 semaine.
  • UML 2.0 : non.
  • Webstorage(stockage des données dans le navigateur) : Peut être.
  • Gestion de la concurence : non.
  • Webservice : non.
  • Authentification : non.
  • Minification Grunt : Peut être.
  • Nodes.Js : non.
  • MongoDb : non.
  • Ambition Commerciale : ?.
  • Etude de Marché, Barrières commerciales  : non.

Journal de dev, en mode Agile :


Jour 1 : 1 heure :

  • Elaboration du Logo.
  • « Brain Storming »

Jour 2 : 2 heures de code :

  • Elaboration des Css
  • Elaboration des Divs avec des % pour les css
  • Elaboration de l’appel Ajax avec http de Angular
  • Elaboration des tabs(onglets).

Jour 3 : 3 heures de code :

  • Elaboration du filtre des rendez vous en fonction d’un « date picker », explication: Soit var omegaCandidat l’intégralité des rendez vous de l’organisation(chargée avec Ajax)(Le modèle), alors $scope.candidats sera les rendez vous de la date choisie dans le date picker. En d’autres termes, var omegaCandidat est copie du modèle complet qui est un objet JSON, et $scope.candidats est son résultat filtré sous contrainte du Date Picker, sauf au démarrage de l’appli(pour la démo). On peut le tester en cliquant sur le 21 avril 2015.
  • Echec de la création d’un service Angular Date Picker dans le temps imparti, j’ai mis tout les code dans le même controller, tant pis, je verrais demain.

Jour 4 : 3 heures de code

  • Activation du bouton d’évaluation en fonction de l’id du candidat à auditer.
  • « Brain Storming » à propos d’une foncitonnalité de classement de candidats par adéquation métier ou adéquation catégorie.
  • Début d’intégration des étoiles Bootstrap
  • Légère simplification du code, avec une copie d’objet JSON en guise de filtre par datepicker.
  • Création d’un service HTTP qui devra évaluer vers un service CRUD

Jour 5 : 3 Heures de Code 

  • Activation de l’évaluation par étoiles… Le crud n’est pas encore en place, bien sur, donc cela n’enregistre pas.
  • Intégration de la notion de pré-requis métier.
  • En local, début de testing de http://a5hik.github.io/ng-sortable/#/kanban (Compliqué, mais génial !)
  • Intégration d’un premier Graphe HighCharts, pas encore relié aux données
  • Création d’un contrôleur spécifique pour les graphiques, et pour les notations par étoiles.
  • Restructuration sommaire des données JSon(présence d’un sous objet Json « evaluation »dans l’objet « candidats »)
  • En projet : Un Crud simple Php ou MongoDb + Web Storage. Le pb est qu’il faudra déconstruire l’objet JSON, pour le stocker dans la bdd relationnelle, et c’est un peu lourd.
  • Intégration de CkEditor.
  • Intégration de graphiques d3.js(C’est plus dur que highcharts et jqplot)

Jour 5 : 2h30 Heures de Code

  • Liaison des données (Evaluation+Prérequis Métier) avec le graphe en temps réel, il faut choisir le métier sous l’onglet évaluation, pour que ces données s’affichent dans le graphes en temps reel
  • Activation de CkEditor (N’enregistre pas encore)

J’ai de nouveau du supprimer le controleur des graphiques à cause des variables hors scope, et tout mettre dans le controlleur principal, il faut que je fasses des exos avec des factories et des controleurs secondaires, pour évaluer la portée des variables avec Angular. Du coup le code est un gros paté que je n’aime pas trop, et qui est tout le contraire de ce que j’aimerais faire ( Factories bien faites etc …) Mais vu que je n’ai pas trop de temps à consacrer à ça…

De plus, je serais censé utiliser des vues et le routing Angular pour cet exercice, mais je n’ai pas envie de le faire pour cet exo.

La partie la plus intéressante va être le système CRUD Php.

Jour 6 : 4H de Code

Après une pause de 3 semaines, j’ai repris aujourd’hui :

  • Encore de gros problèmes et perte de temps suit à des tentatives de dialogue entre Contrôleurs.  Du coup, je n’utilise plus qu’un seul contrôleur, et je mettrais dès que le code sera fini, des portions de codes dans des services (Les graphes, Les étoiles). Faire dialoguer des controleurs entre eux n’est vraiment pas pratique (Exemple :http://jsfiddle.net/simpulton/XqDxG/), et je n’aime pas du tout, lorsqu’il y a plein de variables à transmettre, cela devient trop compliqué, alors je laisse tomber et mets tout dans le même contrôleur, point, j’en ai marre!
  • Les onglets de Boostrap bugguent plus ou moins avec $scope, j’ai dû aussi mettre le menu déroulant des métiers en haut , mais cela ne choque pas. En revanche, cela fait bugguer le graphique HIghcharts qui lorsqu’il est regénéré devient petit, c’est compliqué de gérer ça, je vois pas comment je vais faire encore, c’est du aux onglets . Je pense que la librairie jqplot n’aura pas ce pb.

Jour 7 : 3H30 de Code :

  • Une analyse du code m’a fait comprendre que toute copie de modèle même partielle rendait le code super complexe à comprendre pour les autres dev ( et pour moi). Il faut donc dans tous les cas mieux élaborer des filtres plutôt que des créer des copies parcellaires, même si c’est plus difficile. Le modèle est un objet Angular-Javascript JSON qui est modifié en temps réel, et qui ne doit pas être copié ou ‘parcellisé’ (si possible). Le problème est que cela peut induire des lenteurs si le modèle est trop grand. Donc à réflechir, mais en tout cas la démarche est plus claire dorénavant. J’essaye donc de modifier le code et de filtrer dès que possible dans la vue à partir de maintenant, avec des filtres personnels comme dans cet exemple : http://stackoverflow.com/questions/11923142/how-to-filter-json-data-with-angularjs.
  • En application de cela, lorsqu’un rendez vous est enregistré, il doit être flaggé à 1(booléen) dans le modèle, à cet endroit $scope.candidats[x].rdvEffectue et aussi , par conséquent en Base de données(Planification à inventer, en fonction de la future conception CRUD).

Jour 8 : 2 h De code.

Suite à mes réflexions du jour 7 à propos du modèle, j’ai opéré un important remaniement du code.

Voici comment j’avais commencé à concevoir le code au jour 1 (J’ai fait un graphique sommaire):

fonctionnement

On constate que j’avais dupliqué partiellement le modèle (omégaCandidat->$scope.candidats filtré par date ) pour pouvoir filtrer par date. C’était une solution provisoire, mais qui a compliqué incroyablement le code par la suite.

J’ai ensuite également créé un nouveau modèle partiel contenant un seul candidat, qui s’appelle $scope.entretienCandidat.

Finalement, suite à ma réflexion du jour 7, j’ai constaté que c’était mal d’agir comme cela, et inutile.

Voici comment le code doit être créé, il faut conserver un seul modèle :

focntionnementvoulu

Et cet unique modèle doit être

  • Filtré par la vue.
  • Modifié par le contrôleur.

Tout cela avec Angular, bien sur.

Le modèle, qui est un objet JSON, peut être complexe, avoir plusieurs sous imbrications, mais ne doit pas être copié ou parcellisé sous peine de compliquer incroyablement le code, alors que c’est inutile. Cet unique modèle est modifié en temps réel par le contrôleur Angular, et il est filtré en temps réel par Angular. Tout devient alors beaucoup plus simple, il faut juste passer plus de temps à filtrer.

J’ai déjà commencé à remanier le code, j’ai donc éliminé le json omegaCandidat, et $scopeCandidat est l’unique modèle dorénavant. J’ai créé un filtre Angular, qui se sert de Date PIcker pour filtrer le modèle $scopeCandidat. Plus de copie d’objet Json, on se repère désormais aisément dans le code car on sait que le modèle est unique, et qu’il ne peut qu’être filtré par la VUE(dans le html) ou modifié par le contrôleur Angular.

Egalement, plutôt que d’utiliser un nouvel objet Json $scope.entretiensEffectues pour stocker les entretiens effectués, je flague le modèle unique $scope.candidats à cet endroit $scope.candidats.entretienEffectue avec le booléen 1, comme en SQL, de cette manière, je conserve la loi de ne garder qu’une seul modèle et de ne pas créer de nouveaux objets Json(Bien qu’en cas extrême cela pourra tout de même servir qui sait, mais il faut éviter.)

La portée des variables avec Angular


Il me reste à faire des exos sur la portée des variables entre modules, entre Factories et entre contrôleurs pour bien comprendre comment cela à été fait, à noter également la présence de $rootScope qui s’apparenterait au window.variable de javascript. (Les livres que j’ai téléchargé font part d’astuces très intéressantes…). Le concept d’injection de dépendances n’est pas encore très claire pour moi car je ne comprends pas  si une dépendance peut être autre chose qu’une factory(car dans les livres ils semblent dire qu’un autre module peut être une dépendance), cependant, je crée déjà des factories et des filtres, ce qui n’est pas mal et permet déjà de créer des single pages applications.

Pour le testing avec Jasmine, c’est je trouve assez long à mettre en place, et je n’en ai pas encore saisi l’utilité.

Ce que j’aimerais c’est pouvoir organiser le code par classe plus ou moins comme dans Java, même si cela n’en porte pas le nom. Par contre, je pense qu’Angular est plus rapide et simple à comprendre (Et le binding live des données est incroyable). Idéal pour créer des tableaux de bords, des petites applications d’indicateurs, on conçoit que cela sert à ça, et que c’est très bien fait.

Le truc c’est que dans un objet Json, les variables ne sont pas typées, du coup, je suppose que cela peut induire des erreurs.

Autres choses

  • Le système d’évaluation par étoiles(Qui peut être utilisé pour pleins d’autres choses comme des objets par exemple) pourrait aussi être au format curseur.
  • De plus, plutôt que de coder en Html chaque « rate » d’évaluation par étoile, cela devrait être généré par un ng-repeat, de cette façon,  l’utilisateur pourrait ajouter, à l’aide d’un icone « plus », ajouter de nouvelles catégories d’évaluation en temps réel.
  • BIg Problem avec CK Editor qui ne s’actualise pas avec le live binding Angular ! Le live Binding fonctionne parfaitement dans un , mais ne fonctionne pas lorsque j’active CKEDITOR, lors que les variables de la note sont bien modifiées dans le modèle.

Jour 9 : 3h30 de code


  • Il n’y a plus qu’un seul un modèle unique.
  • J’ai mis en place le tri des candidats par notes en fonction d’un emploi.
  • j’ai commencé à essayer d’autogénerer les évaluations par étoiles mais c’est un peu dur, il faudra pourtant le faire car les utilisateurs doivent pouvoir créer leurs propres évaluations en cliquant sur un icone +. De plus, on sent un petit ralentissement désagréable quand on clique sur les étoiles car le modèle et le graphe sont reliés en temps réel, quand le modèle était parcelisé cela ne faisait pas de lenteur. Je ne vois pas trop comment éviter cette lenteur pour l’instant hormis de nouveau parceliser ce système à étoile.
  • On commence  avoir un aperçu du fonctionnement global de la micro application, Elle ne buggue relativement pas pour l’instant, mis à part ckeditor que j’ai pas eu le temps de traiter, mais c’est le plug … Et le graphe qui arrête pas de changer de proportions.

Jour 10 : 3h30 de code :


j’ai réussi à intégrer basiquement les élements de l’onglet « Projet ». Le code du dev original étant très bien fait, avec des répertoires un rep de vues, de controleurs séparé, il est relativement simple à comprendre à ce niveau là.

J’ai essayé de « dé-binder » les étoiles, mais la latence est encore là. Je vais entamer une application 8, à partir du livre Angular JS que j’ai en anglais, il y a des étoiles je verrais alors comment ils ont fait eux.

Donc voici ce qui doit encore être activé pour finaliser une première version de cette maquette et la rendre fonctionnelle:

  • L’onglet « Projet » doit enregistrer (Le Modèle  est à associer au modèle principal, par ID) , assez compliqué)
  •  L’onglet « notes » doit enregistrer, avec un autre éditeur wisiwig si il le faut.(Il enregistre déjà, c’est CKeditor qui ne se rafraichit pas.
    • le graphique doit avoir un comportement normal

Ensuite, on pourra ajouter

  • La pyramide des ages des candidats
  • La possibilité d’ajouter des candidats et des métiers.

A noter que je n’ai pas utilisé le routing volontairement, parce que c’est plus simple d’uploader une page seule quand on fait des exercices.

Le code à J+9:


<html ng-app="evalentretien">
	<head>
		<meta charset="utf8" >
		<!-- -----------------------------------------------DEBUT DU CHARGEMENT DES LIBRAIRIES------------------------ -->
		
		<!--	APPEL LIB ANGULAR -->
		<script	type="text/javascript" 	src="angular-1.3.13/angular.min.js"></script>
		<script src="angular-filter.min.js"></script>
		<script src="librairies/angular-locale_fr-fr.js"></script>
		
		<!--	APPEL LIB JQUERY -->
		<script	type="text/javascript" 	src="librairies/jquery.min.js"></script>
		<!--	APPEL LIB JQUERY UI ( look sympa du programme) -->
		<script type="text/javascript" 	src="librairies/jquery-ui.min.js"				></script>
		<link 	href="librairies/jquery-ui.min.css" rel="stylesheet" type="text/css" 	/>
		<script type="text/javascript" 	src="librairies/jquery.dialogextend.js"		></script>
		
		<!--	APPEL LIB BOOTSTRAP -->
		<script src="librairies/ui-bootstrap.min.js"></script>
		<link rel="stylesheet" href="librairies/bootstrap/css/bootstrap.css">
		
		<!-- APPEL LIB HIGHCHARTS -->
		<script src="librairies/Highcharts-4.1.1/js/highcharts.js"></script>
		<script src="librairies/Highcharts-4.1.1/js/highcharts-3d.js"></script>
		<script src="librairies/Highcharts-4.1.1/js/modules/exporting.js"></script>
		

		<!-- APPEL LIB Angular Sortable and Draggable Demo-->
		   <title>.</title>
			<!--styles -->
		<!-- 	<link rel="stylesheet" type="text/css" href="bootstrap.min.css"> -->
			<link rel="stylesheet" type="text/css" href="ng-sortable.min.css">
			<link rel="stylesheet" type="text/css" href="ng-sortable.style.min.css">
			<link rel="stylesheet" type="text/css" href="board.css">
			<!--scripts-->
			<script type="text/javascript" src="angular.min.js"></script>
			<script type="text/javascript" src="angular-route.min.js"></script>
			<script type="text/javascript" src="ui-bootstrap.min.js"></script>
			<script type="text/javascript" src="ui-bootstrap-tpls.min.js"></script>
			<script type="text/javascript" src="ng-sortable.js"></script>
			<script type="text/javascript" src="model.js"></script>
			<script type="text/javascript" src="app.js"></script>
			<script type="text/javascript" src="scripts/services/BoardManipulator.js"></script>
			<script type="text/javascript" src="scripts/services/BoardDataFactory.js"></script>
			<script type="text/javascript" src="scripts/services/BoardService.js"></script>
			<script type="text/javascript" src="scripts/controllers/KanbanController.js"></script>
			<script type="text/javascript" src="scripts/controllers/SprintController.js"></script>
			<script type="text/javascript" src="scripts/controllers/NewCardController.js"></script>

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

var monAppli 		= angular.module('evalentretien',['ui.bootstrap','angular.filter','demoApp']);
		
		<!-- SERVICE AJAX CRUD DE LAPPLICATION (ANGULAR) -->
		monAppli.factory('ajax', function($http) {
		   
		   <!-- Récupérer la liste des candidats -->
		   return {
				 getCandidats: function(callback) {
				   $http.get('listePersonnes.json').success(callback);
				 }
			}
		});
		

	
<!-- CONTROLEUR PRINCIPAL -->
		monAppli.controller("Controleur", function ($scope,$http,$filter,ajax) {
			
<!------------------------------------------ INITIALISATION DES VARIABLES -->
			
			$scope.candidats		=	[]; <!-- Le modèle Unique(Liste de tous les candidats et de leur entretien )-->
			$scope.idAudit			=	1; <!-- Lorsqu'on clique sur evaluer ou modifier, cette variable se remplit de l'id  du candidat à auditer. -->
		
			
				
			<!-- PREREQUIS METIERS (provisoire, cela stocké dans un fichier JSON)-->
			$scope.metier 	= 
				[
				{"id":"1",	"nom":"Technicien Info",		"prerequis":	{"maths":"12","lettres":"10","motivation":"15","cv":"8","orthographe":"15","etudes":"8","experience":"14","diplome":"Bts","disponibilite":"12","communication":"6","creativite":"3","sportivite":"10"}},
				{"id":"2",	"nom":"Plombier",				"prerequis":	{"maths":"4","lettres":"2","motivation":"15","cv":"2","orthographe":"2","etudes":"6","experience":"14","diplome":"Cap","disponibilite":"10","communication":"10","creativite":"10","sportivite":"18"}},
				{"id":"3",	"nom":"Plaquiste",				"prerequis":	{"maths":"1","lettres":"1","motivation":"8","cv":"3","orthographe":"2","etudes":"3","experience":"5","diplome":"Cap","disponibilite":"3","communication":"5","creativite":"2","sportivite":"18"}},
				{"id":"4",	"nom":"Electricien",			"prerequis":	{"maths":"5","lettres":"5","motivation":"7","cv":"9","orthographe":"2","etudes":"2","experience":"6","diplome":"Bac","disponibilite":"2","communication":"5","creativite":"3","sportivite":"15"}},
				{"id":"5",	"nom":"Ingénieur Informatique",	"prerequis":	{"maths":"18","lettres":"15","motivation":"18","cv":"12","orthographe":"15","etudes":"15","experience":"10","diplome":"Ingénieur","disponibilite":"12","communication":"14","creativite":"10","sportivite":"6"}},
				{"id":"6",	"nom":"Commercial",				"prerequis":	{"maths":"8","lettres":"4","motivation":"6","cv":"3","orthographe":"4","etudes":"10","experience":"6","diplome":"Licence","disponibilite":"16","communication":"17","creativite":"4","sportivite":"3"}}
				]
				;
			
			
			
			
			<!-- ONGLETS DYNAMIQUES -->
			$scope.tabs = [ {
					title: "Notes",
					content: '<h1>tab 4</h1>'
				}
			];
			
<!--------------------------------------------------------- DEBUT DU PROGRAMME -->
			
			<!-- APPEL AJAX de la listePersonnes via le service ajax -->
		ajax.getCandidats(function(data){
			$scope.candidats = data; 			<!-- Chargement du modèle. -->
			$scope.getCandidat(1); 				<!-- Initialisation provisoire du programme avec le candidat qui a lid 1  -->
		});
			
	

		  
		
<!-- CHOIX DUN CANDIDAT	PUIS ENTRETIEN -->
		<!-- Affichage des données d'un candidat en fonction de son id ,de la fenêtre entretien, après un click sur le bouton evaluer -->
		$scope.getCandidat = function(id){
			$scope.idAudit	 = id-1;		<!-- On affecte l'id du candidat choisi à idAudit pour que la vue de la fenetre entretien change en live -->
			$scope.getGraph1(null,id); 		<!-- On dessine le graphe avec les données Json contenues dans $scope.candidats -->
			
			<!-- LES NOTES : -->
			var notes = $scope.candidats[id].notes;
			<!-- $("#note").html(notes);   -->	<!-- Le refresh de ckeditor ne fonctionne pas avec angular ng-model -->
			<!--  $( document ).ready( function() {$( 'textarea#note' ).ckeditor();}); -->  <!-- Le refresh de ckeditor ne fonctionne pas avec angular ng-model -->
		}		
		
	

<!-- ENREGISTREMENT D UN ENTRETIEN -->
	$scope.rEntretien = function(){
		var note	= $( 'textarea#note' ).val();
		$scope.candidats[$scope.idAudit].rdvEffectue = "1";								<!--  Affecte le boolén 1 au candidat qui a été evalué -->
		$scope.candidats[$scope.idAudit].idmetier 	= $scope.correctlySelected.id-1; 	<!-- Affecte l'id metier au candidat -->
		$scope.candidats[$scope.idAudit].emploi 	= $scope.correctlySelected.nom; 	<!-- Affecte le nom du metier au candidat -->
		$scope.candidats[$scope.idAudit].notes 		= note;
		
		
		
		
		
		
				$scope.candidats[$scope.idAudit].resultat 	= getResultatTotal().toFixed(2);
		
		function getResultatTotal(){ 
		var x = eval($scope.candidats[$scope.idAudit].evaluation.motivation)
		+eval($scope.candidats[$scope.idAudit].evaluation.cv)+
		+eval($scope.candidats[$scope.idAudit].evaluation.orthographe)+
		+eval($scope.candidats[$scope.idAudit].evaluation.etudes)+
		+eval($scope.candidats[$scope.idAudit].evaluation.experience)+
		+eval($scope.candidats[$scope.idAudit].evaluation.disponibilite)+
		+eval($scope.candidats[$scope.idAudit].evaluation.communication)+
		+eval($scope.candidats[$scope.idAudit].evaluation.maths)+
		+eval($scope.candidats[$scope.idAudit].evaluation.lettres)+
		+eval($scope.candidats[$scope.idAudit].evaluation.creativite)+
		+eval($scope.candidats[$scope.idAudit].evaluation.sportivite);
		return x;
		};
		
		
		
		
		
		
		
		
		
		$scope.candidats[$scope.idAudit].noteMoyenne 	= getResultatTotalMoyenne().toFixed(2);
		
		function getResultatTotalMoyenne(){ 
		var x = eval($scope.candidats[$scope.idAudit].evaluation.motivation)
		+eval($scope.candidats[$scope.idAudit].evaluation.cv)+
		+eval($scope.candidats[$scope.idAudit].evaluation.orthographe)+
		+eval($scope.candidats[$scope.idAudit].evaluation.etudes)+
		+eval($scope.candidats[$scope.idAudit].evaluation.experience)+
		+eval($scope.candidats[$scope.idAudit].evaluation.disponibilite)+
		+eval($scope.candidats[$scope.idAudit].evaluation.communication)+
		+eval($scope.candidats[$scope.idAudit].evaluation.maths)+
		+eval($scope.candidats[$scope.idAudit].evaluation.lettres)+
		+eval($scope.candidats[$scope.idAudit].evaluation.creativite)+
		+eval($scope.candidats[$scope.idAudit].evaluation.sportivite);
		return x/11;
		};
		
		
		
		
		function getPrerequisTotalMoyenne(){
		var x =  eval($scope.metier[$scope.correctlySelected.id-1].prerequis.motivation)
		+eval($scope.metier[$scope.correctlySelected.id-1].prerequis.cv)+
		+eval($scope.metier[$scope.correctlySelected.id-1].prerequis.orthographe)+
		+eval($scope.metier[$scope.correctlySelected.id-1].prerequis.etudes)+
		+eval($scope.metier[$scope.correctlySelected.id-1].prerequis.experience)+
		+eval($scope.metier[$scope.correctlySelected.id-1].prerequis.disponibilite)+
		+eval($scope.metier[$scope.correctlySelected.id-1].prerequis.communication)+
		+eval($scope.metier[$scope.correctlySelected.id-1].prerequis.maths)+
		+eval($scope.metier[$scope.correctlySelected.id-1].prerequis.lettres)+
		+eval($scope.metier[$scope.correctlySelected.id-1].prerequis.creativite)+
		+eval($scope.metier[$scope.correctlySelected.id-1].prerequis.sportivite);
		return x/11;
		};
		
		
		$scope.candidats[$scope.idAudit].matching 	= getResultatTotalMoyenne().toFixed(2)-getPrerequisTotalMoyenne().toFixed(2);
		
		
		
		

	};
	
	
	
	

	
<!-- MODIFICATION DUN ENTRETIEN DEJA EFFECTUE-->
	$scope.modifCandidat = function(id){
		$scope.idAudit	 = id-1;
		var emploiCandidate = $scope.candidats[id-1].idmetier; <!-- retrouve l'emploi pour lequel la personne a été auditée -->
		$scope.correctlySelected = $scope.metier[emploiCandidate]; <!-- Mets le select de lemploi a la bonne valeur -->
		$scope.getGraph1(emploiCandidate,id-1); <!-- On dessine le graphe avec les données Json contenues dans $scope.entretienCandidat -->
		var notes = candidats[$scope.idAudit].notes;
		
		<!-- $("#note").html(notes);	 -->  <!-- Le refresh de ckeditor ne fonctionne pas avec angular ng-model -->
		<!-- $( document ).ready( function() {$( 'textarea#note' ).ckeditor();}); -->  <!-- Le refresh de ckeditor ne fonctionne pas avec angular ng-model -->
		}
		  
		  
		 <!-- Permet de supprimer un onglet dans la fenetre de l' entretien -->
		$scope.removeTab = function (index) {
			$scope.tabs.splice(index, 1);
		}; 
		
		
<!------------------------------------------------- TOUT CE QUI CONCERNE LE GRAPHIQUE HIGH CHART COMPARAISON PREREQUIS-CANDIDAT -->
		
			<!-- Récupère les variables de l'évaluation en temps réel et les injecte dans le graphe -->
		$scope.getGraph1 =  function(idPrerequis,idAudit){
			
			if (idPrerequis == null){// Affecte un prérequis par défaut à l'ouverture du programme
				idPrerequis = 1;
			};
			
				<!-- Partie du Graphe avec les données du prérequis métier -->
			$scope.evaluationPrerequis = [
					eval($scope.metier[idPrerequis].prerequis.motivation),
					eval($scope.metier[idPrerequis].prerequis.cv),
					eval($scope.metier[idPrerequis].prerequis.orthographe),
					eval($scope.metier[idPrerequis].prerequis.etudes),
					eval($scope.metier[idPrerequis].prerequis.experience),
					eval($scope.metier[idPrerequis].prerequis.communication),
					eval($scope.metier[idPrerequis].prerequis.disponibilite),
					eval($scope.metier[idPrerequis].prerequis.maths),
					eval($scope.metier[idPrerequis].prerequis.lettres),
					eval($scope.metier[idPrerequis].prerequis.creativite),
					eval($scope.metier[idPrerequis].prerequis.sportivite)
					];
		<!-- Partie du Graphe avec les données de l'évaluation du candidat -->
			$scope.evaluationG = [
					eval($scope.candidats[idAudit].evaluation.motivation),
					eval($scope.candidats[idAudit].evaluation.cv),
					eval($scope.candidats[idAudit].evaluation.orthographe),
					eval($scope.candidats[idAudit].evaluation.etudes),
					eval($scope.candidats[idAudit].evaluation.experience),
					eval($scope.candidats[idAudit].evaluation.communication),
					eval($scope.candidats[idAudit].evaluation.disponibilite),
					eval($scope.candidats[idAudit].evaluation.maths),
					eval($scope.candidats[idAudit].evaluation.lettres),
					eval($scope.candidats[idAudit].evaluation.creativite),
					eval($scope.candidats[idAudit].evaluation.sportivite)
					];

		
		}
		
		
		
		
		
		
		
		
		$scope.G3=function() {
		
		
			$('#gstats1').empty();
		//evaluation
			$('#gstats1').highcharts({
								chart: {
									type: 'column',
									margin: 80,
									options3d: {
										enabled: false,
										alpha: 5,
										beta: 5,
										depth: 50
									}
								},
								title: {
									text: 'Evaluation'
								},
								tooltip: {
									headerFormat: '<b>{point.key}</b><br>',
									pointFormat: '<span style="color:{series.color}">\u25CF</span> {series.name}: {point.y} / {point.stackTotal}'
								},
								
								        legend: {
									align: 'right',
									verticalAlign: 'top',
									layout: 'vertical',
									x: 0,
									y: 20
								},
								
								
								
								subtitle: {
									text: 'Comparaison Candidat->Pré-requis Métier'
								},
								plotOptions: {
									column: {
										depth: 10
									}
								},
								xAxis: {
									categories: ['Motivation', 'Curriculum Vitae', 'Orthographe', 'Etudes', 'Expérience','Communication','Disponibilité','Maths','Lettres','Créativité','Sportivité'] 
									
								},
								yAxis: {
									title: {
										text: "Etoiles"
									}
								},
								series: [   {
											name: 'Candidat',
											data: $scope.evaluationG ,
											type: 'spline'
											},
											
											{
											name: 'Prérequis',
											data: $scope.evaluationPrerequis,
											},
										]
							});
			};
			
			$scope.G3();
			
			 
			 
			 
			 
<!--------------------------------------------------------------------------  FILTRES -->
			 
			 <!--  FILTRE LE MODELE PAR RDV EFFECTUE OUI ou NON -->
			  $scope.isActive = function(candidat) {
				return candidat.rdvEffectue === "0";
			};
			
			<!--  FILTRE LE MODELE PAR RDV EFFECTUE OUI ou NON -->
			  $scope.notActive = function(candidat) {
				return candidat.rdvEffectue === "1";
			};
			
			
			<!--  FILTRE LE MODELE PAR DATE -->
			  $scope.filtreDate = function(candidat) {
					var date = $scope.dt ; 
					var date = $filter('date')(date,'dd-MM-yyyy'); 
					return candidat.dateRdv === date;
				};
			
			<!-- FILTRE LE MODELE PAR EMPLOI -->
				$scope.filtreEmploi = function(candidat) {
					return candidat.emploi === $scope.correctlySelectedAdequation.nom;
					
				};
				
				$scope.getResultat = function(candidat){
				
				var resultat = eval(candidat.evaluation.etudes);
				return resultat;
					
				
				
				
				}
			

			
			

<!------------------------------------------------------------- DATE PICKER -->
		$scope.today = function() {
			$scope.dt = new Date();
		  };
		  $scope.today();

		  $scope.clear = function () {
			$scope.dt = null;
		  };

		  // Disable weekend selection
		  $scope.disabled = function(date, mode) {
			return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
		  };
		$scope.toggleMin = function() {
			$scope.minDate = $scope.minDate ? null : new Date();
		  };
		  $scope.toggleMin();

		  $scope.open = function($event) {
			$event.preventDefault();
			$event.stopPropagation();

			$scope.opened = true;
		  };

		  $scope.dateOptions = {
			formatYear: 'yy',
			startingDay: 1
		  };

		  $scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
		  $scope.format = $scope.formats[0];
		  
		  
<!-------------------------------------------------------- EVALUATIONS PAR ETOILES -->
		$scope.rate = 0;
		$scope.max = 20;
		$scope.isReadonly = false;
		$scope.correctlySelected = $scope.metier[0];// select des competences metier
		$scope.correctlySelectedAdequation = $scope.metier[0];
		$scope.x = 0;
		

		$scope.getIdMetier = function(){
			$scope.x = $scope.correctlySelected.id-1;// choisi le nom dans le menu select de "prerequis metier"
			
			$scope.getGraph1($scope.x);
		};
		



$scope.scdt = function (){
			$( "#listeCandidats" ).dialog("open");
};


<!-- Fin du Controleur		 -->	
});
	
	
	
	$(document).ready(function() {
		$(function() {
				$( "#listeEntretiens" ).dialog({width:900,height:800,autoOpen: true,draggable:false,appendTo: 'body'}).dialogExtend({
						"closable" : true,
						"maximizable" : false,
						"minimizable" : false,
						"collapsable" : true,
						"dblclick" : "collapse",
						"minimizeLocation" : "left",
						});
				$( "#listeEntretiens" ).dialog("close");
			});
			
		
			
			
		$(function() {
				$( "#listeCandidats" ).dialog({width:600,height:800,autoOpen: true,draggable: false,appendTo: 'body'}).dialogExtend({
						"closable" : true,
						"maximizable" : false,
						"minimizable" : false,
						"collapsable" : true,
						"dblclick" : "collapse",
						"minimizeLocation" : "left",
						});
				$( "#listeCandidats" ).dialog("close");
			});
		});
		

		
function sent(){
			$( "#listeEntretiens" ).dialog("open");
};
				
		
</script>
</head>
<body ng-controller='Controleur' >

<div class="main" class="outer">
		
	<!-- MENU -->
	<div id="menu">
			<button ng-click="scdt()" class="menutop">Sélectionner un candidat <img src="candidat.jpg" class="miniphoto button "></button>
			<button onclick="sent()" class="menutop">Entretiens effectués <img src="listeEntretiens.jpg" class="miniphoto button "></button>
			<!-- <button ng-click="parametrer()" class="menutop">Meilleures adéquations <img src="adequation.png" class="miniphoto button "></button> -->
			<button ng-click="parametrer()" class="menutop">Statistiques <img src="stats.png" class="miniphoto button "></button>
	</div>
	
	<!-- L ENTRETIEN ET SES ONGLETS -->
	<div id="entretienUnique" class="outer"><div class="topBar"><img src="entretien.jpg" class="image"> Entretien de <b>{{candidats[idAudit].prenom}} {{candidats[idAudit].nom.toUpperCase()}}</b>
	 pour l'emploi de <select ng-model="correctlySelected" ng-options="opt as opt.nom for opt in metier" ng-change="getIdMetier()" > 	
							</select><br>
	</div>
	

		<div>
			<tabset>
			
				<!-- LES INFOS GENERALE DU CANDIDAT -->
				<tab heading="Informations">
				
					<table class="CSSTableGenerator bigLetters" >
						<tr>
							<th>Description</th>
							<th>Détail</th>
						
						<tr>
							<td>Photo:</td>
							<td><img class="imageBig" src="{{candidats[idAudit].photo}}" ></img></td>
						</tr>
						
						
						
						<tr>
							<td>Id :</td>
							<td>{{candidats[idAudit].id}}</input></td>
						</tr>
						<tr>
							<td>Prénom :</td>
							<td><input ng-model="candidats[idAudit].prenom" ></input></td>
						</tr>
						<tr>
							<td>Nom :</td>
							<td><input ng-model="candidats[idAudit].nom" ></input></td>
						</tr>
						<tr>
							<td>Age :</td>
							<td><input ng-model="candidats[idAudit].age" disabled></input></td>
						</tr>
						<tr>
							<td>CSP: :</td>
							<td><input ng-model="candidats[idAudit].csp" disabled></input></td>
						</tr>
						<tr>
						<tr>
							<td>Catégorie :</td>
							<td><input ng-model="candidats[idAudit].categorie" disabled></input></td>
						</tr>
						<tr>
							<td>Emploi :</td>
							<td><input ng-model="candidats[idAudit].emploi" disabled></input></td>
						</tr>
						<tr>
							<td>Heure:</td>
							<td><input ng-model="candidats[idAudit].heure" disabled></input></td>
						</tr>
						<tr>
							<td>Date:</td>
							<td><input ng-model="candidats[idAudit].dateRdv"></input></td>
						</tr>
						
					
					</table>	
			</tab>
				
			
				
				
			<!-- 	L EVALUATION PAR ETOILES DU CANDIDAT -->
				<tab heading="Evaluation" >
					<div>
					
						<div class="encadre" style="float:left;width:50%">
						
						<h3>Evaluation du Candidat</h3>  <br>
				
							<!-- <table> <tr ng-model="candidats" ng-repeat="truc in candidats[idAudit].evaluation" >
							<td>{{motivation}}</td>
							<td></td>
							</tr>
							</table> -->
							<p>
							Motivation<br>
							   <rating ng-model="candidats[idAudit].evaluation.motivation" 		ng-change="getGraph1(null,idAudit)" max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>{{candidats[idAudit].evaluation.motivation}}/20
								<br>
								<rating ng-model="metier[x].prerequis.motivation" 	style="color:red"		max="max" readonly="isReadonly"	></rating>{{metier[x].prerequis.motivation}}/20<br>
								   
							Curriculum Vitae<br>
								<rating ng-model="candidats[idAudit].evaluation.cv" 			ng-change="getGraph1(null,idAudit)"  max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>{{candidats[idAudit].evaluation.cv}}/20<br>
								<rating ng-model="metier[x].prerequis.cv" 			style="color:red"	max="max" readonly="isReadonly"	></rating>{{metier[x].prerequis.cv}}/20<br>

							
							Niveau d'études<br>
								<rating ng-model="candidats[idAudit].evaluation.etudes" 		ng-change="getGraph1(null,idAudit)"  max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>{{candidats[idAudit].evaluation.etudes}}/20<br>
							<rating ng-model="metier[x].prerequis.etudes" 		style="color:red"		max="max" readonly="isReadonly"	></rating><br>
							
							Expérience <br>
								<rating ng-model="candidats[idAudit].evaluation.experience" 	ng-change="getGraph1(null,idAudit)"  max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>{{candidats[idAudit].evaluation.experience}}/20<br>
								<rating ng-model="metier[x].prerequis.experience" 	style="color:red"		max="max" readonly="isReadonly" ></rating><br>
							Communication<br>
								<rating ng-model="candidats[idAudit].evaluation.communication" 	ng-change="getGraph1(null,idAudit)"  max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>{{candidats[idAudit].evaluation.communication}}/20<br>
								<rating ng-model="metier[x].prerequis.communication" style="color:red"		max="max" readonly="isReadonly" ></rating><br>
							Disponibilité<br>
								<rating ng-model="candidats[idAudit].evaluation.disponibilite" 	ng-change="getGraph1(null,idAudit)"  max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>{{candidats[idAudit].evaluation.disponibilite}}/20<br>
								<rating ng-model="metier[x].prerequis.disponibilite" style="color:red"		max="max" readonly="isReadonly" ></rating><br>
							Orthographe<br>
								<rating ng-model="candidats[idAudit].evaluation.orthographe" 	ng-change="getGraph1(null,idAudit)"  max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>{{candidats[idAudit].evaluation.orthographe}}/20<br>
								<rating ng-model="metier[x].prerequis.orthographe" 	style="color:red"		max="max" readonly="isReadonly"	></rating><br>
							
							
							Maths<br>
							   <rating ng-model="candidats[idAudit].evaluation.maths" max="max" ng-change="getGraph1(null,idAudit)"  readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>{{candidats[idAudit].evaluation.maths}}/20<br>
								<rating ng-model="metier[x].prerequis.maths" 		style="color:red"		max="max" readonly="isReadonly" ></rating><br>
							Lettres<br>
								<rating ng-model="candidats[idAudit].evaluation.lettres" 		ng-change="getGraph1(null,idAudit)"  max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>{{candidats[idAudit].evaluation.lettres}}/20<br>
								<rating ng-model="metier[x].prerequis.lettres" 		style="color:red"		max="max" readonly="isReadonly" ></rating><br>
							Créativité<br>
								<rating ng-model="candidats[idAudit].evaluation.creativite" 	ng-change="getGraph1(null,idAudit)"  max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>{{candidats[idAudit].evaluation.creativite}}/20<br>
								<rating ng-model="metier[x].prerequis.creativite" 	style="color:red"		max="max" readonly="isReadonly" ></rating><br>
							Sportivité<br>
								<rating ng-model="candidats[idAudit].evaluation.sportivite" 	ng-change="getGraph1(null,idAudit)"  max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>{{candidats[idAudit].evaluation.sportivite}}/20<br>
								<rating ng-model="metier[x].prerequis.sportivite" 	style="color:red"		max="max" readonly="isReadonly" ></rating><br>
							</p>
						
						</div>
						
						<div class="encadre" style="float:left;width:50%;background-color:oldlace">
						
						<h3>Prérequis du Métier :</h3> Diplôme 
									<b>{{metier[x].prerequis.diplome}}</b>
							<br>	<br>
							
							<p>
							Motivation<br>
								   <rating ng-model="metier[x].prerequis.motivation" 	style="color:red"		max="max" readonly="isReadonly"	></rating><br>
								   
								   
							Curriculum Vitae<br>
									<rating ng-model="metier[x].prerequis.cv" 			style="color:red"	max="max" readonly="isReadonly"	></rating><br>
							Orthographe<br>
									<rating ng-model="metier[x].prerequis.orthographe" 	style="color:red"		max="max" readonly="isReadonly"	></rating><br>
							Etudes<br>
									<rating ng-model="metier[x].prerequis.etudes" 		style="color:red"		max="max" readonly="isReadonly"	></rating><br>
							Expérience <br>
									<rating ng-model="metier[x].prerequis.experience" 	style="color:red"		max="max" readonly="isReadonly" ></rating><br>
							Communication<br>
									<rating ng-model="metier[x].prerequis.communication" style="color:red"		max="max" readonly="isReadonly" ></rating><br>
							Disponibilité<br>
									<rating ng-model="metier[x].prerequis.disponibilite" style="color:red"		max="max" readonly="isReadonly" ></rating><br>
							Maths<br>
								   <rating ng-model="metier[x].prerequis.maths" 		style="color:red"		max="max" readonly="isReadonly" ></rating><br>
							Lettres<br>
									<rating ng-model="metier[x].prerequis.lettres" 		style="color:red"		max="max" readonly="isReadonly" ></rating><br>
							Créativité<br>
									<rating ng-model="metier[x].prerequis.creativite" 	style="color:red"		max="max" readonly="isReadonly" ></rating><br>
							Sportivité<br>
									<rating ng-model="metier[x].prerequis.sportivite" 	style="color:red"		max="max" readonly="isReadonly" ></rating><br>
							
							
							
							<h3>Taux de matching de {{candidats[idAudit].prenom}}:{{candidats[idAudit].matching}}%</h3>	
							
							</p>
							 
						</div>
					</div>
				</tab>
				
				
				<!-- LES PROJETS DU CANDIDAT	 -->
				<tab heading="Projets">
				<div style="overflow:auto;">
				<nav class="navbar navbar-default " role="navigation">
					<div class="container-fluid" >
						<div class="board-header">
							<ul class="nav nav-tabs nav-justified">
								<li><a href="#/kanban" ng-class="{active: isActive('#/kanban')}">Mes projets</a></li>
						<!-- 	  <li><a href="#/sprint" ng-class="{active: isActive('#/sprint')}">Sprint</a></li>  -->
							</ul>
						</div>
					<div ng-view ></div>
				</nav>
					Dévelopement originel : http://a5hik.github.io/ng-sortable/#/kanban
				</div>
				</tab>
				
				<!-- 	LES STATISTIQUES DU CANDIDAT -->
				<tab heading="Statistiques d'adéquation">
				
					Des graphes qui vont récapituler l'adéquation du candidat etc ...
			<!-- 		<div style="width:100%;height:100%;"> -->
						<div id="gstats1" ng-model="G3()" style="width:100%;height:80%"></div>
						
					<!-- </div> -->

				</tab>
				
				<!-- LES ONGLETS AUTO GENERES	 -->
				<tab ng-repeat="t in tabs">
					<tab-heading>{{t.title}} <a  ng-click="removeTab($index)" data-target="#Evaluation"><i class="glyphicon glyphicon-remove-sign"></i></a></tab-heading>
					<!-- <div ng-bind='t.content'></div> -->
					<textarea  ng-model="::candidats[idAudit].notes"	name="note" id="note" style = "width:100%;height:70%""></textarea>
					<!-- <button class="buttonform right" type="buttonform" onclick="ckeditor()" >Enregistrer</button> -->
				</tab>
			</tabset>
		</div>
	</div>

<div class="barreBas">
			
			<button ng-click="rEntretien()" class="menutop"> <span class="glyphicon glyphicon-floppy-disk"></span> Enregistrer</button>
		</div>
	</div>
	
	
	
	
	
	
	
	
	
	
	
	
	
	<!-- LISTE DES CANDIDATS -->
	<div id="listeCandidats" title="Sélectionner un Candidat" class="outer"><div class="topBar "><img src="candidat.jpg" class="image"></img>Candidats </div>
		
		<div id ="tableListeCandidats">
		Recherche:<input ng-model="query" type="text" />
			<table class="CSSTableGenerator " >	
				<tr >
					<th>id</th>
					<th>Photo</th>
					<th>Prénom</th>
					<th>Nom</th>
					<th>Heure</th>
					<th>Evaluer</th>
				</tr>
				<tr ng-repeat="candidat in candidats | filter:query | filter:isActive |filter:filtreDate| orderBy:'heure'" >
					<td>{{candidat.id}}</td>
					<td><img src="{{candidat.photo}}" class="miniphoto"></img></td>
					<td>{{candidat.prenom}}</td>
					<td>{{candidat.nom.toUpperCase()}}</td>
					<td>{{candidat.heure}}</td>
					<td><button ng-click="getCandidat(candidat.id)">Evaluer</button></td>
				</tr>
			</table>
			
		</div>
		<div class="barreBas">
	
		</div>

		<!-- LE CALENDRIER -->
		<br>
		<div id="calendrier"><div class="topBar"><img src="calendrier.png" class="image"> Calendrier</div>
				 <div  id="date">
				
				Pour la démo, choisir le 21 Avril 2015
				<pre>Vous avez sélectionné cette date: <em>{{dt | date:'dd-MM-yyyy' }} </em></pre>

				
				<div style="display:inline-block; min-height:100px;">
					<datepicker ng-model="dt" min-date="" show-weeks="true" class="well well-sm"></datepicker>
					 <p class="input-group">
           
            </p>
				</div>
				</div>
		</div>
		
		
		<div class="barreBas">
		

		</div>
	</div>
		
	
	
	
	
	
	
	
	
	

	<!-- LA LISTE DES ENTRETIENS EFFECTUES -->
	
	<div id="listeEntretiens" title="Entretiens Effectués" class="outer"><div class="topBar"><img src="listeEntretiens.jpg" class="image"> Entretiens Effectués</div>
		<div id="lst">
			
		Recherche:<input ng-model="queryg" type="text" />
			<table class="CSSTableGenerator " >	
				<tr >
					<th>id</th>
					<th>Photo</th>
					<th>Emploi</th>
					<th>Nom</th>
					<th>Date</th>
					<th>Modifier</th>
				</tr>
				<tr ng-model="candidats" ng-repeat="candidat in candidats | filter:queryg |filter:notActive  |orderBy:'heure'" >
					<td>{{candidat.id}}</td>
					<td><img src="{{candidat.photo}}" class="miniphoto"></img></td>
					<td>{{candidat.emploi}}</td>
					<td>{{candidat.nom.toUpperCase()}}</td>
					<td>{{candidat.dateRdv}}</td>
					<td><button ng-click="modifCandidat(candidat.id)">Modifier</button></td>
				</tr>
			</table>
			
		
		</div>
		
		<!-- LES MEILLEURES ADEQUATIONS -->
		<div id="adequation">
			<div class="topBar" ><img src="adequation.png" class="image">  Meilleures Adéquations</div>
					Ici, on pourra visionner dans l'ordre les meilleurs candidats en fonction d'un emploi ou d'une catégorie.
			
			<select ng-model="correctlySelectedAdequation" ng-options="opt as opt.nom for opt in metier" ng-change="getIdMetier()" >
							</select><br>
			<!-- <input ng-model="query" type="text" /> -->
			<table class="CSSTableGenerator " >	
				<tr >
					<th>id</th>
					<th>Photo</th>
					<th>Emploi</th>
					<th>Nom</th>
					<th>Date</th>
					<th >Note moyenne</th>
					<th ng-click="predicate='resultat'">Résultat</th>
					<th>Taux de Matching</th>
				</tr>
				<tr ng-model="candidats" ng-repeat="candidat in candidats | filter:query |filter:notActive  |filter:filtreEmploi |orderBy:predicate |orderBy:'candidat.resultat'" >
					<td>{{candidat.id}}</td>
					<td><img src="{{candidat.photo}}" class="miniphoto"></img></td>
					<td>{{candidat.emploi}}</td>
					<td>{{candidat.nom.toUpperCase()}}</td>
					<td>{{candidat.dateRdv}}</td>
					<td><b>{{candidat.noteMoyenne}}/20</b></td>
					<td><b>{{candidat.resultat}}</b></td>
					<td><b>{{candidat.matching}}%</b></td>
				</tr>
			</table>
			
			
			
			
			
			
			
			
			
			
			<div class="barreBas">
				Recherche:<input ng-model="query" type="text" />
			</div>
		</div>
	</div>
	
	<!-- < LA DIV INFERIEURE>	 -->
	<div class="barreBas">
		</img>
	</div>
	
<!-- FIN DE LA DIV MAIN -->
</div>
</body>
</html>


<style>

p,h3{
margin-left:5px;
}

.image{
margin-left:8px;
margin-top:5px;
width:40px;
height:40px;

}

.miniphoto{
width:25px;
height:25px;

}

.imageBig{
width:150px;
height:150px;
}



.encadre{
	text-align:left;
	-moz-border-radius-bottomright:14px;
	-webkit-border-bottom-right-radius:14px;
	border-bottom-right-radius:14px;
	
	-moz-border-radius-topright:14px;
	-webkit-border-top-right-radius:14px;
	border-top-right-radius:14px;
	
	-moz-border-radius-topleft:14px;
	-webkit-border-top-left-radius:14px;
	border-top-left-radius:14px;
	-webkit-border-radius: 4px 4px 4px 4px;
	border-radius: 4px 4px 4px 4px;
	-webkit-box-shadow:inset 2px 2px 2px 2px #635453;


}


.topBar{
	height:50px;
		font-size:1.2em;
	background-color:darkgrey;

	-webkit-box-shadow:inset 2px 2px 2px 2px #635453;
	box-shadow:inset 2px 2px 2px 2px #635453;

	font-size:12px;
	font-style:bold;
	overflow:auto;
}


#menu{
	margin-top:auto;
	margin-left:auto;
	margin-right:auto;
	margin-bottom:auto;
	width:100%;
	height:5%;
	background-color:white;

	float:left;


}





#entretienUnique{
	margin-top:auto;
	margin-left:auto;
	margin-right:auto;
	margin-bottom:auto;
	width:100%;
	min-width:100%;
	height:95%;
		;-webkit-border-radius: 12px 12px 12px 12px;-moz-border-radius: 12px 12px 12px 12px;border-radius: 12px 12px 12px 12px;border:5px solid #757575;background-color:#ffffff;-webkit-box-shadow: #B3B3B3 8px 8px 8px;-moz-box-shadow: #B3B3B3 8px 8px 8px; box-shadow: #B3B3B3 8px 8px 8px;
	
	float:left;
	
}



#listeEntretiens{
	margin-top:5%;
	margin-left:auto;
	margin-right:auto;
	margin-bottom:auto;
	width:45%;
	height:100%;
	;-webkit-border-radius: 12px 12px 12px 12px;-moz-border-radius: 12px 12px 12px 12px;border-radius: 12px 12px 12px 12px;border:5px solid #757575;background-color:#ffffff;-webkit-box-shadow: #B3B3B3 8px 8px 8px;-moz-box-shadow: #B3B3B3 8px 8px 8px; box-shadow: #B3B3B3 8px 8px 8px;
	
	float:left;

	
}




#lst{
overflow:auto;
max-height:40%;
min-height:40%;

}

#adequation{
	height:35%;
	margin-top:auto;
	margin-left:auto;
	margin-right:auto;
	margin-bottom:auto;
	<!-- width:25%; -->
	<!-- height:43%; -->
	
	<!-- float:left; -->

}



#calendrier{
	margin-top:auto;
	margin-left:auto;
	margin-right:auto;
	margin-bottom:auto;
	<!-- width:25%; -->
	<!-- height:43%; -->
	
	<!-- float:left; -->

}


#tableListeCandidats{
overflow:auto;
max-height:40%;
min-height:40%;

}




/*PERMET DE PLACER UNE DIV EN ABS DUNE AUTRE DIV CONTENER. OUTER EST LA CLASSE DE LA DIV CONTENER, BARREBAS EST LA DIV A METTRE EN BAS*/

.barreBas{
	background-color:white;
    bottom: 0px;
	position:absolute;
	width:100%;
	text-align:right;
	background-color:lightgrey;
	border-radius: 12px 12px 12px 12px;

	
}
.outer {
	position: relative;
}
/* FIN  */

.logo{
width:10%;
heiht:10%
}

.bigLetters{
font-size:20px;

}



.CSSTableGenerator {
	margin:0px;padding:0px;
	width:100%;	box-shadow: 10px 10px 5px #888888;
	border:1px solid #000000;

	-moz-border-radius-bottomleft:14px;
	-webkit-border-bottom-left-radius:14px;
	border-bottom-left-radius:14px;

	-moz-border-radius-bottomright:14px;
	-webkit-border-bottom-right-radius:14px;
	border-bottom-right-radius:14px;

	-moz-border-radius-topright:14px;
	-webkit-border-top-right-radius:14px;
	border-top-right-radius:14px;

	-moz-border-radius-topleft:14px;
	-webkit-border-top-left-radius:14px;
	border-top-left-radius:14px;
}

.CSSTableGenerator table{
	width:100%;
	height:100%;
	margin:0px;padding:0px;
}.CSSTableGenerator th:last-child td:last-child {
-moz-border-radius-bottomright:14px;
-webkit-border-bottom-right-radius:14px;
border-bottom-right-radius:14px;
}
.CSSTableGenerator table th:first-child th:first-child {
-moz-border-radius-topleft:14px;
-webkit-border-top-left-radius:14px;
border-top-left-radius:14px;
}


.CSSTableGenerator table th:first-child td:last-child {
-moz-border-radius-topright:14px;
-webkit-border-top-right-radius:14px;
border-top-right-radius:14px;
}

.CSSTableGenerator tr:last-child td:first-child{
-moz-border-radius-bottomleft:14px;
-webkit-border-bottom-left-radius:14px;
border-bottom-left-radius:14px;
}

.CSSTableGenerator tr:hover td{
background-color:#ffffff;
}


.CSSTableGenerator td{
vertical-align:middle;
background-color:ivory;
border:1px solid white;
border-width:0px 1px 1px 0px;
text-align:left;
padding:7px;
font-size:12px;
font-family:Arial;
font-weight:normal;
color:#000000;
}

.CSSTableGenerator th{
vertical-align:middle;
background-color:salmon;
border:1px solid white;
border-width:0px 1px 1px 0px;
text-align:left;
padding:7px;
font-size:12px;
font-family:Arial;
font-weight:normal;
color:#000000;
}

















.CSSTableGenerator tr:last-child td{
border-width:0px 1px 0px 0px;
}.CSSTableGenerator tr td:last-child{
border-width:0px 0px 1px 0px;
}.CSSTableGenerator tr:last-child td:last-child{
border-width:0px 0px 0px 0px;
}
.CSSTableGenerator th:first-child td{
	background:-o-linear-gradient(bottom, #cccccc 5%, #b2b2b2 100%);	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #cccccc), color-stop(1, #b2b2b2) );	background:-moz-linear-gradient( center top, #cccccc 5%, #b2b2b2 100% );	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#cccccc", endColorstr="#b2b2b2");	background: -o-linear-gradient(top,#cccccc,b2b2b2);
background-color:#cccccc;
border:0px solid #000000;
text-align:center;
border-width:0px 0px 1px 1px;
font-size:14px;
font-family:Arial;
font-weight:bold;
color:#000000;
}
.CSSTableGenerator tr:first-child:hover td th{
	background:-o-linear-gradient(bottom, #cccccc 5%, #b2b2b2 100%);	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #cccccc), color-stop(1, #b2b2b2) );	background:-moz-linear-gradient( center top, #cccccc 5%, #b2b2b2 100% );	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#cccccc", endColorstr="#b2b2b2");	background: -o-linear-gradient(top,#cccccc,b2b2b2);
background-color:#cccccc;
}
.CSSTableGenerator tr:first-child td:first-child{
border-width:0px 0px 1px 0px;
}
.CSSTableGenerator tr:first-child td:last-child{
border-width:0px 0px 1px 1px;
}

Button {
	-moz-box-shadow: 0px 1px 0px 0px #1c1b18;
	-webkit-box-shadow: 0px 1px 0px 0px #1c1b18;
	box-shadow: 0px 1px 0px 0px #1c1b18;
	background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #eae0c2), color-stop(1, #ccc2a6));
	background:-moz-linear-gradient(top, #eae0c2 5%, #ccc2a6 100%);
	background:-webkit-linear-gradient(top, #eae0c2 5%, #ccc2a6 100%);
	background:-o-linear-gradient(top, #eae0c2 5%, #ccc2a6 100%);
	background:-ms-linear-gradient(top, #eae0c2 5%, #ccc2a6 100%);
	background:linear-gradient(to bottom, #eae0c2 5%, #ccc2a6 100%);
	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eae0c2', endColorstr='#ccc2a6',GradientType=0);
	background-color:#eae0c2;
	-moz-border-radius:15px;
	-webkit-border-radius:15px;
	border-radius:3px;
	border:2px solid #333029;
	display:inline-block;
	cursor:pointer;
	color:#010101;
	font-family:arial;
	font-size:12px;
	font-weight:bold;
	padding:2px 9px;
	text-decoration:none;
	text-shadow:0px 1px 0px #cecece;
	
	<!-- margin-top:5px; -->
}
Button:hover {
	background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #ccc2a6), color-stop(1, #eae0c2));
	background:-moz-linear-gradient(top, #ccc2a6 5%, #eae0c2 100%);
	background:-webkit-linear-gradient(top, #ccc2a6 5%, #eae0c2 100%);
	background:-o-linear-gradient(top, #ccc2a6 5%, #eae0c2 100%);
	background:-ms-linear-gradient(top, #ccc2a6 5%, #eae0c2 100%);
	background:linear-gradient(to bottom, #ccc2a6 5%, #eae0c2 100%);
	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ccc2a6', endColorstr='#eae0c2',GradientType=0);
	background-color:#ccc2a6;
}
Button:active {
	position:relative;
	top:1px;
}

.logo{
	height:50px;
	color:white;
}
</style>




Le fichier candidats.json

[


{"id":"1","photo":"man.jpg", "prenom":"Theodore", "nom":"Juvet","heure":"17:30", "dateRdv":"21-04-2015", "evaluation" : {"motivation":"0","cv":"0","orthographe":"0","etudes":"0","experience":"0","disponibilite":"0","communication":"0","maths":"0","lettres":"0","creativite":"0","sportivite":"0"},"notes":"Test","rdvEffectue":"0","emploi":"","idmetier":"1","resultat":""},
{"id":"2","photo":"man.jpg", "prenom":"Axel", "nom":"Chavert","heure":"08:30", "dateRdv":"21-04-2015", "evaluation" : {"motivation":"0","cv":"0","orthographe":"0","etudes":"0","experience":"0","disponibilite":"0","communication":"0","maths":"0","lettres":"0","creativite":"0","sportivite":"0"},"notes":"Test2","rdvEffectue":"0","emploi":"","idmetier":"2","resultat":""},
{"id":"3","photo":"candidat.jpg", "prenom":"Mohammed", "nom":"Fata","heure":"10:30", "dateRdv":"21-04-2015", "evaluation" : {"motivation":"0","cv":"0","orthographe":"0","etudes":"0","experience":"0","disponibilite":"0","communication":"0","maths":"0","lettres":"0","creativite":"0","sportivite":"0"},"notes":"Test3","rdvEffectue":"0","emploi":"","idmetier":"4","resultat":""},
{"id":"4","photo":"candidat.jpg", "prenom":"Chavez", "nom":"Williams","heure":"11:30", "dateRdv":"21-04-2015", "evaluation" : {"motivation":"0","cv":"0","orthographe":"0","etudes":"0","experience":"0","disponibilite":"2","communication":"3","maths":"4","lettres":"4","creativite":"5","sportivite":"3"},"notes":"Test4","rdvEffectue":"1","emploi":"Plombier","idmetier":"1","resultat":"19"},
{"id":"5","photo":"candidat.jpg", "prenom":"Phillipe", "nom":"Andrieux","heure":"17:30", "dateRdv":"21-04-2015", "evaluation" : {"motivation":"0","cv":"0","orthographe":"0","etudes":"0","experience":"0","disponibilite":"0","communication":"0","maths":"0","lettres":"0","creativite":"0","sportivite":"0"},"notes":"Test8","rdvEffectue":"0","emploi":"","idmetier":"2","resultat":""},
{"id":"6","photo":"candidat.jpg", "prenom":"Axel", "nom":"Dubourg","heure":"08:30", "dateRdv":"21-04-2015", "evaluation" : {"motivation":"0","cv":"0","orthographe":"0","etudes":"0","experience":"0","disponibilite":"0","communication":"0","maths":"0","lettres":"0","creativite":"0","sportivite":"0"},"notes":"Test7","rdvEffectue":"0","emploi":"","idmetier":"1","resultat":""},
{"id":"7","photo":"candidat.jpg", "prenom":"Trisha", "nom":"Ravel","heure":"10:30", "dateRdv":"21-04-2015", "evaluation" : {"motivation":"0","cv":"0","orthographe":"0","etudes":"0","experience":"0","disponibilite":"0","communication":"0","maths":"0","lettres":"0","creativite":"0","sportivite":"0"},"notes":"Test40","rdvEffectue":"0","emploi":"","idmetier":"3","resultat":""},
{"id":"8","photo":"candidat.jpg", "prenom":"Robert", "nom":"Zarinas","heure":"11:30", "dateRdv":"21-04-2015", "evaluation" : {"motivation":"0","cv":"0","orthographe":"0","etudes":"0","experience":"0","disponibilite":"0","communication":"0","maths":"0","lettres":"0","creativite":"0","sportivite":"0"},"notes":"Test","rdvEffectue":"0","emploi":"","idmetier":"2","resultat":""},
{"id":"9","photo":"candidat.jpg", "prenom":"Abdel", "nom":"Silias","heure":"17:30", "dateRdv":"21-04-2015", "evaluation" : {"motivation":"4","cv":"8","orthographe":"4","etudes":"9","experience":"1","disponibilite":"2","communication":"3","maths":"4","lettres":"4","creativite":"5","sportivite":"3"},"notes":"Test","rdvEffectue":"1","emploi":"Plaquiste","idmetier":"2","resultat":"43"},
{"id":"10","photo":"candidat.jpg", "prenom":"Patrick", "nom":"Gonzales","heure":"08:30", "dateRdv":"21-04-2015", "evaluation" : {"motivation":"0","cv":"0","orthographe":"0","etudes":"0","experience":"0","disponibilite":"0","communication":"0","maths":"0","lettres":"0","creativite":"0","sportivite":"0"},"notes":"Test","rdvEffectue":"0","emploi":"","idmetier":"0","resultat":""},
{"id":"11","photo":"candidat.jpg", "prenom":"Thierry", "nom":"Roc","heure":"10:30", "dateRdv":"21-04-2015", "evaluation" : {"motivation":"0","cv":"0","orthographe":"0","etudes":"0","experience":"0","disponibilite":"0","communication":"0","maths":"0","lettres":"0","creativite":"0","sportivite":"0"},"notes":"Test","rdvEffectue":"0","emploi":"","idmetier":"4","resultat":""},
{"id":"12","photo":"candidat.jpg", "prenom":"Ursula", "nom":"Hembert","heure":"11:30", "dateRdv":"21-04-2015", "evaluation" : {"motivation":"0","cv":"0","orthographe":"0","etudes":"0","experience":"0","disponibilite":"0","communication":"0","maths":"0","lettres":"0","creativite":"0","sportivite":"0"},"notes":"Test","rdvEffectue":"0","emploi":"","idmetier":"1","resultat":""},
{"id":"13","photo":"personne.gif", "prenom":"William", "nom":"Cindrocik","heure":"15:30", "dateRdv":"21-04-2015", "evaluation" : {"motivation":"0","cv":"0","orthographe":"0","etudes":"0","experience":"0","disponibilite":"0","communication":"0","maths":"0","lettres":"0","creativite":"0","sportivite":"0"},"notes":"Test","rdvEffectue":"0","emploi":"","idmetier":"2","resultat":""},
{"id":"14","photo":"candidat.jpg", "prenom":"Hammed", "nom":"Chaverto","heure":"11:30", "dateRdv":"21-04-2015", "evaluation" : {"motivation":"0","cv":"0","orthographe":"0","etudes":"7","experience":"0","disponibilite":"2","communication":"3","maths":"4","lettres":"4","creativite":"5","sportivite":"3"},"notes":"Test","rdvEffectue":"1","emploi":"Commercial","idmetier":"5","resultat":"28"},
{"id":"15","photo":"personne.gif", "prenom":"Grondin", "nom":"Kirckpatrick","heure":"15:30","dateRdv":"21-04-2015", "evaluation" : {"motivation":"0","cv":"5","orthographe":"0","etudes":"0","experience":"0","disponibilite":"2","communication":"3","maths":"4","lettres":"4","creativite":"5","sportivite":"3"},"notes":"Test","rdvEffectue":"1","emploi":"Commercial","idmetier":"5","resultat":"26"}



]

Publicités