Mercurial > hg > fapweb
comparison genajax.js @ 1069:5f92fa5e683a
Refactor how the "AJAX" stuff works.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 24 Jan 2017 17:25:48 +0200 |
parents | ajax.js@82ecea33c477 |
children | 7da8bde9b7be |
comparison
equal
deleted
inserted
replaced
1068:50d005dd22d8 | 1069:5f92fa5e683a |
---|---|
1 // | |
2 // FAPWeb - Simple Web-based Demoparty Management System | |
3 // Common JavaScript / AJAX code | |
4 // (C) Copyright 2012-2015 Tecnic Software productions (TNSP) | |
5 // | |
6 var jsMessageBoxCBCancel = null, jsMessageBoxCBData = null, jsMessageBoxCBOK = null; | |
7 var jsUploadCBS = []; | |
8 | |
9 | |
10 function jsHandleMessageBoxKeys(ev) | |
11 { | |
12 ev = ev || window.event; | |
13 var key = ev.keyCode ? ev.keyCode : ev.which; | |
14 if (key == 27) | |
15 { | |
16 jsCloseMessageBox(jsMessageBoxCBCancel, jsMessageBoxCBData); | |
17 return false; | |
18 } | |
19 else | |
20 return true; | |
21 } | |
22 | |
23 | |
24 function jsSetMessageBoxCBs(cb_ok, cb_cancel, cb_data) | |
25 { | |
26 jsMessageBoxCBOK = cb_ok; | |
27 jsMessageBoxCBCancel = cb_cancel; | |
28 jsMessageBoxCBData = cb_data; | |
29 } | |
30 | |
31 | |
32 function jsCloseMessageBox(callback, cb_data) | |
33 { | |
34 var nitem = document.getElementById("messageBox"); | |
35 if (nitem) | |
36 { | |
37 document.onkeydown = null; | |
38 jsSetMessageBoxCBs(null, null, null); | |
39 | |
40 if (nitem.style.display != "none") | |
41 { | |
42 nitem.style.display = "none"; | |
43 | |
44 if (callback && typeof(callback) === "function") | |
45 callback(cb_data); | |
46 } | |
47 } | |
48 } | |
49 | |
50 | |
51 function jsMessageBox(msg) | |
52 { | |
53 var nitem = document.getElementById("messageBox"); | |
54 if (nitem) | |
55 { | |
56 nitem.innerHTML = "<div class='messageBoxInner'>"+ msg + | |
57 "<div class='messageBoxControls'>"+ | |
58 "<input id='msgBoxConfirmClose' type='button' value=' OK '>"+ | |
59 "</div></div>"; | |
60 | |
61 document.onkeydown = jsHandleMessageBoxKeys; | |
62 jsSetMessageBoxCBs(null, null, null); | |
63 | |
64 var elem = document.getElementById("msgBoxConfirmClose"); | |
65 elem.onclick = function () { jsCloseMessageBox(0, 0); } | |
66 | |
67 nitem.style.display = "block"; | |
68 } | |
69 } | |
70 | |
71 | |
72 function jsErrorMessageBox(msg) | |
73 { | |
74 jsMessageBox("<h1>Error!</h1><div>"+msg+"</div>"); | |
75 } | |
76 | |
77 | |
78 function jsTitleMessageBox(title, msg) | |
79 { | |
80 jsMessageBox("<h1>"+title+"</h1><div>"+msg+"</div>"); | |
81 } | |
82 | |
83 | |
84 function jsConfirmBox(msg, cb_ok, cb_cancel, cb_data) | |
85 { | |
86 var nitem = document.getElementById("messageBox"); | |
87 if (nitem) | |
88 { | |
89 nitem.innerHTML = "<div class='messageBoxInner'><h1>Confirmation</h1><p>"+ msg +"</p>"+ | |
90 "<div class='messageBoxControls'>"+ | |
91 "<input id='msgBoxConfirmCancel' type='button' value=' Cancel '>"+ | |
92 "<input id='msgBoxConfirmOK' type='button' value=' OK '>"+ | |
93 "</div></div>"; | |
94 | |
95 document.onkeydown = jsHandleMessageBoxKeys; | |
96 jsSetMessageBoxCBs(cb_ok, cb_cancel, cb_data); | |
97 | |
98 var elem = document.getElementById("msgBoxConfirmCancel"); | |
99 elem.onclick = function () { jsCloseMessageBox(cb_cancel, cb_data); } | |
100 | |
101 elem = document.getElementById("msgBoxConfirmOK"); | |
102 elem.onclick = function () { jsCloseMessageBox(cb_ok, cb_data); } | |
103 | |
104 nitem.style.display = "block"; | |
105 } | |
106 } | |
107 | |
108 | |
109 function jsStatusMsg(msg) | |
110 { | |
111 var nitem = document.getElementById("nstatus"); | |
112 if (nitem) nstatus.innerHTML = msg; | |
113 } | |
114 | |
115 | |
116 function strtrim(str) | |
117 { | |
118 if (!str || str == null) | |
119 return ""; | |
120 return str.replace(/^\s+|\s+$/g,'') | |
121 } | |
122 | |
123 | |
124 function strencode(str) | |
125 { | |
126 return encodeURIComponent(str); | |
127 } | |
128 | |
129 | |
130 function jsCreateXMLRequest() | |
131 { | |
132 var req; | |
133 if (window.XMLHttpRequest) | |
134 { | |
135 // Modern browsers | |
136 req = new XMLHttpRequest(); | |
137 } | |
138 else | |
139 { | |
140 // Old IE versions | |
141 req = new ActiveXObject("Microsoft.XMLHTTP"); | |
142 } | |
143 return req; | |
144 } | |
145 | |
146 | |
147 // | |
148 // Function for creating AJAX POST request arguments list based | |
149 // on fields and giving them specified types. Also basic check | |
150 // for validity can be performed (e.g. field empty or not) | |
151 // | |
152 var lastPostArgs = Object(); | |
153 function jsMakePostArgs(fields, fprefix, fsuffix, nofail) | |
154 { | |
155 var res = []; | |
156 lastPostArgs = Object(); | |
157 | |
158 for (var id in fields) | |
159 { | |
160 var elname = fprefix + id + fsuffix; | |
161 switch (fields[id]) | |
162 { | |
163 case 4: | |
164 elname += "Sel"; | |
165 break; | |
166 } | |
167 | |
168 var elem = document.getElementById(elname); | |
169 if (!elem && !nofail) | |
170 { | |
171 jsErrorMessageBox("No such DOM element '"+ elname +"'."); | |
172 return ""; | |
173 } | |
174 | |
175 if (elem) | |
176 { | |
177 switch (fields[id]) | |
178 { | |
179 case 1: | |
180 var vstr = strtrim(elem.value); | |
181 res.push(id+"="+strencode(vstr)); | |
182 lastPostArgs[id] = vstr; | |
183 break; | |
184 | |
185 case 2: | |
186 var vint = parseInt(strtrim(elem.value)); | |
187 res.push(id+"="+vint); | |
188 lastPostArgs[id] = vint; | |
189 break; | |
190 | |
191 case 3: | |
192 res.push(id+"="+(elem.checked ? "1" : "0")); | |
193 lastPostArgs[id] = elem.checked; | |
194 break; | |
195 | |
196 case 4: | |
197 var vval = (elem.selectedIndex != -1) ? elem.options[elem.selectedIndex].value : -1; | |
198 res.push(id+"="+vval); | |
199 lastPostArgs[id] = vval; | |
200 break; | |
201 | |
202 default: | |
203 jsErrorMessageBox("Unsupported field type in "+ elname); | |
204 return ""; | |
205 } | |
206 } | |
207 } | |
208 return res.join("&"); | |
209 } | |
210 | |
211 | |
212 function jsGetValue(elname, eltype) | |
213 { | |
214 var elem = document.getElementById(elname); | |
215 if (!elem) | |
216 { | |
217 jsErrorMessageBox("No such DOM element '"+ elname +"'."); | |
218 return ""; | |
219 } | |
220 | |
221 switch (eltype) | |
222 { | |
223 case 1: | |
224 var vstr = strtrim(elem.value); | |
225 return strencode(vstr); | |
226 | |
227 case 2: | |
228 var vint = parseInt(strtrim(elem.value)); | |
229 return vint; | |
230 | |
231 case 3: | |
232 return elem.checked ? "1" : "0"; | |
233 | |
234 case 4: | |
235 if (elem.selectedIndex != -1) | |
236 return elem.options[elem.selectedIndex].value; | |
237 else | |
238 return null; | |
239 | |
240 default: | |
241 jsErrorMessageBox("Unsupported field type in "+ elname); | |
242 return ""; | |
243 } | |
244 } | |
245 | |
246 | |
247 function jsShowPreviewImage(file) | |
248 { | |
249 var nitem = document.getElementById("messageBox"); | |
250 if (nitem) | |
251 { | |
252 nitem.innerHTML = "<div class='imageBoxInner'>"+ | |
253 "<img src='"+file+"' alt='"+file+"' />"+ | |
254 "</div>"; | |
255 | |
256 var elem = document.getElementById("messageBox"); | |
257 elem.onclick = function () { jsCloseMessageBox(0, 0); } | |
258 | |
259 nitem.style.display = "block"; | |
260 | |
261 return false; | |
262 } | |
263 | |
264 return true; | |
265 } | |
266 | |
267 | |
268 function jsFormatSize(bytes) | |
269 { | |
270 var suffixes = ["Bytes", "KiB", "MiB"]; | |
271 var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); | |
272 return (bytes / Math.pow(1024, i)).toFixed(1) +' '+ suffixes[i]; | |
273 } | |
274 | |
275 | |
276 function jsStartFileUpload(formID, formTarget, fileSelID, fileMaxSize, fileCallback) | |
277 { | |
278 var formFile = document.getElementById(fileSelID).files[0]; | |
279 if (!formFile || typeof(formFile) !== "object") | |
280 { | |
281 jsErrorMessageBox("No file selected to be uploaded."); | |
282 return; | |
283 } | |
284 | |
285 if (formFile.size > fileMaxSize) | |
286 { | |
287 jsErrorMessageBox("File size exceeds "+ jsFormatSize(fileMaxSize) +"."); | |
288 return; | |
289 } | |
290 | |
291 var filename = formFile.name; | |
292 var formElem = document.getElementById(formID); | |
293 if (!formElem) | |
294 { | |
295 jsErrorMessageBox("File upload form '"+ formID +"' element not found!"); | |
296 return; | |
297 } | |
298 | |
299 var formData = new FormData(formElem); | |
300 var req = jsCreateXMLRequest(); | |
301 req.upload.addEventListener("progress", function(e) | |
302 { | |
303 if (e.lengthComputable) | |
304 { | |
305 var complete = Math.round(e.loaded * 100 / e.total); | |
306 if (complete < 100) | |
307 jsStatusMsg("Uploaded ["+filename+"] "+ complete.toString() +'%, '+ jsFormatSize(e.loaded)); | |
308 else | |
309 jsStatusMsg("Upload ["+filename+"] finished ..."); | |
310 } | |
311 }, false); | |
312 req.addEventListener("error", function(e) | |
313 { | |
314 jsErrorMessageBox("Error occured while uploading "+filename); | |
315 }, false); | |
316 req.addEventListener("abort", function(e) | |
317 { | |
318 jsStatusMsg("Upload of '"+filename+"' aborted."); | |
319 }, false); | |
320 | |
321 req.onreadystatechange = function() | |
322 { | |
323 if (req.readyState == 4) | |
324 { | |
325 switch (req.status) | |
326 { | |
327 case 902: | |
328 jsStatusMsg(req.statusText); | |
329 jsMessageBox(req.responseText); | |
330 break; | |
331 | |
332 case 903: | |
333 { | |
334 var nitem = document.getElementById("messageBox"); | |
335 if (nitem) | |
336 { | |
337 nitem.innerHTML = "<div class='messageBoxInner'>"+ req.responseText + | |
338 "<div class='messageBoxControls'>"+ | |
339 "</div></div>"; | |
340 nitem.style.display = "block"; | |
341 } | |
342 } | |
343 break; | |
344 | |
345 case 200: | |
346 if (fileCallback) | |
347 { | |
348 var tid = setTimeout(function(qtid) | |
349 { | |
350 jsRemoveUploadCB(qtid); | |
351 setTimeout(fileCallback, 10); | |
352 //jsTitleMessageBox("File upload", req.responseText); | |
353 }, 10, qtid); | |
354 jsUploadCBS.push(tid); | |
355 } | |
356 break; | |
357 | |
358 default: | |
359 jsStatusMsg("["+req.status+" - "+req.statusText+"] "+ req.responseText); | |
360 break; | |
361 } | |
362 } | |
363 } | |
364 | |
365 req.open("POST", formTarget); | |
366 req.send(formData); | |
367 } | |
368 | |
369 | |
370 function jsCancelUploadCBS() | |
371 { | |
372 if (jsUploadCBS.length > 0) | |
373 { | |
374 for (var tid in jsUploadCBS) | |
375 clearTimeout(tid); | |
376 } | |
377 } | |
378 | |
379 | |
380 function jsRemoveUploadCB(tid) | |
381 { | |
382 var index = jsUploadCBS.indexOf(tid); | |
383 if (index >= 0) | |
384 jsUploadCBS.splice(index, 1); | |
385 } |