How to Hook Events

Many of the JavaScript objects created by the site raise events. If you are comfortable with writing JavaScript then you can inject scripts that hook these events and change how the site behaves to a greater degree than just changing the settings.

Scripts that hook events are less future-proof than scripts that just change settings. They rely on the behaviour of the objects that they hook, and the objects that they call, remaining the same between versions of Virtual Radar Server. They may need to be modified when a new version of Virtual Radar Server is released.

Events

All objects that raise events expose a number of functions whose name begins with hook and one function called unhook.

The hook functions always take two parameters:

  • A mandatory function that is called when the event is raised. Depending on the event being hooked the function may be passed parameters.
  • An optional object that will be set to this when the function is called.

The hook functions always return an object, which the code usually refers to as the hook result. The hook result identifies an instance of a hook.

The unhook function always takes a hook result from a previous hook call. It detaches your function from the event.

Global Events

There are a small number of events that are not associated with a JavaScript object. These are the global events. They are exposed by the VRS.globalDispatch object. They do not have named hook functions - instead there is a single hook method that takes three parameters:

  • A VRS.globalEvent value that indicates which global event you would like to hook.
  • A mandatory function that is called when the event is raised. Depending on the event being hooked the function may be passed parameters.
  • An optional object that will be set to this when the function is called.

The global events can be found in event.js. At the time of writing they are:

  • VRS.globalEvent.bootstrapCreated - called immediately after the page has loaded and the server configuration read, but before any further initialisation is performed. Passed the bootstrap object.
  • VRS.globalEvent.displayUpdated - called after an aircraft list update has been processed by all of the objects that listen to the aircraft list update event.
  • VRS.globalEvent.serverConfigChanged - called whenever the server configuration has changed. Gets passed the new server configuration.

The Bootstrap and PageSettings Objects

When an HTML page is loaded it creates a bootstrap object (not to be confused with the Bootstrap library - VRS does not use BootStrap) and calls the initialise method on it, passing in a pageSettings object that carries settings for the initialise method to work with. Each page has a different bootstrap object but all of them have a common base. The initialise method creates new objects and wires them together. When it creates new objects it typically adds them to the pageSettings object that it was passed, and for some key objects it raises events to indicate that the objects have been created.

You can use the bootstrapCreated global event to gain access to the bootstrap object and hook events on it. You can then use those events to hook events on objects that initialise creates.

Bootstrap event handlers are always passed two objects - the pageSettings object and the bootStrap object.

Event Map Page Report Page Description
hookMapInitialising Both Both Called before bootstrap starts doing any work. You can change the pageSettings options here to alter what gets shown to the user.
hookConfigStorageInitialised Both Both Called after VRS.configStorage has been initialised.
hookLocaleInitialised Both Both Called after the locale has been loaded from storage and the language files have finished loading.
hookCreatedSettingsMenu Both Both Called after the pageSettings.settingsMenu has been created. You can hook this to add your own menu items.
hookMapSettingsInitialised Both - Called after pageSettings.mapSettings has been created but before it is used to create the map. You can use this to modify the map settings before use.
hookMapLoaded Both - Called after the map has been loaded. pageSettings.mapJQ and pageSettings.mapPlugin are filled by this point.
hookReportCreated - Both Called after pageSettings.report has been created and criteria loaded from the query string.
hookAircraftDetailPanelInitialised Both - Called after the aircraft detail panel has been created.
hookAircraftListPanelInitialised Both - Called after the aircraft list has been created.
hookPageManagerInitialised Mobile Only Mobile Only Called after VRS.pageManager has been initialised with all of the mobile pages.
hookLayoutsInitialised Desktop Only Desktop Only Called after VRS.layoutManager has been initialised with all of the splitter panel layouts.
hookInitialised Both Both Called after everything has been initialised but before fetching the first aircraft list or fetching the report. The pageSettings will be fully formed at this point.

Example Scripts

Keep Map Centred on Initial Location

This script centres the map on the location configured by the server and stops the user from moving the map. If the initial location is changed on the server then the map is moved to the new location.

The script will only work with the /desktop.html and /mobile.html pages.

<script type="text/javascript">
    if(VRS && VRS.globalDispatch && VRS.serverConfig) {
        VRS.globalDispatch.hook(VRS.globalEvent.bootstrapCreated, function(bootStrap) {
            // This will be set to a reference to the map if a map has been loaded. If the
            // page is loaded without a map then this will always be undefined / null.
            var _Map;
            
            // This function gets the server configuration object and returns a lat/lng
            // object from it that holds the configured map centre.
            function getServerConfigMapCentre()
            {
                var serverConfig = VRS.serverConfig.get();
                return {
                    lat: serverConfig.InitialLatitude,
                    lng: serverConfig.InitialLongitude
                };
            }
            
            // This function sets the map and current location to the server map centre
            function moveToServerMapCentre()
            {
                var centre = getServerConfigMapCentre();
                if(_Map) _Map.panTo(centre);
                if(VRS.currentLocation) VRS.currentLocation.setCurrentLocation(centre);
            }
            
            // Configure the globalOptions to hide any elements that allow the user to move
            // the map. We also want to ignore the user's configured location.
            VRS.globalOptions.aircraftInfoWindowEnablePanning = false;
            VRS.globalOptions.currentLocationConfigurable = false;
            VRS.globalOptions.currentLocationUseGeoLocation = false;
            VRS.globalOptions.currentLocationUseBrowserLocation = false;
            VRS.globalOptions.detailPanelShowCentreOnAircraft = false;
            
            // Hook the bootstrap initialised event so that we can change the pageSettings.
            // We want to hide the menu options that let the user scroll the map.
            bootStrap.hookInitialised(function(pageSettings) {
                pageSettings.showGotoSelectedAircraft = false;
                pageSettings.showGotoCurrentLocation = false;
                pageSettings.showMovingMapSetting = false;
            });
            
            // Hook the map settings initialised event and set the map up so that it is not
            // draggable. We cannot set the centre here - the map will ignore us and use
            // the last saved state. We don't want to interfere with that so we'll move the
            // map after it's been opened.
            bootStrap.hookMapSettingsInitialised(function(pageSettings) {
                pageSettings.mapSettings.draggable = false;
            });
            
            // Hook the initialised event and keep a reference to the object that is
            // controlling the map. We need this for when we want to mess about with the
            // map after it's been opened.
            bootStrap.hookInitialised(function(pageSettings) {
                // Keep a record of the map - remember, if the user doesn't load the map
                // then this will be null/undefined.
                _Map = pageSettings.mapPlugin;
                moveToServerMapCentre();
            });
            
            // Hook the server configuration changed event so that we can move the user's
            // map when we change the coordinates on the server.
            VRS.globalDispatch.hook(VRS.globalEvent.serverConfigChanged, function() {
                moveToServerMapCentre();
            });
        });
    }
</script>