ImageUpload: modal undismissable + cancel
[kivitendo-erp.git] / js / kivi.ImageUpload.js
1 namespace("kivi.ImageUpload", function(ns) {
2   "use strict";
3
4   const MAXSIZE = 15*1024*1024; // 5MB size limit
5   const M = kivi.Materialize;
6
7   let num_images = 0;
8   ns.upload_in_progress = undefined;
9
10   ns.add_files = function(target) {
11     let files = [];
12     for (var i = 0; i < target.files.length; i++) {
13       files.push(target.files.item(i));
14     }
15
16     kivi.FileDB.store_image(files[0], files[0].name, () => {
17       ns.reload_images();
18       target.value = null;
19     });
20   };
21
22   ns.reload_images = function() {
23     kivi.FileDB.retrieve_all((data) => {
24       $('#stored-images').empty();
25       num_images = data.length;
26
27       data.forEach(ns.create_thumb_row);
28       ns.set_image_button_enabled();
29     });
30   };
31
32   ns.create_thumb_row = function(file)  {
33     let URL = window.URL || window.webkitURL;
34     let file_url = URL.createObjectURL(file);
35
36     let $row = $("<div>").addClass("row image-upload-row");
37     let $button = $("<a>")
38       .addClass("btn-floating btn-large waves-effect waves-light red")
39       .click((event) => ns.remove_image(event, file.name))
40       .append($("<i>delete</i>").addClass("material-icons"));
41     $row.append($("<div>").addClass("col s3").append($button));
42
43     let $image = $('<img>').attr("src", file_url).addClass("materialboxed responsive-img");
44     $row.append($("<div>").addClass("col s9").append($image));
45
46     $("#stored-images").append($row);
47   };
48
49   ns.remove_image = function(event, key) {
50     let $row = $(event.target).closest(".image-upload-row");
51     kivi.FileDB.delete_key(key, () => {
52       $row.remove();
53       num_images--;
54       ns.set_image_button_enabled();
55     });
56   };
57
58   ns.set_image_button_enabled = function() {
59     $('#upload_images_submit').attr("disabled", num_images == 0 || !$('#object_id').val());
60   };
61
62
63   ns.upload_files = function() {
64     let id = $('#object_id').val();
65     let type = $('#object_type').val();
66
67     ns.upload_selected_files(id, type, MAXSIZE);
68   };
69
70   ns.upload_selected_files = function(id, type, maxsize) {
71     $("#upload_modal").modal({ dismissible: false });
72     $("#upload_modal").modal("open");
73
74     kivi.FileDB.retrieve_all((myfiles) => {
75       let filesize  = 0;
76       myfiles.forEach(file => {
77         filesize  += file.size;
78         if (filesize > maxsize) {
79           M.flash(kivi.t8("filesize too big: ") + ns.format_si(filesize) + kivi.t8(" > ") + ns.format_si(maxsize));
80           $("#upload_modal").modal("close");
81           return;
82         }
83
84         let data = new FormData();
85         data.append("uploadfiles[]", file);
86         data.append("action", "File/ajax_files_uploaded");
87         data.append("json", "1");
88         data.append("object_type", type);
89         data.append("object_id", id);
90         data.append("file_type", "attachment");
91
92         $("#upload_result").html(kivi.t8("start upload"));
93
94         let xhr = new XMLHttpRequest;
95         xhr.open('POST', 'controller.pl', true);
96         xhr.onload = ns.upload_complete;
97         xhr.upload.onprogress = ns.progress;
98         xhr.upload.onerror = ns.failed;
99         xhr.upload.onabort = ns.abort;
100         xhr.send(data);
101
102         ns.upload_in_progress = xhr;
103       });
104     });
105   };
106
107   ns.progress = function(event) {
108     if (event.lengthComputable) {
109       var percent_complete = (event.loaded / event.total) * 100;
110       console.log(percent_complete);
111       $("#upload_progress div").removeClass("indeterminate").addClass("determinate").attr("style", "width: " + percent_complete + "%");
112     }
113   };
114
115   ns.failed = function() {
116     $('#upload_modal').modal('close');
117     M.flash(kivi.t8("An error occurred while transferring the file."));
118   };
119
120   ns.abort = function() {
121     $('#upload_modal').modal('close');
122     M.flash(kivi.t8("The transfer has been canceled by the user."));
123
124     ns.upload_in_progress = undefined;
125   };
126
127   ns.upload_complete = function() {
128     $('#upload_modal').modal('close');
129     M.flash(kivi.t8("Files have been uploaded successfully."));
130     kivi.FileDB.delete_all(ns.reload_images);
131   };
132
133   ns.resolve_object = function(event) {
134     let obj_type = $('#object_type').val();
135     let number   = event.target.value;
136
137     $.ajax({
138       url: "controller.pl",
139       data: {
140         action: "ImageUpload/resolve_object_by_number",
141         object_type: obj_type,
142         object_number: number
143       },
144       type: "json",
145       success: (json) => {
146         if (json.error) {
147           $("#object_description").html("");
148           $("#object_id").val("");
149         } else {
150           $("#object_description").html(json.description);
151           $("#object_id").val(json.id);
152         }
153         ns.set_image_button_enabled();
154       },
155       error: () => {
156         $("#object_description").html("");
157         $("#object_id").val("");
158         ns.set_image_button_enabled();
159       }
160     });
161   };
162
163   /* this tries to format the number human readable. 3 significant digits, si suffix, */
164   ns.format_si = function(n) {
165     const prefixes = ["", "K" , "M", "G", "T", "P"];
166     let i = 0;
167     while (n >= 1024) {
168       n /= 1024;
169       i++;
170     }
171
172     return kivi.format_amount(n, 3 - (n|0).toString().length) + prefixes[i] + "B";
173   };
174
175   ns.init = function() {
176     ns.reload_images();
177   };
178 });
179
180 $(kivi.ImageUpload.init);