[AngularJs] Exploiter le Glissé-déposer

Introduction :


Le glissé déposé peut servir dans les jeux pour les enfants, ou pour simplifier et enrichir l’expérience utilisateur.

Les librairies disponibles :


  • Angular Drag And Drop List : super pour des applications professionelles (CRM ..), il y a surtout la multi-selection mais le code est compliqué (Modèle de données bizarres…)
  • Angular ui Tree : très intéressant avec de la substitution, des accordéons et j’en passe.
  • Angular- Drag n Drop : Le plus simple à comprendre au début.

Une première Micro App avec Angular Drag -n Drop : Un panier ou l’on peut glisser-déposer des objets.


panier.jpg

Le code permet d’affecter des objets à un panier, ensuite, il ne reste plus qu’à sauvegarder ce panier dans le Back END. A tester ici .

Prérequis :

  • Installer AngularJs, Jquery, JqueryUi et Angular Drag N drop avec BOWER

 

LE CONTROLEUR ANGULARJS


Voici le controleur AngularJs qui comprends 3 modèle de données contenant les objets, et le modèle de données vide qui sera notre réceptacle, il s’appelle $scope.list4.

Comme d’habitude, les modèles de données sont des tableaux d’objets JSON

Ce controleur est dans le fichier app.js

A noter la function permettant de supprimer un objet dans le panier (AngularJS est génial, c’est méga simple):


angular.module('neutre', ['ngDragDrop'])

.controller('neutreCtrl', function($scope, $timeout) {
  $scope.list1 = [{'title': 'T Shirt Bleu','img':'Blue_Tshirt.jpg'},{'title': 'Cheezeburger Shirt','img':'t-shirt-hamburger-pour-homme-femme-250x250.jpg'},{'title': 'TShirt Gris','img':'test.jpg'}];
  $scope.list2 = [{'title': 'Sac Zebre','img':'20090601-roberta-di-camerino-zebra-bag.jpg'},{'title': 'Cuir Noir','img':'366899_200_ss_01.jpg'},{'title': 'Cuir d Alligator ','img':'Alligator_Leather.jpg'}];
  $scope.list3 = [{'title': 'iPhone','img':'apple_iphone_5s_16go_noir_p1512093812006A_173325534.jpg'},{'title': 'iPod','img':'IPod_family.png'},{'title': 'iPad','img':'featured-content-ipad-icon_2x.png'}];

  $scope.list4 = [];

  $scope.hideMe = function() {
    return $scope.list4.length > 0;
  }
	$scope.supprimer = function(index){
		$scope.list4.splice(index,1);

	}

/* FIN DU CONTROLEUR */
});

 

LA VUE HTML


La vue index.html, elle, charge les libs en début de script, puis un peu de CSS, et enfin, liste les objets avec des ng-repeats …

Très simple à comprendre… Tant que l’on utilise pas les options …


<!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/jquery-ui/jquery-ui.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">
		<link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.min.css" type="text/css">
		 <link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/ui-lightness/jquery-ui.min.css" rel="stylesheet" type="text/css" />
        <!-- ANGULARJS -->
        <script src='bower_components/angular/angular.min.js'></script>
		
		<!-- ANGULAR-DRAGDROP -->
		<script src="bower_components/angular-dragdrop/src/angular-dragdrop.min.js"></script>
		
		<!-- APPLICATION PERSO -->
		<script src="js/app.js"></script>
		<link rel="stylesheet" type="text/css" href="css/style.css">
		
		<!-- FIN DE CHARGEMENT DES LIBRAIRIES -->
		
		  <style>
			  .thumbnail { height: 280px !important; }
			  .btn-droppable { width: 180px; height: 30px; padding-left: 4px; }
			  .btn-draggable { width: 160px; }
			  .emage { height: 215px; }
			  h1 { padding: .2em; margin: 0; }
			  #products { float:left; width: 500px; margin-right: 2em; }
			  #cart { width: 200px; float: left; margin-top: 1em; }
			  #cart ol { margin: 0; padding: 1em 0 1em 3em; }
			  .img{width:100px;height:100px}
			</style>
  </head>

<body ng-app="neutre" ng-controller="neutreCtrl">
	<div class="container-fluid">
 
		<nav class="navbar navbar-inverse">
			<div class="container-fluid">
				<!-- Brand and toggle get grouped for better mobile display -->
				<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">Toggle navigation</span>
					</button>
					<a class="navbar-brand" href="#">Exercice de Glissé-Déposé</a>
				</div>
				<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
				</div><!-- /.navbar-collapse -->
			</div><!-- /.container-fluid -->
		</nav>
		
		<div class="row ">
			<div class="col-lg-12 " >
				 <div class="panel panel panel-warning">
					
					<div class="panel-heading"> Mon Magasin
						<i class="fa fa-picture-o"></i> 
						<div class="box-tools pull-right">
							<button class="btn btn-primary btn-sm pull-right" ng-model="collapsed" ng-click="collapsed=!collapsed" data-widget="collapse"><i class="fa fa-minus"></i></button>
						</div>
					</div>
					
					
				
					<div ng-show="!collapsed" class="panel-body table-responsive" style="min-height:350px;">
					
						<div class="col-lg-4" >
						  <h1 class="ui-widget-header">Produits</h1>
						  <div id="catalog" style="max-height:500px;overflow:auto">
							<h2><a href="#">T-Shirts</a></h2>
							<div>
							  <ul>
								<li ng-repeat='item in list1' ng-show="item.title" data-drag="true" data-jqyoui-options="{revert: 'invalid', helper: 'clone'}" ng-model="list1" jqyoui-draggable="{index: {{$index}}, animate: true, placeholder: 'keep'}">
								<img src="img/{{item.img}}" class="img"></img>
								{{item.title}}</li>
							  </ul>
							</div>
							<h2><a href="#">Sacs</a></h2>
							<div>
							  <ul>
								<li ng-repeat='item in list2' ng-show="item.title" data-drag="true" data-jqyoui-options="{revert: 'invalid', helper: 'clone'}" ng-model="list2" jqyoui-draggable="{index: {{$index}}, placeholder: 'keep'}">
								<img src="img/{{item.img}}" class="img"></img>
								{{item.title}}</li>
								</li>
							  
							  </ul>
							</div>
							<h2><a href="#">Gadgets</a></h2>
							<div>
							  <ul>
								<li ng-repeat='item in list3' ng-show="item.title" data-drag="true" data-jqyoui-options="{revert: 'invalid', helper: 'clone'}" ng-model="list3" jqyoui-draggable="{index: {{$index}}, placeholder: 'keep'}">
								<img src="img/{{item.img}}" class="img"></img>
								{{item.title}}
								</li>
							  </ul>
							</div>
						  </div>
						</div> 
						
						
						<div class="col-lg-4">
							<h1 class="ui-widget-header">Mon panier</h1>
							<div class="ui-widget-content">
								<ol data-drop="true" ng-model='list4' jqyoui-droppable="{multiple:true}">
									<li ng-repeat="item in list4 track by $index" ng-show="item.title" data-drag="true" data-jqyoui-options="{revert: 'invalid', helper: 'clone'}" ng-model="list4" jqyoui-draggable="{index: {{$index}},animate:true}"><img src="img/{{item.img}}" class="img"></img> {{item.title}} <button ng-click="supprimer($index)">Supprimer</button></li>
									<li class="placeholder" ng-hide="hideMe()">Ajoutez votre produit ici</li>
								</ol>
							</div>
						</div>
					
					</div>
					
					<div class="panel-footer ">
						<div class="form-group"></div> 
					</div>
					
				 </div>
			</div>
		</div>
	</div>

</body>
</html>

On peut constater les défauts suivants : il faut « bien viser » pour mettre le produit dans le panier, on peut résoudre cela en modifiant la DIV droppable.
Le second problème est bien plus embétant : On peut cloner les objets alors qu’il faudrait un compteur pour les additionner … Ca ça peut être résolu soit avec les options de angular-dragdrop, soit en ajoutant une fonction spéciale.

Publicités

#cart, #products