]> BookStack Code Mirror - bookstack/blob - resources/assets/js/directives.js
Fixes #58
[bookstack] / resources / assets / js / directives.js
1 "use strict";
2 var DropZone = require('dropzone');
3
4 var toggleSwitchTemplate = require('./components/toggle-switch.html');
5 var imagePickerTemplate = require('./components/image-picker.html');
6 var dropZoneTemplate = require('./components/drop-zone.html');
7
8 module.exports = function (ngApp, events) {
9
10     /**
11      * Toggle Switches
12      * Has basic on/off functionality.
13      * Use string values of 'true' & 'false' to dictate the current state.
14      */
15     ngApp.directive('toggleSwitch', function () {
16         return {
17             restrict: 'E',
18             template: toggleSwitchTemplate,
19             scope: true,
20             link: function (scope, element, attrs) {
21                 scope.name = attrs.name;
22                 scope.value = attrs.value;
23                 scope.isActive = scope.value == true && scope.value != 'false';
24                 scope.value = (scope.value == true && scope.value != 'false') ? 'true' : 'false';
25
26                 scope.switch = function () {
27                     scope.isActive = !scope.isActive;
28                     scope.value = scope.isActive ? 'true' : 'false';
29                 }
30
31             }
32         };
33     });
34
35
36     /**
37      * Image Picker
38      * Is a simple front-end interface that connects to an ImageManager if present.
39      */
40     ngApp.directive('imagePicker', ['$http', 'imageManagerService', function ($http, imageManagerService) {
41         return {
42             restrict: 'E',
43             template: imagePickerTemplate,
44             scope: {
45                 name: '@',
46                 resizeHeight: '@',
47                 resizeWidth: '@',
48                 resizeCrop: '@',
49                 showRemove: '=',
50                 currentImage: '@',
51                 currentId: '@',
52                 defaultImage: '@',
53                 imageClass: '@'
54             },
55             link: function (scope, element, attrs) {
56                 var usingIds = typeof scope.currentId !== 'undefined' || scope.currentId === 'false';
57                 scope.image = scope.currentImage;
58                 scope.value = scope.currentImage || '';
59                 if (usingIds) scope.value = scope.currentId;
60
61                 function setImage(imageModel, imageUrl) {
62                     scope.image = imageUrl;
63                     scope.value = usingIds ? imageModel.id : imageUrl;
64                 }
65
66                 scope.reset = function () {
67                     setImage({id: 0}, scope.defaultImage);
68                 };
69
70                 scope.remove = function () {
71                     scope.image = 'none';
72                     scope.value = 'none';
73                 };
74
75                 scope.showImageManager = function () {
76                     imageManagerService.show((image) => {
77                         scope.updateImageFromModel(image);
78                     });
79                 };
80
81                 scope.updateImageFromModel = function (model) {
82                     var isResized = scope.resizeWidth && scope.resizeHeight;
83
84                     if (!isResized) {
85                         scope.$apply(() => {
86                             setImage(model, model.url);
87                         });
88                         return;
89                     }
90
91                     var cropped = scope.resizeCrop ? 'true' : 'false';
92                     var requestString = '/images/thumb/' + model.id + '/' + scope.resizeWidth + '/' + scope.resizeHeight + '/' + cropped;
93                     $http.get(requestString).then((response) => {
94                         setImage(model, response.data.url);
95                     });
96                 };
97
98             }
99         };
100     }]);
101
102     /**
103      * DropZone
104      * Used for uploading images
105      */
106     ngApp.directive('dropZone', [function () {
107         return {
108             restrict: 'E',
109             template: dropZoneTemplate,
110             scope: {
111                 uploadUrl: '@',
112                 eventSuccess: '=',
113                 eventError: '='
114             },
115             link: function (scope, element, attrs) {
116                 var dropZone = new DropZone(element[0].querySelector('.dropzone-container'), {
117                     url: scope.uploadUrl,
118                     init: function () {
119                         var dz = this;
120                         dz.on('sending', function (file, xhr, data) {
121                             var token = window.document.querySelector('meta[name=token]').getAttribute('content');
122                             data.append('_token', token);
123                         });
124                         if (typeof scope.eventSuccess !== 'undefined') dz.on('success', scope.eventSuccess);
125                         dz.on('success', function (file, data) {
126                             $(file.previewElement).fadeOut(400, function () {
127                                 dz.removeFile(file);
128                             });
129                         });
130                         if (typeof scope.eventError !== 'undefined') dz.on('error', scope.eventError);
131                         dz.on('error', function (file, errorMessage, xhr) {
132                             console.log(errorMessage);
133                             console.log(xhr);
134                             function setMessage(message) {
135                                 $(file.previewElement).find('[data-dz-errormessage]').text(message);
136                             }
137
138                             if (xhr.status === 413) setMessage('The server does not allow uploads of this size. Please try a smaller file.');
139                             if (errorMessage.file) setMessage(errorMessage.file[0]);
140
141                         });
142                     }
143                 });
144             }
145         };
146     }]);
147
148
149     ngApp.directive('dropdown', [function () {
150         return {
151             restrict: 'A',
152             link: function (scope, element, attrs) {
153                 var menu = element.find('ul');
154                 element.find('[dropdown-toggle]').on('click', function () {
155                     menu.show().addClass('anim menuIn');
156                     element.mouseleave(function () {
157                         menu.hide();
158                         menu.removeClass('anim menuIn');
159                     });
160                 });
161             }
162         };
163     }]);
164
165
166 };