[ Application 58] « Scanne ton Employé » Journal de développement au jour 3

scanneIntroduction


Aujourd’hui, on continue sur la vue nouveau.html, et on mets en place la vue liste.html.

Durée : 3h30 .

Pour tester l’application au jour 3 , cliquer ici.

Rappel de l’architecture de l’application  :


système angular api scannersystème angular api scanner-page-001

 

Fonctionnalités ajoutées dans la vue nouveau.html:


  • Possibilités d’imprimer la carte avec le code barre grâce à la fonction $scope.imprimerDiv().
  • Restriction de clics sur les boutons « Imprimer la carte » ou « sauvegarder » si l’id n’a pas été créé auparavant ( et donc que nouvelEmploye.identifiant soit inexistant ->ng-disabled= »!nouvelEmploye.identifiant « 
  • Analyse de l’objet Google Map récupéré par autocomplete.js, finalement, je ne récupère que formatted_address dans l’objet nouvelEmploye, on pourrait aussi récupérer seulement la ville ou le code postal ou etc …
  • Ajout du style « overflow:auto » sur la div de la carte, pour que cela ne dépasse pas sur mobile.

Fonctionnalités ajoutées dans la vue liste.html:


  • Affichage de la liste des employé dans une table HMTL, provenant du back end Firebase.
  • Ajout du style « overflow:auto », pour que la table ne soit pas horrible sur mobile.

Voici le look d’un enregistrement au format JSON sur Firebase, c’est très pratique !  (On voit qu’au jour 3 il manque encore la date de naissance, qui est un objet que je n’ai pas encore formaté dans la vue nouveau:

rscanner

Chaque nouvel employé est ajouté dans le tableau d’objets JSON employes sur Firebase, en ligne !

 

Ajout de modules AngularJs 1.5 avec BOWER:


  • Ajout du module angular-notifier pour toutes les notifications dans l’application(Remplace les alert de js).
  • Ajout du module Firebase pour le gérer back-end, vu qu’on ne traite qu’un seul tableau (array) nommé employes au pluriel sur le back end firebase,  on ajoute au contrôleur seulement $firebaseArray(Voir le code)

 

 

Le Code


Index.html : de nouvelles libs sont ajoutées !

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Neutre</title>
	<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">

		<!-- CHARGEMENT DES LIBRAIRIES -->

		<!-- JQUERY ET BOOTSRAP -->
		<script src="bower_components/jquery/dist/jquery.min.js"></script>
		<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
		<link rel="stylesheet" type="text/css" href="bower_components/bootstrap/dist/css/bootstrap.min.css">

		<!-- ANGULARJS -->
		<script src='bower_components/angular/angular.min.js'></script>
		<script src="bower_components/angular-route/angular-route.min.js"></script>
		<script src="bower_components/angular-locale_fr-fr/angular-locale_fr-fr.js"></script>
		<script src="bower_components/angular-messages/angular-messages.min.js"></script>
		<script src="bower_components/angular-animate/angular-animate.min.js"></script>

		 <!-- CHARGEMENT LIB FIREBASE -->
        <script src='bower_components/firebase/firebase.js'></script>

        <!-- MODULE ANGULARJS AngularFire pour firebase-->
        <script src="bower_components/angularfire/dist/angularfire.min.js"></script>

		<!-- DIRECTIVE GENERATRICE DE CODE BARRES -->
		<link rel="stylesheet" href="bower_components/barcodeGenerator/barcode.css" type="text/css"/>
		<script type="text/javascript" src="bower_components/barcodeGenerator/barcodeGenerator.js"></script>	

		<!-- GOOGLE MAP ET AUTOCOMPLETE GOOGLE -->
		<script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
		<script src="bower_components/angular-google-places-autocomplete/src/autocomplete.js"></script>
		<link rel="stylesheet" href="bower_components/angular-google-places-autocomplete/src/autocomplete.css">

		<!-- MODULE ANGULARJS NOTIFICATIONS -->
		<link rel="stylesheet" href="bower_components/angular-notifier-master/dist/angular-notifier.min.css">
		<script src="bower_components/angular-notifier-master/dist/angular-notifier.min.js"></script>

		<!-- APPLICATION PERSO -->
		<script src="js/app.js"></script>  <!-- Chargement des modules AngularJs et des controleurs -->
		<script src="js/directives.js"></script>  <!-- Chargement des directives et des filtres -->
		<link rel="stylesheet" type="text/css" href="css/style.css"><!-- // Les css de notre app -->

		<!-- cdn for modernizr, if you haven't included it already -->
	<!-- 	<script src="http://cdn.jsdelivr.net/webshim/1.12.4/extras/modernizr-custom.js"></script> -->

		<!-- FIN DE CHARGEMENT DES LIBRAIRIES -->
</head>

<body ng-app="neutre" >

<!--  MENU -->
       <nav class="navbar navbar-default" >
		  <div class="container-fluid">
			<!-- Grouping pour meilleur affichage mobile -->
			<div class="navbar-header">
			  <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
				<span class="sr-only">Activer la navigation</span>
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
			  </button>
			  <a class="navbar-brand" href="#"><img src="img-app/scanne.jpg" style="width:130px;height:70px;"></img></a>
			</div>

			<!-- Collecte les liens pour que lors de l utilisation sur un mobile, cela se contracte bien -->
			<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
			  <ul class="nav navbar-nav" bs-active-link>
			  <li class="active"><a href="#/accueil"><span class="glyphicon glyphicon-home" aria-hidden="true"></span></i>  Accueil <span class="sr-only">(current)</span></a></li>
				<li ><a href="#/nouveau"><span class="glyphicon glyphicon-user" aria-hidden="true"></span></i>  Nouveau <span class="sr-only">(current)</span></a></li>
				<li><a href="#/liste"><span class="  glyphicon glyphicon-barcode" aria-hidden="true"></span> Liste</a></li>
				<li class="dropdown">
				  <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class=" glyphicon  glyphicon-scale" aria-hidden="true"></span> Paramêtres<span class="caret"></span></a>
				  <ul class="dropdown-menu">

					<li><a href="#">Paramétrer le scanner</a></li>
					<li><a href="#">Paramétrer la page d'accueil</a></li>

					<li role="separator" class="divider"></li>
					<li><a href="#">Gérer les catégories d'employés</a></li>
					<li><a href="#">Gérer les horaires</a></li>
				  </ul>
				</li>
				<li class="dropdown">
				  <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon  glyphicon-log-in" aria-hidden="true"></span>  Identification<span class="caret"></span></a>
				  <ul class="dropdown-menu">
					<li><a href="#">Mon compte</a></li>
					<li role="separator" class="divider"></li>
					<li><a href="#">Sortir</a></li>
				  </ul>
				</li>
			  </ul>

			  <ul class="nav navbar-nav navbar-right">
			  <form class="navbar-form navbar-right" role="search">
				<div class="form-group">
				  <input type="text" class="form-control" placeholder="Rechercher">
				</div>
				<button type="submit" class="btn btn-default">Soumettre</button>
			  </form>
				<!-- <li><a href="#">Link</a></li> -->

			  </ul>
			</div><!-- /.navbar-collapse -->
		  </div><!-- /.container-fluid -->
		</nav>

	<!-- <ol class="breadcrumb">
	  <li><a href="#/accueil">Accueil</a></li>
	  <li><a href="#/nouveau">Nouveau</a></li>
	  <li> <a href="#/scanner">Scanner</a></li>
	</ol> -->

<!-- Cette balise NG-View va afficher les différentes vues -->
<div ng-view></div>						

</body>
</html>

La vue nouveau.html : On voit qu’il y a des ng-disabled sur les 3 fonctions des boutons.

<div class="row ">
	<div class="col-lg-12 " >
		 <div class="panel panel-warning">

			<!-- EN TETE DU PANEL -->
			<div class="panel-heading">
				<span class="glyphicon glyphicon glyphicon-user"  aria-hidden="true"></span> Nouveau
			</div>
			<form name="myForm"  >
			<!-- CORPS DU PANEL -->
			<div class="panel-body " style="min-height:600px;" >

				<div class="col-lg-12" >
					<div class="form-group input-group">
					  <span class="input-group-addon">Image</span>
						  <img src = "{{nouvelEmploye.image}}" id="nouvelleImage" class = "img-responsive" style ="width : 100px; height:100px;">
					</div>
				</div >
				<div class="col-lg-6" >

						<div class="form-group input-group">
							<span class="input-group-addon" >Nom</span>
							<input name="nom" type="text" class="form-control text " ng-model = "nouvelEmploye.nom" ng-minlength="1" ng-maxlength="20" required /></input>
							<div ng-messages="myForm.nom.$error" role="alert"  ng-if="myForm.$submitted" style="color:red">
								<div ng-message="required" >Entrez une valeur.</div>
								<div ng-message="minlength">Pas assez long.</div>
								<div ng-message="maxlength">Trop long.</div>
							  </div>
						</div>
						<div class="form-group input-group">
							<span class="input-group-addon" >Prénom</span>
							<input name="prenom" type="text" class="form-control text " ng-model = "nouvelEmploye.prenom" ng-minlength="1" ng-maxlength="20" required /></input>
							<div ng-messages="myForm.prenom.$error" role="alert"  ng-if="myForm.$submitted" style="color:red">
								<div ng-message="required" >Entrez une valeur.</div>
								<div ng-message="minlength">Pas assez long.</div>
								<div ng-message="maxlength">Trop long.</div>
							 </div>
						</div>
						<div class="form-group input-group">
							<span class="input-group-addon">Date Naissance</span>
							<input type="date" class="form-control text " ng-model = "nouvelEmploye.dateNaissance" required /></input>
						</div>

				</div>

				<div class="col-lg-6" >
					<div class="form-group input-group">
						<span class="input-group-addon">Adresse</span>
						<input type="text" class="form-control text " g-places-autocomplete ng-model = "nouvelEmploye.adresse" ng-minlength="2" ng-maxlength="200" required /></input>
					</div>
					<!-- <pre ng-bind="nouvelEmploye.adresse.formatted_address | json"></pre>  -->

					<div class="form-group input-group">
						<span class="input-group-addon">Email</span>
						<input name="email" type="email" class="form-control text " ng-model = "nouvelEmploye.email" ng-minlength="1" ng-maxlength="45" required /></input>
						<div ng-messages="myForm.email.$error" role="alert"  ng-if="myForm.$submitted" style="color:red">
							<div ng-message="required" >Entrez une valeur.</div>
							<div ng-message="minlength">Pas assez long.</div>
							<div ng-message="maxlength">Trop long.</div>
						 </div>
					</div>

					<div class="form-group input-group" ng-show="nouvelEmploye.identifiant">
						<span class="input-group-addon">Identifiant </span>
						<input type="text" class="form-control text " ng-model = "nouvelEmploye.identifiant" disabled /></input>
					</div>
				</div>

				<div class="col-lg-12" >
					<div class="panel well" style="overflow:auto">
						<span class="glyphicon glyphicon-credit-card"  aria-hidden="true"></span> Carte identifiante avec Code Barre
						<!-- GENERATION DE LA CARTE -->
						<div class="card" >
							<div class="card-body" id="card2">
								<div  barcode-generator="{{generationCodeBarre}}" style="height:85px;"></div>

								<h4 style="color:black;">{{nouvelEmploye.nom | capitalize}} {{nouvelEmploye.prenom | capitalize}}</h4>
							</div>
						</div>
					</div>
				</div>
			</div>

			<!-- PIED DE PAGE DU PANEL -->
			<div class="panel-footer text-right">
				<div class="btn-group" role="group" aria-label="...">
					<button class="btn btn-default" ng-click="imprimerDiv('card2')" ng-disabled="!nouvelEmploye.identifiant ">
						<span class="glyphicon  glyphicon-print"  aria-hidden="true"></span>
						imprimer la carte
					</button >
					<button type="submit" ng-click="myForm.$valid && genererCarte()" class="btn btn-default" ng-disabled="!myForm.$valid">
						<span class="glyphicon  glyphicon-credit-card"  aria-hidden="true"></span>
						Générer la carte
					</button >
					<button ng-click="myForm.$valid && sauvegarderUtilisateur()" class="btn btn-default" ng-disabled="!nouvelEmploye.identifiant ">
						<span class="glyphicon  glyphicon-ok"  aria-hidden="true"></span>
						Sauvegarder
					</button>
				</div>
				</form>
			</div>

		 </div>
	</div>
</div> 

Le controleur de la vue nouveau : il a bien changé.

/* CONTROLEUR DE LA VUE NOUVEAU */
.controller('nouveauCtrl', function($scope, notifier,$firebaseArray) {

	/* INITIALISATION DES VARIABLES ET OBJETS :	 */
	$scope.nouvelEmploye		={};/*  L'objet contiendra toutes  les variables forumlaire du nouvel employé */
	$scope.nouvelEmploye.image	="img-app/employe.jpg";/*  Tant qu on a pas uploade une image, cest celle ci qui s affiche */
	$scope.generationCodeBarre	=""; /* Initialise le code Barre */
	notifier.notify('Remplissez le formulaire pour générer la carte de l\'employé avec son code barre !');

	/* FONCTIONS */
	$scope.genererCarte = function(){

		/* FORMATAGE DU CODE BARRE , CA NOUS DONNE UN TRUC COMME CA : ALBERT DUPONT NE LE 03/02/1956 NOUS DONNE AU FORMAT CODEBAR AD03021956 CEST SON IDENTIFIANT*/
		var prefixe 		= $scope.nouvelEmploye.prenom.substring(0,1);
		var nom 			= $scope.nouvelEmploye.nom.substring(0,1);;

		var jour =  $scope.nouvelEmploye.dateNaissance.getUTCDate();
		var mois =  $scope.nouvelEmploye.dateNaissance.getUTCMonth() + 1; //months from 1-12
		var annee =  $scope.nouvelEmploye.dateNaissance.getUTCFullYear();
		if(jour<10)  { jour='0'+jour };
		if(mois<10)  { mois='0'+mois };

		$scope.generationCodeBarre			=	prefixe+nom+jour+mois+annee;
		$scope.nouvelEmploye.identifiant 	=  	prefixe+nom+jour+mois+annee;

		notifier.notify('La carte a bien été générée');
		$scope.nouvelEmploye.adresse 		= 	$scope.nouvelEmploye.adresse.formatted_address // gère l'\objet adresse retourné par google map, celui ci ramene trop de donnees
	};

	$scope.sauvegarderUtilisateur = function(){
		var ref = new Firebase("https://blinding-heat-8502.firebaseio.com/employes/");
		$scope.employes = $firebaseArray(ref);
		$scope.employes.$add($scope.nouvelEmploye);
		notifier.notify('L\'employé a bien été enregistré !');

	};

	$scope.imprimerDiv = function (NomDeLaDiv) {
		notifier.notify('Fermez la fenêtre qui s\'ouvre pour revenir au programme');
		var printContents = document.getElementById(NomDeLaDiv).innerHTML; //Récupère le contenu de la div a afficher dans le popup d impression
		console.log(printContents);
		var originalContents = document.body.innerHTML;      

		/* CODE SPECIAL POUR CHROME */
		if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
			var popupWin = window.open('', '_blank', 'width=1200,height=1200,scrollbars=no,menubar=no,toolbar=no,location=no,status=no,titlebar=no');
			popupWin.window.focus();
			popupWin.document.write('<!DOCTYPE html><html><head>' +
				'<link rel="stylesheet" type="text/css" href="bower_components/barcodeGenerator/barcode.css" />' +
				'</head><body onload="window.print()"><div class="reward-body">' + printContents + ' </div></html>');
			popupWin.onbeforeunload = function (event) {
				popupWin.close();
				return '.\n';
			};
			popupWin.onabort = function (event) {
				popupWin.document.close();
				popupWin.close();
			}
		} else {
			/* CODE POUR LES AUTRES NAVIGATEURS */
			var popupWin = window.open('', '_blank', 'width=300,height=300');
			popupWin.document.open();
			popupWin.document.write('<html><head><link rel="stylesheet" type="text/css" href="bower_components/barcodeGenerator/barcode.css" /></head><body onload="window.print()">' + printContents + '</html>');
			popupWin.document.close();
		}
		popupWin.document.close();

		return true;
	}

/* FIN DU CONTROLEUR */
})

Et enfin, la vue liste.html

<div class="row ">
	<div class="col-lg-12 " >
		 <div class="panel panel-warning">

			<!-- EN TETE DU PANEL -->
			<div class="panel-heading">
				<span class="  glyphicon glyphicon-barcode" aria-hidden="true"></span> Liste des employés scannés
			</div>

			<!-- CORPS DU PANEL -->
			<div class="panel-body " style="min-height:600px;overflow:auto">
				<table class="table table-bordered table-hover   " style="width:100%">
					<thead>
						<tr>
						   <th>
								image
							</th>
							<th  >
								<a href="#" ng-click="sortType = 'prenom'; sortReverse = !sortReverse">
								Prénom
								<span ng-show="sortType == 'prenom' && !sortReverse" class="fa fa-caret-down"></span>
								<span ng-show="sortType == 'prenom' && sortReverse" class="fa fa-caret-up"></span></a>
							</th>
							<th>
								<a href="#" ng-click="sortType = 'nom'; sortReverse = !sortReverse">
								Nom
								<span ng-show="sortType == 'nom' && !sortReverse" class="fa fa-caret-down"></span>
								<span ng-show="sortType == 'nom' && sortReverse" class="fa fa-caret-up"></span></a>
							</th>
							<th>
								<a href="#" ng-click="sortType = 'identifiant'; sortReverse = !sortReverse">
								Identifiant
								<span ng-show="sortType == 'identifiant' && !sortReverse" class="fa fa-caret-down"></span>
								<span ng-show="sortType == 'identifiant' && sortReverse" class="fa fa-caret-up"></span></a>
							</th>
							<th>
								Editer
							</th>
						</tr>
					</thead>
					<tbody>
						<tr ng-repeat="employe in employes | orderBy:sortType:sortReverse |filter:q">
							<td><img src = "{{employe.image}}" class = "img-responsive" style ="width : 50px; height:50px;"></img></td>
							<td>{{employe.prenom}}</td>
							<td>{{employe.nom}}</td>
							<td>{{employe.identifiant}}</td>
							<td><button ng-click="editerEmploye(employe)" class= "fa fa-edit">Editer</button></td>
							</tr>
					</tbody>
				</table>
			</div>
			<!-- PIED DE PAGE DU PANEL -->
			<div class="panel-footer ">
				<div class="form-group"></div>
			</div>
		<!-- FIN DU PANEL -->
		</div>
	</div>
</div> 

Et son controleur qui charge la liste sur le back end Firebase

/* CONTROLEUR DE LA VUE LISTE */
.controller('listeCtrl', function($scope, notifier,$firebaseArray) {
var ref = new Firebase("https://blinding-heat-8502.firebaseio.com/employes/");
$scope.employes = $firebaseArray(ref);
/* FIN DU CONTROLEUR */
})
Publicités