view genajax.js @ 1120:b2bca5f6d0ff default tip

Cosmetic cleanup: remove trailing whitespace.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 13 Dec 2020 13:47:13 +0200
parents 5f48cb05bfff
children
line wrap: on
line source

//
// FAPWeb - Simple Web-based Demoparty Management System
// Common JavaScript / AJAX code
// (C) Copyright 2012-2017 Tecnic Software productions (TNSP)
//
var jsMessageBoxCBCancel = null, jsMessageBoxCBData = null, jsMessageBoxCBOK = null;
var jsUploadCBS = [];


function jsAddEventListener(velem, vev, vfunc)
{
  if (velem)
  {
    if (velem.attachEvent)
       return velem.attachEvent('on'+ vev, vfunc);
     else
       return velem.addEventListener(vev, vfunc, false);
  }
}


function jsAddEventListenerById(velem, vev, vfunc)
{
  jsAddEventListener(document.getElementById(velem), vev, vfunc);
}


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);

    jsAddEventListenerById("msgBoxConfirmClose", "click", 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);

    jsAddEventListenerById("msgBoxConfirmCancel", "click", function () { jsCloseMessageBox(cb_cancel, cb_data); });
    jsAddEventListenerById("msgBoxConfirmOK", "click", 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>";

    jsAddEventListenerById("messageBox", "click", 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()
            {
              jsRemoveUploadCB(tid);
              setTimeout(fileCallback, 10);
              //jsTitleMessageBox("File upload", req.responseText);
            }, 10);
            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);
}