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: