diff --git a/pom.xml b/pom.xml
index 90c6060a78463837266b55d0e3c9c42685ad0fe6..0ac1a9a540ed37ee4ddcd97fd68523c487adb6a9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,6 +63,7 @@
         <materializecss.version>1.0.0</materializecss.version>
         <fontawesome.version>5.0.10</fontawesome.version>
         <sortablejs.version>1.8.1</sortablejs.version>
+        <mousetrap.version>1.6.1</mousetrap.version>
         <webdrivermanager.version>2.2.1</webdrivermanager.version>
         <selenium.version>3.141.59</selenium.version>
 
@@ -183,6 +184,11 @@
             <artifactId>sortablejs</artifactId>
             <version>${sortablejs.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.webjars.npm</groupId>
+            <artifactId>mousetrap</artifactId>
+            <version>${mousetrap.version}</version>
+        </dependency>
 
         <!-- selenium -->
         <dependency>
diff --git a/src/main/resources/static/js/hotkeys.js b/src/main/resources/static/js/hotkeys.js
new file mode 100644
index 0000000000000000000000000000000000000000..a0328e0c9d6aee8f06ec4e79f8a5caa9e5de05a9
--- /dev/null
+++ b/src/main/resources/static/js/hotkeys.js
@@ -0,0 +1,27 @@
+Mousetrap.bind('n', function () {
+    window.location.href = rootURL + '/transactions/newTransaction/normal';
+});
+
+Mousetrap.bind('r', function () {
+    window.location.href = rootURL + '/transactions/newTransaction/repeating';
+});
+
+Mousetrap.bind('t', function () {
+    window.location.href = rootURL + '/transactions/newTransaction/transfer';
+});
+
+Mousetrap.bind('f', function () {
+    window.location.href = rootURL + '/transactions#modalFilter';
+});
+
+Mousetrap.bind('s', function () {
+    document.getElementById('search').focus();
+});
+
+Mousetrap.bind('esc', function () {
+    var searchElement = document.getElementById('search');
+    var isSearchFocused = (document.activeElement === searchElement);
+    if (isSearchFocused) {
+        document.getElementById('nav-logo-container').focus();
+    }
+});
diff --git a/src/main/resources/static/js/transactions.js b/src/main/resources/static/js/transactions.js
index 090a50dd16c5907caee80ee0b955949ecdee9ec6..e451c972422f2c6a860ebcefe0db65d8d771affd 100644
--- a/src/main/resources/static/js/transactions.js
+++ b/src/main/resources/static/js/transactions.js
@@ -1,6 +1,12 @@
 $( document ).ready(function() {
     $('#modalConfirmDelete').modal('open');
 
+    // open filter modal if corresponding anchor is in url (originating from hotkeys.js)
+    if(window.location.href.endsWith('#modalFilter'))
+    {
+        $('#modalFilter').modal('open');
+    }
+
     if($(".datepicker").length)
     {
         var pickerStartDate = M.Datepicker.init(document.getElementById('transaction-datepicker'), {
@@ -185,13 +191,13 @@ $( document ).ready(function() {
     // scroll to highlighted transaction
     var highlightedSmall = document.getElementById("highlighted-small");
     var highlightedLarge = document.getElementById("highlighted-large");
-    if(highlightedSmall !== undefined && !isHidden(highlightedSmall))
+    if(highlightedSmall !== undefined  && highlightedSmall != null && !isHidden(highlightedSmall))
     {
         $('html, body').animate({
             scrollTop: $(highlightedSmall).offset().top
         }, 500);
     }
-    else if(highlightedLarge !== undefined && !isHidden(highlightedLarge))
+    else if(highlightedLarge !== undefined && highlightedLarge != null && !isHidden(highlightedLarge))
     {
         $('html, body').animate({
             scrollTop: $(highlightedLarge).offset().top
diff --git a/src/main/resources/templates/helpers/navbar.ftl b/src/main/resources/templates/helpers/navbar.ftl
index 6978277fd0f2d1053c72b66373ce5bcbaac8a70a..eac9575fe24b8d7cfca12cca859a7f12240ee95d 100644
--- a/src/main/resources/templates/helpers/navbar.ftl
+++ b/src/main/resources/templates/helpers/navbar.ftl
@@ -76,7 +76,7 @@
                 <input type="hidden" name="searchTags" value="true">
 
                 <div class="input-field">
-                    <input id="search" class="text-color" name="searchText" type="search">
+                    <input id="search" class="text-color mousetrap" name="searchText" type="search">
                     <label class="label-icon" for="search"><i class="material-icons">search</i></label>
                     <i id="buttonSearch" class="material-icons">send</i>
                     <i id="buttonClearSearch" class="material-icons">close</i>
diff --git a/src/main/resources/templates/helpers/scripts.ftl b/src/main/resources/templates/helpers/scripts.ftl
index af457e2e45f93405f5835e4490a84c41401ec917..38f2d1bd30c777cc4b82548ec852db0e9a802f97 100644
--- a/src/main/resources/templates/helpers/scripts.ftl
+++ b/src/main/resources/templates/helpers/scripts.ftl
@@ -2,9 +2,11 @@
 <#import "/spring.ftl" as s>
 <script src="<@s.url '/webjars/jquery/3.3.1/jquery.min.js'/>"></script>
 <script src="<@s.url '/webjars/materializecss/1.0.0/js/materialize.min.js'/>"></script>
+<script src="<@s.url '/webjars/mousetrap/1.6.1/mousetrap.js'/>"></script>
 <script>
     rootURL = "<@s.url ''/>"
 </script>
+<script src="<@s.url '/js/hotkeys.js'/>"></script>
 <script src="<@s.url '/js/main.js'/>"></script>
 <script>
     accountPlaceholderName = "${locale.getString("account.all")}";
diff --git a/src/main/resources/templates/transactions/transactionsMacros.ftl b/src/main/resources/templates/transactions/transactionsMacros.ftl
index 9a6ce3a29ecb96643ffee62e9a60d082866aade2..4dea01de1ee20cc160af409702b0969914911847 100644
--- a/src/main/resources/templates/transactions/transactionsMacros.ftl
+++ b/src/main/resources/templates/transactions/transactionsMacros.ftl
@@ -155,8 +155,8 @@
 
 <#macro buttonFilter isFilterActive>
     <#if isFilterActive>
-        <a href="#modalFilter" class="modal-trigger waves-effect waves-light btn budgetmaster-red"><i class="fas fa-filter left"></i>${locale.getString("filter.active")}</a>
+        <a href="#modalFilter" id="modalFilterTrigger" class="modal-trigger waves-effect waves-light btn budgetmaster-red"><i class="fas fa-filter left"></i>${locale.getString("filter.active")}</a>
     <#else>
-        <a href="#modalFilter" class="modal-trigger waves-effect waves-light btn budgetmaster-blue"><i class="fas fa-filter left"></i>${locale.getString("title.filter")}</a>
+        <a href="#modalFilter" id="modalFilterTrigger" class="modal-trigger waves-effect waves-light btn budgetmaster-blue"><i class="fas fa-filter left"></i>${locale.getString("title.filter")}</a>
     </#if>
 </#macro>