diff --git a/Gruntfile.js b/Gruntfile.js
index 332d0474a865dbe0ff55fa0ae7991501e8f1ee58..7c54f2d4b9f04b2eb72096f48b4f488c21d95296 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -304,6 +304,28 @@ module.exports = function (grunt) {
                         flatten: true
                     }
                 ]
+            },
+            typeahead: {
+                files: [
+                    {
+                        cwd: 'bower_components/corejs-typeahead/dist',
+                        src: [
+                            "typeahead.bundle.min.js"
+                        ],
+                        expand: true,
+                        dest: typo3_js,
+                        flatten: true
+                    },
+                    {
+                        cwd: 'bower_components/corejs-typeahead/dist',
+                        src: [
+                            "typeahead.bundle.min.js"
+                        ],
+                        expand: true,
+                        dest: 'js/',
+                        flatten: true
+                    }
+                ]
             }
         },
         uglify: {
diff --git a/bower.json b/bower.json
index 249fe0462c3892ae6d52ab1427bccd2f7ec6c0c2..46da5a2c5d61f1d9c620ef3de0f0e1610229a250 100644
--- a/bower.json
+++ b/bower.json
@@ -23,6 +23,7 @@
     "eventEmitter": "^4.3.0",
     "bootstrap-validator": "^0.11.5",
     "Chart.js": "^2.1.2",
-    "tinymce": "tinymce-dist#^4.4.3"
+    "tinymce": "tinymce-dist#^4.4.3",
+    "corejs-typeahead": "^1.1.1"
   }
 }
diff --git a/javascript/src/QfqPage.js b/javascript/src/QfqPage.js
index 340fb0f081b30e9a50e6aaed1e14083f08f0e512..cef6916b4e3a4072d721f4f44f793cea6a1949b2 100644
--- a/javascript/src/QfqPage.js
+++ b/javascript/src/QfqPage.js
@@ -33,6 +33,7 @@ var QfqNS = QfqNS || {};
                 refreshUrl: "typo3conf/ext/qfq/qfq/api/load.php",
                 fileUploadTo: "typo3conf/ext/qfq/qfq/api/upload.php",
                 fileDeleteUrl: "typo3conf/ext/qfq/qfq/api/filedelete.php",
+                typeAheadUrl: "typo3conf/ext/qfq/qfq/api/typeahead.php",
                 pageState: new n.PageState()
             }, settings
         );
@@ -78,6 +79,8 @@ var QfqNS = QfqNS || {};
             n.Log.error(e.message);
             this.qfqForm = null;
         }
+
+        QfqNS.TypeAhead.install(this.settings.typeAheadUrl);
     };
 
     /**
diff --git a/javascript/src/TypeAhead.js b/javascript/src/TypeAhead.js
new file mode 100644
index 0000000000000000000000000000000000000000..3ba5bca39af5ea4ad0402e917b6deea291fc1f0a
--- /dev/null
+++ b/javascript/src/TypeAhead.js
@@ -0,0 +1,116 @@
+/**
+ * @author Rafael Ostertag <rafael.ostertag@math.uzh.ch>
+ */
+
+/* global $ */
+/* global console */
+/* global Bloodhound */
+/* global Math */
+
+/* @depend Utils.js */
+
+var QfqNS = QfqNS || {};
+
+(function (n) {
+    'use strict';
+
+    n.TypeAhead = {};
+
+
+    /**
+     *
+     * @param typeahead_endpoint the endpoint to be called
+     * @constructor
+     */
+    n.TypeAhead.install = function (typeahead_endpoint) {
+
+        $('.qfq-type-ahead').each(function () {
+            var $element = $(this);
+            var suggestions = new Bloodhound({
+                datumTokenizer: Bloodhound.tokenizers.obj.whitespace('key', 'value'),
+                queryTokenizer: Bloodhound.tokenizers.whitespace,
+                identify: function (obj) {
+                    return obj.key;
+                },
+                remote: {
+                    url: n.TypeAhead.makeUrl(typeahead_endpoint, $element),
+                    wildcard: '%QUERY'
+                }
+            });
+
+            n.TypeAhead.makeShadowElement($element);
+
+            $element.typeahead({
+                    hint: n.TypeAhead.getHint($element),
+                    highlight: n.TypeAhead.getHighlight($element),
+                    minLength: n.TypeAhead.getMinLength($element)
+                },
+                {
+                    display: 'value',
+                    source: suggestions,
+                    templates: {
+                        suggestion: function (obj) {
+                            return "<div>" + n.TypeAhead.htmlEncode(obj.value) + "</div>";
+                        },
+                        notFound: function (obj) {
+                            return "<div>'" + n.TypeAhead.htmlEncode(obj.query) + "' not found";
+                        }
+                    }
+                });
+            $element.bind('typeahead:select typeahead:autocomplete', function (event, suggestion) {
+                var $shadowElement = $(event.delegateTarget).data('shadow-element');
+                $shadowElement.val(suggestion.key);
+            });
+        });
+
+    };
+
+    n.TypeAhead.makeUrl = function (endpoint, element) {
+        return endpoint + "?query=%QUERY" + "&sip=" + n.TypeAhead.getSip(element);
+    };
+
+    n.TypeAhead.getSip = function ($element) {
+        return $element.data('sip');
+    };
+
+    n.TypeAhead.getName = function ($element) {
+        return $element.attr('name');
+    };
+
+    n.TypeAhead.getValue = function ($element) {
+        return $element.val();
+    };
+
+    n.TypeAhead.getMinLength = function ($element) {
+        return $element.data('ta-min-length') || 2;
+    };
+
+    n.TypeAhead.getHighlight = function ($element) {
+        return $element.data('ta-higlight') || true;
+    };
+
+    n.TypeAhead.getHint = function ($element) {
+        return $element.data('ta-hint') || true;
+    };
+
+    n.TypeAhead.htmlEncode = function (value) {
+        return $('<div/>').text(value).html();
+    };
+
+    n.TypeAhead.makeShadowElement = function ($element) {
+        var $parent, inputName, uniqueId, $shadowElement;
+
+        $parent = $element.parent();
+        inputName = $element.attr('name');
+        $element.removeAttr('name');
+
+        $shadowElement = $('<input>')
+            .attr('type', 'hidden')
+            .attr('name', inputName);
+
+        $element.data('shadow-element', $shadowElement);
+
+        $parent.append($shadowElement);
+    };
+})(QfqNS);
+
diff --git a/mockup/api/typeahead.php b/mockup/api/typeahead.php
new file mode 100644
index 0000000000000000000000000000000000000000..7927aa3c93860aae26ce33d7335581a507998d40
--- /dev/null
+++ b/mockup/api/typeahead.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * @author Rafael Ostertag <rafael.ostertag@math.uzh.ch>
+ */
+
+header('Content-Type: application/json');
+
+if (!isset($_GET['query'])) {
+    echo json_encode(['message' => 'wrong arguments']);
+    exit(0);
+}
+
+if (!isset($_GET['sip'])) {
+    echo json_encode(['message' => 'no sip']);
+    exit(0);
+}
+
+$dict = [
+    ['value' => "Alabama", 'key' => "AL"],
+    ['value' => "Alaska", 'key' => "AK"],
+    ['value' => "Arizona", 'key' => "AZ"],
+    ['value' => "Arkansas", 'key' => "AR"],
+    ['value' => "California", 'key' => "CA"],
+    ['value' => "Colorado", 'key' => "CO"],
+    ['value' => "Connecticut", 'key' => "CT"],
+    ['value' => "Delaware", 'key' => "DE"],
+    ['value' => "Florida", 'key' => "FL"],
+    ['value' => "Georgia", 'key' => "GA"],
+    ['value' => "Hawaii", 'key' => "HI"],
+    ['value' => "Idaho", 'key' => "ID"],
+    ['value' => "Illinois", 'key' => "IL"],
+    ['value' => "Indiana", 'key' => "IN"],
+    ['value' => "Iowa", 'key' => "IA"],
+    ['value' => "Kansas", 'key' => "KS"],
+    ['value' => "Kentucky", 'key' => "KY"],
+    ['value' => "Louisiana", 'key' => "LA"],
+    ['value' => "Maine", 'key' => "ME"],
+    ['value' => "Maryland", 'key' => "MD"],
+    ['value' => "Massachusetts", 'key' => "MA"],
+    ['value' => "Michigan", 'key' => "MI"],
+    ['value' => "Minnesota", 'key' => "MN"],
+    ['value' => "Mississippi", 'key' => "MS"],
+    ['value' => "Missouri", 'key' => "MO"],
+    ['value' => "Montana", 'key' => "MT"],
+    ['value' => "Nebraska", 'key' => "NE"],
+    ['value' => "Nevada", 'key' => "NV"],
+    ['value' => "New Hampshire", 'key' => "NH"],
+    ['value' => "New Jersey", 'key' => "NJ"],
+    ['value' => "New Mexico", 'key' => "NM"],
+    ['value' => "New York", 'key' => "NY"],
+    ['value' => "North Carolina", 'key' => "NC"],
+    ['value' => "North Dakota", 'key' => "ND"],
+    ['value' => "Ohio", 'key' => "OH"],
+    ['value' => "Oklahoma", 'key' => "OK"],
+    ['value' => "Oregon", 'key' => "OR"],
+    ['value' => "Pennsylvania", 'key' => "PA"],
+    ['value' => "Rhode Island", 'key' => "RI"],
+    ['value' => "South Carolina", 'key' => "SC"],
+    ['value' => "South Dakota", 'key' => "SD"],
+    ['value' => "Tennessee", 'key' => "TN"],
+    ['value' => "Texas", 'key' => "TX"],
+    ['value' => "Utah", 'key' => "UT"],
+    ['value' => "Vermont", 'key' => "VT"],
+    ['value' => "Virginia", 'key' => "VA"],
+    ['value' => "Washington", 'key' => "WA"],
+    ['value' => "West Virginia", 'key' => "WV"],
+    ['value' => "Wisconsin", 'key' => "WI"],
+    ['value' => "Wyoming", 'key' => "WY"],
+];
+
+$result = [];
+foreach ($dict as $obj) {
+    if (stristr($obj['value'], $_GET['query']) ||
+        stristr($obj['key'], $_GET['query'])
+    ) {
+        $result[] = $obj;
+    }
+}
+
+echo json_encode($result);
+?>
\ No newline at end of file
diff --git a/mockup/typeahead.html b/mockup/typeahead.html
new file mode 100644
index 0000000000000000000000000000000000000000..b4b2debdc15ee379162f16e8be646a9fb71948cb
--- /dev/null
+++ b/mockup/typeahead.html
@@ -0,0 +1,163 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <link rel="stylesheet" href="../css/bootstrap.min.css">
+    <link rel="stylesheet" href="../css/bootstrap-theme.min.css">
+    <link rel="stylesheet" href="../css/jqx.base.css">
+    <link rel="stylesheet" href="../css/qfq-bs.css">
+    <title>Type Ahead</title>
+</head>
+<body>
+
+
+<label>Submit to
+    <select name="submitTo" id="submitTo">
+        <option>404 error</option>
+        <option>save_error_matno.json</option>
+        <option>save_error_geburtstag.json</option>
+        <option>save_no_redirect.json</option>
+        <option>save_server_redirect.json</option>
+        <option>save_client_redirect.json</option>
+    </select>
+</label>
+
+<label>Delete URL
+    <select name="deleteUrl" id="deleteUrl">
+        <option>404 error</option>
+        <option>delete_client_redirect.json</option>
+        <option>delete_error.json</option>
+        <option>delete_no_redirect.json</option>
+        <option>delete_server_redirect.json</option>
+    </select>
+</label>
+
+<label>Upload to
+    <select name="uploadTo" id="uploadTo">
+        <option>404 error</option>
+        <option>uploadhandler.php</option>
+        <option>uploadhandler_error.php</option>
+    </select>
+</label>
+
+<label>File Delete Url
+    <select name="fileDeleteUrl" id="fileDeleteUrl">
+        <option>404 error</option>
+        <option>delete_file_ok.json</option>
+        <option>delete_file_error.json</option>
+    </select>
+</label>
+
+
+<div class="container-fluid">
+    <div class="row hidden-xs">
+        <div class="col-md-12">
+            <h1>Title with a long text</h1>
+        </div>
+    </div>
+
+    <div class="row">
+        <div class="col-md-12 ">
+            <div class="btn-toolbar pull-right" role="toolbar">
+                <div class="btn-group" role="group">
+                    <button id="save-button" type="button" class="btn btn-default navbar-btn"
+                            data-class-on-change="wdc"><span
+                            class="glyphicon glyphicon-ok"></span></button>
+                    <button id="close-button" type="button" class="btn btn-default navbar-btn"><span
+                            class="glyphicon glyphicon-remove"></span></button>
+                </div>
+                <div class="btn-group" role="group">
+                    <button id="delete-button" type="button" class="btn btn-default navbar-btn"><span
+                            class="glyphicon glyphicon-trash"></span></button>
+                </div>
+                <div class="btn-group" role="group">
+                    <a id="form-new-button" href="personmock.html?s=badcaffe1" class="btn btn-default navbar-btn"><span
+                            class="glyphicon glyphicon-plus"></span></a>
+                </div>
+            </div>
+        </div>
+
+    </div>
+
+
+    <form id="myForm" class="form-horizontal" data-toggle="validator">
+
+        <div id="formgroup1" class="form-group">
+            <div class="col-md-2">
+                <label for="dropdown1" class="control-label">Text input</label>
+            </div>
+
+            <div class="col-md-6">
+                <input id="dropdown1" type="text" class="form-control qfq-type-ahead" name="dropdown1"
+                       data-sip="abcde" data-template="template1">
+            </div>
+
+        </div>
+
+        <div id="formgroup2" class="form-group">
+            <div class="col-md-2">
+                <label for="dropdown2" class="control-label">Text input 2</label>
+            </div>
+
+            <div class="col-md-6">
+                <input id="dropdown2" type="text" class="form-control qfq-type-ahead" name="dropdown2"
+                       data-sip="abcdef">
+            </div>
+
+        </div>
+
+    </form>
+</div>
+
+<script type="text/x-handlebars-template">
+
+</script>
+
+<script src="../js/jquery.min.js"></script>
+<script src="../js/bootstrap.min.js"></script>
+<script src="../js/validator.min.js"></script>
+<script src="../js/jqx-all.js"></script>
+<script src="../js/EventEmitter.min.js"></script>
+<script src="../js/typeahead.bundle.min.js"></script>
+<script src="../js/qfq.debug.js"></script>
+<script type="text/javascript">
+    $(function () {
+        var qfqPage = new QfqNS.QfqPage({
+            tabsId: 'myTabs',
+            formId: 'myForm',
+            submitTo: 'api/' + $("#submitTo").val(),
+            deleteUrl: 'api/' + $("#deleteUrl").val(),
+            fileUploadTo: 'api/' + $("#uploadTo").val(),
+            fileDeleteUrl: 'api/' + $("#fileDeleteUrl").val(),
+            typeAheadUrl: 'api/typeahead.php'
+        });
+
+        $("#submitTo").on("change", function (evt) {
+            qfqPage.settings.submitTo = 'api/' + $(evt.target).val();
+            qfqPage.qfqForm.submitTo = 'api/' + $(evt.target).val();
+        });
+
+        $("#deleteUrl").on("change", function (evt) {
+            qfqPage.settings.deleteUrl = 'api/' + $(evt.target).val();
+            qfqPage.qfqForm.deleteUrl = 'api/' + $(evt.target).val();
+        });
+
+        $("#uploadTo").on("change", function (evt) {
+            qfqPage.settings.fileUploadTo = 'api/' + $(evt.target).val();
+            qfqPage.qfqForm.fileUploader.targetUrl = 'api/' + $(evt.target).val();
+        });
+
+        $("#fileDeleteUrl").on("change", function (evt) {
+            qfqPage.settings.fileDeleteUrl = 'api/' + $(evt.target).val();
+            qfqPage.qfqForm.fileDeleter.targetUrl = 'api/' + $(evt.target).val();
+        });
+
+        $('#myForm').on('invalid', function () {
+            console.log("Invalid event catched");
+        });
+
+        QfqNS.Log.level = 0;
+    });
+</script>
+</body>
+</html>