Let the platform do the work

Shortcuts

Overview

Shortcuts is a framework to add shortcut keys to the application. When shortcut keys are registered, they are registered to a particular shortcut session. Shortcut sessions group shortcut keys, and they can be activated, deactivated, saved, and restored. Global shortcut keys can be registered, but they are not tied to a particular shortcut session. They are rather applied everywhere in the application and can only be applied once.

The Shortcut framework is implemented on top of Mousetrap library.

Shortcut Sessions

In order to register a shortcut in Sugar, a shortcut session must first be created by adding ShortcutSession plugin to the top-level layout JavaScript controller.

  plugins: ['ShortcutSession']

Then, the top-level layout needs to list which shortcuts are allowed in the shortcut session. Shortcuts can be listed in the top-level layout JavaScript controller :

./custom/clients/layout/my-layout/my-layout.js

  shortcuts: [
    'Sidebar:Toggle',
    'Record:Save',
    'Record:Cancel',
    'Record:Action:More'
]

Shortcuts can also be listed in the metadata :

./custom/clients/layout/my-layout/my-layout.php

  'shortcuts' => array(
    'Sidebar:Toggle',
    'Record:Save',
    'Record:Cancel',
    'Record:Action:More'
),

Register

Once a shortcut session is created, shortcut keys can be registered by adding the following in your JavaScript code :

  app.shortcuts.register('<unique shortcut ID>', '<shortcut keys>', <callback function>, <current component>, <call on focus?>);

Since shortcut keys should only be registered once in your component, they should be registered inside initialize() or someplace where re-rendering the component would not register more than once.

Shortcut IDs

Shortcut IDs should be unique across the application. They should be namespaced by convention, for example Record:Next, Sidebar:Toggle, List:Edit. If the namespace starts with Global:, it assumes that the shortcut is global.

Global shortcuts

Global shortcuts are shortcut keys that are applied once and are available everywhere in the application.

  app.shortcuts.register(app.shortcuts.GLOBAL + 'Footer:Help', '?', function() {}, this, false);

Shortcut Keys

There are only certain keys that are supported under the Shortcut framework. The following keyboard keys can be used : 

  • All alphanumeric characters and symbols
  • shift, ctrl, alt, option, meta, command
  • backspace, tab, enter, return, capslock, esc, escape, space, pageup, pagedown, end, home, ins, del
  • left, up, right, down

Additional Features

In addition to standard keys, the Shortcut framework also supports some additional features :

  • Key combinations : 'ctrl+s'
  • Multiple keys : ['ctrl+a', 'command+a']
  • Key sequences : 'f a'

Input Focus

The fifth parameter in the register method specifies whether or not the shortcut key should be fired when the user is focused in an input field. It is false by default.

  app.shortcuts.register('Record:Save', ['ctrl+s','command+s'], function() {}, this, true);

Limitations

Shortcut keys do not work on side panels, like dashboards and previews.

Shortcuts Help

Anytime a new shortcut is created, a help text should be provided in ./clients/base/layouts/shortcuts/shortcuts.php with a shortcut ID and a language string.

  'List:Favorite' => 'LBL_SHORTCUT_FAVORITE_RECORD',

Shortcuts help is displayed when Shortcuts button is clicked.

Advanced Features

Enable/disable dynamically

Shortcuts feature can be enabled and disabled dynamically via code by calling app.shortcuts.enable() and app.shortcuts.disable().

Dynamically saving, creating new, and restoring sessions

A new shortcut session is created when a user visits a top-level layout with ShortcutSession plugin. A new session can be created dynamically:

  app.shortcuts.createSession(<array of shorcut IDs>, <component>);

But before creating a new session, the current session should be saved first.

  app.shortcuts.saveSession();
app.shortcuts.createSession(<array of shorcut IDs>, <component>);

Once a new session is created, shortcut keys can be registered to it. When the need for the session is done, the previous shortcut session can be restored.

  app.shortcuts.restoreSession();

Example

The following example will be to add some custom shortcuts onto a custom layout. For more information on how to create a custom layout, please refer to the Creating Layouts documentation.

First, on our custom JavaScript controller for our layout, we must enable the ShortcutSession plugin as well as list the shortcuts we will be enabling :

./custom/clients/base/layouts/my-layout/my-layout.js

  ({
    plugins: ['ShortcutSession'],
    shortcuts: [
        'Global:MyLayout:MyCallback',
    ],
})

Next, on the custom view being rendered on our layout, we will register the new shortcuts as well as define a callback method : 

./custom/clients/base/views/my-view/my-view.js

...
initialize: function(options){
    this._super('initialize', [options]);

    // call myCallback method when command + a is pressed
    app.shortcuts.register(app.shortcuts.GLOBAL + 'MyLayout:MyCallback', 'command+a', this.myCallback, this, false);

    app.shortcuts.saveSession();
    app.shortcuts.createSession([
        'MyLayout:InlineCall'
    ], this);

    // call inline code when control + m or command + m is pressed
    app.shortcuts.register('MyLayout:InlineCall', ['ctrl+m','command+m'], function() {
		console.log("Ctrl or Command m has been pressed");
    }, this, false);
},
myCallback: function(){
    console.log("MyCallback called from Command a");
},
...

The last step will be to create a new label for our shortcut help text and register the help so it displays when "Shortcuts" is click in the footer of the page :

./custom/Extension/application/Ext/Language/en_us.LBL_MYLAYOUT_SHORTCUT_HELP.php

  <?php

$app_strings['LBL_MYLAYOUT_MYCALLBACK_HELP'] = "Activates my Callback Method";
$app_strings['LBL_MYLAYOUT_MYINLINECALL_HELP'] = "Activates Inline Code";

./custom/Extension/application/Ext/clients/base/layouts/shortcuts/shortcuts.php

  <?php

$viewdefs['base']['layout']['shortcuts']['help']['Global:MyLayout:MyCallback'] = 'LBL_MYLAYOUT_MYCALLBACK_HELP';
$viewdefs['base']['layout']['shortcuts']['help']['MyLayout:InlineCall'] = 'LBL_MYLAYOUT_MYINLINECALL_HELP';

Navigate to Admin > Repair > Quick Repair and Rebuild. The system will then rebuild the extensions and add the new shortcut to the custom layout.

Topics