js knockout hotkey
/**
* Examples:
* - hotkey: 'ctrl+5' -> when control and 5 are pressed the binding element either is clicked or focus (input, select, textarea, .hotkey-focus)
* - hotkey: {trigger: 'shift+b} => same as above but with shift and b
* - hotkey: 'ctrl+shift+5' -> same as above but also with shift
* - hotkey: {trigger: obsHotKey, action: function(element)} => A trigger or action can be an observable as well. action takes a function. If a non function
* is passed in then the default focus or click event is fired
* */
ko.bindingHandlers.hotkey = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var options = ko.utils.unwrapObservable(valueAccessor());
if (typeof options === "object") {
var trigger = ko.utils.unwrapObservable(options.trigger.toLowerCase());
var action = ko.utils.unwrapObservable(options.action);
} else {
var trigger = options;
}
var shift = trigger.indexOf("shift") > -1;
var ctrl = trigger.indexOf("ctrl") > -1;
var alt = trigger.indexOf("alt") > -1;
var key = trigger.substring(trigger.length - 1);
$(document).on("keydown", function (e) {
if (e.shiftKey === shift && e.ctrlKey === ctrl && e.altKey === alt && e.which === key.toUpperCase().charCodeAt(0)) {
// hot key hit
if ($(element).hasClass("hotkey-pressed") === true) return;
$(element).addClass("hotkey-pressed");
if (action && typeof action === "function") {
action(element);
} else {
//if a input select or textarea lets focus on it
if (element.tagName.toLowerCase() == "input"
|| element.tagName.toLowerCase() == "textarea"
|| element.tagName.toLowerCase() == "select")
$(element).focus();
else
$(element).click();
}
e.preventDefault();
}
});
//to keep from continuing calling of the hot key
$(document).on("keyup", function (e) {
$(element).removeClass("hotkey-pressed");
});
}
};