XWiki JavaScript API

Version 31.1 by Marius Dumitru Florea on 2015/07/16
Warning: For security reasons, the document is displayed in restricted mode as it is not the current version. There may be differences and errors due to this.

Observable XWiki Events

Stay in touch with what happens in the wiki! XWiki will fire custom javascript events on certain moment and upon certain actions that occur in the navigation flow.

Event names are build on the following model: xwiki:modulename:eventname. Your JavaScript script or extension can get notified of such an event the following way:

document.observe("xwiki:modulename:eventname", function(event) {
 // Here, do something that will be executed at the moment the event is fired
 doSomething();

 // The event can have an option memo object to pass to its observers some information:
 console.log(event.memo.somethingINeedToKnow);
});

Check out the real examples below or read more about Prototype.js's event system.

DOM Events (xwiki.js)

  • xwiki:dom:loaded
    This event is similar to prototype's dom:loaded event, with the difference that in the time-lapse between dom:loaded and xwiki:dom:loaded, XWiki may have transformed the DOM. Example of DOM transformations operated by XWiki is setting the right target of links that have rel="external" attribute so that the document can be XHTML valid and still have the desired effect, making internal rendering error messages expandable, insert document template handlers for links to non-existent documents, and so on. In the future there might be more transformations operated by XWiki upon DOM initialization. This event is meant for code to be notified of loading of the XWiki-transformed version of the initial DOM. As dom:loaded, it can be used as follows:
    document.observe("xwiki:dom:loaded", function(){
     // Initialization that can rely on the fact the DOM is XWiki-tranformed goes here.
    });

    It is recommended to bind startup scripts to this event instead of window.load or document.dom:loaded.

  • xwiki:dom:loading
    xwiki:dom:loading is sent between dom:loaded and xwiki:dom:loaded, before XWiki changes the DOM. This is the event that should start all scripts making important DOM changes that other scripts should see.
  • xwiki:dom:updated
    This event is sent whenever an important change in the DOM occurs, such as loading new content in a dialog box or tab, or refreshing the document content. Scripts that add behavior to certain elements, or which enhance the DOM, should listen to this event as well and re-apply their initialization process on the updated content, the same way that the whole DOM is enhanced on xwiki:dom:loaded. The list of new or updated elements is sent in the event.memo.elements property. For example:
    var init = function(elements) {
     // Search for special content to enhance in each DOM element in the "elements" list and enhance it
     elements.each(function(element) {
        element.select('.someBehavioralClass').each(function(item) {
          enhance(item);
        });
      });
    }
    ['xwiki:dom:loaded', 'xwiki:dom:updated'].each(function(eventName) {
     document.observe(eventName, function(event) {
        init(event.memo && event.memo.elements || [document.documentElement]);
      });
    });

    If your script is loaded deferred, all these events may be triggered before your script is executed and therefore before it has the ablity to observe these events. Since 3.1.1, to prevent your handler to never being called, never use dom:loaded anymore, and check XWiki.isInitialized before waiting for xwiki:dom:loading, and XWiki.domIsLoaded before waiting for xwiki:dom:loaded. If the flag is true, you should proceed immediately with your handler. Here is a simple construct to properly handle this:

    function init() {
     // This is your initialization handler, that you generally hook to xwiki:dom:loaded
    }
    (XWiki && XWiki.domIsLoaded && init()) || document.observe("xwiki:dom:loaded", init);

    Document content events (actionButtons.js)

    • xwiki:document:saved
      This event is sent after the document has been successfully saved in an asynchronous request (i.e. after clicking the Save and Continue button).
    • xwiki:document:saveFailed
      This event is sent when a save and continue attempt failed for some reason. The XMLHttpRequest response object is sent in the memo, as event.memo.response.

    Action events (actionButtons.js)

    • xwiki:actions:cancel
      This event is sent after the user clicks the "Cancel" button of an editor (Wiki, WYSIWYG, object, rights, etc.), but before actually cancelling the edit.
    • xwiki:actions:preview
      This event is sent after the user clicks the "Preview" button of an editor (Wiki, WYSIWYG, object, rights, etc.), but before actually leaving the edit mode.
    • xwiki:actions:save
      This event is sent after the user clicks the "Save" or "Save & Continue" button of an editor (Wiki, WYSIWYG, object, rights, etc.), but before actually submitting the form. A memo is available if you need to know if the intend is to continue after the save, in event.memo['continue']. You can use it as follows:
      document.observe("xwiki:actions:save", function(event){
       var doContinue = event.memo['continue'];
       if (doContinue) {
         // do something specific
       }
      });

      While most properties can be accessed as event.memo.property, this doesn't work with event.memo.continue since continue is a reserved keyword.

      All these events contain as extra information, in the second parameter sent to event listeners (the memo), the original click event (if any, and which can be stopped to prevent the action from completing), and the form being submitted, as event.memo.originalEvent, and event.memo.form respectively.

    Document extra events (xwiki.js)

    • xwiki:docextra:loaded
      This event is fired upon reception of the content of a document footer tab by AJAX. This event is useful if you need to operate transformations of the received content. You can filter on which tab content to operate (comments or attachment or information or ...) using the event memo. The DOM element in which the retrieved content has been injected is also passed to facilitate transformations.
      document.observe("xwiki:docextra:loaded", function(event){
        var tabID = event.memo.id;
        if (tabID == "attachments") {
          // do something with the attachments tab retrieved content.
          doSomething(event.memo.element);
         }
      });
    • xwiki:docextra:activated
      This event is fired upon activation of a tab. It differs from the loaded event since tabs are loaded only once if the user clicks going back and forth between tabs. This event will notify of each tab activation, just after the tab content is actually made visible. The tab ID is passed in the memo as for xwiki:docextra:loaded

    WYSIWYG events (XWikiWysiwyg.js)

    WYSIWYG has it's own custom events list.

    Suggest events (ajaxSuggest.js)

    • xwiki:suggest:selected (since 2.3)
      This event is fired on the target input when a value was selected.

    Fullscreen events (fullScreenEdit.js)

    • xwiki:fullscreen:enter (since 3.0 M3) (fired before entering full screen editing)
    • xwiki:fullscreen:entered (since 2.5.1) (fired after entering full screen editing)
    • xwiki:fullscreen:exit (since 3.0 M3) (fired before exiting full screen editing)
    • xwiki:fullscreen:exited (since 2.5.1) (fired after exiting full screen editing)
    • xwiki:fullscreen:resized (since 2.5.1)

    All events have the target DOM element in event.memo.target.

    Annotations events (AnnotationCode/Settings jsx)

    • xwiki:annotations:filter:changed
    • xwiki:annotations:settings:loaded

    Livetable events (livetable.js)

    • xwiki:livetable:newrow (event.memo.row holds the new row)
    • xwiki:livetable:loadingEntries (since 2.3 RC1)
    • xwiki:livetable:receivedEntries (since 2.3 RC1) (event.memo.data contains the received JSON data)
    • xwiki:livetable:loadingComplete (since 2.4 M1) (event.memo.status contains the response status code)
    • xwiki:livetable:displayComplete (since 2.4 M1)
    • xwiki:livetable:ready (since 2.4.4)
    • xwiki:livetable:loading (since 3.1.1) (should be used in place of xwiki:dom:loading to startup livetables)

    The livetable sends both generic events, named as above, and events specific to each livetable, containing the table name on the third position, such as xwiki:livetable:alldocs:loadingEntries. The generic event has the table name in the memo, as event.memo.tableId.

    RequireJS and jQuery APIs

    By default XWiki uses PrototypeJS which is bound to the $ symbol. Starting in XWiki 5.2, you may use jQuery by requiring it using the RequireJS AMD standard. To do this you would write your code as follows:

    require(['jquery'], function ($) {
        $('#xwikicontent').append('<p>Inside of this function, $ becomes jquery!</p>');
    });

    The best part is, any scripts which are loaded using require are loaded asynchronously (all at the same time) and if they are not required, they are never loaded at all.

    Bridging custom XWiki events between Prototype and jQuery

    Starting with XWiki 6.4 you can catch from jQuery the custom XWiki events that are fired from Prototype.

    require(['jquery', 'xwiki-events-bridge'], function($) {
      $('.some-element').on('xwiki:moduleName:eventName', function(event, data) {
       // Here, do something that will be executed at the moment the event is fired.
       doSomething();

       // The passed data is a reference to the event.memo from Prototype.
       console.log(data.somethingINeedToKnow);
      });
    });

    Starting with XWiki 7.1M1 the event listeners registered from Prototype are notified when a custom XWiki event is fired using the jQuery API. This doesn't mean you should write new event listeners using Prototype but that you can rely on existing event listeners until they are rewritten using jQuery.

    // Prototype (old code that you don't have time to rewrite)
    document.observe('xwiki:dom:updated', function(event) {
      event.memo.elements.each(function(element) {
       // Do something.
     });
    });
    ...
    // jQuery (new code, in a different file/page)
    require(['jquery', 'xwiki-events-bridge'], function($) {
      $(document).trigger('xwiki:dom:updated', {'elements': $('.some-container').toArray()});
    });

    Get some information about the current document (Since 6.3M2)

    In your javascript's applications, you can get (meta) information about the current document, though an AMS module.

    require(['xwiki-meta'], function (xm) {
      xm.document    // get the current document (eg: Main.WebHome)
     xm.wiki        // get the current wiki (eg: xwiki)
     xm.space       // get the current space (eg: Main)
     xm.page        // get the current page name (eg: WebHome)
     xm.version     // get the current document version (eg: 1.1)
     xm.restURL     // get the REST url of the current doc (eg: /xwiki/rest/wikis/xwiki/spaces/Main/pages/WebHome)
     xm.form_token  // get the current CSRF token that you should pass to your scripts to avoid CSRF attacks.
    });

    It is actually the only clean way. In the past, we used to add some <meta> tags in the <head> section of the page, but is not even valid in HTML5. So now we have introduced this API that we will maintain, meanwhile relying on any other element in the page could be broken in the future!

    Be retro-compatible with versions older than 6.3

    If you want to be compatible with older version, you can use this trick:

    require(['xwiki-meta'], function (xm) {
     // Note that the require['xwiki-meta'] (meta information about the current document) is not available on  
     // XWiki versions < 6.3, then we get these meta information directly from the DOM.
     var document   = xm ? xm.document   : $('meta[name="document"]').attr('content');
     var wiki       = xm ? xm.wiki       : $('meta[name="wiki"]').attr('content');
     var space      = xm ? xm.space      : $('meta[name="space"]').attr('content');
     var page       = xm ? xm.wiki       : $('meta[name="page"]').attr('content');
     var version    = xm ? xm.version    : $('meta[name="version"]').attr('content');
     var restURL    = xm ? xm.restURL    : $('meta[name="restURL"]').attr('content');
     var form_token = xm ? xm.form_token : $('meta[name="form_token"]').attr('content');
    });

    Work with Entity References

    Starting with XWiki 4.2M1 you can resolve and serialize Entity References on the client side easily:

    var documentReference = XWiki.Model.resolve('wiki:Space.Page', XWiki.EntityType.DOCUMENT);
    var attachmentReference = new XWiki.AttachmentReference('logo.png', documentReference);
    XWiki.Model.serialize(attachmentReference);

    You can check the full API here.

    Starting with XWiki 7.2M1 the Unknown macro: XWiki.Model. Click on this message for details.

Tags:
   

Get Connected