view genajax.js @ 1096:bbc0a3d0b51e

Major renaming / refactor of site messages. Some that were previously modifiable from admin interface are now "hardcoded" in the configuration file. Having these settings made modifiable from there made no sense and just took space in the UI.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 27 Jan 2017 22:15:06 +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);
}