Recently I had a requirement where the end users want to interact with the Fiori applications using the keyboard keys(Hotkeys). Off course SAP UI5 controls are by default can be interacted using the keyboard as accessibility is one of the main features of Fiori. Eg: Using Tab, page down/up, arrow buttons…

The application that I’ve developed is mainly used in desktops and users needed keyboard shortcuts that are similar to SAP GUI(F8, SHIFT+F5.., etc combinations)

 

To achieve this functionality, we can always go for the traditional jquery as shown below:

$(document).keydown(function(evt){
   if (evt.keyCode==83 && (evt.ctrlKey)){
       evt.preventDefault();
       alert('worked');
   }
});

The complexity of the above code is that we have to spend a lot of time to find the Keyboard key codes like for example “83” is one of the keycodes for a key in the keyboard. Also, it will be more complex if we want to deregister a function for a keycode combination.

 

While I was investigating the above issues and complexity, I came across an open source plugin “jQuery HotKeys”.

https://github.com/jeresig/jquery.hotkeys

 

The above library is very simple and will offer the registration and deregistration for hotkeys easily. I will go through the code below for better understanding.

 

Requirement:

  1. Quick focus on the filter bar search fields using Alt + Function key combination eg: Alt+F1
  2. Posting the documents on the click of F8- We have a post button available but on the click of F8 key, the documents should be posted.
  3. Much more options can be provided like Tab Bar navigations(Changing the selected Tabs using the function key combinations) etc.., which I am not showing in the current blog

Step 1:

Copy the Hotkey API to the project util folder:

 

Step 2:

Create an interface for the Hotkey API & our application (This is an optional one).

sap.ui.define([
	"sap/ui/base/Object"
], function(ui5Object) {
	"use strict";
	var HotkeyInterface = ui5Object.extend("sap.test.listreport.util.hotkeyInterface", {
		constructor: function(oComponent) {
			this.oComponent = oComponent;
		},

		bindHotKeys: function(combinations) {
			combinations.forEach(function(mItem) {
				// First Remove if that keycombinaiton is availble already, as we only will have at a time one
				this.unBindHotKey(mItem.keyCombination);
				// Now call the actual binding
				this.bindHotKey(mItem.keyCombination, mItem.control, mItem.fnHandler, mItem.hanlder);
			}, this);
		},

		bindHotKey: function(keyCombination, control, fnHandler, hanlder) {
			$(document).bind("keydown." + this.getNameSpace(keyCombination), keyCombination, function(oEvent) {
				if (control && control.getDomRef() && control.getDomRef().getBoundingClientRect()) {
					// Check if the control is visible in DOM currently, 
					// sometimes,the control might be hidden becuase of a tab change or view change
					var aMargin = control.getDomRef().getBoundingClientRect();
					if (aMargin.width) {// If the width is availble, then it is visible
						fnHandler.call(this, oEvent, control);
					}
				}
			}.bind(hanlder));
		},

		unBindHotKeys: function(keyCombinations) {
			// Remove the hotkeys
			keyCombinations.forEach(function(mItem) {
				this.unBindHotKey(mItem.keyCombination);
			}, this);
		},

		unBindHotKey: function(keyCombination) {
			$(document).unbind("keydown." + this.getNameSpace(keyCombination));
		},

		getNameSpace: function(keyCombination) {
			// Create a unique key for the hotkey we are using
			return "pocApplication_" + keyCombination.replace("+", "_");
		}
	});

	return {
		getInstance: function(oComponent) {
			// Singleton
			if (!this.instance) {
				this.instance = new HotkeyInterface(oComponent);
			}
			return this.instance;
		}
	};

});

 

Include the both APIs in the manifest file:

 

Step 3:

Now use the API we have developed in our views as shown below:

 

Include the API in our view Controller:

 

In the Init method, create an object which will have the hotkey and event handler methods:

			this.hotKeyHanlders = [{
				keyCombination: "Alt+f1",
				control: this.getView().byId("inputPopup"),
				fnHandler: this.focusOnSearchFields,
				hanlder: this
			}, {
				keyCombination: "Alt+f2",
				control: this.getView().byId("idOrderInput"),
				fnHandler: this.focusOnSearchFields,
				hanlder: this
			}, {
				keyCombination: "F8",
				control: this.getView().byId("idPostDocuments"),
				fnHandler: this.handleHotKeyPost,
				hanlder: this
			}];

Now instantiate the API and register our hotkeys:

hotkeyInterface.getInstance(this.getOwnerComponent()).bindHotKeys(this.hotKeyHanlders);

 

		focusOnSearchFields: function(oEvent, oControl) {
			oEvent.preventDefault();
			oControl.focus();
		},

		handleHotKeyPost: function(oEvent, oControl) {
			oEvent.preventDefault();
			this.postDocuments();
		},

For Unbinding the hotkeys, we can also unbind the hotkeys individually. It will be done at onexit event.

	unBindAllHotKeys: function() {
			hotkeyInterface.getInstance(this.getOwnerComponent()).unBindHotKeys(this.hotKeyHanlders);
		},

 

Now we have instantiated the hotkeys API and registered the Hotkeys with event handler functions.

Once the Fiori App is loaded, then on the press of the above function key combinations, the respective event handlers will get triggered.

 

Sorry to disappoint the ones who are expecting the UI5 screens, this blog is just about the jQuery Hotkey plug usage in UI5 ;p

 

Note: just be careful while assigning the Hotkeys, go through the plugin URL that I’ve mentioned, there are some limitations as in few cases browser shortcuts will take more priority than the shortcuts we have assigned.

 

Thanks,
Mahesh

 

 

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply