Name

global.AbstractTimelineSchedulePage

Description

Abstract timeline script include for all schedule pages. Each schedule page should reference a script include that extends from this base class. At a minimum, extending classes should override the getItems() method. Note that the script include will automatically receive all Uri parameters from the original Url whose prefix begins with sysparm_timeline_ . To access the values of these, use this.getParameter( sysparm_timeline_VARIABLE ); inside your implementing class. This is useful if you need to display a schedule page from a dynamic element, such as from a context menu from a list. By passing in dynamic data via the Url the schedule page will auto-include these parameters inside the Ajax calls and therefore will be accessible inside the AbstractSchedulePage script includes. Additionally note that the private methods inside this class are denoted with a double underscore prefix. This is done as the extending classes have capability to potentially overwrite core methods of this base class because of the prototype/rhino implementation. The following sections describe how data is processed by the GlideTimeline after receiving the AJAX response from the script include. // PHASE 1 RETURN CLIENT PROCESSING - RE-RENDERING The timeline will first check to see if any items need to be updated before doing anything else. There are three options for manipulating the timeline data. 1. Action No updating (Leave existing items on timeline). --> How?- No action required. Do not set any nodes and do not set the rerender true. 2. Action Update with specific items (e.g. These items may not be set in database ... a preview mode). --> How?- Append to the XML document TimelineItem schedule items as implemented in the getItems() method. 3. Action Re-render the timeline data (This will call the getItems()). --> How?- this.setDoReRenderTimeline(true) Note If both TimelineItems are returned and setDoReRenderTimeline is set to true, the system will ignore the DoReRenderTimeline and explicitly show only the TimelineItems returned in the XML response. // PHASE 2 RETURN CLIENT PROCESSING - DIALOG After potentially updating timeline items on the screen, a second phase can be used to perform additional functionality and message popups. The following options are available 1. Action Display nothing (No dialog) Note the loading will stop automatically . --> How?- Do nothing ... especially do not set any status setters below! 2. Action Display a SUCCESS dialog box. --> How?- this.setStatusSuccess(strTitle, strMessage); 3. Action Display an ERROR dialog box. --> How?- this.setStatusError(strTitle, strMessage); 4. Action Display a question with Yes / No buttons that can perform additional functionality. --> How?- this.setStatusPrompt(strDialogTitle, // Specifies the title for the dialog prompt strDialogMessage, // Specifies the message for the dialog this._yesScriptIncludeFunction , // Function to execute if the user clicks Yes this._noScriptIncludeFunction , // Function to execute if the user clicks No this._cancelScriptIncludeFunction // Function to execute if the user clicks X/Close );

Script

// Class Imports
var TimelineFrameSeparator = GlideTimelineFrameSeparator;

var AbstractTimelineSchedulePage = Class.create();
AbstractTimelineSchedulePage.prototype = Object.extendsObject(AbstractAjaxProcessor, {

ERROR_TITLE: gs.getMessage('Error'),
ERROR_INVALID_FUNC_MSG: gs.getMessage('You specified an invalid event: '),
ERROR_NO_FUNC_MSG: gs.getMessage('No script include function defined for the specified event: '),
AJAXRESPONSE: { NODE_PAGE_TITLE: 'pagetitle',
                NODE_STATUS: 'statusresult',
                NODE_ITEM: 'item',
                ATTR_RENDER: 'render',
                ATTR_STATUS: 'status',
                ATTR_MESSAGE: 'message',
                ATTR_TITLE: 'title',
                ATTR_OK_FUNC: 'ok_func',
                ATTR_CANCEL_FUNC: 'cancel_func',
                ATTR_CLOSE_FUNC: 'close_func',
                CUSTOM_FUNC: 'sysparm_custom_func',
                PROMPT: 'prompt',
                SUCCESS: 'success',
                ERROR: 'error' },

/**
 * Core function that obtains AJAX parameters and calls appropriate script include. This
 * method should NOT be overriden by any sub classes.
 */
process: function() {
  if (this.getName() == 'getItems') {
    return this.__getItems();
  } else if (this.getName() == 'elementMoveX') {
    return this.__elementMoveX();
  } else if (this.getName() == 'elementMoveY') {
    return this.__elementMoveY();
  } else if (this.getName() == 'elementMoveXY') {
    return this.__elementMoveXY();
  } else if (this.getName() == 'elementSuccessor') {
    return this.__elementSuccessor();
  } else if (this.getName() == 'elementTimeAdjustStart') {
    return this.__elementTimeAdjustStart();
  } else if (this.getName() == 'elementTimeAdjustEnd') {
    return this.__elementTimeAdjustEnd();
  } else if (this.getName() == 'inputBox') {
    return this.__inputBox();
  } else if (this.getName() == 'itemMove') {
    return this.__itemMove();
  } else {
    return this.setStatusError(this.ERROR_TITLE, this.ERROR_INVALID_FUNC_MSG + this.getName());
  }
},


////////////////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
////////////////////////////////////////////////////////////////////////////////////////////

add: function(node) {
  node.appendXML(this.getDocument(), this.getRootElement());
},

addSeparator: function() {
  var node = new TimelineFrameSeparator();
  node.appendXML(this.getDocument(), this.getRootElement());
},

setPageTitle: function(strTitle) {
  var e = this.__getNode(this.AJAXRESPONSE.NODE_PAGE_TITLE);
  if (strTitle != '') 
    e.setAttribute(this.AJAXRESPONSE.ATTR_TITLE, strTitle);
},

setDoReRenderTimeline: function(bool) {
  var e = this.__getNode(this.AJAXRESPONSE.NODE_STATUS);
  e.setAttribute(this.AJAXRESPONSE.ATTR_RENDER, bool);
},

setStatusError: function(strTitle, strMsg) {
  this.__setStatus(this.AJAXRESPONSE.ERROR, strTitle, strMsg);
},

setStatusSuccess: function(strTitle, strMsg) {
  this.__setStatus(this.AJAXRESPONSE.SUCCESS, strTitle, strMsg);
},

setStatusPrompt: function(strTitle, strMsg, strOkFunc, strCancelFunc, strCloseFunc) {
  this.__setStatus(this.AJAXRESPONSE.PROMPT, strTitle, strMsg, strOkFunc, strCancelFunc, strCloseFunc);
},


////////////////////////////////////////////////////////////////////////////////////////////
// PRIVATE
////////////////////////////////////////////////////////////////////////////////////////////

__setStatus: function(strType, strTitle, strMsg, strOkFunc, strCancelFunc, strCloseFunc) {
  var e = this.__getNode(this.AJAXRESPONSE.NODE_STATUS);
  e.setAttribute(this.AJAXRESPONSE.ATTR_STATUS, strType);
  if (strMsg != '')
    e.setAttribute(this.AJAXRESPONSE.ATTR_MESSAGE, strMsg);
  if (strTitle != '')
    e.setAttribute(this.AJAXRESPONSE.ATTR_TITLE, strTitle);
  if (strOkFunc != '')
    e.setAttribute(this.AJAXRESPONSE.ATTR_OK_FUNC, strOkFunc);
  if (strCancelFunc != '')
    e.setAttribute(this.AJAXRESPONSE.ATTR_CANCEL_FUNC, strCancelFunc);
  if (strCloseFunc != '')
    e.setAttribute(this.AJAXRESPONSE.ATTR_CLOSE_FUNC, strCloseFunc);
},

__getNode: function(node) {
  var nodes = this.getDocument().getElementsByTagName(node);
  if (nodes.getLength() > 0)
    return nodes.item(0);
  else {
    var e = this.getDocument().createElement(node);
    this.getRootElement().appendChild(e);
    return e;
  }
},
  
  __functionExistsString: function(f) {
  	return typeof this[f] == 'function';
  },

__functionExists: function(f) {
  return typeof f == 'function';
},
  														 
  __getFunctionName: function(f) {
  	var func = f.toString();
  	if (func.length() > 5 && func.substring(0, 5) == "this.")
  		return func.substring(5, f.length());
  	return func;
  },

__getItems: function() { 
  if (this.__functionExists(this.getItems)) {
    this.getItems();
    
    // Generate a hash code against the current XML document
    var transformer = Packages.javax.xml.transform.TransformerFactory.newInstance().newTransformer();
    var result = new Packages.javax.xml.transform.stream.StreamResult(new Packages.java.io.StringWriter());
    var source = new Packages.javax.xml.transform.dom.DOMSource(this.getDocument());
    transformer.transform(source, result);
    var hashCode = result.getWriter().toString().hashCode();
    this.getRootElement().setAttribute('sysparm_hashcode', hashCode);

    if (this.getParameter("sysparm_hashcode") == hashCode)
      this.getRootElement().setTextContent('');

    return;
  }
  
  this.setStatusError(this.ERROR_TITLE, this.ERROR_NO_FUNC_MSG  + this.getName());
},

__elementMoveX: function() {
  var f = this.getParameter(this.AJAXRESPONSE.CUSTOM_FUNC);
  if (f != null)
  	f = this.__getFunctionName(f);
  if (this.__functionExistsString(f))
    return this[f](this.getParameter('sysparm_span_id'), 
  				 this.getParameter('sysparm_new_start_date_time_ms'));
  else if (this.__functionExists(this.elementMoveX))
    return this.elementMoveX(this.getParameter('sysparm_span_id'),
                             this.getParameter('sysparm_new_start_date_time_ms'));

  this.setStatusError(this.ERROR_TITLE, this.ERROR_NO_FUNC_MSG + this.getName());
},

__elementMoveY: function() {
  var f = this.getParameter(this.AJAXRESPONSE.CUSTOM_FUNC);
  if (f != null)
  	f = this.__getFunctionName(f);
  if (this.__functionExistsString(f))
    return this[f](this.getParameter('sysparm_span_id'),
                             this.getParameter('sysparm_item_id'),
                             this.getParameter('sysparm_new_item_id'));
  else if (this.__functionExists(this.elementMoveY))
    return this.elementMoveY(this.getParameter('sysparm_span_id'),
                             this.getParameter('sysparm_item_id'),
                             this.getParameter('sysparm_new_item_id'));

  this.setStatusError(this.ERROR_TITLE, this.ERROR_NO_FUNC_MSG + this.getName());
},

__elementMoveXY: function() {
  var f = this.getParameter(this.AJAXRESPONSE.CUSTOM_FUNC);
  if (f != null)
  	f = this.__getFunctionName(f);
  if (this.__functionExistsString(f))
    return this[f](this.getParameter('sysparm_span_id'), 
  				 this.getParameter('sysparm_item_id'), 
  				 this.getParameter('sysparm_new_item_id'), 
  				 this.getParameter('sysparm_new_start_date_time_ms'));
  else if (this.__functionExists(this.elementMoveXY))
    return this.elementMoveXY(this.getParameter('sysparm_span_id'),
                              this.getParameter('sysparm_item_id'),
                              this.getParameter('sysparm_new_item_id'),
                              this.getParameter('sysparm_new_start_date_time_ms'));

  this.setStatusError(this.ERROR_TITLE, this.ERROR_NO_FUNC_MSG + this.getName());
},

__elementSuccessor: function() {
  var f = this.getParameter(this.AJAXRESPONSE.CUSTOM_FUNC);
  if (f != null)
  	f = this.__getFunctionName(f);
  if (this.__functionExistsString(f))
    return this[f](this.getParameter('sysparm_span_id'),
  				 this.getParameter('sysparm_new_succ_span_id'));
  else if (this.__functionExists(this.elementSuccessor))
    return this.elementSuccessor(this.getParameter('sysparm_span_id'),
                                 this.getParameter('sysparm_new_succ_span_id'));

  this.setStatusError(this.ERROR_TITLE, this.ERROR_NO_FUNC_MSG + this.getName());
},

__elementTimeAdjustStart: function() {
  var f = this.getParameter(this.AJAXRESPONSE.CUSTOM_FUNC);
  if (f != null)
  	f = this.__getFunctionName(f);
  if (this.__functionExistsString(f))
    return this[f](this.getParameter('sysparm_span_id'),
  				 this.getParameter('sysparm_new_start_date_time_ms'));
  else if (this.__functionExists(this.elementTimeAdjustStart))
    return this.elementTimeAdjustStart(this.getParameter('sysparm_span_id'),
                                       this.getParameter('sysparm_new_start_date_time_ms'));

  this.setStatusError(this.ERROR_TITLE, this.ERROR_NO_FUNC_MSG + this.getName());
},

__elementTimeAdjustEnd: function() {
  var f = this.getParameter(this.AJAXRESPONSE.CUSTOM_FUNC);
  if (f != null)
  	f = this.__getFunctionName(f);
  if (this.__functionExistsString(f))
    return this[f](this.getParameter('sysparm_span_id'),
                    this.getParameter('sysparm_new_end_date_time_ms'));
  else if (this.__functionExists(this.elementTimeAdjustEnd))
    return this.elementTimeAdjustEnd(this.getParameter('sysparm_span_id'),
                                     this.getParameter('sysparm_new_end_date_time_ms'));

  this.setStatusError(this.ERROR_TITLE, this.ERROR_NO_FUNC_MSG + this.getName());
},

__inputBox: function() {
  var f = this.getParameter(this.AJAXRESPONSE.CUSTOM_FUNC);
  if (f != null)
  	f = this.__getFunctionName(f);
  if (this.__functionExistsString(f))
    return this[f](this.getParameter('sysparm_input_text'));
  else if (this.__functionExists(this.inputBox))
    return this.inputBox(this.getParameter('sysparm_input_text'));

  this.setStatusError(this.ERROR_TITLE, this.ERROR_NO_FUNC_MSG + this.getName());
},

__itemMove: function() {
  var f = this.getParameter(this.AJAXRESPONSE.CUSTOM_FUNC);
  if (f != null)
  	f = this.__getFunctionName(f);
  if (this.__functionExistsString(f))
    return this[f](this.getParameter('sysparm_item_sys_id'), this.getParameter('sysparm_new_item_sys_id'));
  else if (this.__functionExists(this.itemMove))
    return this.itemMove(this.getParameter('sysparm_item_sys_id'), this.getParameter('sysparm_new_item_sys_id'));

  this.setStatusError(this.ERROR_TITLE, this.ERROR_NO_FUNC_MSG + this.getName());
}

});

Sys ID

4b8f322f0a0a0b3d6c47d20c1b9bbfdb

Offical Documentation

Official Docs: