login/pass: error messages below page title
[minimedit.git] / progress.js
1 function showsize(bytes) {
2         return (bytes / 1024 / 1024).toFixed(2);
3 }
4
5 function enablesubmit(form) {
6         let submit = form.querySelector('input[type="submit"]:disabled');
7         if (!submit) return;
8         submit.disabled = false;
9 }
10
11 function trackupload(input) {
12         var progress = document.getElementById('progress');
13         if (!progress) {
14                 progress = document.createElement('DIV');
15                 progress.id = 'progress';
16                 progress.textContent = '0%';
17                 progress.style.width = '0';
18                 var bar = document.createElement('DIV');
19                 bar.className = 'bar';
20                 bar.appendChild(progress);
21                 input.parentNode.insertBefore(bar, input.nextSibling);
22         }
23
24         var ajax = new XMLHttpRequest();
25         ajax.upload.addEventListener('progress', function (e) {
26                 var percent = (e.loaded / e.total) * 100;
27                 progress.style.width = percent + '%';
28                 progress.textContent = Math.floor(percent) + '%';
29                 progress.innerHTML += ' <small>(' + showsize(e.loaded) + ' / ' + showsize(e.total) + ' MB)</small>';
30         }, false);
31         ajax.addEventListener('load', function (e) {
32                 if (e.target.status == 200) {
33                         progress.textContent = 'voltooid';
34                         progress.innerHTML += ' <small>(' + showsize(input.files[0].size) + ' MB)</small>';
35                         window.location.assign(e.target.response);
36                 }
37                 else {
38                         progress.textContent = 'fout';
39                         progress.innerHTML += ': <small>' + e.target.responseText + '</small>';
40                         enablesubmit(input.form);
41                 }
42                 progress.style.width = '100%';
43                 input.parentNode.removeChild(cancel);
44         }, false);
45         ajax.addEventListener('error', function (e) {
46                 progress.textContent = 'mislukt: ' + e.target.responseText;
47                 enablesubmit(input.form);
48         }, false);
49         ajax.addEventListener('abort', function (e) {
50                 progress.textContent = 'afgebroken';
51                 input.parentNode.removeChild(cancel);
52                 input.parentNode.removeChild(progress.parentNode);
53                 enablesubmit(input.form);
54         }, false);
55
56         ajax.open('POST', input.form.action);
57         ajax.setRequestHeader('Accept', 'text/plain')
58         ajax.send(new FormData(input.form));
59
60         var cancel = document.createElement('BUTTON');
61         cancel.textContent = 'Afbreken';
62         cancel.onclick = function () { ajax.abort() };
63         cancel.style.float = 'left';
64         input.parentNode.insertBefore(cancel, progress.parentNode);
65 }
66
67 document.addEventListener('DOMContentLoaded', e => {
68         for (let form of document.forms) {
69                 form.addEventListener('submit', e => {
70                         if (e.explicitOriginalTarget) {
71                                 e.explicitOriginalTarget.disabled = true;
72                         }
73                         if (upload = e.target.querySelector('input[type="file"]')) {
74                                 if (upload.value) {
75                                         e.preventDefault();
76                                         trackupload(upload);
77                                 }
78                         }
79                 });
80         }
81 });