Mercurial > hg > fapweb
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genajax.js Tue Jan 24 17:25:48 2017 +0200 @@ -0,0 +1,385 @@ +// +// FAPWeb - Simple Web-based Demoparty Management System +// Common JavaScript / AJAX code +// (C) Copyright 2012-2015 Tecnic Software productions (TNSP) +// +var jsMessageBoxCBCancel = null, jsMessageBoxCBData = null, jsMessageBoxCBOK = null; +var jsUploadCBS = []; + + +function jsHandleMessageBoxKeys(ev) +{ + ev = ev || window.event; + var key = ev.keyCode ? ev.keyCode : ev.which; + if (key == 27) + { + jsCloseMessageBox(jsMessageBoxCBCancel, jsMessageBoxCBData); + return false; + } + else + return true; +} + + +function jsSetMessageBoxCBs(cb_ok, cb_cancel, cb_data) +{ + jsMessageBoxCBOK = cb_ok; + jsMessageBoxCBCancel = cb_cancel; + jsMessageBoxCBData = cb_data; +} + + +function jsCloseMessageBox(callback, cb_data) +{ + var nitem = document.getElementById("messageBox"); + if (nitem) + { + document.onkeydown = null; + jsSetMessageBoxCBs(null, null, null); + + if (nitem.style.display != "none") + { + nitem.style.display = "none"; + + if (callback && typeof(callback) === "function") + callback(cb_data); + } + } +} + + +function jsMessageBox(msg) +{ + var nitem = document.getElementById("messageBox"); + if (nitem) + { + nitem.innerHTML = "<div class='messageBoxInner'>"+ msg + + "<div class='messageBoxControls'>"+ + "<input id='msgBoxConfirmClose' type='button' value=' OK '>"+ + "</div></div>"; + + document.onkeydown = jsHandleMessageBoxKeys; + jsSetMessageBoxCBs(null, null, null); + + var elem = document.getElementById("msgBoxConfirmClose"); + elem.onclick = function () { jsCloseMessageBox(0, 0); } + + nitem.style.display = "block"; + } +} + + +function jsErrorMessageBox(msg) +{ + jsMessageBox("<h1>Error!</h1><div>"+msg+"</div>"); +} + + +function jsTitleMessageBox(title, msg) +{ + jsMessageBox("<h1>"+title+"</h1><div>"+msg+"</div>"); +} + + +function jsConfirmBox(msg, cb_ok, cb_cancel, cb_data) +{ + var nitem = document.getElementById("messageBox"); + if (nitem) + { + nitem.innerHTML = "<div class='messageBoxInner'><h1>Confirmation</h1><p>"+ msg +"</p>"+ + "<div class='messageBoxControls'>"+ + "<input id='msgBoxConfirmCancel' type='button' value=' Cancel '>"+ + "<input id='msgBoxConfirmOK' type='button' value=' OK '>"+ + "</div></div>"; + + document.onkeydown = jsHandleMessageBoxKeys; + jsSetMessageBoxCBs(cb_ok, cb_cancel, cb_data); + + var elem = document.getElementById("msgBoxConfirmCancel"); + elem.onclick = function () { jsCloseMessageBox(cb_cancel, cb_data); } + + elem = document.getElementById("msgBoxConfirmOK"); + elem.onclick = function () { jsCloseMessageBox(cb_ok, cb_data); } + + nitem.style.display = "block"; + } +} + + +function jsStatusMsg(msg) +{ + var nitem = document.getElementById("nstatus"); + if (nitem) nstatus.innerHTML = msg; +} + + +function strtrim(str) +{ + if (!str || str == null) + return ""; + return str.replace(/^\s+|\s+$/g,'') +} + + +function strencode(str) +{ + return encodeURIComponent(str); +} + + +function jsCreateXMLRequest() +{ + var req; + if (window.XMLHttpRequest) + { + // Modern browsers + req = new XMLHttpRequest(); + } + else + { + // Old IE versions + req = new ActiveXObject("Microsoft.XMLHTTP"); + } + return req; +} + + +// +// Function for creating AJAX POST request arguments list based +// on fields and giving them specified types. Also basic check +// for validity can be performed (e.g. field empty or not) +// +var lastPostArgs = Object(); +function jsMakePostArgs(fields, fprefix, fsuffix, nofail) +{ + var res = []; + lastPostArgs = Object(); + + for (var id in fields) + { + var elname = fprefix + id + fsuffix; + switch (fields[id]) + { + case 4: + elname += "Sel"; + break; + } + + var elem = document.getElementById(elname); + if (!elem && !nofail) + { + jsErrorMessageBox("No such DOM element '"+ elname +"'."); + return ""; + } + + if (elem) + { + switch (fields[id]) + { + case 1: + var vstr = strtrim(elem.value); + res.push(id+"="+strencode(vstr)); + lastPostArgs[id] = vstr; + break; + + case 2: + var vint = parseInt(strtrim(elem.value)); + res.push(id+"="+vint); + lastPostArgs[id] = vint; + break; + + case 3: + res.push(id+"="+(elem.checked ? "1" : "0")); + lastPostArgs[id] = elem.checked; + break; + + case 4: + var vval = (elem.selectedIndex != -1) ? elem.options[elem.selectedIndex].value : -1; + res.push(id+"="+vval); + lastPostArgs[id] = vval; + break; + + default: + jsErrorMessageBox("Unsupported field type in "+ elname); + return ""; + } + } + } + return res.join("&"); +} + + +function jsGetValue(elname, eltype) +{ + var elem = document.getElementById(elname); + if (!elem) + { + jsErrorMessageBox("No such DOM element '"+ elname +"'."); + return ""; + } + + switch (eltype) + { + case 1: + var vstr = strtrim(elem.value); + return strencode(vstr); + + case 2: + var vint = parseInt(strtrim(elem.value)); + return vint; + + case 3: + return elem.checked ? "1" : "0"; + + case 4: + if (elem.selectedIndex != -1) + return elem.options[elem.selectedIndex].value; + else + return null; + + default: + jsErrorMessageBox("Unsupported field type in "+ elname); + return ""; + } +} + + +function jsShowPreviewImage(file) +{ + var nitem = document.getElementById("messageBox"); + if (nitem) + { + nitem.innerHTML = "<div class='imageBoxInner'>"+ + "<img src='"+file+"' alt='"+file+"' />"+ + "</div>"; + + var elem = document.getElementById("messageBox"); + elem.onclick = function () { jsCloseMessageBox(0, 0); } + + nitem.style.display = "block"; + + return false; + } + + return true; +} + + +function jsFormatSize(bytes) +{ + var suffixes = ["Bytes", "KiB", "MiB"]; + var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); + return (bytes / Math.pow(1024, i)).toFixed(1) +' '+ suffixes[i]; +} + + +function jsStartFileUpload(formID, formTarget, fileSelID, fileMaxSize, fileCallback) +{ + var formFile = document.getElementById(fileSelID).files[0]; + if (!formFile || typeof(formFile) !== "object") + { + jsErrorMessageBox("No file selected to be uploaded."); + return; + } + + if (formFile.size > fileMaxSize) + { + jsErrorMessageBox("File size exceeds "+ jsFormatSize(fileMaxSize) +"."); + return; + } + + var filename = formFile.name; + var formElem = document.getElementById(formID); + if (!formElem) + { + jsErrorMessageBox("File upload form '"+ formID +"' element not found!"); + return; + } + + var formData = new FormData(formElem); + var req = jsCreateXMLRequest(); + req.upload.addEventListener("progress", function(e) + { + if (e.lengthComputable) + { + var complete = Math.round(e.loaded * 100 / e.total); + if (complete < 100) + jsStatusMsg("Uploaded ["+filename+"] "+ complete.toString() +'%, '+ jsFormatSize(e.loaded)); + else + jsStatusMsg("Upload ["+filename+"] finished ..."); + } + }, false); + req.addEventListener("error", function(e) + { + jsErrorMessageBox("Error occured while uploading "+filename); + }, false); + req.addEventListener("abort", function(e) + { + jsStatusMsg("Upload of '"+filename+"' aborted."); + }, false); + + req.onreadystatechange = function() + { + if (req.readyState == 4) + { + switch (req.status) + { + case 902: + jsStatusMsg(req.statusText); + jsMessageBox(req.responseText); + break; + + case 903: + { + var nitem = document.getElementById("messageBox"); + if (nitem) + { + nitem.innerHTML = "<div class='messageBoxInner'>"+ req.responseText + + "<div class='messageBoxControls'>"+ + "</div></div>"; + nitem.style.display = "block"; + } + } + break; + + case 200: + if (fileCallback) + { + var tid = setTimeout(function(qtid) + { + jsRemoveUploadCB(qtid); + setTimeout(fileCallback, 10); + //jsTitleMessageBox("File upload", req.responseText); + }, 10, qtid); + jsUploadCBS.push(tid); + } + break; + + default: + jsStatusMsg("["+req.status+" - "+req.statusText+"] "+ req.responseText); + break; + } + } + } + + req.open("POST", formTarget); + req.send(formData); +} + + +function jsCancelUploadCBS() +{ + if (jsUploadCBS.length > 0) + { + for (var tid in jsUploadCBS) + clearTimeout(tid); + } +} + + +function jsRemoveUploadCB(tid) +{ + var index = jsUploadCBS.indexOf(tid); + if (index >= 0) + jsUploadCBS.splice(index, 1); +}