File: 0.00.0a/js/freedesk.js (View as Code)

1: /* ------------------------------------------------------------- 2: This file is part of FreeDESK 3: 4: FreeDESK is (C) Copyright 2012 David Cutting 5: 6: FreeDESK is free software: you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation, either version 3 of the License, or 9: (at your option) any later version. 10: 11: FreeDESK is distributed in the hope that it will be useful, 12: but WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14: GNU General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with FreeDESK. If not, see www.gnu.org/licenses 18: 19: For more information see www.purplepixie.org/freedesk/ 20: -------------------------------------------------------------- */ 21: 22: /** 23: * The main FreeDESK JavaScript client-side code 24: **/ 25: 26: function FreeDESK() 27: { 28: this.sid = ""; // Session ID 29: 30: // Statuses of requests (text) 31: this.requestStatus = new Array(); 32: // List of display fields for request list 33: this.fieldList = new Array(); 34: 35: // XML of last request list fetched (for redisplay) 36: this.lastListXML = null; 37: 38: // Last Request Details 39: this.lastTeam = 0; 40: this.lastUser = ""; 41: 42: // Last subpage 43: this.lastSubpage = ""; 44: this.lastSubpageOpts = ""; 45: 46: // Sort Criteria 47: this.sortField = "requestid"; 48: this.sortOrder = "D"; 49: 50: // Refresh Event 51: this.refreshEvent = null; 52: 53: // Login Support 54: this.login_action = function(responseXML) 55: { 56: //alert(responseXML); 57: //var txt = document.createTextNode(responseXML); 58: //document.getElementById("login_content").appendChild(txt); 59: if (DESK.isError(responseXML)) 60: { 61: DESK.show_login(DESK.getError(responseXML)); 62: } 63: else 64: { 65: var newsid = responseXML.getElementsByTagName("sid")[0].childNodes[0].nodeValue; 66: if (DESK.sid == "") // no current session so reload to index 67: { 68: //var loc = "./?sid="+newsid; 69: //window.location.href = loc; 70: document.forms['login_sid_form'].elements['sid'].value = newsid; 71: document.forms['login_sid_form'].submit(); 72: } 73: else 74: { 75: DESK.sid = newsid; 76: DESK.hide_login(); 77: // Any other actions? 78: } 79: } 80: } 81: 82: this.login_click=function() 83: { 84: var req = new ServerRequest(); 85: req.url = "api.php?mode=login&type=user&username=" 86: +document.getElementById("login_username").value 87: +"&password=" 88: +document.getElementById("login_password").value; 89: req.callback = DESK.login_action; 90: req.Get(); 91: } 92: 93: this.show_login=function(errormsg) 94: { 95: this.backdrop(true); 96: var txt = ""; 97: if (errormsg !== undefined) 98: txt=errormsg; 99: document.getElementById("login_message").innerHTML = txt; 100: document.getElementById("login_form").style.display = "block"; 101: } 102: 103: this.hide_login=function() 104: { 105: document.getElementById("login_form").style.display = "none"; 106: document.getElementById("login_message").style.display = "none"; 107: this.backdrop(false); 108: } 109: 110: // Logout 111: this.logout_click=function() 112: { 113: var req = new ServerRequest(); 114: req.url="api.php?mode=logout&sid="+this.sid; 115: req.callback = DESK.logout_action; 116: req.Get(); 117: } 118: 119: this.logout_action=function() 120: { 121: window.location.href="./"; 122: } 123: 124: // Show/Hide Backdrop 125: this.backdrop = function(set) 126: { 127: var bd = document.getElementById("screen_backdrop"); 128: if (set === undefined) // toggle 129: { 130: if (bd.style.display == "block") 131: set = false; 132: else 133: set = true; 134: } 135: 136: if (set) 137: bd.style.display = "block"; 138: else 139: bd.style.display = "none"; 140: } 141: 142: // Check for errors 143: this.isError = function(xml) 144: { 145: //alert(xml); 146: //alert(xml.documentElement); 147: //alert(xml.documentElement.tagName); 148: //alert(xml.getElementsByTagName("error")[0].childNodes[0].nodeValue); 149: if (xml.documentElement.tagName == "error") 150: //if (xml.getElementsByTagName("error").length > 0) 151: return true; 152: return false; 153: } 154: 155: this.getError = function(xml) 156: { 157: var out = xml.getElementsByTagName("code")[0].childNodes[0].nodeValue; 158: out += ": "; 159: out += xml.getElementsByTagName("text")[0].childNodes[0].nodeValue; 160: return out; 161: } 162: 163: this.getErrorCode = function(xml) 164: { 165: return xml.getElementsByTagName("code")[0].childNodes[0].nodeValue; 166: } 167: 168: // Display main or sub page (true for main, false for sub) 169: this.displayMain = function(disp) 170: { 171: if (disp) 172: { 173: document.getElementById("subpage").style.display="none"; 174: document.getElementById("mainpage").style.display="block"; 175: } 176: else 177: { 178: document.getElementById("mainpage").style.display="none"; 179: document.getElementById("subpage").style.display="block"; 180: } 181: } 182: 183: // Load sub-pages 184: this.displaySubpage = function(text) 185: { 186: document.getElementById("subpage").innerHTML = text; 187: DESK.displayMain(false); 188: } 189: 190: this.loadSubpage = function(page, opts) 191: { 192: if (opts == undefined) 193: var opts = ""; 194: this.lastSubpage = page; 195: this.lastSubpageOpts = opts; 196: var sr = new ServerRequest(); 197: sr.xmlrequest=false; 198: sr.url = "page.php?page="+page; 199: if (opts != "") 200: sr.url += "&"+opts; 201: sr.url += "&sid="+this.sid; 202: sr.callback = DESK.displaySubpage; 203: sr.Get(); 204: } 205: 206: // Refresh the subpage 207: this.refreshSubpage = function() 208: { 209: DESK.loadSubpage(DESK.lastSubpage, DESK.lastSubpageOpts); 210: } 211: 212: // Load a Request List to the Main Pane 213: this.mainPane = function(teamid, username) 214: { 215: if (teamid == undefined) 216: var teamid = 0; 217: if (username == undefined) 218: var username=""; 219: //alert(teamid+" "+username); 220: var sr = new ServerRequest(); 221: this.lastTeam = teamid; 222: this.lastUser = username; 223: 224: sr.url = "api.php?mode=requests_assigned&teamid="+teamid+"&username="+username; 225: if (this.sortField != "") 226: { 227: sr.url += "&sort="+this.sortField; 228: sr.url += "&order="+this.sortOrder; 229: } 230: sr.url += "&sid="+this.sid; 231: sr.callback = DESK.mainPaneDisplay; 232: sr.Get(); 233: } 234: 235: // Refresh the Main Pane 236: this.mainPaneRefresh = function() 237: { 238: DESK.mainPane(DESK.lastTeam, DESK.lastUser); 239: } 240: 241: // Display a request list in the main pane 242: this.mainPaneDisplay = function(xml) 243: { 244: DESK.lastListXML = xml; 245: var table = document.createElement("table"); // table for results 246: table.border=0; 247: table.width="100%"; 248: table.className="requestList"; 249: 250: var container = document.getElementById('mainright'); 251: 252: if (container.hasChildNodes()) 253: { 254: while(container.childNodes.length >= 1) 255: container.removeChild(container.firstChild); 256: } 257: 258: var requests = xml.getElementsByTagName("request"); 259: 260: if (requests.length <= 0) 261: { 262: container.innerHTML = "

No Requests Found

";
263: return; 264: } 265: 266: container.appendChild(table); 267: 268: var title = table.insertRow(0); 269: title.className = "requestListTitle"; 270: for (var i=0; i271: { 272: if (DESK.fieldList[i][1] == 1) // displayed field 273: { 274: var cell = title.insertCell(-1); 275: 276: var fieldTitle = DESK.fieldList[i][0]; 277: 278: var link = ""; 279: link += fieldTitle; 280: 281: if (DESK.sortField == DESK.fieldList[i][2]) 282: if (DESK.sortOrder == "D") 283: link+=" >"; 284: else 285: link+=" <"; 286: 287: link+""; 288: 289: cell.innerHTML = link; 290: } 291: } 292: 293: for (var req=0; req294: { 295: var request = requests[req]; 296: var row = table.insertRow(table.getElementsByTagName("tr").length); 297: row.className="requestList"; 298: 299: for (var fc=0; fc300: { 301: var field = DESK.fieldList[fc]; 302: if (field[1] == 1) // display this field 303: { 304: var contents = ""; 305: var data = request.getElementsByTagName(field[2])[0]; 306: if (!data) // no field data of this form returned 307: { 308: contents=" -"; 309: } 310: else 311: { 312: contents = (data.textContent == undefined) ? data.firstChild.nodeValue : data.textContent; 313: if (field[2]=="status") 314: contents = DESK.requestStatus[contents]; 315: else if (field[2]=="requestid") 316: { 317: var id = contents; 318: contents = ""+contents+""; 319: // row.onclick = function(){ return DESK.displayRequest(id); }; // Always uses last - TODO fix it 320: } 321: } 322: 323: var cell = row.insertCell(-1); 324: cell.innerHTML = contents; 325: } 326: } 327: } 328: } 329: 330: // Set main pane sort 331: this.mainPaneSort = function(field) 332: { 333: if (DESK.sortField == field) 334: { 335: if (DESK.sortOrder == "D") 336: DESK.sortOrder = "A"; 337: else 338: DESK.sortOrder = "D"; 339: } 340: else 341: { 342: DESK.sortField = field; 343: DESK.sortOrder = "D"; 344: } 345: DESK.mainPane(DESK.lastTeam, DESK.lastUser); 346: } 347: 348: // Option Displays for Main Page 349: this.optionDisplay = function(opt) 350: { 351: if (opt == 1) 352: { 353: document.getElementById('option_select').style.display = "none"; 354: 355: var container = document.getElementById('option_dialog'); 356: 357: if (container.hasChildNodes()) 358: { 359: while(container.childNodes.length >= 1) 360: container.removeChild(container.firstChild); 361: } 362: 363: for (var i=0; i364: { 365: var displayed = false; 366: if (this.fieldList[i][1]==1) 367: displayed=true; 368: var a = ""; 369: if (displayed) 370: a += ""; 371: a += "372: if (displayed) 373: a+="0"; 374: else 375: a+="1"; 376: a+="); DESK.optionDisplay(1);\">"; 377: //container.innerHTML += a; 378: a += this.fieldList[i][0]; 379: a += ""; 380: if (displayed) 381: a += ""; 382: container.innerHTML += a; 383: container.innerHTML += "
";
384: } 385: 386: 387: container.innerHTML += "
Close and Apply";
388: 389: container.style.display = "block"; 390: } 391: else 392: { 393: document.getElementById('option_dialog').style.display = "none"; 394: document.getElementById('option_select').style.display = "block"; 395: } 396: } 397: 398: // Set a fieldDisplay property 399: this.setFieldDisplay = function(index, setting) 400: { 401: this.fieldList[index][1]=setting; 402: } 403: 404: // Display a Request 405: this.displayRequest = function(id) 406: { 407: var url = "request.php?id="+id+"&sid="+DESK.sid; 408: DESK.openWindow("FreeDESK Request", url); 409: } 410: 411: // Open a Window 412: this.openWindow = function(windowname, url, xsize, ysize, resizeable) 413: { 414: if (xsize == undefined) 415: var xsize = 700; 416: if (ysize == undefined) 417: var ysize = 500; 418: 419: if (resizeable == undefined) 420: var resizeable = 1; 421: else if(resizeable) 422: resizeable=1; 423: else if(!resizeable) 424: resizable=0; 425: 426: var windowopts = "location=0,status=0,scrollbars=1,toolbar=0,width="+xsize+",height="+ysize+",resizeable="+resizeable; 427: 428: window.open(url, windowname, windowopts); 429: } 430: 431: // Perform an entity search 432: this.entitySearch = function(entity, callback, fields) 433: { 434: var url = "entity.php?mode=search&entity="+entity; 435: 436: if (callback != undefined) 437: url += "&callback="+callback; 438: if (fields != undefined) 439: { 440: for (var i=0; i441: { 442: url += "&" + fields[i][0] + "=" + fields[i][1]; // escape? 443: } 444: } 445: url += "&sid=" + this.sid; 446: 447: this.openWindow("Search "+entity, url); 448: } 449: 450: // Open Edit Entity 451: this.editEntity = function(entity, keyfield, keyfieldValue) 452: { 453: var url = "entity.php?mode=edit&entity="+entity+"&keyfield="+keyfield+"&value="+keyfieldValue; 454: url += "&sid=" + this.sid; 455: 456: this.openWindow("Edit "+entity, url); 457: } 458: 459: // Perform an entity creation 460: this.entityCreate = function(entity, callback) 461: { 462: var url = "entity.php?mode=create&entity="+entity; 463: 464: if (callback != undefined) 465: url += "&callback="+callback; 466: 467: url += "&sid=" + this.sid; 468: 469: this.openWindow("Create "+entity, url); 470: } 471: 472: // Convert form to query string 473: this.formToQuery = function(formid) 474: { 475: var data = ""; 476: 477: function add(name, value) 478: { 479: if (value == undefined) 480: var value = ""; 481: 482: data += (data.length > 0 ? "&" : ""); // add & if required 483: 484: data += escape(name).replace(/\+/g, "%2B") + "="; 485: 486: data += escape(value).replace(/\+/g, "%2B"); 487: } 488: 489: var form = document.forms[formid]; 490: if (!form) 491: return ""; 492: var elements = form.elements; 493: 494: for (var i=0; i495: { 496: var element = elements[i]; 497: var type = element.type.toLowerCase(); 498: var name = element.name; 499: 500: if (name) 501: { 502: if ( type == "text" || type == "password" || 503: type == "button" || type == "reset" || 504: type == "file" || type == "submit" || 505: type == "image" || type == "hidden" || 506: type == "textarea" ) 507: add(name, element.value); 508: 509: else if ( type == "checkbox" && element.checked ) 510: add(name, element.value ? element.value : "On"); 511: 512: else if ( type == "radio" && element.checked) 513: add(name, element.value); 514: 515: else if ( type.indexOf("select") != -1 ) 516: { 517: for (var x=0; x518: { 519: var opt = element.options[x]; 520: if (opt.selected) 521: add(name, opt.value ? opt.value : opt.text); 522: } 523: } 524: } 525: } 526: 527: return data; 528: } 529: 530: // API Form Action e.g. save entity 531: this.formAPI = function(formid, closeOnComplete, reloadOnComplete, callbackOnComplete) 532: { 533: if (closeOnComplete == undefined) 534: var closeOnComplete = false; 535: if (reloadOnComplete == undefined) 536: var reloadOnComplete = false; 537: if (callbackOnComplete == undefined) 538: var callbackOnComplete = false; 539: 540: 541: var q = DESK.formToQuery(formid); 542: 543: q += "&sid=" + DESK.sid; 544: 545: var sr = new ServerRequest(); 546: sr.url = "api.php"; 547: sr.callback = DESK.formAPIcallback; 548: sr.additional = new Array(); 549: sr.additional[0] = closeOnComplete; 550: sr.additional[1] = reloadOnComplete; 551: sr.additional[2] = callbackOnComplete; 552: sr.Post(q); 553: } 554: 555: this.formAPIcallback = function(xml, additional) 556: { 557: if (DESK.isError(xml)) 558: { 559: Alerts.add(DESK.getError(xml), 2, 10); 560: } 561: else 562: { 563: // We got this far - no DESK error or XML error so we can say success! 564: Alerts.add("Operation Successful", 0); 565: 566: if (additional[0]) 567: window.close(); 568: else if (additional[1]) 569: window.location.reload(); 570: else if (additional[2]) 571: { 572: additional[2](xml); 573: } 574: } 575: } 576: 577: // Switch a pane 578: this.paneSwitch = function(pid, oid) 579: { 580: var pane = document.getElementById("pane_"+pid); 581: var header = document.getElementById("pane_"+pid+"_header"); 582: 583: var child = header.firstChild; 584: 585: var spans = header.getElementsByTagName("SPAN"); 586: 587: for (var i=0; i588: { 589: var arr = spans[i].id.split("_"); 590: var opt = arr[arr.length-1]; 591: 592: var contentid = "pane_"+pid+"_"+opt+"_content"; 593: 594: if (oid == opt) 595: spans[i].className = "pane_option_selected"; 596: else 597: spans[i].className = "pane_option"; 598: // Always hide the divs to avoid duplicate display 599: document.getElementById(contentid).className = "pane_content_hidden"; 600: } 601: 602: var contentid = "pane_"+pid+"_"+oid+"_content"; 603: document.getElementById(contentid).className = "pane_content"; 604: 605: } 606: 607: // Open new create request window 608: this.createRequest = function(reqclass) 609: { 610: if (reqclass == undefined) 611: var reqclass = ""; 612: 613: var url = "request.php?"; 614: if (reqclass != "") 615: url += "class="+reqclass+"&"; 616: url += "sid="+DESK.sid; 617: 618: DESK.openWindow("FreeDESK Request", url); 619: } 620: 621: // Debug data output 622: this.debugData = function(container, session) 623: { 624: var out = "Client-Side JavaScript Debug

";
625: if (session == DESK.sid) 626: out += "Session IDs match server and client side

";
627: else 628: out += "Session ID mis-match between client and server

";
629: 630: document.getElementById(container).innerHTML = out; 631: } 632: 633: // Relogin (use current SID and re-post login form) 634: this.relogin = function() 635: { 636: document.forms['login_sid_form'].elements['sid'].value = DESK.sid; 637: document.forms['login_sid_form'].submit(); 638: } 639: 640: // Start Auto-refreshing 641: this.startRefresh = function(interval) 642: { 643: if (interval == undefined) 644: var interval = 30; 645: interval = interval * 1000; 646: 647: DESK.refreshEvent = setInterval( 648: function(){ DESK.mainPaneRefresh(); }, 649: interval ); 650: } 651: 652: // Stop Auto-refreshing 653: this.stopRefresh = function() 654: { 655: clearInterval(DESK.refreshEvent); 656: } 657: 658: } 659: 660: var DESK = new FreeDESK(); 661: 662: