1 | /** |
||
2 | * INSPINIA - Responsive Admin Theme |
||
3 | * |
||
4 | * Main directives.js file |
||
5 | * Define directives for used plugin |
||
6 | * |
||
7 | * |
||
8 | * Functions (directives) |
||
9 | * - sideNavigation |
||
10 | * - iboxTools |
||
11 | * - minimalizaSidebar |
||
12 | * - vectorMap |
||
13 | * - sparkline |
||
14 | * - icheck |
||
15 | * - ionRangeSlider |
||
16 | * - dropZone |
||
17 | * - responsiveVideo |
||
18 | * - chatSlimScroll |
||
19 | * - customValid |
||
20 | * - fullScroll |
||
21 | * - closeOffCanvas |
||
22 | * - clockPicker |
||
23 | * - landingScrollspy |
||
24 | * - fitHeight |
||
25 | * - iboxToolsFullScreen |
||
26 | * - slimScroll |
||
27 | * - truncate |
||
28 | * - touchSpin |
||
29 | * - markdownEditor |
||
30 | * - resizeable |
||
31 | * |
||
32 | */ |
||
33 | |||
34 | |||
35 | /** |
||
36 | * pageTitle - Directive for set Page title - mata title |
||
37 | */ |
||
38 | function pageTitle($rootScope, $timeout, $translate) { |
||
39 | return { |
||
40 | link: function(scope, element) { |
||
41 | var listener = function(event, toState, toParams, fromState, fromParams) { |
||
42 | |||
43 | // Create your own title pattern |
||
44 | if (toState.data && toState.data.pageTitle) |
||
45 | title = $translate.instant(toState.data.pageTitle); |
||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
46 | $timeout(function() { |
||
47 | element.text(title); |
||
0 ignored issues
–
show
|
|||
48 | }); |
||
49 | }; |
||
50 | $rootScope.$on('$stateChangeStart', listener); |
||
51 | } |
||
52 | } |
||
53 | }; |
||
54 | |||
55 | /** |
||
56 | * sideNavigation - Directive for run metsiMenu on sidebar navigation |
||
57 | */ |
||
58 | function sideNavigation($timeout) { |
||
59 | return { |
||
60 | restrict: 'A', |
||
61 | link: function(scope, element) { |
||
62 | // Call the metsiMenu plugin and plug it to sidebar navigation |
||
63 | $timeout(function(){ |
||
64 | element.metisMenu(); |
||
65 | |||
66 | }); |
||
67 | } |
||
68 | }; |
||
69 | }; |
||
70 | |||
71 | /** |
||
72 | * responsibleVideo - Directive for responsive video |
||
73 | */ |
||
74 | function responsiveVideo() { |
||
75 | return { |
||
76 | restrict: 'A', |
||
77 | link: function(scope, element) { |
||
78 | var figure = element; |
||
79 | var video = element.children(); |
||
80 | video |
||
81 | .attr('data-aspectRatio', video.height() / video.width()) |
||
82 | .removeAttr('height') |
||
83 | .removeAttr('width') |
||
84 | |||
85 | //We can use $watch on $window.innerWidth also. |
||
86 | $(window).resize(function() { |
||
87 | var newWidth = figure.width(); |
||
88 | video |
||
89 | .width(newWidth) |
||
90 | .height(newWidth * video.attr('data-aspectRatio')); |
||
91 | }).resize(); |
||
92 | } |
||
93 | } |
||
94 | } |
||
95 | |||
96 | /** |
||
97 | * iboxTools - Directive for iBox tools elements in right corner of ibox |
||
98 | */ |
||
99 | function iboxTools($timeout) { |
||
100 | return { |
||
101 | restrict: 'A', |
||
102 | scope: true, |
||
103 | templateUrl: 'views/common/ibox_tools.html', |
||
104 | controller: function ($scope, $element) { |
||
105 | // Function for collapse ibox |
||
106 | $scope.showhide = function () { |
||
107 | var ibox = $element.closest('div.ibox'); |
||
108 | var icon = $element.find('i:first'); |
||
109 | var content = ibox.find('div.ibox-content'); |
||
110 | content.slideToggle(200); |
||
111 | // Toggle icon from up to down |
||
112 | icon.toggleClass('fa-chevron-up').toggleClass('fa-chevron-down'); |
||
113 | ibox.toggleClass('').toggleClass('border-bottom'); |
||
114 | $timeout(function () { |
||
115 | ibox.resize(); |
||
116 | ibox.find('[id^=map-]').resize(); |
||
117 | }, 50); |
||
118 | }; |
||
119 | // Function for close ibox |
||
120 | $scope.closebox = function () { |
||
121 | var ibox = $element.closest('div.ibox'); |
||
122 | ibox.remove(); |
||
123 | } |
||
124 | } |
||
125 | }; |
||
126 | } |
||
127 | |||
128 | /** |
||
129 | * iboxTools with full screen - Directive for iBox tools elements in right corner of ibox with full screen option |
||
130 | */ |
||
131 | function iboxToolsFullScreen($timeout) { |
||
132 | return { |
||
133 | restrict: 'A', |
||
134 | scope: true, |
||
135 | templateUrl: 'views/common/ibox_tools_full_screen.html', |
||
136 | controller: function ($scope, $element) { |
||
137 | // Function for collapse ibox |
||
138 | $scope.showhide = function () { |
||
139 | var ibox = $element.closest('div.ibox'); |
||
140 | var icon = $element.find('i:first'); |
||
141 | var content = ibox.find('div.ibox-content'); |
||
142 | content.slideToggle(200); |
||
143 | // Toggle icon from up to down |
||
144 | icon.toggleClass('fa-chevron-up').toggleClass('fa-chevron-down'); |
||
145 | ibox.toggleClass('').toggleClass('border-bottom'); |
||
146 | $timeout(function () { |
||
147 | ibox.resize(); |
||
148 | ibox.find('[id^=map-]').resize(); |
||
149 | }, 50); |
||
150 | }; |
||
151 | // Function for close ibox |
||
152 | $scope.closebox = function () { |
||
153 | var ibox = $element.closest('div.ibox'); |
||
154 | ibox.remove(); |
||
155 | }; |
||
156 | // Function for full screen |
||
157 | $scope.fullscreen = function () { |
||
158 | var ibox = $element.closest('div.ibox'); |
||
159 | var button = $element.find('i.fa-expand'); |
||
160 | $('body').toggleClass('fullscreen-ibox-mode'); |
||
161 | button.toggleClass('fa-expand').toggleClass('fa-compress'); |
||
162 | ibox.toggleClass('fullscreen'); |
||
163 | setTimeout(function() { |
||
164 | $(window).trigger('resize'); |
||
165 | }, 100); |
||
166 | } |
||
167 | } |
||
168 | }; |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * minimalizaSidebar - Directive for minimalize sidebar |
||
173 | */ |
||
174 | function minimalizaSidebar($timeout) { |
||
175 | return { |
||
176 | restrict: 'A', |
||
177 | template: '<a class="navbar-minimalize minimalize-styl-2 btn btn-primary " href="" ng-click="minimalize()"><i class="fa fa-bars"></i></a>', |
||
178 | controller: function ($scope, $element) { |
||
179 | $scope.minimalize = function () { |
||
180 | $("body").toggleClass("mini-navbar"); |
||
181 | if (!$('body').hasClass('mini-navbar') || $('body').hasClass('body-small')) { |
||
182 | // Hide menu in order to smoothly turn on when maximize menu |
||
183 | $('#side-menu').hide(); |
||
184 | // For smoothly turn on menu |
||
185 | setTimeout( |
||
186 | function () { |
||
187 | $('#side-menu').fadeIn(400); |
||
188 | }, 200); |
||
189 | } else if ($('body').hasClass('fixed-sidebar')){ |
||
190 | $('#side-menu').hide(); |
||
191 | setTimeout( |
||
192 | function () { |
||
193 | $('#side-menu').fadeIn(400); |
||
194 | }, 100); |
||
195 | } else { |
||
196 | // Remove all inline style from jquery fadeIn function to reset menu state |
||
197 | $('#side-menu').removeAttr('style'); |
||
198 | } |
||
199 | } |
||
200 | } |
||
201 | }; |
||
202 | }; |
||
203 | |||
204 | |||
205 | function closeOffCanvas() { |
||
206 | return { |
||
207 | restrict: 'A', |
||
208 | template: '<a class="close-canvas-menu" ng-click="closeOffCanvas()"><i class="fa fa-times"></i></a>', |
||
209 | controller: function ($scope, $element) { |
||
210 | $scope.closeOffCanvas = function () { |
||
211 | $("body").toggleClass("mini-navbar"); |
||
212 | } |
||
213 | } |
||
214 | }; |
||
215 | } |
||
216 | |||
217 | /** |
||
218 | * vectorMap - Directive for Vector map plugin |
||
219 | */ |
||
220 | function vectorMap() { |
||
221 | return { |
||
222 | restrict: 'A', |
||
223 | scope: { |
||
224 | myMapData: '=', |
||
225 | }, |
||
226 | link: function (scope, element, attrs) { |
||
227 | var map = element.vectorMap({ |
||
0 ignored issues
–
show
|
|||
228 | map: 'world_mill_en', |
||
229 | backgroundColor: "transparent", |
||
230 | regionStyle: { |
||
231 | initial: { |
||
232 | fill: '#e4e4e4', |
||
233 | "fill-opacity": 0.9, |
||
234 | stroke: 'none', |
||
235 | "stroke-width": 0, |
||
236 | "stroke-opacity": 0 |
||
237 | } |
||
238 | }, |
||
239 | series: { |
||
240 | regions: [ |
||
241 | { |
||
242 | values: scope.myMapData, |
||
243 | scale: ["#1ab394", "#22d6b1"], |
||
244 | normalizeFunction: 'polynomial' |
||
245 | } |
||
246 | ] |
||
247 | }, |
||
248 | }); |
||
249 | var destroyMap = function(){ |
||
250 | element.remove(); |
||
251 | }; |
||
252 | scope.$on('$destroy', function() { |
||
253 | destroyMap(); |
||
254 | }); |
||
255 | } |
||
256 | } |
||
257 | } |
||
258 | |||
259 | |||
260 | /** |
||
261 | * sparkline - Directive for Sparkline chart |
||
262 | */ |
||
263 | function sparkline() { |
||
264 | return { |
||
265 | restrict: 'A', |
||
266 | scope: { |
||
267 | sparkData: '=', |
||
268 | sparkOptions: '=', |
||
269 | }, |
||
270 | link: function (scope, element, attrs) { |
||
271 | scope.$watch(scope.sparkData, function () { |
||
272 | render(); |
||
273 | }); |
||
274 | scope.$watch(scope.sparkOptions, function(){ |
||
275 | render(); |
||
276 | }); |
||
277 | var render = function () { |
||
278 | $(element).sparkline(scope.sparkData, scope.sparkOptions); |
||
279 | }; |
||
280 | } |
||
281 | } |
||
282 | }; |
||
283 | |||
284 | /** |
||
285 | * icheck - Directive for custom checkbox icheck |
||
286 | */ |
||
287 | function icheck($timeout) { |
||
288 | return { |
||
289 | restrict: 'A', |
||
290 | require: 'ngModel', |
||
291 | link: function($scope, element, $attrs, ngModel) { |
||
292 | return $timeout(function() { |
||
293 | var value; |
||
294 | value = $attrs['value']; |
||
295 | |||
296 | $scope.$watch($attrs['ngModel'], function(newValue){ |
||
297 | $(element).iCheck('update'); |
||
298 | }) |
||
299 | |||
300 | return $(element).iCheck({ |
||
301 | checkboxClass: 'icheckbox_square-green', |
||
302 | radioClass: 'iradio_square-green' |
||
303 | |||
304 | }).on('ifChanged', function(event) { |
||
305 | if ($(element).attr('type') === 'checkbox' && $attrs['ngModel']) { |
||
306 | $scope.$apply(function() { |
||
307 | return ngModel.$setViewValue(event.target.checked); |
||
308 | }); |
||
309 | } |
||
310 | if ($(element).attr('type') === 'radio' && $attrs['ngModel']) { |
||
311 | return $scope.$apply(function() { |
||
312 | return ngModel.$setViewValue(value); |
||
313 | }); |
||
314 | } |
||
315 | }); |
||
316 | }); |
||
317 | } |
||
318 | }; |
||
319 | } |
||
320 | |||
321 | /** |
||
322 | * ionRangeSlider - Directive for Ion Range Slider |
||
323 | */ |
||
324 | function ionRangeSlider() { |
||
325 | return { |
||
326 | restrict: 'A', |
||
327 | scope: { |
||
328 | rangeOptions: '=' |
||
329 | }, |
||
330 | link: function (scope, elem, attrs) { |
||
331 | elem.ionRangeSlider(scope.rangeOptions); |
||
332 | } |
||
333 | } |
||
334 | } |
||
335 | |||
336 | /** |
||
337 | * dropZone - Directive for Drag and drop zone file upload plugin |
||
338 | */ |
||
339 | function dropZone() { |
||
340 | return { |
||
341 | restrict: 'C', |
||
342 | link: function(scope, element, attrs) { |
||
343 | |||
344 | var config = { |
||
345 | maxFilesize: 100, |
||
346 | paramName: "uploadfile", |
||
347 | maxThumbnailFilesize: 10, |
||
348 | parallelUploads: 1, |
||
349 | autoProcessQueue: false |
||
350 | }; |
||
351 | |||
352 | var eventHandlers = { |
||
353 | 'addedfile': function(file) { |
||
354 | scope.file = file; |
||
355 | if (this.files[1]!=null) { |
||
356 | this.removeFile(this.files[0]); |
||
357 | } |
||
358 | scope.$apply(function() { |
||
359 | scope.fileAdded = true; |
||
360 | }); |
||
361 | }, |
||
362 | |||
363 | 'success': function (file, response) { |
||
364 | } |
||
365 | |||
366 | }; |
||
367 | |||
368 | dropzone = new Dropzone(element[0], config); |
||
0 ignored issues
–
show
|
|||
369 | |||
370 | angular.forEach(eventHandlers, function(handler, event) { |
||
371 | dropzone.on(event, handler); |
||
372 | }); |
||
373 | |||
374 | scope.processDropzone = function() { |
||
375 | dropzone.processQueue(); |
||
376 | }; |
||
377 | |||
378 | scope.resetDropzone = function() { |
||
379 | dropzone.removeAllFiles(); |
||
380 | } |
||
381 | } |
||
382 | } |
||
383 | } |
||
384 | |||
385 | /** |
||
386 | * chatSlimScroll - Directive for slim scroll for small chat |
||
387 | */ |
||
388 | function chatSlimScroll($timeout) { |
||
389 | return { |
||
390 | restrict: 'A', |
||
391 | link: function(scope, element) { |
||
392 | $timeout(function(){ |
||
393 | element.slimscroll({ |
||
394 | height: '234px', |
||
395 | railOpacity: 0.4 |
||
396 | }); |
||
397 | |||
398 | }); |
||
399 | } |
||
400 | }; |
||
401 | } |
||
402 | |||
403 | /** |
||
404 | * customValid - Directive for custom validation example |
||
405 | */ |
||
406 | function customValid(){ |
||
407 | return { |
||
408 | require: 'ngModel', |
||
409 | link: function(scope, ele, attrs, c) { |
||
410 | scope.$watch(attrs.ngModel, function() { |
||
411 | |||
412 | // You can call a $http method here |
||
413 | // Or create custom validation |
||
414 | |||
415 | var validText = "Inspinia"; |
||
416 | |||
417 | if(scope.extras == validText) { |
||
418 | c.$setValidity('cvalid', true); |
||
419 | } else { |
||
420 | c.$setValidity('cvalid', false); |
||
421 | } |
||
422 | |||
423 | }); |
||
424 | } |
||
425 | } |
||
426 | } |
||
427 | |||
428 | |||
429 | /** |
||
430 | * fullScroll - Directive for slimScroll with 100% |
||
431 | */ |
||
432 | function fullScroll($timeout){ |
||
433 | return { |
||
434 | restrict: 'A', |
||
435 | link: function(scope, element) { |
||
436 | $timeout(function(){ |
||
437 | element.slimscroll({ |
||
438 | height: '100%', |
||
439 | railOpacity: 0.9 |
||
440 | }); |
||
441 | |||
442 | }); |
||
443 | } |
||
444 | }; |
||
445 | } |
||
446 | |||
447 | /** |
||
448 | * slimScroll - Directive for slimScroll with custom height |
||
449 | */ |
||
450 | function slimScroll($timeout){ |
||
451 | return { |
||
452 | restrict: 'A', |
||
453 | scope: { |
||
454 | boxHeight: '@' |
||
455 | }, |
||
456 | link: function(scope, element) { |
||
457 | $timeout(function(){ |
||
458 | element.slimscroll({ |
||
459 | height: scope.boxHeight, |
||
460 | railOpacity: 0.9 |
||
461 | }); |
||
462 | |||
463 | }); |
||
464 | } |
||
465 | }; |
||
466 | } |
||
467 | |||
468 | /** |
||
469 | * clockPicker - Directive for clock picker plugin |
||
470 | */ |
||
471 | function clockPicker() { |
||
472 | return { |
||
473 | restrict: 'A', |
||
474 | link: function(scope, element) { |
||
475 | element.clockpicker(); |
||
476 | } |
||
477 | }; |
||
478 | }; |
||
479 | |||
480 | |||
481 | /** |
||
482 | * landingScrollspy - Directive for scrollspy in landing page |
||
483 | */ |
||
484 | function landingScrollspy(){ |
||
485 | return { |
||
486 | restrict: 'A', |
||
487 | link: function (scope, element, attrs) { |
||
488 | element.scrollspy({ |
||
489 | target: '.navbar-fixed-top', |
||
490 | offset: 80 |
||
491 | }); |
||
492 | } |
||
493 | } |
||
494 | } |
||
495 | |||
496 | /** |
||
497 | * fitHeight - Directive for set height fit to window height |
||
498 | */ |
||
499 | function fitHeight(){ |
||
500 | return { |
||
501 | restrict: 'A', |
||
502 | link: function(scope, element) { |
||
503 | element.css("height", $(window).height() + "px"); |
||
504 | element.css("min-height", $(window).height() + "px"); |
||
505 | } |
||
506 | }; |
||
507 | } |
||
508 | |||
509 | /** |
||
510 | * truncate - Directive for truncate string |
||
511 | */ |
||
512 | function truncate($timeout){ |
||
513 | return { |
||
514 | restrict: 'A', |
||
515 | scope: { |
||
516 | truncateOptions: '=' |
||
517 | }, |
||
518 | link: function(scope, element) { |
||
519 | $timeout(function(){ |
||
520 | element.dotdotdot(scope.truncateOptions); |
||
521 | |||
522 | }); |
||
523 | } |
||
524 | }; |
||
525 | } |
||
526 | |||
527 | |||
528 | /** |
||
529 | * touchSpin - Directive for Bootstrap TouchSpin |
||
530 | */ |
||
531 | function touchSpin() { |
||
532 | return { |
||
533 | restrict: 'A', |
||
534 | scope: { |
||
535 | spinOptions: '=' |
||
536 | }, |
||
537 | link: function (scope, element, attrs) { |
||
538 | scope.$watch(scope.spinOptions, function(){ |
||
539 | render(); |
||
540 | }); |
||
541 | var render = function () { |
||
542 | $(element).TouchSpin(scope.spinOptions); |
||
543 | }; |
||
544 | } |
||
545 | } |
||
546 | }; |
||
547 | |||
548 | /** |
||
549 | * markdownEditor - Directive for Bootstrap Markdown |
||
550 | */ |
||
551 | function markdownEditor() { |
||
552 | return { |
||
553 | restrict: "A", |
||
554 | require: 'ngModel', |
||
555 | link: function (scope, element, attrs, ngModel) { |
||
556 | $(element).markdown({ |
||
557 | savable:false, |
||
558 | onChange: function(e){ |
||
559 | ngModel.$setViewValue(e.getContent()); |
||
560 | } |
||
561 | }); |
||
562 | } |
||
563 | } |
||
564 | }; |
||
565 | |||
566 | // 创建一个名为 captcha 的指令 |
||
567 | function captcha() { |
||
568 | return { |
||
569 | restrict: 'AE', |
||
570 | replace: true, |
||
571 | name: 'captcha', |
||
572 | scope: { |
||
573 | captchaText: '=captchaText', |
||
574 | refreshCaptcha: '=refresh' |
||
575 | }, |
||
576 | template: '<canvas height="34" ng-click="refreshCaptcha()" width="86" class="cell-captcha-canvas" ng-model="text"></canvas>', |
||
577 | link: function(scope, elem, attrs) { |
||
578 | // 生成随机字符串作为验证码 |
||
579 | function generateCode() { |
||
580 | var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'; |
||
581 | var codeLength = 5; |
||
582 | var code = ''; |
||
583 | for (var i = 0; i < codeLength; i++) { |
||
584 | var randomIndex = Math.floor(Math.random() * chars.length); |
||
585 | code += chars.substring(randomIndex, randomIndex + 1); |
||
586 | scope.captchaText = code; |
||
587 | } |
||
588 | return code; |
||
589 | } |
||
590 | |||
591 | // 绘制验证码 |
||
592 | function draw(canvas, code) { |
||
593 | var context = canvas.getContext('2d'); |
||
594 | context.fillStyle = '#EEE'; |
||
595 | context.fillRect(0, 0, canvas.width, canvas.height); |
||
596 | context.font = '24px Arial'; |
||
597 | context.fillStyle = 'black'; |
||
598 | context.textAlign = 'center'; |
||
599 | context.fillText(code, canvas.width / 2, canvas.height / 2 + 10); |
||
600 | } |
||
601 | |||
602 | // 初始化生成验证码 |
||
603 | var canvas = elem[0]; |
||
604 | var code = generateCode(); |
||
605 | draw(canvas, code); |
||
606 | |||
607 | // 刷新验证码 |
||
608 | scope.refreshCaptcha = function() { |
||
609 | code = generateCode(); |
||
610 | draw(canvas, code); |
||
611 | }; |
||
612 | |||
613 | }}; |
||
614 | }; |
||
615 | |||
616 | /** |
||
617 | * |
||
618 | * Pass all functions into module |
||
619 | */ |
||
620 | app |
||
621 | .directive('pageTitle', pageTitle) |
||
622 | .directive('sideNavigation', sideNavigation) |
||
623 | .directive('iboxTools', iboxTools) |
||
624 | .directive('minimalizaSidebar', minimalizaSidebar) |
||
625 | .directive('vectorMap', vectorMap) |
||
626 | .directive('sparkline', sparkline) |
||
627 | .directive('icheck', icheck) |
||
628 | .directive('ionRangeSlider', ionRangeSlider) |
||
629 | .directive('dropZone', dropZone) |
||
630 | .directive('responsiveVideo', responsiveVideo) |
||
631 | .directive('chatSlimScroll', chatSlimScroll) |
||
632 | .directive('customValid', customValid) |
||
633 | .directive('fullScroll', fullScroll) |
||
634 | .directive('closeOffCanvas', closeOffCanvas) |
||
635 | .directive('clockPicker', clockPicker) |
||
636 | .directive('landingScrollspy', landingScrollspy) |
||
637 | .directive('fitHeight', fitHeight) |
||
638 | .directive('iboxToolsFullScreen', iboxToolsFullScreen) |
||
639 | .directive('slimScroll', slimScroll) |
||
640 | .directive('truncate', truncate) |
||
641 | .directive('touchSpin', touchSpin) |
||
642 | .directive('markdownEditor', markdownEditor) |
||
643 | .directive('captcha', captcha) |
||
644 |