[Application 58 ] « Scanne ton Employé » Création de groupes par glissé déposé

Introduction


Aujourd’hui, je crée la possibilité de créer des groupes par glissé-déposé.

Durée approximative de Codage : de 3 heures à 5 heures.

Cette fonctionnalité est orientée Ordinateur de Bureau.

AngularJs 1.5 excelle dans le temps réel, et il est temps de commencer à s’en servir  !!(Et surtout pas de angular 2,bien sur, par contre les components en 1.5 ca à l’air pas mal !)

Méthode :


  • Téléchargement de la librairie ngDraggable avec BOWER, Installation du module dans le framework AngularJs 1.5.
  • Création d’une vue groupe.html et d’un controleur groupeCtrl.js
  • Ajout de la référence à la nouvelle vue dans le routing angularJs
  • Codage en Js,

Photo :


appdrag

Explication du Code:


Lors du clic sur « Gérer un groupe d’employé », la vue groupe.html est affichée et son controleur groupeCtrl.js est exécuté avec ses paramètres, qui comprends la factory(ou service) CRUD groupeService.

Désormais, ce type de menu « Gérer xxxx » dans l’application implique la création d’une factory  CRUD (Créer Lire Mettre à jour Supprimer) AngularJS dédiée, il s’agit d’une démarche normalisée et à optique professionelle !

Etape 1 : Création de la factory  dédiée au back end Firebase qui va nous permettre de faire du CRUD sur les groupes d’employé(Remarquer qu’elle est en français, c’est agréable) :


app.factory('groupesService', ['$firebaseArray', 'FIREBASE_URI', function ($firebaseArray, FIREBASE_URI) {

	var ref = new Firebase(FIREBASE_URI);
	var groupes = $firebaseArray(ref.child('groupes'));

    var getGroupes = function () {
        return groupes;
    };

    var ajouterGroupe = function (groupe) {
        groupes.$add(groupe);
    };

    var majGroupe = function (id) {
        groupes.$save(id);
    };

    var supprimerGroupe = function (id) {
        groupes.$remove(id);
    };

	return {
        getGroupes: 		getGroupes,
        ajouterGroupe: 	ajouterGroupe,
        majGroupe: 		majGroupe,
        supprimerGroupe: 	supprimerGroupe

    }
}])	 

Etape 2 : On crée la vue avec les css Bootstrap 3.0, elle doit ressembler dans le format aux autres vues au maximum. Pour ma part, au début, cela ne fonctionnait pas, du coup j’ai téléchargé l’exemple de ngDraggable  au format HTML qui marchait bien, puis je l’ai collé dans ma vue, puis j’ai modifié jusqu’à ce  que cela marche !

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

		<div class="col-md-12">
			<div class="form-group input-group">
					<span class="input-group-addon">Chercher un employé</span>
					<input type="text" class="form-control " ng-model="q" placeholder="Tapez ...">
					<select ng-model="c" class="form-control form-field">
					<option value="">Choisir la catégorie</option>
						<option ng-repeat="categorie in categEmployes" value="{{::categorie.nom}}">{{::categorie.nom}}
						</option>
					</select>
			</div>
		</div>	

		<div class="col-md-12 " >
			<div class="well" style="min-height:220px; max-height:220px;overflow:auto">
			<ul class="draggable-objects">
				<li  ng-repeat="obj in draggableObjects|filter:q|filter:c" >
					<div ng-drag="true" ng-drag-data="obj" data-allow-transform="true">
						{{obj.prenom | capitalize}} {{::obj.nom | uppercase}}
						<img src = "{{::obj.image}}" style ="width : 100px; height:100px;">
					 </div>
				</li>
			</ul>
			</div>
		</div>  

		 <div class="col-md-12 " >

			<div ng-drop="true" ng-drop-success="onDropComplete1($data,$event)" style="min-height:300px; max-height:300px;overflow:auto">
				<span class="title">Groupe</span>
				<ul class="draggable-objects">
					<li ng-repeat="obj in droppedObjects1" ng-drag="true" ng-drag-data="obj" ng-drag-success="onDragSuccess1($data,$event)" ng-center-anchor="{{centerAnchor}}">
					  {{obj.nom}}
					  <img src = "{{::obj.image}}"  style ="width : 100px; height:100px;">
					</li>
				</ul>
			</div>

		  <form name="myForm">
			<div class="form-group input-group">
				<span class="input-group-addon" >Nom du groupe :</span>
				<input type="text" class="form-control text " ng-model="nouveauGroupe.nom" required></input>
			</div>
			<button class="btn btn-block" ng-click="myForm.$valid && enregistrerGroupe()"><span class="glyphicon  glyphicon-ok"  aria-hidden="true"></span>
						Sauvegarder</button>
		  </form>

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

Etape 3 : Le controleur de la vue :

Dans un premier temps, on télécharge le modèle de donnée des employés, ce qui est assez couteux, puis on le copie dans une variable autonome avec angular.copy() pour rompre le 3ways data binding d’avec firebase.

Ensuite, on modifie un peu les fonctions de l’exemple de ngDraggble pour les adapter à notre modèle de données.

Enfin, on ajoute une fonction qui enregistre le tableau de $id des employés choisis pour le groupe, afin de pouvoir les retrouver dans la liste ensuite, bien sur on enregistre que les $id  pour que cela ne soit pas couteux. On enregistre tous les employés dans notre node groupe dans firebase !

Pour l’instant, le CRUD n’est pas encore complet, on ne peut que créer un groupe …


/* CONTROLEUR DE LA VUE GRoupe */
app.controller('groupeCtrl', function($scope,notifier,employesService,categoriesService,groupesService) {	
	
	notifier.notify('Glissez-déposez les employés vers le groupe.');
	
		/* Chargement des modèles de données */
		var ep	= employesService.getEmployes(); 
		$scope.categEmployes 	= categoriesService.getCategories();
	
        $scope.centerAnchor = true;
        $scope.toggleCenterAnchor = function () {$scope.centerAnchor = !$scope.centerAnchor}
        $scope.draggableObjects = angular.copy(ep) ;
		$scope.droppedObjects1 = [];
		$scope.groupes = groupesService.getGroupes();
		$scope.nouveauGroupe = [];
		$scope.nouveauGroupe.ids = [];
		
		$scope.onDropComplete1=function(data,evt){
			/* CECI PERMET DE SUPPRIMER LES EMPLOYES LORSQUILS ONT ETE CHOISIS */
			var x= 0;
			$scope.droppedObjects1.push(data);
				for (x=0;x<$scope.draggableObjects.length;x++){
					if($scope.draggableObjects[x].$id==data.$id){
							$scope.draggableObjects.splice(x, 1);
					}
				}
			$scope.nouveauGroupe.ids.push(data.$id);
		}

		var inArray = function(array, obj) {
            var index = array.indexOf(obj);
        }
		
		$scope.enregistrerGroupe = function(){
			groupesService.ajouterGroupe($scope.nouveauGroupe);
			notifier.notify('Le groupe a bien été créé');
		}
	
/* FIN DU CONTROLEUR */
})

Voici le look de mon node sur le back end firebase.com, il y a le nom de chaque groupes, et pour chaque groupe, les $id des employés  :

fbdrag

Etape 4 : Modification de la vue liste et du controleur listeCtrl.js pour pouvoir filtrer les groupes !

C’est la partie la plus dure puisqu’il faut filtrer le modèle de données de employés en fonction d’un tableau de $id !

Tout d’abord je télécharge le modèle de données des groupes dans listeCtrl.js:

$scope.groupes = groupesService.getGroupes();

Ensuite, je crée donc ce filtre dans le controleur de la vue liste.html , qui filtre par le tableau de  $id d’employés présent dans un groupe particulier  :


/* GESTION DU MENU DEROULANT GROUPE */
$scope.$watch('groupe', function() {
        
			if( $scope.groupe != undefined){
				$scope.myFilter = function(value) {
					return ($scope.groupe.indexOf(value.$id) !== -1);
				};  
			}
			if( $scope.groupe == undefined || $scope.groupe == null || $scope.groupe == '' ){
				 $scope.myFilter = undefined;
				}
		
    });

Puis, dans la vue liste.html, j’ajoute le menu déroulant qui permet de filtrer par groupe d’employés:

<select ng-model="groupe" class="form-control form-field">
				<option value="" >Choisir le Groupe</option>
					<option ng-repeat="groupe in groupes" value="{{::groupe.ids}}">{{::groupe.nom}}
					</option>
				</select>
Publicités