PageSourceSearch

https://abonnement.motomag.com/core/aboshop/app.directives.js?v=

js motomag.com collected 2026-09-24 09:46:36 UTC 108,055 bytes, 2,679 lines download raw bytes

1// ***************************************************************
2//  AboShop Directives
3//  ------------------------------
4// ***************************************************************
5
6angular.module('AboShopApp')
7
8.directive('linkpage', ['$location', '$rootScope', function($location,$rootScope) {
9    return {
10        restrict: 'A',
11        link: function(scope, elem, attrs) {
12        	elem.bind("click",function(e) {
13            	e.preventDefault();
14            	if($(this).attr('data-ismodal') == "true"){
15	        	} else {
16        			$rootScope.goPageCms(e, $(this).attr('data-id'));
17	        	}
18            });
19
20
21        },
22    };
23}])
24
25.directive('productline', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
26    return {
27        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
28        replace: false,
29        templateUrl: commonConfig.commonroot+"/content/templates/productline.html?v="+commonConfig.forceversion,
30        controller: ['$scope', function ($scope) {
31        	$scope.buttonAddToCartGoToProduct = commonConfig.buttonAddToCartGoToProduct;
32        }]
33    };
34}])
35
36.directive('product', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
37    return {
38        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
39        replace: false,
40        templateUrl: commonConfig.commonroot+"/content/templates/product.html?v="+commonConfig.forceversion,
41        controller: ['$scope', function ($scope) {
42        	$scope.buttonAddToCartGoToProduct = commonConfig.buttonAddToCartGoToProduct;
43            $scope.nbCharTruncateLibProduct = commonConfig.nbCharTruncateLibProduct;
44        }]
45    };
46}])
47
48.directive('categorie', ['commonConfig', '$rootScope',function (commonConfig, $rootScope) {
49    return {
50        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
51        replace: false,
52        templateUrl: commonConfig.commonroot+"/content/templates/categorie.html?v="+commonConfig.forceversion,
53        link: function($scope, elem, attrs) {
54        },
55        controller: ['$scope', function ($scope) {
56
57        }]
58    };
59}])
60
61.directive('categorieenfant', ['commonConfig', '$rootScope',function (commonConfig, $rootScope) {
62	return {
63		restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
64		replace: false,
65		templateUrl: commonConfig.commonroot+"/content/templates/categorie-child.html?v="+commonConfig.forceversion,
66		link: function($scope, elem, attrs) {
67		},
68		controller: ['$scope', function ($scope) {
69
70		}]
71	};
72}])
73
74.directive('categorielight', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
75    return {
76        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
77        replace: false,
78        templateUrl: commonConfig.commonroot+"/content/templates/categorielight.html?v="+commonConfig.forceversion,
79        controller: ['$scope', function ($scope) {
80
81        }]
82    };
83}])
84
85.directive('productblock', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
86    return {
87        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
88        replace: false,
89        templateUrl: commonConfig.commonroot+"/content/templates/productblock.html?v="+commonConfig.forceversion,
90        controller: ['$scope', function ($scope) {
91
92        }]
93    };
94}])
95
96.directive('productfooter', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
97    return {
98        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
99        replace: false,
100        templateUrl: commonConfig.commonroot+"/content/product-footer.html?v="+commonConfig.forceversion,
101        controller: ['$scope', function ($scope) {
102
103        }]
104    };
105}])
106
107
108.directive('adresse', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
109    return {
110        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
111        replace: false,
112        templateUrl: commonConfig.commonroot+"/content/templates/adresse.html?v="+commonConfig.forceversion,
113        controller: ['$scope', function ($scope) {
114        }]
115    };
116}])
117
118.directive("selectlangue", function(dico) {
119        return {
120            restrict: 'A',
121            link: function (scope, elem, attrs) {
122                elem.bind("click",function(e) {
123                	e.preventDefault();
124                	$(this).parent().find('a').removeClass('active');
125                	$(this).addClass('active');
126                	dico.use($(this).attr("data-code-iso"));
127		            scope.$apply();
128                });
129            }
130        };
131})
132
133.directive('slider', ['productsManager','commonConfig','$rootScope','$timeout','wishlistManager','menusManager',function(productsManager,commonConfig,$rootScope,$timeout,wishlistManager,menusManager){
134    return {
135        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
136        replace: false,
137        templateUrl: commonConfig.commonroot+"/content/home/slider.html?v="+commonConfig.forceversion,
138        controller: ['$scope', '$filter', 'TbsWS', '$location', '$rootScope', function ($scope, $filter, TbsWS, $location, $rootScope) {
139        	$scope.buttonAddToCartGoToProduct = commonConfig.buttonAddToCartGoToProduct;
140            $rootScope.$watch('preferredLanguage',function(){
141            	reloadSlider();
142            });
143
144            $rootScope.$watch('user',function(){
145            	reloadSlider();
146            });
147
148            $scope.products = [];
149			$scope.footer = {};
150
151            var reloadInProgress = false;
152            function reloadSlider(){
153            	if(!reloadInProgress){
154            		reloadInProgress = true;
155
156            		menusManager.buildMenu(commonConfig.footerconf).then(
157						function(data){
158				        	$scope.footer = data;
159				          }
160				          ,function(error) {
161				        	  $scope.footer = {};
162				        }
163					);
164
165	            	productsManager.getProductsCarousel().then(
166		          		function(products){
167		          			$scope.products = products;
168		          			if($scope.products.length > 0){
169			          			$timeout(function() {
170								    $(".carousel").carousel({
171										interval : parseInt(commonConfig.slidetransition)*1000
172									});
173									reloadInProgress = false;
174								});
175							}
176		          		}
177				          ,function(error) {
178				        	  $scope.products = [];
179				        }
180		          	);
181	          	}
182            }
183            $scope.wishlistForm = wishlistManager.getWishlistForm();
184            $scope.addToWishlist = function addToWishlist(wishlistForm, product, $event){
185            	$($event.currentTarget).prop('checked', !$($event.currentTarget).is(":checked"));
186		    	wishlistManager.addToWishlist(wishlistForm, product).then(function(status){
187		    		if(status){
188		    			$($event.currentTarget).prop('checked', true);
189		    		} else {
190		    			$($event.currentTarget).prop('checked', false);
191		    		}
192		    	});
193		    };
194
195        }]
196    };
197}])
198
199.directive('banniere', ['productsManager','commonConfig','$rootScope','$timeout','wishlistManager','menusManager',function(productsManager,commonConfig,$rootScope,$timeout,wishlistManager,menusManager){
200    return {
201        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
202        replace: false,
203        templateUrl: commonConfig.commonroot+"/content/home/banniere.html?v="+commonConfig.forceversion,
204        controller: ['$scope', '$filter', 'TbsWS', '$location', '$rootScope', function ($scope, $filter, TbsWS, $location, $rootScope) {
205        	$scope.buttonAddToCartGoToProduct = commonConfig.buttonAddToCartGoToProduct;
206            $rootScope.$watch('preferredLanguage',function(){
207            	reloadSlider();
208            });
209
210            $rootScope.$watch('user',function(){
211            	reloadSlider();
212            });
213
214            $scope.products = [];
215			$scope.footer = {};
216
217            var reloadInProgress = false;
218            function reloadSlider(){
219            	if(!reloadInProgress){
220            		reloadInProgress = true;
221
222            		menusManager.buildMenu(commonConfig.footerconf).then(
223						function(data){
224				        	$scope.footer = data;
225				          }
226				          ,function(error) {
227				          	console.error(error);
228				        }
229					);
230
231	            	productsManager.getProductsCarousel().then(
232		          		function(products){
233		          			$scope.products = products;
234		          			if($scope.products.length > 0){
235			          			$timeout(function() {
236								    $(".carousel").carousel({
237										interval : parseInt(commonConfig.slidetransition)*1000
238									});
239									reloadInProgress = false;
240								});
241							}
242		          		}
243				          ,function(error) {
244				          	console.error('Chargement du slider impossible');
245				        }
246		          	);
247	          	}
248            }
249            $scope.wishlistForm = wishlistManager.getWishlistForm();
250            $scope.addToWishlist = function addToWishlist(wishlistForm, product, $event){
251            	$($event.currentTarget).prop('checked', !$($event.currentTarget).is(":checked"));
252		    	wishlistManager.addToWishlist(wishlistForm, product).then(function(status){
253		    		if(status){
254		    			$($event.currentTarget).prop('checked', true);
255		    		} else {
256		    			$($event.currentTarget).prop('checked', false);
257		    		}
258		    	});
259		    };
260
261        }]
262    };
263}])
264
265.directive('categorieshomeselect', ['productsManager','commonConfig','$rootScope','$timeout','categoriesManager',function(productsManager,commonConfig,$rootScope,$timeout,categoriesManager){
266    return {
267        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
268        replace: false,
269        templateUrl: commonConfig.commonroot+"/content/home/categories-select.html?v="+commonConfig.forceversion,
270        controller: ['$scope', function ($scope) {
271        	$scope.categorieform={};
272        	$scope.categorieform.selectedcategorie = {};
273        	$scope.changeCategorie = function changeCategorie(){
274        		//console.log($scope.categorieform.selectedcategorie);
275        		$rootScope.goPage(undefined,'common/categories/'+$scope.categorieform.selectedcategorie);
276        	};
277        	$scope.categoriesselect = [];
278
279        	categoriesManager.getCategoriesAndPrepare().then(
280					function(catarbo){
281						if(catarbo.length > 3){
282							$scope.categoriesselect = [];
283							for(let i = 0;i<3;i++){
284								$scope.categoriesselect.push(catarbo[i]);
285							}
286						} else {
287							$scope.categoriesselect = catarbo;
288						}
289					}
290				);
291        }]
292    };
293}])
294
295.directive('categorieshomelink', ['productsManager','commonConfig','$rootScope','$timeout','categoriesManager',function(productsManager,commonConfig,$rootScope,$timeout,categoriesManager){
296    return {
297        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
298        replace: false,
299        templateUrl: commonConfig.commonroot+"/content/home/categories-link.html?v="+commonConfig.forceversion,
300        controller: ['$scope', function ($scope) {
301        	$scope.categorieslink=[];
302
303        	categoriesManager.getCategoriesAndPrepare().then(
304					function(catarbo){
305						if(catarbo.length > 3){
306							$scope.categorieslink = [];
307							for(let i = 0;i<3;i++){
308								$scope.categorieslink.push(catarbo[i]);
309							}
310						} else {
311							$scope.categorieslink = catarbo;
312						}
313
314						if(commonConfig.categorieslinkcms[0] !== undefined && $scope.categorieslink[0] !== undefined){
315							$scope.categorieslink[0].linkcms = commonConfig.categorieslinkcms[0];
316						}
317
318						if(commonConfig.categorieslinkcms[1] !== undefined && $scope.categorieslink[1] !== undefined){
319							$scope.categorieslink[1].linkcms = commonConfig.categorieslinkcms[1];
320						}
321
322						if(commonConfig.categorieslinkcms[2] !== undefined && $scope.categorieslink[2] !== undefined){
323							$scope.categorieslink[2].linkcms = commonConfig.categorieslinkcms[2];
324						}
325					}
326				);
327        }]
328    };
329}])
330
331.directive('categorieshomeparent', ['productsManager','commonConfig','$rootScope','$timeout','categoriesManager',function(productsManager,commonConfig){
332	return {
333		restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
334		replace: false,
335		templateUrl: commonConfig.commonroot+"/content/home/categories-home-parent.html?v="+commonConfig.forceversion,
336		controller: ['$scope', '$element', '$filter', 'TbsWS', '$location', '$rootScope', 'categoriesManager', 'commonConfig', function ($scope, $element, $filter,TbsWS, $location, $rootScope, categoriesManager, commonConfig) {
337			TbsWS.canAccess().then(
338				function(){
339
340					$scope.loaddataended = false;
341					var reloadInProgress = false;
342
343					$scope.classline = "col-md-3";
344					if(commonConfig.nbproductsbyline == 3){
345						$scope.classline = "col-sm-4 ";
346					}
347
348					reloadListOfCategories();
349
350					function loadCategories() {
351						var path = $location.path(), res = path.split("/");
352
353						categoriesManager.getCategoriesHomeAndPrepare().then(
354							function(categories) {
355								$scope.categoriesHome = categories;
356								$scope.categoriesHome = $filter('orderBy')($scope.categoriesHome, 'positionHome');
357
358								$scope.loaddataended = true;
359							}
360						);
361					}
362
363					function reloadListOfCategories() {
364						$scope.loaddataended = false;
365						if (!reloadInProgress) {
366							reloadInProgress = true;
367							$scope.categoriesHome = [];
368							loadCategories();
369						}
370					}
371				}
372				,function(error) {
373					$rootScope.goPage(undefined,'common/login');
374				}
375			);
376
377		}]
378
379	};
380}])
381
382
383.directive('slidertwo', ['productsManager','commonConfig','$rootScope','$timeout','wishlistManager','menusManager',function(productsManager,commonConfig,$rootScope,$timeout,wishlistManager,menusManager){
384    return {
385        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
386        replace: false,
387        templateUrl: commonConfig.commonroot+"/content/home/slidertwo.html?v="+commonConfig.forceversion,
388        controller: ['$scope', '$filter', 'TbsWS', '$location', '$rootScope', function ($scope, $filter, TbsWS, $location, $rootScope) {
389        	$scope.buttonAddToCartGoToProduct = commonConfig.buttonAddToCartGoToProduct;
390            $rootScope.$watch('preferredLanguage',function(){
391            	reloadSlider();
392            });
393
394            $rootScope.$watch('user',function(){
395            	reloadSlider();
396            });
397
398            $scope.slides = [];
399			$scope.footer = {};
400
401            var reloadInProgress = false;
402            function reloadSlider(){
403            	if(!reloadInProgress){
404            		reloadInProgress = true;
405
406            		menusManager.buildMenu(commonConfig.footerconf).then(
407						function(data){
408				        	$scope.footer = data;
409				          }
410				          ,function(error) {
411				          	console.error(error);
412				        }
413					);
414
415	            	productsManager.getProductsCarousel().then(
416		          		function(products){
417		          			var nbSlide=0;
418		          			for (var i=0;i<products.length;i=i+2){
419		          				$scope.slides[nbSlide]=[];
420		          				$scope.slides[nbSlide][0]=products[i];
421		          				if(products[i+1] !== undefined){
422		          					$scope.slides[nbSlide][1]=products[i+1];
423		          				}
424		          				nbSlide++;
425		          			}
426
427		          			if($scope.slides.length > 0){
428			          			$timeout(function() {
429								    $(".carousel").carousel({
430										interval : parseInt(commonConfig.slidetransition)*1000
431									});
432									reloadInProgress = false;
433								});
434							}
435		          		}
436				          ,function(error) {
437				          	console.error('Chargement du slider impossible');
438				        }
439		          	);
440	          	}
441            }
442            $scope.wishlistForm = wishlistManager.getWishlistForm();
443            $scope.addToWishlist = function addToWishlist(wishlistForm, product, $event){
444            	$($event.currentTarget).prop('checked', !$($event.currentTarget).is(":checked"));
445		    	wishlistManager.addToWishlist(wishlistForm, product).then(function(status){
446		    		if(status){
447		    			$($event.currentTarget).prop('checked', true);
448		    		} else {
449		    			$($event.currentTarget).prop('checked', false);
450		    		}
451		    	});
452		    };
453        }]
454    };
455}])
456
457.directive('secure', ['productsManager','commonConfig','$rootScope','$timeout','wishlistManager','menusManager',function(productsManager,commonConfig,$rootScope,$timeout,wishlistManager,menusManager){
458    return {
459        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
460        replace: false,
461        templateUrl: commonConfig.commonroot+"/content/home/secure.html?v="+commonConfig.forceversion,
462        controller: ['$scope', '$filter', 'TbsWS', '$location', '$rootScope', function ($scope, $filter, TbsWS, $location, $rootScope) {
463        }]
464    };
465}])
466
467.directive('listofcategories', ['commonConfig', 'utils', '$rootScope' ,'$timeout', 'categoriesManager', function (commonConfig, utils, $rootScope, $timeout, categoriesManager) {
468    return {
469        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
470        replace: false,
471        templateUrl: commonConfig.commonroot+"/content/categories-list.html?v="+commonConfig.forceversion,
472        link: function($scope, elem, attrs) {
473        	$scope.$watch('categorieshome', function (newVal, oldVal) {
474        		if (commonConfig.enabledIsotope) {
475					$scope.$watch('categorieslist', function (newVal, oldVal) {
476						if (oldVal !== undefined) {
477							function buildOptions() {
478								const options = {filter: '*'};
479								if ($scope.allsorts !== undefined) {
480									const sort = {};
481									for (let i = 0; i < $scope.allsorts.length; i++) {
482										sort[$scope.allsorts[i]] = "." + $scope.allsorts[i] + " parseInt";
483									}
484									options.filter = '.' + $scope.allsorts[0];
485									options.sortBy = $scope.allsorts[0];
486									options.getSortData = sort;
487								}
488								return options;
489							}
490
491							if ($scope.initIsotope == false) {
492								$scope.initIsotope = true;
493								//Premiere fois creation de lisotope
494								//Fixed correction bug sur chrome si on attend pas assez longtemps
495								//les images se chevauchent
496
497								//Fixed correction pour la version mobile, le chargement de lisotope est assez long et aleatoire
498								//On palie a ce cas, en rechargeant plusieurs fois l'isotope a partir du moment ou la hauteur de la liste a commencé à bouger
499								//C'est à dire que le chargement des images est entrain de se faire.
500								var nbFois = 0;
501
502
503								function tryInitIsotope() {
504									if ($(elem).find('#categorieslist').length > 0) {
505										var relance = false;
506										if ($(elem).find('#categorieslist').height() > 0) {
507
508
509											$(elem).find('#categorieslist').isotope(buildOptions());
510											nbFois++;
511											if (nbFois <= 5) {
512												relance = true;
513											}
514										} else {
515											relance = true;
516										}
517										if (relance) {
518											$timeout(function () {
519												tryInitIsotope();
520											}, 500);
521										}
522									}
523								}
524
525								$timeout(function () {
526									tryInitIsotope();
527								}, 500);
528
529							} else if (newVal.length > oldVal.length) {
530								//Pour toutes les autres fois, on ajoute les elements non isotope
531								$isotope = $(elem).find('#categorieslist');
532								$timeout(function () {
533									console.log("test 2");
534									$isotope.isotope('reloadItems');
535									$(elem).find('#categorieslist').isotope(buildOptions())
536								});
537							}
538						}
539					});
540				}
541				$scope.$watch('selectcategoriebutton', function(newVal){
542
543					if(newVal !== undefined && newVal != ''){
544						if (commonConfig.enabledIsotope) {
545							$timeout(function() {
546								$(elem).find('#categorieslist').isotope({ filter: '.'+newVal, sortBy: newVal });
547							});
548						} else {
549							$('.filter').not('.'+newVal).hide();
550
551							$('.filter.'+newVal).sort(function(a,b) {
552								if($(a).find('.' + newVal).text() !== '' && $(b).find('.' + newVal).text() !== '') {
553									return parseInt($(a).find('.' + newVal).text()) > parseInt($(b).find('.' + newVal).text()) ? 1 : -1;
554								} else {
555									return -1;
556								}
557							}).appendTo("#categorieslist");
558							/*
559							$('.filter.'+newVal).each(function(a) {
560								console.log($(this).find('.product-item-img').attr('data-refcategorie') + ' ' + $(this).find('.' + newVal).text());
561							})
562							 */
563							$('.filter').filter('.'+newVal).show();
564						}
565					}
566				});
567	    	});
568        },
569        controller: ['$scope', function ($scope) {
570        	$scope.initIsotope = false;
571        	$scope.selectcategoriebutton = '';
572			$scope.loadCategories = function loadCategories(filterValue){
573				$scope.selectcategoriebutton = filterValue;
574			};
575        }]
576    };
577}])
578
579.directive('listofproducts', ['commonConfig','$timeout','$interval',function (commonConfig,$timeout,$interval) {
580    return {
581        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
582        replace: false,
583        templateUrl: commonConfig.commonroot+"/content/products-list.html?v="+commonConfig.forceversion,
584        link: function($scope, elem, attrs) {
585			$scope.categorieDisplayHome=false;
586			if(attrs && attrs.refcategorie !== undefined){
587				$scope.categorieDisplayHome=true;
588				$scope.catKey=attrs.refcategorie;
589			}
590        	if (commonConfig.enabledIsotope) {
591        		$scope.$watch('products', function(newVal, oldVal){
592			    	if(oldVal !== undefined){
593		        		if(oldVal.length == 0 && newVal.length > 0){
594		        			//Premiere fois creation de lisotope
595		        			//Fixed correction bug sur chrome si on attend pas assez longtemps
596		        			//les images se chevauchent
597
598		        			//Fixed correction pour la version mobile, le chargement de lisotope est assez long et aleatoire
599		        			//On palie a ce cas, en rechargeant plusieurs fois l'isotope a partir du moment ou la hauteur de la liste a commencé à bouger
600		        			//C'est à dire que le chargement des images est entrain de se faire.
601		        			var nbFois=0;
602		        			function tryInitIsotope(){
603		        				if($(elem).find('#products').length > 0){
604		        					var relance=false;
605			        				if($(elem).find('#products').height() > 0){
606			        					$(elem).find('#products').isotope({ filter: '*', sortBy: 'number', sortAscending: true});
607			        					nbFois++;
608			        					if(nbFois<=5){
609			        						relance=true;
610			        					}
611			        				} else{
612			        					relance=true;
613			        				}
614			        				if(relance){
615			        					$timeout(function() {tryInitIsotope();},200);
616			        				}
617		        				}
618		        			}
619
620		        			$timeout(function() {tryInitIsotope();},200);
621
622		        		} else if(newVal.length > oldVal.length){
623		        			//Pour toutes les autres fois, on ajoute les elements non isotope
624		        			$isotope = $(elem).find('#products');
625					        $timeout(function() {
626					        	console.log("test 1");
627			        			$isotope.isotope( 'reloadItems' );
628			        			$isotope.isotope({ sortBy: 'original-order' });
629			        			$(elem).find('#products').isotope({ filter: '*' });
630			        		});
631		        		}
632			    	}
633			      });
634        		}
635
636		    $scope.$watch('categories', function(newVal, oldVal){
637		        $(elem).find('.filter').on( 'click', 'a', function() {
638		          $(elem).find('.filter a').removeClass('active');
639				  $(this).addClass('active');
640				  var filterValue = $(this).attr('data-filter');
641				  var textValue = $(this).text();
642				  if(filterValue == "*"){
643				  	textValue = "";
644				  }
645				  if (commonConfig.enabledIsotope) {
646					$timeout(function() {
647						$scope.selectcategorie = textValue;
648						$(elem).find('#products').isotope({ filter: filterValue });
649					});
650				  }
651				});
652		      });
653        },
654        controller: ['$scope', '$element', '$filter', 'TbsWS', '$location', '$rootScope', 'productsManager', 'categoriesManager', 'commonConfig', '$window', '$stateParams', 'seo', 'pianoManager',
655			function ($scope, $element, $filter,TbsWS, $location, $rootScope, productsManager, categoriesManager, commonConfig, $window, $stateParams, seo, pianoManager) {
656
657			TbsWS.canAccess().then(
658				function(){
659
660		            $scope.productline = commonConfig.productline;
661
662		            $scope.classline = "col-md-3";
663		            if(commonConfig.nbproductsbyline == 3){
664		            	$scope.classline = "col-sm-4 ";
665		            }
666
667					$scope.displayaccrocheonhomemonthproduct = commonConfig.displayaccrocheonhomemonthproduct;
668
669		            $scope.loaddataended = false;
670		            var reloadInProgress = false;
671		            $scope.selectcategorie = "";
672
673		            $rootScope.$watch('preferredLanguage',function(){
674		            	reloadListOfProducts("preferredLanguage");
675		            });
676
677		            $rootScope.$watch('user',function(){
678		            	reloadListOfProducts("user");
679		            });
680
681		            $scope.loadmore=true;
682		            function setProducts(products, offset){
683		    			$scope.maxProducts -= products.length;
684		        		if(offset > 0){
685		        			products = $scope.products.concat(products);
686			          	}
687
688		            	if(products.length == 0 || $scope.maxProducts == 0){
689		    				$scope.loadmore=false;
690		    			}
691
692		            	$scope.products = products;
693						$scope.categories = productsManager.getCategoriesFilter($scope.products);
694
695			          	$scope.loaddataended = true;
696			          	reloadInProgress = false;
697		        	}
698
699		            function searchPage(){
700		            	$scope.title = 'DICO_DIRECTIVE_RESULTAT_DE_LA_RECHERCHE';
701		            	var path = $location.path(), res = path.split("/"),filtre="DICO_NO_FILTER";
702		            	$scope.searchvalue = decodeURI(res[3]);
703		            	$scope.searchfilter = decodeURI(res[4]);
704
705		            	if($scope.searchfilter == "nofilter"){
706		            		$scope.searchfilterdisplay = filtre;
707		            	} else {
708		            		categoriesManager.getCategory($scope.searchfilter).then(
709								function(category){
710									if(category !== undefined){
711										$scope.searchfilterdisplay = category.value;
712										//Pour ne pas afficher la liste des categories sur la droite
713				            			$scope.category="";
714					        		}
715								}
716							);
717		            	}
718
719
720		            	productsManager.countSearchProducts($scope.searchvalue, $scope.searchfilter).then(
721							function(nb){
722		        				$scope.maxProducts = nb;
723								if(nb > 0){
724					        		$scope.loadMore = function loadMore(offset){
725										$rootScope.spinnerShow();
726										productsManager.searchProducts($scope.searchvalue, $scope.searchfilter, offset).then(
727											function(products){
728												$timeout(function() {
729													$rootScope.spinnerHide().then(
730								    					function(){
731								    						setProducts(products, offset);
732								    					}
733							    					);
734												},100);
735											}
736										);
737					        		};
738
739					        		$scope.loadMore(0);
740
741								} else {
742					          		setProducts([], 0);
743								}
744							}
745						);
746		            }
747
748		            function loadCategorieProducts(){
749						if(!$scope.categorieDisplayHome) {
750							let path = $location.path(), res = path.split("/");
751
752							$scope.loadDateDeParution = function loadDateDeParution(catKey,year,month){
753								if(year == "all"){
754									$location.path('/common/categories/'+catKey+'/'+year+'/all');
755								} else {
756									$location.path('/common/categories/'+catKey+'/'+year+'/'+month);
757								}
758							};
759
760							$scope.catKey = $stateParams.ID_CATEGORIE;
761						}
762
763						let filter={};
764						filter.year = $stateParams.YEAR;
765						filter.month = $stateParams.MONTH;
766
767						if(filter.year === undefined || filter.month === undefined){
768							//Produits de la categories
769							filter.year="all";
770							filter.month="all";
771						}
772
773						categoriesManager.getCategory($scope.catKey).then(
774							function(category){
775								if(category !== undefined){
776									$scope.category = category;
777
778									// piano tracking
779									pianoManager.addCoreProperty('page', category.nom);
780									pianoManager.addCoreProperty('page_chapter1', category.nom);
781
782									if($scope.categorieDisplayHome == false){
783										if (category.page) {
784											$rootScope.goPage(undefined,'common/categories-list/' + category.refCategorie);
785										}
786									}
787
788									$scope.displaycategorytitleonproductspage = commonConfig.displaycategorytitleonproductspage && !$scope.categorieDisplayHome;
789									$scope.displayCategoryDescriptionOnProductsPage = commonConfig.displayCategoryDescriptionOnProductsPage && !$scope.categorieDisplayHome;
790
791									if(!$scope.categorieDisplayHome){
792										$scope.profil = ($scope.category.profil === null ? undefined : $scope.category.profil);
793										$rootScope.profil = $scope.profil;
794										if($window !== undefined){
795											var body = $window.document.body;
796											if(body !== undefined){
797												body.className = $scope.profil;
798											}
799										}
800
801										$rootScope.categoryBreadcrumb={};
802										$rootScope.categoryBreadcrumb.type="categorie";
803										$rootScope.categoryBreadcrumb.label=category.nom;
804										$rootScope.categoryBreadcrumb.id=category.refCategorie;
805										$rootScope.categoryBreadcrumb.parent=category.refCategorieParent;
806									}
807
808									$scope.displayproductsbreadcrumb = commonConfig.displayproductsbreadcrumb && !$scope.categorieDisplayHome;
809									$scope.affichageEtendu = _.contains(commonConfig.displaymodeabonnements, String($scope.catKey));
810									$scope.displaypriceonarticlelibre = commonConfig.displaypriceonarticlelibre;
811									$scope.filterForm = categoriesManager.getFiltreParDateForm(category,filter);
812
813									if (category.refCategorieParent != null) {
814										categoriesManager.getCategory(category.refCategorieParent).then(
815											function(category){
816												$scope.categoryParent = category;
817											}
818										)
819									}
820
821									productsManager.nbProductsByCategories($scope.category.refCategorie,filter).then(
822										function(nb){
823											$scope.maxProducts = nb;
824											if(nb > 0){
825								        		$scope.loadMore = function loadMore(offset){
826								        			$rootScope.spinnerShow();
827													productsManager.productsByCategories($scope.category, offset, filter).then(
828														function(products){
829															$timeout(function() {
830																$rootScope.spinnerHide().then(
831											    					function(){
832											    						setProducts(products, offset);
833											    					}
834										    					);
835															},100);
836														}
837													);
838								        		};
839
840								        		$scope.loadMore(0);
841
842											} else {
843								          		setProducts([], 0);
844											}
845										}
846									);
847
848				        		}
849							}
850						);
851		            }
852
853		            function listOfProducts(){
854		            	productsManager.nbProducts().then(
855							function(nb){
856
857		        				$scope.maxProducts = nb;
858								if(nb > 0){
859					            	$scope.loadMore = function loadMore(offset){
860					            		$rootScope.spinnerShow();
861										productsManager.getProducts(offset).then(
862											function(products){
863												$timeout(function() {
864													$rootScope.spinnerHide().then(
865								    					function(){
866								    						setProducts(products, offset);
867								    					}
868							    					);
869												},100);
870											}
871										);
872					        		};
873
874					        		$scope.loadMore(0);
875
876								} else {
877					          		setProducts([], 0);
878								}
879							}
880						);
881		            }
882
883		            function listOfProductsOfMonth(){
884		            	productsManager.getProductsOfMonth().then(
885							function(products){
886								$scope.maxProducts = products.length;
887								setProducts(products);
888							}
889						);
890		            }
891
892		            function reloadListOfProducts(from){
893		            	$scope.loaddataended = false;
894		            	if(!reloadInProgress){
895		            		reloadInProgress = true;
896				            $scope.products = [];
897				            $scope.categories = [];
898
899				            let oldPath = seo.getOldPath($location.path());
900				            if(oldPath.startsWith('/common/search')){
901				            	searchPage();
902							} else {
903								if(oldPath.startsWith('/common/products')){
904									$scope.title = 'DICO_DIRECTIVE_LISTE_DES_PRODUITS';
905				            		listOfProducts();
906								} else if(oldPath.startsWith('/common/categories') || $scope.categorieDisplayHome){
907				            		loadCategorieProducts();
908								} else if(oldPath.startsWith('/') && commonConfig.forceRedirectToCategorie != undefined) {
909									loadCategorieProducts();
910								} else {
911									console.log('reloadListOfProducts');
912			            			$scope.title = 'DICO_DIRECTIVE_PRODUIT_DU_MOIS';
913				            		listOfProductsOfMonth();
914								}
915							}
916						}
917		            }
918				}
919				,function(error) {
920	        	  $rootScope.goPage(undefined,'common/login');
921				}
922		    );
923
924        }]
925    };
926}])
927
928.directive('listofcategorieschild', ['commonConfig','$timeout','$interval',function (commonConfig,$timeout,$interval) {
929	return {
930		restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
931		replace: false,
932		templateUrl: commonConfig.commonroot+"/content/categories-child-list.html?v="+commonConfig.forceversion,
933		link: function($scope, elem, attrs) {
934			if (commonConfig.enabledIsotope) {
935				$scope.$watch('categories', function (newVal, oldVal) {
936					if (oldVal !== undefined) {
937						if (oldVal.length == 0 && newVal.length > 0) {
938							//Premiere fois creation de lisotope
939							//Fixed correction bug sur chrome si on attend pas assez longtemps
940							//les images se chevauchent
941
942							//Fixed correction pour la version mobile, le chargement de lisotope est assez long et aleatoire
943							//On palie a ce cas, en rechargeant plusieurs fois l'isotope a partir du moment ou la hauteur de la liste a commencé à bouger
944							//C'est à dire que le chargement des images est entrain de se faire.
945							var nbFois = 0;
946
947							function tryInitIsotope() {
948								if ($(elem).find('#categories').length > 0) {
949									var relance = false;
950									if ($(elem).find('#categories').height() > 0) {
951										$(elem).find('#categories').isotope({filter: '*'});
952										nbFois++;
953										if (nbFois <= 5) {
954											relance = true;
955										}
956									} else {
957										relance = true;
958									}
959									if (relance) {
960										$timeout(function () {
961											tryInitIsotope();
962										}, 200);
963									}
964								}
965							}
966
967							$timeout(function () {
968								tryInitIsotope();
969							}, 200);
970
971						} else if (newVal.length > oldVal.length) {
972							//Pour toutes les autres fois, on ajoute les elements non isotope
973							$isotope = $(elem).find('#categories');
974							$timeout(function () {
975								$isotope.isotope('reloadItems');
976								$isotope.isotope({sortBy: 'original-order'});
977								$(elem).find('#categories').isotope({filter: '*'});
978							});
979						}
980					}
981				});
982			}
983			$scope.$watch('categories', function(newVal, oldVal){
984				$(elem).find('.filter').on( 'click', 'a', function() {
985					$(elem).find('.filter a').removeClass('active');
986					$(this).addClass('active');
987					var filterValue = $(this).attr('data-filter');
988					var textValue = $(this).text();
989					if(filterValue == "*"){
990						textValue = "";
991					}
992
993				});
994			});
995		},
996		controller: ['$scope', '$element', '$filter', 'TbsWS', '$location', '$rootScope', 'productsManager', 'categoriesManager', 'commonConfig', '$window', 'seo', '$stateParams', function ($scope, $element, $filter,TbsWS, $location, $rootScope, productsManager, categoriesManager, commonConfig, $window, seo, $stateParams) {
997			TbsWS.canAccess().then(
998				function(){
999					$scope.productline = commonConfig.productline;
1000
1001					$scope.classline = "col-md-3";
1002					if(commonConfig.nbproductsbyline == 3){
1003						$scope.classline = "col-sm-4 ";
1004					}
1005
1006					$scope.loaddataended = false;
1007					var reloadInProgress = false;
1008
1009					$rootScope.$watch('preferredLanguage',function(){
1010						reloadListOfCategories("preferredLanguage");
1011					});
1012
1013					$rootScope.$watch('user',function(){
1014						reloadListOfCategories("user");
1015					});
1016
1017					$scope.loadmore=true;
1018					function setCategories(categories, offset){
1019						$scope.maxCategories -= categories.length;
1020						if(offset > 0){
1021							categories = $scope.categories.concat(categories);
1022						}
1023
1024						if(categories.length == 0 || $scope.maxCategories == 0){
1025							$scope.loadmore=false;
1026						}
1027
1028						$scope.categories = categories;
1029
1030						$scope.loaddataended = true;
1031						reloadInProgress = false;
1032					}
1033
1034					function loadCategorieEnfant() {
1035						if($stateParams.ID_CATEGORIE === undefined){
1036							return;
1037						}
1038						$scope.catKey = $stateParams.ID_CATEGORIE;
1039
1040						categoriesManager.getCategory($scope.catKey).then(
1041							function (category) {
1042								if (category !== undefined) {
1043									$scope.category = category;
1044									if (!category.page) {
1045										$rootScope.goPage();
1046									}
1047
1048									$scope.displaycategorytitleonproductspage = commonConfig.displaycategorytitleonproductspage;
1049									$scope.displayCategoryDescriptionOnCategoryChildPage = commonConfig.displayCategoryDescriptionOnCategoryChildPage;
1050
1051									$scope.profil = ($scope.category.profil === null ? undefined : $scope.category.profil);
1052									$rootScope.profil = $scope.profil;
1053									if ($window !== undefined) {
1054										var body = $window.document.body;
1055										if (body !== undefined) {
1056											body.className = $scope.profil;
1057										}
1058									}
1059
1060									$scope.displayproductsbreadcrumb = commonConfig.displayproductsbreadcrumb;
1061
1062									categoriesManager.nbCategoriesEnfants($scope.category.refCategorie).then(
1063										function (nb) {
1064											$scope.maxCategories = nb;
1065											if (nb > 0) {
1066												$scope.loadMore = function loadMore(offset) {
1067													$rootScope.spinnerShow();
1068													categoriesManager.getEnfantsCategories($scope.category.refCategorie).then(
1069														function (products) {
1070															$timeout(function () {
1071																$rootScope.spinnerHide().then(
1072																	function () {
1073																		setCategories(products, offset);
1074																	}
1075																);
1076															}, 100);
1077														}
1078													);
1079												};
1080
1081												$scope.loadMore(0);
1082
1083											} else {
1084												setCategories([], 0);
1085											}
1086										}
1087									);
1088
1089								}
1090							}
1091						);
1092					}
1093
1094					function reloadListOfCategories(from) {
1095						$scope.loaddataended = false;
1096						if (!reloadInProgress) {
1097							reloadInProgress = true;
1098							$scope.categories = [];
1099							loadCategorieEnfant();
1100						}
1101					}
1102				}
1103				,function(error) {
1104					$rootScope.goPage(undefined,'common/login');
1105				}
1106			);
1107
1108		}]
1109	};
1110}])
1111
1112.directive('a', function() {
1113    return {
1114        restrict: 'E',
1115        link: function(scope, elem, attrs) {
1116            if(attrs.ngClick || (attrs.href !== undefined && (attrs.href === '' || attrs.href[0] === '#'))){
1117                elem.on('click', function(e){
1118                    e.preventDefault();
1119                });
1120            }
1121        }
1122   };
1123})
1124.directive('qiota', ['commonConfig','customerManager','$rootScope', 'pianoManager',function (commonConfig, customerManager, $rootScope, pianoManager) {
1125    return {
1126        restrict: 'E', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1127        replace: false,
1128        //templateUrl: commonConfig.commonroot+"/content/paiement/qiota.html?v="+commonConfig.forceversion,
1129        template: "<div class='qiota'></div>",
1130        controller: ['$scope', function ($scope) {
1131            $scope.codeTarifInQiotaOrder = commonConfig.codeTarifInQiotaOrder;
1132            $rootScope.isPrelSepaZero = false;
1133        	$scope.$watch("cart",function(newval, oldval,scope){
1134				if($scope !== undefined && $scope.cart !== undefined && $scope.paymentForm !== undefined){
1135
1136               	//Get ID User Aboweb and Call Qiota
1137                customerManager.getCustomer().then(
1138				function(customer){
1139					var q_order_customer = {};
1140					var q_token = $scope.tokenqiota;
1141					var q_typepay = $scope.paymentForm.others.selectedcard.value;
1142					var q_origin = "aboshop";
1143                    $scope.classPayment = '';
1144
1145					if ($scope.paymentForm.others.selectedcard.value != 'PAYPAL') {
1146						if (_.contains(['VISA', 'MASTERCARD'], $scope.paymentForm.others.selectedcard.value) && _.contains(commonConfig.paiementsqiota, "SYSTEMPAY")) {
1147							q_typepay = "SYSTEMPAY";
1148						} else if ($scope.paymentForm.others.selectedcard.value == 'PRELEVEMENT' && (_.contains(commonConfig.paiementsqiota, "SEPA") || _.contains(commonConfig.paiementsqiota, "STRIPE_SEPA"))) {
1149							q_typepay = "SEPA";
1150						} else if ($scope.paymentForm.others.selectedcard.value == 'PRELEVEMENT' && _.contains(commonConfig.paiementsqiota, "SLIMPAY_SEPA")) {
1151							q_typepay = "SP_SEPA";
1152						} else if (($scope.paymentForm.others.selectedcard.value != 'PRELEVEMENT' && $scope.paymentForm.others.selectedcard.value != 'BANCONTACT') && (_.contains(commonConfig.paiementsqiota, "SLIMPAY_CB") || _.contains(commonConfig.paiementsqiota, "SLIMPAY_PRELEV_CB"))) {
1153							q_typepay = "SP_CB";
1154						} else if (($scope.paymentForm.others.selectedcard.value != 'PRELEVEMENT' && $scope.paymentForm.others.selectedcard.value != 'BANCONTACT') && (_.contains(commonConfig.paiementsqiota, "PAYZEN_CB") || _.contains(commonConfig.paiementsqiota, "PAYZEN_PRELEV_CB"))) {
1155							q_typepay = "PAYZEN";
1156						} else if ($scope.paymentForm.others.selectedcard.value == 'PRELEVEMENT' && _.contains(commonConfig.paiementsqiota, "PAYZEN_SEPA")) {
1157							q_typepay = "PAYZEN_SEPA";
1158							$scope.classPayment = "payzen_sepa";
1159						} else if (($scope.paymentForm.others.selectedcard.value != 'PRELEVEMENT' && $scope.paymentForm.others.selectedcard.value != 'BANCONTACT') && (_.contains(commonConfig.paiementsqiota, "STANCER_CB") || _.contains(commonConfig.paiementsqiota, "STANCER_PRELEV_CB"))) {
1160							q_typepay = "STANCER_CB";
1161							$scope.classPayment = "stancer";
1162						} else if ($scope.paymentForm.others.selectedcard.value == 'PRELEVEMENT' && _.contains(commonConfig.paiementsqiota, "STANCER_SEPA")) {
1163							q_typepay = "STANCER_SEPA";
1164							$scope.classPayment = "stancer";
1165						}
1166					}
1167					if(($scope.paymentForm.others.selectedcard.value == 'PRELEVEMENT' && _.contains(commonConfig.paiementsqiota, "SLIMPAY_SEPA")) ||
1168						($scope.paymentForm.others.selectedcard.value == 'PRELEV_CB' && (_.contains(commonConfig.paiementsqiota, "SLIMPAY_CB") || _.contains(commonConfig.paiementsqiota, "SLIMPAY_PRELEV_CB"))) ||
1169						$scope.paymentForm.others.selectedcard.value == 'BANCONTACT') {
1170						q_order_customer = {
1171								givenName: (isEmptyString(customer.adressePrincipale.prenom) == false ?customer.adressePrincipale.prenom:"Inconnu"),
1172								familyName: (isEmptyString(customer.adressePrincipale.nom) == false ?customer.adressePrincipale.nom:"Inconnu"),
1173								street1: (isEmptyString(customer.adressePrincipale.adresse2) == false ?customer.adressePrincipale.adresse2:"Inconnu"),
1174								city: (isEmptyString(customer.adressePrincipale.ville) == false ?customer.adressePrincipale.ville:"Inconnu"),
1175								postalCode: customer.adressePrincipale.codepostal, // required
1176								country: (isEmptyString(customer.adressePrincipale.codeIso) == false ?customer.adressePrincipale.codeIso:"FR"), // required
1177						};
1178					}
1179
1180                     var q_modepay;
1181
1182					if ($scope.paymentForm.others.selectedcard.value != "PRELEV_CB" && !($scope.paymentForm.others.selectedcard.value == 'PRELEVEMENT' && (_.contains(commonConfig.paiementsqiota, "SLIMPAY_SEPA") || _.contains(commonConfig.paiementsqiota, "STRIPE_SEPA") || _.contains(commonConfig.paiementsqiota, "SEPA") || _.contains(commonConfig.paiementsqiota, "PAYZEN_SEPA") || _.contains(commonConfig.paiementsqiota, "STANCER_SEPA")))) {
1183	                     q_modepay = 1;
1184                 	 } else {
1185                 	 	 q_modepay = 0;
1186                 	 }
1187
1188				     var amount_cents = parseInt($scope.cart.totalAvecLivraisonTtc.replace(/,/g, ""));
1189				     var q_urlcallback = $scope.urlcbqiota;
1190
1191				     var q_customer =  {
1192                            person: {
1193                                email: customer.email,   //required
1194                                idabm: customer.codeClient,
1195                            },
1196                        };
1197					 const q_lang = $rootScope.preferredLanguage === 'be' ? 'fr' : $rootScope.preferredLanguage;
1198
1199                     var description = "AboShop order :"+$scope.cart.id;
1200                     var lstCodeTarif = "";
1201                     if($scope.cart.lignes.length > 0) {
1202	                     for(var i=0;i<$scope.cart.lignes.length;i++){
1203							let desc = " ["+"t="+$scope.cart.lignes[i].refTarif+",";
1204                            if($scope.codeTarifInQiotaOrder){
1205                                desc += "c="+$scope.cart.lignes[i].codeTarif+",";
1206                            }
1207							desc += "p="+$scope.cart.lignes[i].produit.refProduit+",";
1208							desc += "q="+$scope.cart.lignes[i].quantite+"],";
1209							description += desc + " ";
1210
1211                            if($scope.codeTarifInQiotaOrder){
1212                                let lstCode = "["+$scope.cart.lignes[i].codeTarif+"]"
1213                                lstCodeTarif += lstCode + ",";
1214                            }
1215	                     }
1216                     }
1217
1218					if (amount_cents <= 0 && q_typepay == "STANCER_SEPA") {
1219                        $rootScope.isPrelSepaZero = true;
1220					}
1221
1222				     var q_order = {
1223                            product: {
1224                            	partner: q_token,
1225                                editor: $scope.editorName,  	//required
1226                                company: $scope.companyName,	//required
1227                                reference_id: $scope.cart.id,   //required
1228                                description: description, //required
1229                                codetarif: lstCodeTarif,
1230                                amount: amount_cents, //required
1231                                category: 4,	   //required
1232								uri_referer: "", //required
1233								origin: q_origin //required
1234                            }
1235                        };
1236
1237                     	for (var attrname in q_order_customer) { q_order[attrname] = q_order_customer[attrname]; }
1238                        console.log("q_customer : "+q_customer);
1239                        console.log("q_typepay : "+q_typepay);
1240                        console.log("q_modepay : "+q_modepay);
1241
1242                     	// Create a customer
1243                        QiotaPay.createCustomer(q_token, q_customer, function(response) {
1244                        // If there was a problem creating the customer return with error message
1245                        // This could happen if there is a network error or if the authorization is invali
1245d.
1246                            if(!response.valid){
1247                              	  //console.log(response.responseText);
1248                                return;
1249                            }
1250                                // Set up the ID user created.
1251                                let q_idclient = response.user;
1252                                // The QiotaPay widget will be rendered in an html element : <div class="qiota"></div>
1253                                if($(".qiota").length > 1){
1254                                	$(".qiota").html("Chargement Qiota Erreur - Doublon Iframe");
1255                                } else if ($('.qiota').length > 0) {
1256									QiotaPay.render(q_token, q_typepay, q_modepay, q_idclient, q_order, q_urlcallback, {lang: q_lang});
1257									window.addEventListener('message', evt => {
1258										const qiotaIframe = document.querySelector('.qiota iframe');
1259										if (qiotaIframe != null && evt.origin === (new URL(qiotaIframe.src)).origin && evt.data.action === 'qSubmitPayment') {
1260											// piano tracking
1261											pianoManager.sendEvent('click.action', {
1262												click: 'Valider',
1263												click_chapter1: q_typepay.match(/SEPA/i) ? 'SEPA' : 'Carte',
1264												purchase_amount: parseFloat($scope.cart.totalAvecLivraisonTtc.replace(',','.')),
1265												goal_type: 'Achat'
1266											});
1267										}
1268									});
1269                                }
1270                        });
1271
1272				 });
1273                 // END Call Qiota
1274
1275                }
1276        	}, true);
1277
1278			$scope.$watch("bankdetails",function(){
1279				if($scope !== undefined && $scope.bankdetails !== undefined) {
1280				//Get ID User Aboweb and Call Qiota
1281				customerManager.getCustomer().then(
1282				function(customer){
1283
1284					var q_token = commonConfig.tokenqiota;
1285					if (_.contains(commonConfig.paiementsqiota, "PRELEV_CB")) {
1286						var q_typepay = 'CB';
1287					} else if (_.contains(commonConfig.paiementsqiota, "SLIMPAY_PRELEV_CB")) {
1288						var q_typepay = 'SP_CB';
1289					} else if (_.contains(commonConfig.paiementsqiota, "PAYZEN_CB")) {
1290						var q_typepay = 'PAYZEN';
1291					} else if (_.contains(commonConfig.paiementsqiota, "STANCER_PRELEV_CB")) {
1292						var q_typepay = 'STANCER_CB';
1293						$scope.classPayment = "stancer";
1294					}
1295
1296					var q_modepay = 0;
1297					var q_urlcallback = null;
1298					var q_order = null;
1299					var q_idclient = customer.codeClient;
1300					const q_lang = $rootScope.preferredLanguage === 'be' ? 'fr' : $rootScope.preferredLanguage;
1301
1302					const q_customer = {
1303						person: {
1304							email: customer.email,
1305							idabm: customer.codeClient,
1306						},
1307					};
1308
1309					// Create a customer
1310					QiotaPay.createCustomer(q_token, q_customer, function(response) {
1311						// If there was a problem creating the customer return with error message
1312						// This could happen if there is a network error or if the authorization is invalid.
1313						if (!response.valid) {
1314							return;
1315						}
1316
1317						// The QiotaPay widget will be rendered in an html element : <div class="qiota"></div>
1318						if($(".qiota").length > 1){
1319							$(".qiota").html("Chargement Qiota Erreur - Doublon Iframe");
1320						} else if ($('.qiota').length > 0) {
1321							QiotaPay.render(q_token, q_typepay, q_modepay, q_idclient, q_order, q_urlcallback, {updated: true, lang: q_lang});
1322						}
1323					});
1324				});
1325				// END Call Qiota
1326
1327				}
1328			}, true);
1329        }]
1330    };
1331}])
1332
1333.directive('creditcard', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
1334    return {
1335        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1336        replace: false,
1337        templateUrl: commonConfig.commonroot+"/content/paiement/creditcard.html?v="+commonConfig.forceversion,
1338        controller: ['$scope', function ($scope) {
1339        	$scope.cbActif = 'aboweb';
1340        	if(commonConfig.payboxActif !== undefined && commonConfig.payboxActif == true){
1341        		$scope.cbActif = 'paybox';
1342        	}
1343        	if(commonConfig.tokenqiota !== undefined && (_.contains(commonConfig.paiementsqiota, "CB") || _.contains(commonConfig.paiementsqiota, "PAYZEN_CB") || _.contains(commonConfig.paiementsqiota, "SLIMPAY_CB") || _.contains(commonConfig.paiementsqiota, "SYSTEMPAY") || _.contains(commonConfig.paiementsqiota, "STANCER_CB"))){
1344        		$scope.cbActif = 'qiota';
1345        	}
1346        }]
1347    };
1348}])
1349
1350.directive('slimpay', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
1351    return {
1352        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1353        replace: false,
1354        templateUrl: commonConfig.commonroot+"/content/paiement/slimpay.html?v="+commonConfig.forceversion,
1355        controller: ['$scope', function ($scope) {
1356        }]
1357    };
1358}])
1359
1360.directive('prelevement', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
1361    return {
1362        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1363        replace: false,
1364        templateUrl: commonConfig.commonroot+"/content/paiement/prelevement.html?v="+commonConfig.forceversion,
1365        controller: ['$scope', function ($scope) {
1366        	$scope.prelevementActif = 'aboweb';
1367        	if(commonConfig.tpePrelevement !== undefined){
1368        		if(commonConfig.tpePrelevement == 'slimpay' || (commonConfig.tokenqiota !== undefined && (
1369        				($scope.paymentForm.others.selectedcard.value == 'PRELEV_CB' && (_.contains(commonConfig.paiementsqiota, "PRELEV_CB") || _.contains(commonConfig.paiementsqiota, "SLIMPAY_PRELEV_CB") || _.contains(commonConfig.paiementsqiota, "PAYZEN_PRELEV_CB") || _.contains(commonConfig.paiementsqiota, "STANCER_PRELEV_CB")))
1370        				|| ($scope.paymentForm.others.selectedcard.value == 'PRELEVEMENT' && (_.contains(commonConfig.paiementsqiota, "SEPA") || _.contains(commonConfig.paiementsqiota, "SLIMPAY_SEPA") || _.contains(commonConfig.paiementsqiota, "STRIPE_SEPA") || _.contains(commonConfig.paiementsqiota, "PAYZEN_SEPA") || _.contains(commonConfig.paiementsqiota, "STANCER_SEPA"))) )) ){
1371	        		$scope.prelevementActif = commonConfig.tpePrelevement;
1372	        	} else if(commonConfig.tpePrelevement == 'slimpay'){
1373	        		$scope.prelevementActif = 'slimpay';
1374	        	}
1375        	}
1376        }]
1377    };
1378}])
1379
1380.directive('prelevementinfo', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
1381	return {
1382		restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1383		replace: false,
1384		templateUrl: commonConfig.commonroot+"/content/paiement/prelevement.html?v="+commonConfig.forceversion,
1385		controller: ['$scope', function ($scope) {
1386			$scope.prelevementActif = 'aboweb';
1387			if(commonConfig.tpePrelevement !== undefined){
1388				if(commonConfig.tpePrelevement == 'slimpay' || (commonConfig.tokenqiota !== undefined && (
1389					((_.contains(commonConfig.paiementsqiota, "PRELEV_CB") || _.contains(commonConfig.paiementsqiota, "SLIMPAY_PRELEV_CB") || _.contains(commonConfig.paiementsqiota, "STANCER_PRELEV_CB")))
1390					|| ((_.contains(commonConfig.paiementsqiota, "SEPA") || _.contains(commonConfig.paiementsqiota, "SLIMPAY_SEPA") || _.contains(commonConfig.paiementsqiota, "STRIPE_SEPA") || _.contains(commonConfig.paiementsqiota, "PAYZEN_SEPA") || _.contains(commonConfig.paiementsqiota, "STANCER_SEPA"))) )) ){
1391					$scope.prelevementActif = commonConfig.tpePrelevement;
1392				} else if(commonConfig.tpePrelevement == 'slimpay'){
1393					$scope.prelevementActif = 'slimpay';
1394				}
1395			}
1396		}]
1397	};
1398}])
1399
1400.directive('virement', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
1401    return {
1402        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1403        replace: false,
1404        templateUrl: commonConfig.commonroot+"/content/paiement/virement.html?v="+commonConfig.forceversion,
1405        controller: ['$scope', function ($scope) {
1406        }]
1407    };
1408}])
1409
1410.directive('cheque', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
1411    return {
1412        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1413        replace: false,
1414        templateUrl: commonConfig.commonroot+"/content/paiement/cheque.html?v="+commonConfig.forceversion,
1415        controller: ['$scope', function ($scope) {
1416        }]
1417    };
1418}])
1419
1420.directive('receptionfacture', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
1421    return {
1422        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1423        replace: false,
1424        templateUrl: commonConfig.commonroot+"/content/paiement/reception-facture.html?v="+commonConfig.forceversion,
1425        controller: ['$scope', function ($scope) {
1426        }]
1427    };
1428}])
1429
1430.directive('free', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
1431    return {
1432        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1433        replace: false,
1434        templateUrl: commonConfig.commonroot+"/content/paiement/free.html?v="+commonConfig.forceversion,
1435        controller: ['$scope', function ($scope) {
1436        }]
1437    };
1438}])
1439
1440.directive('iban', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
1441    return {
1442        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1443        replace: false,
1444        templateUrl: commonConfig.commonroot+"/content/paiement/iban.html?v="+commonConfig.forceversion,
1445        controller: ['$scope', function ($scope) {
1446        }]
1447    };
1448}])
1449
1450
1451
1452.directive('paypal', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
1453    return {
1454        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1455        replace: false,
1456        templateUrl: commonConfig.commonroot+"/content/paiement/paypal.html?v="+commonConfig.forceversion,
1457        controller: ['$scope', function ($scope) {
1458        	$scope.paypalActif = 'aboweb';
1459        	if(commonConfig.tokenqiota !== undefined && _.contains(commonConfig.paiementsqiota, "PAYPAL")){
1460        		$scope.paypalActif = 'qiota';
1461        	}
1462        }]
1463    };
1464}])
1465
1466.directive('bancontact', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
1467	return {
1468		restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1469		replace: false,
1470		templateUrl: commonConfig.commonroot+"/content/paiement/bancontact.html?v="+commonConfig.forceversion,
1471		controller: ['$scope', function ($scope) {}]
1472	};
1473}])
1474
1475.directive('spinnermodal', ['commonConfig', 'customerManager', '$rootScope',function (commonConfig,customerManager,$rootScope) {
1476    return {
1477        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1478        replace: false,
1479        templateUrl: commonConfig.commonroot+"/content/modal/spinnermodal.html?v="+commonConfig.forceversion,
1480        link: function($scope, elem, attrs) {
1481            var spinner = new Spinner({color:'#fff', lines: 10}).spin();
1482			$(elem).find(".modal")[0].appendChild(spinner.el);
1483        },
1484        controller: ['$scope', 'TbsWS', '$filter', function ($scope, TbsWS, $filter) {
1485        }]
1486    };
1487}])
1488
1489.directive('forgetmodal', ['commonConfig', 'customerManager', '$rootScope', '$timeout', 'formulaireManager', function (commonConfig,customerManager,$rootScope, $timeout, formulaireManager) {
1490    return {
1491        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1492        replace: false,
1493        templateUrl: commonConfig.commonroot+"/content/modal/forgetmodal.html?v="+commonConfig.forceversion,
1494        link: function($scope, elem, attrs) {
1495            $scope.askPassword = function askPassword(forgetForm){
1496
1497            	if(customerManager.checkAskPassword(forgetForm)){
1498					$rootScope.spinnerShow();
1499					customerManager.askPassword(forgetForm).then(
1500						function(success){
1501							$rootScope.spinnerHide().then(
1502		    					function(){
1503		    						if(success){
1504				            			$('#ForgetModal').on('hidden.bs.modal',
1505				            			function () {
1506				            				$('#ForgetModal').off('hidden.bs.modal');
1507		        							$timeout(function() {
1508					          					$rootScope.openModalInformation( "DICO_INFORMATION", "DICO_DIRECTIVE_MAIL_ENVOYE", 4000 );
1509											});
1510										}).modal('hide');
1511				            		}
1512		    					}
1513	    					);
1514						}
1515					);
1516				}
1517            };
1518        },
1519        controller: ['$scope', 'TbsWS', function ($scope, TbsWS) {
1520            $rootScope.openModalForget = function openModalForget() {
1521            	$scope.prompt = customerManager.getForgetPrompt();
1522            	if($scope.forgetForm === undefined){
1523            		$scope.forgetForm = customerManager.getForgetForm($scope.forgetForm);
1524            	} else {
1525            		formulaireManager.resetForm($scope.forgetForm);
1526            	}
1527	            $('#ForgetModal').modal('show');
1528			};
1529        }]
1530    };
1531}])
1532
1533.directive('addressmodal', ['commonConfig', 'customerManager', '$rootScope','$timeout','cartManager',function (commonConfig,customerManager,$rootScope,$timeout,cartManager) {
1534    return {
1535        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1536        replace: false,
1537        templateUrl: commonConfig.commonroot+"/content/modal/addressmodal.html?v="+commonConfig.forceversion,
1538        link: function($scope, elem, attrs) {
1539
1540        	$scope.autocompleteAddress = commonConfig.autocompleteAddress;
1541
1542        	$scope.closeAddress= function closeAddress(newAddressForm){
1543        		$rootScope.spinnerShow();
1544        		if(newAddressForm.others.estParrainnage && !customerManager.verifAddressFunction(newAddressForm)){
1545        			customerManager.setResetParrainnageAdress().then(
1546	            		function(success){
1547	            			$rootScope.spinnerHide().then(
1548		    					function(){
1549		    						if(success){
1550				            			customerManager.getCustomer(newAddressForm.others.estParrainnage).then(
1551											function(customer){
1552							    				if($scope.callbackOnSuccess !== undefined){
1553							    					$scope.callbackOnSuccess(customer);
1554						            			}
1555								        	}
1556								        );
1557					            	}
1558		    					}
1559	    					);
1560	            		}
1561	            	);
1562        		}
1563        	};
1564
1565            $scope.addAddress = function addAddress(newAddressForm, adresses){
1566            	//$rootScope.spinnerShow();
1567            	function reloadCustomerAndQuit(){
1568            		customerManager.getCustomer(newAddressForm.others.estParrainnage).then(
1569    					function(customer){
1570    						$('#AddressModal').on('hidden.bs.modal', function () {
1571				    			$('#AddressModal').off('hidden.bs.modal');
1572				    			$timeout(function() {
1573				    				if($scope.callbackOnSuccess !== undefined){
1574			            				$scope.callbackOnSuccess(customer);
1575			            			}
1576								});
1577							}).modal('hide');
1578			        	}
1579			        );
1580            	}
1581
1582            	/*function hideAdressModal(info){
1583            		$('#AddressModal').on('hidden.bs.modal', function () {
1584		    			$('#AddressModal').off('hidden.bs.modal');
1585		    				$timeout(function() {
1586		    					$rootScope.openModalInformation( "DICO_INFORMATION", info);
1587						});
1588					}).modal('hide');
1589            	}*/
1590
1591        		if(newAddressForm.others.refAdresse !== undefined){
1592        			customerManager.editAddressFunction(newAddressForm, adresses, $scope.customer).then(
1593	            		function(success){
1594	            			if(success){
1595		            			reloadCustomerAndQuit();
1596			            	}
1597	            		}
1598	            	);
1599        		} else {
1600        			customerManager.addAddressFunction(newAddressForm, adresses, $scope.customer).then(function(success){
1601						if(success) {
1602							//reload adress
1603							if ($rootScope.lastAddress === undefined) {
1604								$rootScope.lastAddress = 1;
1605							} else {
1606								$rootScope.lastAddress++;
1607							}
1608							reloadCustomerAndQuit();
1609						}
1610	            	});
1611        		}
1612            };
1613        },
1614        controller: ['$scope', 'TbsWS', '$filter', function ($scope, TbsWS, $filter) {
1615            $rootScope.openModalAddress = function openModalAddress( address, callbackOnSuccess, isGift, callbackOnClose, isBeneficiary, adresses, customer, forceDisplayAdresse, origin, askComplementInfo) {
1616            	$scope.callbackOnSuccess = callbackOnSuccess;
1617            	$scope.infobulle="";
1618		        $scope.displayinfobulle=false;
1619		        $scope.isBeneficiary = isBeneficiary;
1620		        $scope.customer = customer;
1621				$scope.switchProPartEnabled = true;
1622        		$scope.showCloseButton = true;
1623                $scope.isGift = isGift;
1624                $scope.askComplementInfo = askComplementInfo;
1625
1626                $scope.gopagecart = function($event){
1627                    $('#AddressModal').modal('hide');
1628                    $rootScope.goPage($event,'common/cart');
1629                };
1630
1631                $scope.closeModalGift = function(){
1632                    $('#AddressModal').modal('hide');
1633                };
1634
1635		        var temporaryAddress = false;
1636		        if (commonConfig.temporaryAddress) {
1637		        	$scope.adresses = adresses;
1638		        	if (!isGift && !isBeneficiary) {
1639		        		temporaryAddress = true;
1640		        	}
1641		        }
1642
1643            	$scope.toogleInfoBulle = function toogleInfoBulle(info){
1644            		if(info == undefined){
1645            			$scope.infobulle="";
1646		            	$scope.displayinfobulle=false;
1647            		} else {
1648		            	$scope.infobulle=info;
1649		            	$scope.displayinfobulle=true;
1650		            }
1651            	};
1652
1653            	var backAdresse = function backAdresse(addressForm){
1654		            $scope.addressForm = addressForm;
1655					$scope.addressForm.formOk = true;
1656		            $('#AddressModal').modal('show');
1657
1658					if (askComplementInfo) {
1659						customerManager.verifAddressFunction(addressForm);
1660						$scope.showCloseButton = false;
1661						$('#AddressModal').off('keydown.dismiss.bs.modal').off('click.dismiss.bs.modal');
1662						$('#AddressModal .modal-backdrop').off('click.dismiss.bs.modal');
1663					}
1664            	};
1665
1666				if(address !== undefined){
1667            		$scope.addressForm = {};
1668            		$scope.addressForm.alert = [];
1669            		if(isGift){
1670		            	$scope.titre = 'DICO_DIRECTIVE_ADRESSE_AJOUT_ADRESSE_BENEFICIAIRE';
1671		            	if(address.codepostal === ""||address.codepostal === null){
1672			            	$scope.titrebutton = 'DICO_DIRECTIVE_ADRESSE_AJOUT';
1673			            } else {
1674			            	$scope.titrebutton = 'DICO_DIRECTIVE_ADRESSE_MODIFICATION';
1675			            }
1676		            } else if (address.refAdresse == null) { // duplication d'une adresse
1677			            $scope.titre = 'DICO_DIRECTIVE_ADRESSE_AJOUT_ADRESSE';
1678			            $scope.titrebutton = 'DICO_DIRECTIVE_ADRESSE_AJOUT';
1679		            } else {
1680		            	if (isBeneficiary) {
1681			            	$scope.titre = 'DICO_DIRECTIVE_ADRESSE_MODIFICATION_ADRESSE_BENEFICIAIRE';
1682		            	} else {
1683			            	$scope.titre = 'DICO_DIRECTIVE_ADRESSE_MODIFICATION_ADRESSE';
1684		            	}
1685		            	$scope.titrebutton = 'DICO_DIRECTIVE_ADRESSE_MODIFICATION';
1686						$scope.switchProPartEnabled = false;
1687		            }
1688
1689		            customerManager.getAddressForm($scope.addressForm, address, false, isGift, temporaryAddress, false, customer, forceDisplayAdresse, origin).then(
1690		            	function(addressForm){
1691		            		//Si on trouve au moins un champs lie au client ou un cs, on change le titre
1692		            		let ob = _.findWhere(addressForm.fields, {origin: "customer"});
1693		            		if( ob === undefined ) {
1694		            			ob = _.findWhere(addressForm.fields, {origin: "cs"});
1695		            		}
1696		            		if( ob !== undefined ) {
1697								if (origin === 'profil') {
1698		            				if (addressForm.others.estPrincipale) {
1699										$scope.titre = 'DICO_DIRECTIVE_COMPLEMENT_INFOS_CLIENT_ADRESSE_PROFIL_PRINCIPALE';
1700									} else {
1701										$scope.titre = 'DICO_DIRECTIVE_COMPLEMENT_INFOS_CLIENT_ADRESSE_PROFIL_LIVRAISON';
1702									}
1703								} else {
1704									$scope.titre = 'DICO_DIRECTIVE_COMPLEMENT_INFOS_CLIENT_ADRESSE';
1705								}
1706		            		}
1707		            		backAdresse(addressForm);
1708		            	}
1709		            );
1710
1711	            } else {
1712		            $scope.addressForm = {};
1713            		$scope.addressForm.alert = [];
1714            		if(isGift){
1715		            	$scope.titre = 'DICO_DIRECTIVE_ADRESSE_AJOUT_ADRESSE_BENEFICIAIRE';
1716			            $scope.titrebutton = 'DICO_DIRECTIVE_ADRESSE_AJOUT';
1717		            } else {
1718			            $scope.titre = 'DICO_DIRECTIVE_ADRESSE_AJOUT_ADRESSE';
1719			            $scope.titrebutton = 'DICO_DIRECTIVE_ADRESSE_AJOUT';
1720		            }
1721
1722		            customerManager.getNewAddressForm($scope.addressForm,false,isGift,temporaryAddress, customer, forceDisplayAdresse, origin).then(
1723		            	function(addressForm){
1724		            		backAdresse(addressForm);
1725		            	}
1726		            );
1727	            }
1728			};
1729
1730        }]
1731    };
1732}])
1733
1734.directive('accesmodal', ['commonConfig', 'customerManager', '$rootScope', '$timeout', 'formulaireManager', function (commonConfig, customerManager, $rootScope, $timeout, formulaireManager) {
1735	return {
1736		restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1737		replace: false,
1738		templateUrl: commonConfig.commonroot+"/content/modal/accesmodal.html?v="+commonConfig.forceversion,
1739		link: function($scope, elem, attrs) {
1740
1741			$scope.addAccesBeneficiaire = function addAccesBeneficiaire(accesForm){
1742				function reloadCustomerAndQuit(){
1743					customerManager.getCustomer().then(
1744						function(customer){
1745							$('#AccesModal').on('hidden.bs.modal', function () {
1746								$('#AccesModal').off('hidden.bs.modal');
1747								$timeout(function() {
1748									if($scope.callbackOnSuccess !== undefined){
1749										$scope.callbackOnSuccess(customer);
1750									}
1751									$timeout(function() {
1752										$('#collapseBeneficiaires' + accesForm.refAbonnement).collapse("show");
1753									},1000);
1754								});
1755							}).modal('hide');
1756						}
1757					);
1758				}
1759
1760				customerManager.addAccesBeneficiaireFunction(accesForm).then(function(success){
1761					if(success) {
1762						reloadCustomerAndQuit();
1763					}
1764				});
1765			};
1766		},
1767		controller: ['$scope', 'TbsWS', '$filter', function ($scope, TbsWS, $filter) {
1768			$rootScope.openModalAccesBeneficiaire = function openModalAccesBeneficiaire(refAbonnement, acces, callbackOnSuccess) {
1769				$scope.callbackOnSuccess = callbackOnSuccess;
1770				$scope.accesForm = {};
1771				$scope.accesForm.refAbonnement = refAbonnement;
1772				$scope.accesForm.alert = [];
1773				$scope.accesForm.fields = [];
1774
1775				customerManager.getAccesForm($scope.accesForm).then(
1776					function(accesForm) {
1777						$scope.accesForm = accesForm;
1778						$scope.accesForm.formOk = true;
1779						$('#AccesModal').modal('show');
1780					}
1781				);
1782			};
1783		}]
1784	};
1785}])
1786
1787.directive('pdfmodal', ['commonConfig', 'customerManager', '$rootScope', '$window',function (commonConfig, customerManager, $rootScope, $window) {
1788    return {
1789        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1790        replace: false,
1791        templateUrl: commonConfig.commonroot+"/content/modal/pdfmodal.html?v="+commonConfig.forceversion,
1792        controller: ['$scope', 'TbsWS', '$filter', function ($scope, TbsWS, $filter) {
1793        	$rootScope.openModalPdf = function openModalPdf( event, srcpdf ) {
1794            	event.preventDefault();
1795            	if(srcpdf && srcpdf !== undefined){
1796            		$window.open(srcpdf,'_blank');
1797            		//$scope.srcpdf = srcpdf;
1798	            	//$('#PDFModal').modal({show:true});
1799            	} else {
1800            		$rootScope.openModalInformation( "DICO_INFORMATION", "DICO_DIRECTIVE_AUCUN_PDF_POUR_CE_PRODUIT" );
1801            	}
1802			};
1803        }]
1804    };
1805}])
1806
1807.directive('commentmodal', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
1808    return {
1809    	link: function($scope, elem, attrs) {
1810    		$('#commentModal').modal('hide');
1811        },
1812        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1813        replace: false,
1814        templateUrl: commonConfig.commonroot+"/content/modal/commentmodal.html?v="+commonConfig.forceversion,
1815        controller: ['$scope', 'TbsWS', '$filter', function ($scope, TbsWS, $filter) {
1816
1817            $scope.commentimg = 'img/img-comment.png?v='+commonConfig.forceversion;
1818
1819            $rootScope.$watch('temp.commenttitle',function(){
1820            	$scope.commenttitle = $rootScope.temp.commenttitle;
1821            });
1822
1823            $rootScope.$watch('temp.commenttext',function(){
1824            	$scope.commenttext = $rootScope.temp.commenttext;
1825            });
1826
1827            $rootScope.$watch('temp.commentvalue',function(){
1828            	$scope.commentvalue = $rootScope.temp.commentvalue;
1829            });
1830
1831
1832            //$rootScope.temp.commenttext = undefined;
1833
1834            /*if(user.isConnecte){
1835
1836            } else {
1837            	//<a ng-click="goPage(undefined,'common/login')" href="#">{{'LOG_IN_YOU'|translate}}</a>{{' to comment and note this product'|translate}}
1838            }*/
1839
1840        }]
1841    };
1842}])
1843
1844.directive('validatedmodal', ['commonConfig', '$rootScope', function (commonConfig,$rootScope) {
1845    return {
1846    	link: function($scope, elem, attrs) {
1847    		$('#ValidatedModal').modal('hide');
1848        },
1849        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1850        replace: false,
1851        templateUrl: commonConfig.commonroot+"/content/modal/validatedmodal.html?v="+commonConfig.forceversion,
1852        controller: ['$scope', 'TbsWS', '$filter', function ($scope, TbsWS, $filter) {
1853
1854            $scope.validatedimg = commonConfig.iconcheck;
1855
1856            $rootScope.$watch('temp.validatedtitle',function(){
1857            	$scope.validatedtitle = $rootScope.temp.validatedtitle;
1858            });
1859
1860            $rootScope.$watch('temp.validatedtext',function(){
1861            	$scope.validatedtext = $rootScope.temp.validatedtext;
1862            });
1863
1864        }]
1865    };
1866}])
1867
1868.directive('renewmodal', ['commonConfig', 'customerManager', '$rootScope',function (commonConfig,customerManager,$rootScope) {
1869    return {
1870        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1871        replace: false,
1872        templateUrl: commonConfig.commonroot+"/content/modal/renewmodal.html?v="+commonConfig.forceversion,
1873        controller: ['$scope', 'TbsWS', '$filter', function ($scope, TbsWS, $filter) {
1874
1875            $rootScope.openModalRenew = function openModalRenew( product ) {
1876            	if(product && product !== undefined){
1877            		productsManager.loadProduct(product).then(
1878	          			function(product){
1879		          			if(product!== undefined && product.refProduit !== undefined && product.estUnAbonnement){
1880				    			$('#RenewModal').modal({show:true});
1881					    	} else {
1882					    		$rootScope.openModalInformation( "DICO_INFORMATION", "DICO_DIRECTIVE_AUCUN_PRODUIT_TROUVE" );
1883					    	}
1884		          		}
1885				          ,function(error) {
1886				          	$rootScope.openModalInformation( "DICO_INFORMATION", "DICO_DIRECTIVE_AUCUN_PRODUIT_TROUVE" );
1887				        }
1888		          	);
1889            	} else {
1890            		$rootScope.openModalInformation( "DICO_INFORMATION", "DICO_DIRECTIVE_AUCUN_PRODUIT_TROUVE" );
1891            	}
1892			};
1893        }]
1894    };
1895}])
1896
1897.directive('creditmodal', ['commonConfig', 'customerManager', '$rootScope',function (commonConfig,customerManager,$rootScope) {
1898    return {
1899        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1900        replace: false,
1901        templateUrl: commonConfig.commonroot+"/content/modal/creditmodal.html?v="+commonConfig.forceversion,
1902        controller: ['$scope', 'TbsWS', '$filter', function ($scope, TbsWS, $filter) {
1903
1904        }]
1905    };
1906}])
1907
1908.directive('cmsmodal', ['commonConfig', '$analytics' ,function (commonConfig, $analytics) {
1909    return {
1910        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1911        replace: false,
1912        templateUrl: commonConfig.commonroot+"/content/modal/cmsmodal.html?v="+commonConfig.forceversion,
1913        controller: ['$scope', '$rootScope', 'TbsWS', '$filter', '$sce', function ($scope, $rootScope, TbsWS, $filter, $sce) {
1914            $rootScope.openModalPageCms = function openModalPageCms( idpage ) {
1915            	//On logge analytics
1916            	$analytics.eventTrack('identifiant : '+idpage, {  category: 'OpenCmsModal', label: 'label' });
1917
1918            	$scope.titrePageModal = "";
1919            	$scope.contentPageModal = "";
1920		    	TbsWS.call('getpage/' + $rootScope.preferredLanguage + '/' + idpage,'public').then(
1921			          function(data){
1922			          	if(data && data !== ""){
1923				          	$scope.titrePageModal = data.titrePage;
1924				          	$scope.contentPageModal = data.contentPage;
1925			          	} else {
1926			          		$scope.titrePageModal = $filter('translate')("DICO_DIRECTIVE_CONTENU_INDISPONIBLE");
1927			          	}
1928			          }
1929			          ,function(error) {
1930			          	console.error(error);
1931			        }
1932			    );
1933			};
1934        }]
1935    };
1936}])
1937
1938
1939.directive('bankdetailsmodal', ['commonConfig', '$rootScope', '$timeout',function (commonConfig,$rootScope,$timeout) {
1940    return {
1941        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1942        replace: false,
1943        templateUrl: commonConfig.commonroot+"/content/modal/bankdetailsmodal.html?v="+commonConfig.forceversion,
1944        controller: ['$scope', 'TbsWS', '$filter', function ($scope, TbsWS, $filter) {
1945
1946			$rootScope.openModalBankDetail = function openModalAddToCart() {
1947				$scope.title = 'DICO_DIRECTIVE_MODIFICATION_CB';
1948				$scope.retour = 'DICO_DIRECTIVE_MODIFICATION_CB_RETOUR';
1949				$scope.bankdetails = 'bankdetails';
1950				$('#CbModal').modal('show');
1951
1952				$scope.close = function(){
1953					$scope.bankdetails = null;
1954					$('#CbModal').modal('hide');
1955					$rootScope.loadBankDetails();
1956				};
1957			};
1958        }]
1959    };
1960}])
1961
1962.directive('informationmodal', ['commonConfig', '$rootScope', '$timeout',function (commonConfig,$rootScope,$timeout) {
1963    return {
1964        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
1965        replace: false,
1966        templateUrl: commonConfig.commonroot+"/content/modal/informationmodal.html?v="+commonConfig.forceversion,
1967        controller: ['$scope', 'TbsWS', '$filter', function ($scope, TbsWS, $filter) {
1968
1969			$rootScope.openModalInformation = function openModalInformation( title, content, duration) {
1970            	$scope.titleInformation = title;
1971            	$scope.contentInformation = content;
1972            	$scope.showgologinbutton = false;
1973            	$('#InformationModal').modal('show');
1974            	if(duration !== undefined){
1975          			$timeout(function() {
1976					    $('#InformationModal').modal('hide');
1977					},duration);
1978
1979            	}
1980			};
1981
1982			$rootScope.openModalInformationWithGoLogin = function openModalInformation( title, content, duration) {
1983            	$scope.titleInformation = title;
1984            	$scope.contentInformation = content;
1985            	$scope.showgologinbutton = true;
1986				$scope.gopagelogin = function($event){
1987					$('#InformationModal').modal('hide');
1988					$rootScope.goPage($event,'common/login');
1989				};
1990
1991            	$('#InformationModal').modal('show');
1992            	if(duration !== undefined){
1993          			$timeout(function() {
1994					    $('#InformationModal').modal('hide');
1995					},duration);
1996
1997            	}
1998			};
1999
2000
2001        }]
2002    };
2003}])
2004
2005.directive('addtocartmodal', ['commonConfig', '$rootScope', 'Auth',function (commonConfig,$rootScope, Auth) {
2006    return {
2007        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2008        replace: false,
2009        templateUrl: commonConfig.commonroot+"/content/modal/addtocartmodal.html?v="+commonConfig.forceversion,
2010        controller: ['$scope', 'TbsWS', '$filter', function ($scope, TbsWS, $filter) {
2011
2012			$rootScope.openModalAddToCart = function openModalAddToCart( title, content) {
2013            	$scope.titleInformation = title;
2014            	$scope.contentInformation = content;
2015				$scope.displayBeneficiaries = commonConfig.displayBeneficiaries;
2016            	$('#AddToCartModal').modal('show');
2017
2018            	$scope.close = function(){
2019					$('#AddToCartModal').modal('hide');
2020				};
2021
2022
2023				$scope.gopagecart = function($event){
2024					$('#AddToCartModal').modal('hide');
2025					$rootScope.goPageCart($event,'DICO_VOIR_PANIER');
2026				};
2027			};
2028        }]
2029    };
2030}])
2031
2032.directive('yesnomodal', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
2033    return {
2034        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2035        replace: false,
2036        templateUrl: commonConfig.commonroot+"/content/modal/yesnomodal.html?v="+commonConfig.forceversion,
2037        controller: ['$scope', 'TbsWS', '$filter', function ($scope, TbsWS, $filter) {
2038
2039			$rootScope.openModalYesNo = function openModalYesNo( title, content, fNo, fYes, labelNo, labelYes) {
2040				$scope.showbutton = false;
2041				$scope.showbuttonno = false;
2042				$scope.showbuttonyes = false;
2043				$scope.labelno = 'DICO_NO';
2044				if(labelNo !== undefined){
2045					$scope.labelno = labelNo;
2046				}
2047				$scope.labelyes = 'DICO_YES';
2048				if(labelYes !== undefined){
2049					$scope.labelyes = labelYes;
2050				}
2051
2052				if(fNo && typeof fNo === "function"){
2053					$scope.showbutton = true;
2054					$scope.showbuttonno = true;
2055					$scope.cancel = function(){
2056						$('#YesNoModal').modal('hide');
2057						fNo();
2058					};
2059				}
2060				if(fYes && typeof fYes === "function"){
2061					$scope.showbutton = true;
2062					$scope.showbuttonyes = true;
2063					$scope.confirm = function(){
2064						$('#YesNoModal').modal('hide');
2065						fYes();
2066					};
2067				}
2068            	$scope.titleInformation = title;
2069            	$scope.contentInformation = content;
2070            	$('#YesNoModal').modal('show');
2071			};
2072        }]
2073    };
2074}])
2075
2076.directive('sharemodal', ['commonConfig', 'customerManager', '$rootScope',function (commonConfig,customerManager,$rootScope) {
2077    return {
2078        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2079        replace: false,
2080        templateUrl: commonConfig.commonroot+"/content/modal/sharemodal.html?v="+commonConfig.forceversion,
2081        controller: ['$scope', function ($scope) {
2082			$rootScope.openModalSharePrivate = function openModalSharePrivate( title, url) {
2083	            $scope.shareForm = customerManager.getShareForm(title,url);
2084		        $('#ShareModal').modal('show');
2085			};
2086
2087			$scope.sharePage = function sharePage(shareForm){
2088				customerManager.sharePage(shareForm).then(function(success){
2089            		if(success){
2090            			$('#ShareModal').modal('hide');
2091            		}
2092            	});
2093			};
2094        }]
2095    };
2096}])
2097
2098.directive('detailoffremodal', ['commonConfig', '$rootScope', 'customerManager',function (commonConfig,$rootScope, customerManager) {
2099	return {
2100		restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2101		replace: false,
2102		templateUrl: commonConfig.commonroot+"/content/modal/detailoffremodal.html?v="+commonConfig.forceversion,
2103		controller: ['$scope', 'TbsWS', '$filter', function ($scope, TbsWS, $filter) {
2104			$rootScope.openModalDetailOffre = function openModalDetailOffre(title, offer, isParrain) {
2105				$scope.titleDetailOffre = title;
2106				$scope.libelleOffre = offer.desiFormule;
2107				$scope.hideDateSubscriptions = commonConfig.hideDateSubscriptions;
2108				$scope.libparutionenabled = commonConfig.libparutionenabled;
2109
2110				$scope.subscriptions = [];
2111				customerManager.getSubscriptions(0, 50, offer.refFormule, isParrain).then(
2112					function(subscriptions){
2113						$scope.subscriptions = $scope.subscriptions.concat(subscriptions);
2114						$('#DetailOffreModal').modal('show');
2115
2116						customerManager.getSuspensions().then(
2117							function (suspensions) {
2118								var now = new Date();
2119								now.setHours(0, 0, 0, 0);
2120								for (var i = 0; i < suspensions.length; ++i) {
2121									var s = suspensions[i];
2122									for (var j = 0; j < $scope.subscriptions.length; ++j) {
2123										var abo = $scope.subscriptions[j];
2124										if (s.refAbonnements != null && s.refAbonnements.length > 0
2125												&& abo.refAbonnement != null && abo.refAbonnement == s.refAbonnements[0]
2126												&& s.typeSuspension == 3 && (s.dateFin >= now.getTime())
2127												&& (abo.nextTemporarySuspension == null || abo.nextTemporarySuspension.dateDebut > s.dateDebut)) {
2128											abo.nextTemporarySuspension = s;
2129										}
2130									}
2131								}
2132							}
2133						);
2134					}
2135				);
2136
2137				$scope.articles = [];
2138				customerManager.getArticlesByTarifFormule(offer.refTarif).then(
2139					function(articles){
2140						$scope.articles = $scope.articles.concat(articles);
2141					}
2142				);
2143			};
2144		}]
2145	};
2146}])
2147
2148.directive('wishlistmodal', ['commonConfig', '$rootScope',function (commonConfig,$rootScope) {
2149    return {
2150        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2151        replace: false,
2152        templateUrl: commonConfig.commonroot+"/content/modal/wishlistmodal.html?v="+commonConfig.forceversion,
2153        controller: ['$scope', 'TbsWS', '$filter', function ($scope, TbsWS, $filter) {
2154			$scope.wishlistimg = 'img/img-wishlist.png?v='+commonConfig.forceversion;
2155			$rootScope.openModalWishlist = function openModalWishlist( title, content ) {
2156            	$scope.titleWishlist = title;
2157            	$scope.contentWishlist = content;
2158            	$('#WishlistModal').modal('show');
2159			};
2160        }]
2161    };
2162}])
2163
2164.directive('formulemodal', ['commonConfig',function (commonConfig) {
2165    return {
2166        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2167        replace: false,
2168        templateUrl: commonConfig.commonroot+"/content/modal/formulemodal.html?v="+commonConfig.forceversion,
2169        controller: ['$scope', '$rootScope', '$filter', 'TbsWS','productsManager', 'wishlistManager', function ($scope, $rootScope, $filter, TbsWS, productsManager, wishlistManager) {
2170
2171            $rootScope.closeAndAddToCart = function closeAndAddToCart( $event, product ) {
2172				$('#FormuleModal').modal('hide');
2173            	$rootScope.addToCart(product, 1);
2174            };
2175
2176            $scope.wishlistForm = wishlistManager.getWishlistForm();
2177            $scope.addToWishlist = function addToWishlist(wishlistForm, product, $event){
2178            	$($event.currentTarget).prop('checked', !$($event.currentTarget).is(":checked"));
2179		    	wishlistManager.addToWishlist(wishlistForm, product).then(function(status){
2180		    		if(status){
2181		    			$($event.currentTarget).prop('checked', true);
2182		    		} else {
2183		    			$($event.currentTarget).prop('checked', false);
2184		    		}
2185		    	});
2186		    };
2187
2188            $rootScope.openModalFormule = function openModalFormule( idProduct ) {
2189            	productsManager.loadProductsFormule(idProduct).then(
2190	          		function(products){
2191	          			//On decoupe par bloc de 3 formules pour l'affichage
2192	          			var i = 0,
2193	          				blocks=[];
2194
2195	          			for(var p in products){
2196	          				if(i%3 == 0){
2197	          					blocks[blocks.length] = [];
2198	          				}
2199	          				blocks[blocks.length-1].push(products[p]);
2200	          				i++;
2201
2202	          			}
2203	          			$scope.blocks = blocks;
2204            			$('#FormuleModal').modal('show');
2205	          		}
2206			          ,function(error) {
2207			          	console.error('formulemodal erreur chargement produit:'+idProduct);
2208			        }
2209	          	);
2210			};
2211        }]
2212    };
2213}])
2214
2215.directive('adscontent', ['$timeout',function($timeout) {
2216    return {
2217        restrict: 'A',
2218        link: function($scope, elem, attrs) {
2219	        }
2220        };
2221}])
2222
2223.directive('checkStateCart', ['$anchorScroll','cartManager',function($anchorScroll,cartManager){
2224    return{
2225        restrict: 'A',
2226        link: function($scope, elem, attrs) {
2227            $scope.$watch(function() {
2228				  return cartManager.model.cart.addproduct;
2229				}, function(newVal, oldVal){
2230		        if (newVal) {
2231		          $(elem).addClass("open");
2232		          $anchorScroll();
2233		        }
2234		      });
2235        }
2236    };
2237}])
2238
2239.directive('quantitybutton', function(){
2240    return{
2241        restrict: 'A',
2242        link: function($scope, elem, attrs) {
2243            $(elem).click(function(e){
2244			    e.preventDefault();
2245
2246			    fieldName = $(this).attr('data-field');
2247			    type      = $(this).attr('data-type');
2248			    var input = $("input[name='"+fieldName+"']");
2249			    var currentVal = parseInt(input.val());
2250			    if (!isNaN(currentVal)) {
2251			        if(type == 'minus') {
2252
2253			            if(currentVal > input.attr('min')) {
2254			                input.val(currentVal - 1).change();
2255			            }
2256			            if(parseInt(input.val()) == input.attr('min')) {
2257			                $(this).attr('disabled', true);
2258			            }
2259
2260			        } else if(type == 'plus') {
2261
2262			            if(currentVal < input.attr('max')) {
2263			                input.val(currentVal + 1).change();
2264			            }
2265			            if(parseInt(input.val()) == input.attr('max')) {
2266			                $(this).attr('disabled', true);
2267			            }
2268
2269			        }
2270			    } else {
2271			        input.val(0);
2272			    }
2273			});
2274        }
2275    };
2276})
2277
2278.directive('offerslist', ['commonConfig', '$rootScope', '$parse', function (commonConfig,$rootScope,$parse) {
2279	return {
2280		restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2281		replace: false,
2282		transclude: true,
2283		templateUrl: commonConfig.commonroot+"/content/templates/offers-list.html?v="+commonConfig.forceversion,
2284		link: function($scope, element, attrs) {
2285			$scope.$watch(attrs.offerslist, function(offers) {
2286				if(offers != null) {
2287					$scope.offers = offers;
2288				}
2289			});
2290			$scope.$watch(attrs.activescheckbox, function(activescheckbox) {
2291				$scope.activescheckbox = activescheckbox;
2292			});
2293			$scope.$watch(attrs.selection, function(selection) {
2294				if (selection != null) {
2295					$scope.selection = selection;
2296				}
2297			});
2298			$scope.temporarySuspension = commonConfig.temporarySuspension;
2299			if (commonConfig.temporarySuspension) {
2300				$scope.fnDeleteSuspension = function (refSuspension) {
2301					var confirmDelete = function () {
2302						$parse(attrs.fndeletesuspension)($scope, {refSuspension: refSuspension});
2303					}
2304					$rootScope.openModalYesNo( 'DICO_INFORMATION', 'DICO_SUSPENSION_ETES_SUR_DE_VOULOIR_SUPPRIMER', function () {}, confirmDelete, 'DICO_NON', 'DICO_OUI');
2305				}
2306			}
2307			$scope.selectedValue = function (subscription) {
2308				var i = $scope.selection.indexOf(subscription.refAbonnement);
2309				if (subscription.isChecked && i == -1) {
2310					$scope.selection.push(subscription.refAbonnement);
2311				} else if(!subscription.isChecked && i > -1) {
2312					$scope.selection.splice(i, 1);
2313				}
2314			}
2315			$scope.isActive = function (subscription) {
2316				console.log("ABO MATIRTEEE");
2317				console.log(subscription);
2318				if (subscription.dateDernierNumero == null) {
2319					return true;
2320				} else {
2321					var dateConv = subscription.dateDernierNumero.split('/');
2322					var dateDernierNumero = new Date(dateConv[2], dateConv[1]-1, dateConv[0]);
2323					if (dateDernierNumero.getTime() >= Date.now()) {
2324						return true;
2325					}
2326				}
2327				return false;
2328			}
2329
2330			$scope.fndeleteAccesBeneficiaire = function (refAbonnement, acces) {
2331				var confirmDelete = function () {
2332					$parse(attrs.fndeleteaccesbeneficiaire)($scope, {refAbonnement: refAbonnement, codeClient: acces.codeClient});
2333				}
2334				$rootScope.openModalYesNo( 'DICO_INFORMATION', 'DICO_ACCES_BENEFICIAIRE_ETES_SUR_DE_VOULOIR_SUPPRIMER', function () {}, confirmDelete, 'DICO_NON', 'DICO_OUI');
2335			}
2336		}
2337	};
2338}])
2339
2340.directive('offersofferedlist', ['commonConfig', '$rootScope', '$parse', function (commonConfig,$rootScope,$parse) {
2341	return {
2342		restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2343		replace: false,
2344		transclude: true,
2345		templateUrl: commonConfig.commonroot+"/content/templates/offers-offered-list.html?v="+commonConfig.forceversion,
2346		link: function($scope, element, attrs) {
2347			$scope.$watch(attrs.offersofferedlist, function(offersoffered) {
2348				if(offersoffered != null) {
2349					$scope.offersoffered = offersoffered;
2350				}
2351			});
2352		}
2353	};
2354}])
2355
2356.directive('subscriptionslist', ['commonConfig', '$rootScope', '$parse', function (commonConfig,$rootScope,$parse) {
2357    return {
2358        restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2359        replace: false,
2360        transclude: true,
2361        templateUrl: commonConfig.commonroot+"/content/templates/subscriptions-list.html?v="+commonConfig.forceversion,
2362        link: function($scope, element, attrs) {
2363        	$scope.$watch(attrs.subscriptionslist, function(subscriptions) {
2364
2365        		if(subscriptions != null) {
2366        			$scope.subscriptions = subscriptions;
2367        		}
2368        	});
2369        	$scope.$watch(attrs.activescheckbox, function(activescheckbox) {
2370        		$scope.activescheckbox = activescheckbox;
2371        	});
2372        	$scope.$watch(attrs.selection, function(selection) {
2373        		if (selection != null) {
2374        			$scope.selection = selection;
2375        		}
2376        	});
2377        	$scope.temporarySuspension = commonConfig.temporarySuspension;
2378        	if (commonConfig.temporarySuspension) {
2379        		$scope.fnDeleteSuspension = function (refSuspension) {
2380        			var confirmDelete = function () {
2381        				$parse(attrs.fndeletesuspension)($scope, {refSuspension: refSuspension});
2382        			}
2383        			$rootScope.openModalYesNo( 'DICO_INFORMATION', 'DICO_SUSPENSION_ETES_SUR_DE_VOULOIR_SUPPRIMER', function () {}, confirmDelete, 'DICO_NON', 'DICO_OUI');
2384        		}
2385        	}
2386        	$scope.selectedValue = function (subscription) {
2387        		var i = $scope.selection.indexOf(subscription.refAbonnement);
2388        		if (subscription.isChecked && i == -1) {
2389        			$scope.selection.push(subscription.refAbonnement);
2390        		} else if(!subscription.isChecked && i > -1) {
2391        			$scope.selection.splice(i, 1);
2392        		}
2393        	}
2394        	$scope.isActive = function (subscription) {
2395        		if (subscription.dateDernierNumero == null) {
2396        			return true;
2397        		} else {
2398        			var dateConv = subscription.dateDernierNumero.split('/');
2399            		var dateDernierNumero = new Date(dateConv[2], dateConv[1]-1, dateConv[0]);
2400            		if (dateDernierNumero.getTime() >= Date.now()) {
2401            			return true;
2402            		}
2403        		}
2404        		return false;
2405        	}
2406
2407			$scope.fndeleteAccesBeneficiaire = function (refAbonnement, acces) {
2408				var confirmDelete = function () {
2409					$parse(attrs.fndeleteaccesbeneficiaire)($scope, {refAbonnement: refAbonnement, codeClient: acces.codeClient});
2410				}
2411				$rootScope.openModalYesNo( 'DICO_INFORMATION', 'DICO_ACCES_BENEFICIAIRE_ETES_SUR_DE_VOULOIR_SUPPRIMER', function () {}, confirmDelete, 'DICO_NON', 'DICO_OUI');
2412			}
2413        }
2414    };
2415}])
2416
2417.directive('articleslist', ['commonConfig', '$rootScope', '$parse', 'customerManager', function (commonConfig,$rootScope,$parse,customerManager) {
2418	return {
2419		restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2420		replace: false,
2421		transclude: true,
2422		templateUrl: commonConfig.commonroot+"/content/templates/articles-list.html?v="+commonConfig.forceversion,
2423		link: function($scope, element, attrs) {
2424			$scope.$watch(attrs.articleslist, function(articles) {
2425				if(articles != null) {
2426					$scope.articles = articles;
2427				}
2428			});
2429		}
2430	};
2431}])
2432
2433	.directive('factureslist', ['commonConfig', '$rootScope', '$parse', function (commonConfig,$rootScope,$parse) {
2434		return {
2435			restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2436			replace: false,
2437			transclude: true,
2438			templateUrl: commonConfig.commonroot+"/content/templates/factures-list.html?v="+commonConfig.forceversion,
2439			link: function($scope, element, attrs) {
2440				$scope.$watch(attrs.factureslist, function(factures) {
2441					if(factures != null) {
2442						$scope.factures = factures;
2443					}
2444				});
2445			}
2446		};
2447	}])
2448
2449	.directive('cardslist', ['commonConfig', '$rootScope', '$parse', function (commonConfig,$rootScope,$parse) {
2450		return {
2451			restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2452			replace: false,
2453			transclude: true,
2454			templateUrl: commonConfig.commonroot+"/content/templates/cards-list.html?v="+commonConfig.forceversion,
2455			link: function($scope, element, attrs) {
2456				$scope.$watch(attrs.cardslist, function(cards) {
2457					if(cards != null) {
2458						$scope.cards = cards;
2459					}
2460				});
2461			}
2462		};
2463	}])
2464
2465	.directive('mandatslist', ['commonConfig', '$rootScope', '$parse', function (commonConfig,$rootScope,$parse) {
2466		return {
2467			restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2468			replace: false,
2469			transclude: true,
2470			templateUrl: commonConfig.commonroot+"/content/templates/mandats-list.html?v="+commonConfig.forceversion,
2471			link: function($scope, element, attrs) {
2472				$scope.$watch(attrs.mandatslist, function(mandats) {
2473					if(mandats != null) {
2474						$scope.mandats = mandats;
2475					}
2476				});
2477			}
2478		};
2479	}])
2480
2481	.directive('beneficiarieslist', ['commonConfig', '$rootScope', '$parse', function (commonConfig,$rootScope,$parse) {
2482		return {
2483			restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2484			replace: false,
2485			transclude: true,
2486			templateUrl: commonConfig.commonroot+"/content/templates/beneficiaries-list.html?v="+commonConfig.forceversion,
2487			link: function($scope, element, attrs) {
2488				$scope.$watch(attrs.beneficiarieslist, function(beneficiaries) {
2489					if(beneficiaries != null) {
2490						$scope.beneficiaries = beneficiaries;
2491					}
2492				});
2493			}
2494		};
2495	}])
2496
2497	.directive('whisheslist', ['commonConfig', '$rootScope', '$parse', function (commonConfig,$rootScope,$parse) {
2498		return {
2499			restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2500			replace: false,
2501			transclude: true,
2502			templateUrl: commonConfig.commonroot+"/content/templates/whishes-list.html?v="+commonConfig.forceversion,
2503			link: function($scope, element, attrs) {
2504				$scope.$watch(attrs.whisheslist, function(whishes) {
2505					if(whishes != null) {
2506						$scope.whishes = whishes;
2507					}
2508				});
2509			}
2510		};
2511	}])
2512
2513	.directive('optins', ['commonConfig', '$rootScope', '$parse', function (commonConfig,$rootScope,$parse) {
2514		return {
2515			restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2516			replace: false,
2517			transclude: true,
2518			templateUrl: commonConfig.commonroot+"/content/templates/optins.html?v="+commonConfig.forceversion,
2519			link: function($scope, element, attrs) {
2520				$scope.$watch(attrs.optins, function(optins) {
2521					if(optins != null) {
2522						$scope.optins = optins;
2523					}
2524				});
2525			}
2526		};
2527	}])
2528
2529.directive('addressAutocomplete', ['$http', '$timeout', '$parse', function ($http, $timeout, $parse) {
2530	return {
2531		restrict: 'A',
2532		require: 'ngModel',
2533		link: function (scope, element, attrs, ngModelCtrl) {
2534			if (attrs.addressAutocompleteIf && !scope.$eval(attrs.addressAutocompleteIf)) return;
2535
2536			var suggestions = [];
2537			var selectedIndex = -1;
2538			var debounceTimer = null;
2539			var minChars = 4;
2540			var fieldsExpr = attrs.addressAutocompleteFields ? $parse(attrs.addressAutocompleteFields) : null;
2541			var wrapper = angular.element('<div class="address-autocomplete-wrap"></div>');
2542			var spinner = angular.element('<span class="address-autocomplete-spinner"></span>');
2543			var dropdown = angular.element('<ul class="address-autocomplete-dropdown"></ul>');
2544			element.attr('autocomplete', 'off');
2545			element.after(wrapper);
2546			wrapper.append(element);
2547			wrapper.append(spinner);
2548			wrapper.append(dropdown);
2549
2550			function fetchGeopf(params) {
2551				var qs = Object.keys(params).map(function (k) {
2552					return encodeURIComponent(k) + '=' + encodeURIComponent(params[k]);
2553				}).join('&');
2554				return $http.get('https://data.geopf.fr/geocodage/search?' + qs, {
2555					// bypass auth interceptor for external API
2556					headers: { 'x-tbs-authorization': undefined }
2557				}).then(function (response) { return response.data; });
2558			}
2559
2560			function search(query) {
2561				if (!query || query.length < minChars) {
2562					hide();
2563					return;
2564				}
2565				spinner.addClass('visible');
2566				fetchGeopf({ q: query, limit: 5 }).then(function (data) {
2567					suggestions = data.features || [];
2568					render();
2569				}).catch(function () {
2570					hide();
2571				}).finally(function () {
2572					spinner.removeClass('visible');
2573				});
2574			}
2575
2576			function render() {
2577				selectedIndex = -1;
2578				dropdown.empty();
2579				if (suggestions.length === 0) {
2580					hide();
2581					return;
2582				}
2583				suggestions.forEach(function (feature, i) {
2584					var li = angular.element('<li></li>');
2585					li.text(feature.properties.label);
2586					li.on('mousedown', function (e) {
2587						e.preventDefault();
2588						select(feature);
2589					});
2590					dropdown.append(li);
2591				});
2592				dropdown.addClass('visible');
2593			}
2594
2595			function select(feature) {
2596				var props = feature.properties;
2597				var street = '';
2598				if (props.housenumber) {
2599					street = props.housenumber + ' ' + (props.street || props.name || '');
2600				} else {
2601					street = props.name || props.label || '';
2602				}
2603				scope.$apply(function () {
2604					ngModelCtrl.$setViewValue(street.trim());
2605					ngModelCtrl.$render();
2606					if (fieldsExpr) {
2607						var fields = fieldsExpr(scope);
2608						if (fields) {
2609							var cpField = _.findWhere(fields, {name: "codepostal"});
2610							var cityField = _.findWhere(fields, {name: "city"});
2611							if (cpField && props.postcode) { cpField.value = props.postcode; }
2612							if (cityField && props.city) { cityField.value = props.city; }
2613						}
2614					}
2615				});
2616				hide();
2617			}
2618
2619			function hide() {
2620				suggestions = [];
2621				selectedIndex = -1;
2622				dropdown.empty();
2623				dropdown.removeClass('visible');
2624			}
2625
2626			element.on('input', function () {
2627				var val = element.val();
2628				if (debounceTimer) { $timeout.cancel(debounceTimer); }
2629				debounceTimer = $timeout(function () {
2630					search(val);
2631				}, 300);
2632			});
2633
2634			element.on('keydown', function (e) {
2635				if (!suggestions.length) return;
2636				var items = dropdown.children();
2637				if (e.keyCode === 40) {
2638					e.preventDefault();
2639					selectedIndex = Math.min(selectedIndex + 1, suggestions.length - 1);
2640				} else if (e.keyCode === 38) {
2641					e.preventDefault();
2642					selectedIndex = Math.max(selectedIndex - 1, -1);
2643				} else if (e.keyCode === 13 && selectedIndex >= 0) {
2644					e.preventDefault();
2645					select(suggestions[selectedIndex]);
2646					return;
2647				} else if (e.keyCode === 27) {
2648					hide();
2649					return;
2650				}
2651				items.removeClass('active');
2652				if (selectedIndex >= 0) {
2653					angular.element(items[selectedIndex]).addClass('active');
2654				}
2655			});
2656
2657			element.on('blur', function () {
2658				$timeout(function () { hide(); }, 200);
2659			});
2660
2661			scope.$on('$destroy', function () {
2662				if (debounceTimer) { $timeout.cancel(debounceTimer); }
2663				element.off('input keydown blur');
2664				wrapper.after(element);
2665				wrapper.remove();
2666			});
2667		}
2668	};
2669	}])
2670	
2671	
2672	.directive('economyblock', ['commonConfig', '$rootScope', '$parse', function (commonConfig,$rootScope,$parse) {
2673		return {
2674			restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
2675			replace: false,
2676			transclude: true,
2677			templateUrl: commonConfig.commonroot+"/content/templates/economyblock.html?v="+commonConfig.forceversion
2678		};
2679}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.