Titan CMS v7 - JavaScript Overview

Author:JonK
Last Updated:April 23, 2024 11:31 AM

 

JavaScript Namespace Guide

Titan CMS v7 introduced an overhauled JavaScript implementation using a module-based approach that allows segmentation of code into "namespaces". This pattern is regularly used in connection with front-end code, and has brought order to the Workstation framework.

The primary modules for the Display and Workstation are located in their respective "scripts" directory. The intent of the architecture is that each screen or page only load the scripts required for that interface.

In the Workstation, required scripts are referenced and loaded from the Master Layout View.  All other scripts are loaded adhoc via a Module Registration API developed for the Workstation.

In the Display, required scripts are bundled via server-side code into fake files named "titanscripts.js" and "titanscripts.required.js".  In addition, a page-specific script is generated based on the blocks defined for that page. This script file is named after the Page URL of the current page with a suffix of "_content.js".  (i.e "About.htm" would have a dynamically generated "About_htm_content.js")

In the sections that follow are descriptions of the JavaScript namespaces and examples of the functionality they provide. Each namespace typically represents a physical .js file with the same name (except where otherwise noted). Please note that this code is actively being developed and is subject to change. 

 

NWS

This is the core JavaScript object for our code. This object has one high-level purpose - registering JavaScript objects and functions into our NWS namespace.

This file defines a single function:

  • initNamespace(namespace, initFunction) - Initialize and return a "namespaced" JavaScript object or function.
    • namespace - (string, req) The namespace of the object or function
    • initFunction - (Function, req) The function that initializes the namespace

Note:

Don't modify this code. I have been down the path of extending it, just to later refactor the changes into more appropriate files and namespaces. I'm not suggesting it shouldn't change... just that it probably doesn't need to.

 

NWS.Ajax

This namespace provides functions and objects that facilitate asynchronous Http calls and related callbacks. 

Functions

  • Get(url, responseType, callback) - A function to call a service method using HttpGet. Async callback functions defined by callback
  • Post(url, jsonObj, responseType, callback)  - A function to call a service method using HttpPost. Data to send passed in jsonObj. Async callback functions defined by callback.
  • PostSync(url, jsonObj) - A function call to a service method using HttpPost. Waits for response and returns result.
  • QueuedCallback(name, onLoad, canSkip = true) - A facade function that returns a Callback object that uses callback queuing

Objects

  • Callback(onLoad, onLoadEnd = null, onLoadError = null, name = null, canSkip = true)- An object constructor that defines a callback after an Ajax call.  This object encapsulates the callback related functions Load, LoadEnd, and LoadError.
    • onLoad - (Function, req) Function reference to be called during the load event of the XMLHttpRequest; typically used to process the result and perform any HTML updates to the DOM
    • onLoadEnd - (Function, optional) Optional function reference to be called during the loadend event of the XMLHttpRequest; typically used to perform any post-DOM update steps. This should occur after the other framework code has executed as a result of DOM mutations
    • onLoadError - (Function, optional) Optional function reference to be called during the error event of the XMLHttpRequest
    • name - (string, optional) An optional name to identify this callback in the queue. Used to synchronize the handling of multiple ajax calls with a common callback.
    • canSkip - (boolean, optional)  An optional boolean to indicate if the callback can be skipped/replaced (default is true).
NWS.Ajax.UrlToken

This namespace provides encoding/decoding support. Used for safely submitting XML data.

  • Encode(str) - A function to encode a string value as a base64 token
  • Decode(token) - A function that decodes a base64 token and returns a string
NWS.Ajax.Form

This namespace provides a trivial form submission support

  • PostToNewWindow(action, target, enctype = "text/plain", args = {}) - A function that creates and submits a form element that will POST to a new window.  
NWS.Ajax.CommonCallbacks

This namespace provides common reusable callback functions.

  • DownloadFile(ajaxRequest) - A function to process a Blob response as a downloaded file.

 

NWS.BlockEditors

This namespace contains the objects and functions that support Block Editors in the Workstation. This code isn't ever directly called from Block Editor javascript. It is framework code that knows how to call into Block Editor js for performing workstation operations. 

 

NWS.Bundling

Note: This object is defined in NWS.Util.js

This namespace contains the objects and functions that provide resource bundling and loading. Typically used for JS and CSS resource bundling. 

  • NWS.Bundling.Bundle(fileExtension, config)
    • AddResource(resource)
    • GetBundleUrl
    • GetBundleCallbacks
    • GetCallbackUrls
    • Load(contentLoadedCallback, parentSelector)
  • NWS.Bundling.Callback(onSuccess, onError, onComplete)
    • ListenTo(element)
  • NWS.Bundling.ExtConfig(tagName, urlAttributeName, attributes, extensions)
  • NWS.Bundling.Resource(url[, callback])
    • GetExtension
    • IsAbsolute
    • Exists([config])
    • Load([config[, parentSelector]])

 

NWS.CmsControls

This namespace contains the objects and functions that support all CmsControls (previously referred to as "CmsForms Controls"). This includes the objects that encapsulate the UI logic for a specific control, which are contained in standalone JS files, but registered within this namespace. 

The core objects are Control and ConrolCollection. These provide the integration points for the Workstation. Their methods typically aren't called, except by the Workstation framework. 

  • NWS.CmsControls.Control - an object derived from the standard HTML output for a CmsControl. 
    • A new Control object is constructed from a DIV element that contains the following data- attributes:
      • data-control-id (required) - the ID of an HTML input in the body of the DIV being processed. If none exists, the integration points are not established
      • data-field-binding-info (required) - a JSON object containing field binding configuration to establish integration with the Workstation. 
      • data-messages (optional) - a JSON object containing error messages for configured constraints. Provides localization support for error messages.
    • A Control has the following methods:
      • Validate()
      • HasChanged()
      • ErrorMessage()
      • ChangedMessage()
      • DefaultValue()
      • Value()
  • NWS.CmsControls.ControlCollection - an object representing a list of Control objects.
    • A new ControlCollection is constructed from a name and optional DOM selector.
      • name - the name of the collection. The name is used to define the root Xml element for packaging the data.
      • selector- a DOM selector that identifies all the fields to initialize in the collection. If not provided, an empty collection is created.
    • A ControlCollection has the following methods:
      • InitControl(name, selector)
        • name is the name of a control in the collection. If not in the collection it is added. If already in the collection it is reinitialized and updated
        • selector is a DOM selector that will locate the DOM Element that has the configuration info for the Control.
      • ValidateAll()
      • ValidateOne(name)
        • name is the name of a Control in the collection
      • HasChanged()
      • IsValid()
      • GetChanges([format])
        • format is optional, allowed values are "json" and "xml". The default is "xml".
      • PackageData([format])
        • format is optional, allowed values are "json" and "xml". The default is "xml".

 

NWS.DragAndDrop

This namespace contains the objects and functions that provide support for drag and drop reordering of elements. 

  • NWS.DragAndDrop.DragArea
    • A new DragArea is constructed for draggable elements in a DOM element with:
      • baseNode - the root DOM Element that contains draggable elements to handle
      • multiDragSelector - optional. A DOM selector for identifying the selected items if dragging multiple elements
      • insertFunction - optional. The function that determines insertion point. Accepts "vertical" or "horizontal". Default value is "vertical"
      • dragFunctions - optional. The DragFunctions object that defines the extensibility points for drag events
    • Dispose() - Removes the drag listeners and handlers
  • NWS.DragAndDrop.DragFunctions
    • dropTargetLocator - event handling function that returns the current drop target for the handling of dragover
    • beforeStart - optional. Event handling function to call before primary handling of dragstart
    • beforeOver - optional. Event handling function to call before primary handling of dragover
    • beforeReset - optional. Parameterless function to call during dragend and drop

 

NWS.Fields

This object is responsible for interacting with the value and state of an input. Primarily, this object provides access to the current and default values of an input, regardless of type. It simplifies the API by doing the type checking (i.e. checkbox, radio, dropdown, text, textarea, etc.) and reading the values accordingly. 

There is currently code in this object intended for validation of complex, multi-field inputs (e.g. Geographic Coordinate, Recurring Date, etc). This may change to continue leveraging the native JavaScript Validation API.

  • NWS.Fields.State
    • IsDisabled(id, container)
    • IsHidden(id, container)
    • HasChanged(id, container)
    • GetValue(id, container = null, keepNull = false)
    • GetDefaultValue(id, container)
    • SetValue(id, value, doOnChange, container)
    • Reset(id, container = null, doEvents = true)
  • NWS.Fields.Validate - A collection of validation functions that, given an ID (and an optional container element) indicate the validity of a field's content.
    • IsXml(id, container) - Returns a boolean indicating if the field content was successfully parsed as XML
    • IsHtml(id, container) - Returns a boolean indicating if the field content was successfully parsed as Html
    • MatchesRegEx(id, regEx, container) - Returns a boolean indicating if the field content matches the provided regular expression
    • Exists(id, container) - Returns a boolean indicating if a DOM element with that ID exists in that container
    • IsEnabled(id, container) - Returns a boolean indicating if a DOM element with that ID exists in that container and is not disabled
    • IsNumeric(id, container) - Returns a boolean indicating if the value of the field is a finite number that can be parsed as a float
    • HasValue(id, container) - Returns a boolean indicating if the field has a value.

 

NWS.Logging

Note: This object is defined in NWS.Util.js

This namespace provides support for console logging during debugging. To enable the output, declare in the global space a boolean variable named JSDEBUG that evaluates to true.

  • Log(msg)
  • Warn(msg)

 

NWS.Modules

Note: This object is defined in NWS.Util.js

This namespace contains functions to support js module loading and execution. 

  • ExecuteFunctionByName(funcName, context, args)
    • funcName - The namespaced function name
    • context - The object that provides the "this" context
    • args - The array of arguments to pass to the function
  • LoadResources(resourcePaths[, initList]) - Loads individual resource files
    • resourcePaths - An array containing the relative or fully-qualified resource files to load
    • initList - An optional array containing a list of functions and parameters to call after loading the last file
  • Parse(name, context, type) - Locates and returns a namespaced object or function by the string representation of its name
    • name - The namespaced object or function name
    • context - The object context to begin the search for the object or function. window by default.
    • type - The object type to validate the entity being returned - "function" or "object" 

 

NWS.Util

This namespace provides general-use utility functions.

Among the utility function are several facade functions representing the most commonly used DOM manipulation functions. 

NWS.Util Native JS Equivalent
Get(id) document.getElementById(id)
GetSet(name) document.getElementsByName(name)
GetClosest(element, selector) while loop through element.parentNode looking for selector match (since IE11 doesn't support native .closest)
QueryGet(selector[, target]) (target || document).querySelector(selector)
QueryGetAll(selector[, target]) (target || document).querySelectorAll(selector); returns an actual array safe for use with .forEach, .map, .reduce, .filter
Remove(element) element.parentNode.removeChild(element)
ReplaceHtml(element, newHtml) element.innerHTML = newHtml; but done in a way more efficient for the DOM parser
Event.Cancel(evt, doPrevent) handles logic for evt.stopPropagation() and evt.preventDefault()

 

Functions

  • Get(id) - Get an HTMLElement by ID
  • GetBaseID(id) - Parse the ID string to the last underscore
  • GetBaseNodeForCtl(element) - Get the closest HTML element that contains the CSS class "Field"
  • GetBaseNodeForID(id) - Get the closest HTML element that contains the CSS class "Field"
  • GetClosest(element, selector) - Get the closest element with a matching selector
  • GetSet(name)- Get an array of HTML elements having the provided name
  • QueryGet(selector, target) - Get the first HTML element descendant that matches the provided selector
  • QueryGetAll(selector, target) - Get an array of HTML element descendants that matches the provided selector
  • Remove(element) - Remove an HTML element from its parent element
  • ReplaceHtml(element, newHtml) - Replace the inner HTML of an element with the provided HTML
  • ScrollTo(element, options) - Scroll an element's ancestor containers to bring the element into view.

Objects

  • Notifier(eventName) - An object constructor that defines a simple object that manages a named collection of callback subscriptions.
    • Subscribe(who, callback, callbackArgs = [], once = false) - Adds a callback entry to be executed during Notify.
      • who - (string, req) The name used to identify this subscription. Multiple callbacks with the same name are not allowed.
      • callback - (function, req) A function object to be executed during Notify
      • callbackArgs - (object[], optional) An array of arguments to be passed to the callback function
      • once - (boolean, optional, default is false) A boolean indicating if the callback occurs once and is immediately removed. If false, the callback will be perpetually until Unsubscribed or 
    • Unsubscribe(who) - Removes a named callback entry from the notification list
      • who - (string, req) The name used to identify this subscription
    • Notify(target) - Executes subscribed callbacks
      • target - A DOM element target pertinent to the notification. Added as the last argument to the callbaback function. 
NWS.Util.Date

This namespace contains date-based utility functions

  • Now() - returns a string representation of the current date and time (client-side) in US English locale - mm/dd/yyyy hh:mm:ss AM/PM

 

NWS.Util.Event

This namespace contains common event handling functions.

  • Cancel(evt, doPrevent)
  • CancelInline(func, doPrevent)
  • Debounce(delay, func)
  • DoMouseEvent(ctl, eventType)
  • DoEvent(ctl, eventType)
  • DoHandlerForKeypress(evt, key, handler)

 

NWS.Util.KeyValue

This namespace contains static string values that map directly to KeyboardEvent.key values we handle.

  • Enter
  • Tab
  • Meta
  • ArrowDown
  • ArrowLeft
  • ArrowRight
  • ArrowUp
  • Delete
  • ContextMenu
  • Escape
  • Insert
  • "" (space)

 

NWS.Util.Print
  • PrintPage(printPageString)
  • Email(subjectLine)
  • LogParams()
  • FormatParams()

 

NWS.Util.UI
  • DefaultButton(evt, btn)
  • SearchSubmit(baseURL, searchCtl)
  • GoBack(evt)
  • FreeformPreviewTidy(data)
  • FollowPreviewLink(link, evt)

 

NWS.Wkst

This object encapsulates all Workstation-specific JS modules. This object has one high-level purpose - allow integration of JS code in response to DOM mutations. This is accomplished through a MutationObserver.

NWS.Wkst.ContentObserver

This child object provides the integration point for other JS code to be called after DOM mutations occur. 

  • NWS.Wkst.ContentObserver
    • OnContentMutation(who, callback[, callbackArgs])
      • who - required. A string intended for uniquely identifying the mutation callback.
      • callback - required. The mutation observer callback function. This function will be called on each DOM change and takes at least one parameter: the array of MutationRecord objects. Additional arguments should preceed the mutations array in your function signature as we append the mutations array as the last parameter.
      • callbackArgs - optional. An array of arguments to pass to the callback function in addition to the mutations array
    • Init() - creates an observer and starts 
    • Start() - activates the observation of the body tag for mutations
    • Stop() - deactivates the mutation observer 

We use OnContentMutation during Workstation initialization to activate the automatic Module Registration capabilities for adhoc loading of JS modules required to operate the Workstation. that watches for changes to the DOM that include specific data- attributes that define new JS Modules to load.

When HTML is injected into the DOM under the element ID "WkstContent", the MutationObserver event fires. Any HTML elements included in that mutation event can trigger the loading of a JS Module by including the following data- attributes:

  • data-js-module - (required) the file path to a JavaScript file. 
  • data-js-init-func -  (optional) namespace-qualified function name to call when the script file has loaded, or if the file is already loaded
  • data-js-init-args - (optional) a string that represents a JS Array of arguments to pass to the initialization function

 

NWS.Wkst.ActionButtons

This is the object responsible for all of the top-level actions performed by workstation buttons (e.g. Create, Publish, Save, Delete, etc). Once initialized, no other methods need to be called. The object utilizes a MutationObserver to automatically register button logic to the appropriate private functions when a DOM mutation includes a button element with the following data- attributes:

  • data-action - (required) the named Action for the button. These name values are mapped directly to private functions with the same name.
  • data-action-args - (optional) a string that represents a JS Array of arguments to pass to the action function
  • data-observe-tree  - (optional) a boolean attribute, the existance of which indicates this button is enabled if a tree selection has been made

Additionally, buttons can indicate they are disabled when mutliple selections have been made, by including the css class name "noMulti".

 

NWS.Wkst.Dialog

This namespace contains the objects and functions that support loading dialogs in the Workstation.

  • Open(name, url, args)
    • name - a string to name the dialog. Used primarily with data packaging to define the property name for the content
    • url - the relative url to a controller action that returns a dialog's contents
    • args - arguments object required for the controller action call
  • Submit(url, args, dataFormat, onComplete)
    • url - the relative url to the controller action that handles the submission of the content
    • args - arguments object required for the controller action call. if null, the CmsControls that make up the dialog will be automatically packaged and sent
    • dataFormat - either "json" or "xml". controls the format of the CmsControls packaging
    • onComplete - a callback function to execute after the submission
  • Loading(doShow) - A command to display a Loading image 
    • doShow - Boolean indicating whether to show the loading image or hide it.
  • Close() - forces the top-most dialog to be hidden and the supporting html to be removed
  • GetEditor() - returns a reference to the top-most dialog DOM node
  • GetControl(name) - returns the ControlCollection established for the named dialog
    • name - the name given the dialog on Open. Also the name for the ControlCollection created for the dialog.
  • HasChanged() - returns a Boolean indicating if the top-most dialog has changes
  • IsValid() - returns a Boolean indicaitng if the top-most dialog is valid

 

NWS.Wkst.Icons

An object implementing our Icon Library. Handles the loading of the SVG sprite that includes all of the icons used in the Workstation. Provides helpful utilities for generating html for an icon. 

 

NWS.Wkst.NavTree

An object that handles all the interactions of the Workstation tree.

 

NWS.Wkst.Resizers

An object that handles all the interaction with the resizable areas of the Workstation, including the Nav Tree and columns in a Results view.

 

NWS.Wkst.Tabs

The object that handles all the interaction with the Tabs - Results, Properties, Tags, etc.

 

NWS.Wkst.Tabs.Content

The object that handles interactions with the Content tab

 

NWS.Wkst.Tabs.DisplaySecurity

The object that handles interactions with the Security tab

 

NWS.Wkst.Tabs.Properties

The object that handles interactions with the Properties tab

 

NWS.Wkst.Tabs.Results

The object that handles interactions with the Results tab, including the drag and drop behavior for the Dashboard widgets

 

NWS.Xml

The helper object that provides Xml parsing and formatting functions.

  • MakeTag(tagName, data, attributes, doCData)
    • tagName - string that is the name of the XML element
    • data - the string content of the element
    • attributes - an array of strings representing names/values of attributes on the xml element
    • doCData - a boolean indicating whether to encapsulate data in CData
  • MakeStartTag(tagName, attributes, doCData)
    • tagName - string that is the name of the XML element to start
    • attributes - an array of strings representing names/values of attributes on the xml element
    • doCData - a boolean indicating whether to write starting CData marker
  • MakeEndTag(tagName, doCData)
    • tagName - string that is the name of the XML element being ended
    • doCData - a boolean indicating whether to write closing CData marker
  • MakeAttribute(name, value)
    • name - the attribute name
    • value - the attribute value
  • Parse(xmlString)
    • xmlString - a string to be parsed by DOMParser
  • ToString(xml)
    • xml - an xml document to serialize to a string using XMLSerializer

 

top