diff --git a/src/config.json b/src/config.json
index 511510749233da02e7452d8e86f14f17544617da..0c6dc1dfe4b5839abe92f447489133637279cd4f 100644
--- a/src/config.json
+++ b/src/config.json
@@ -90,8 +90,6 @@
             "user.firstname",
             "email"
         ],
-        "searchKeys": [
-            "email"
-        ]
+        "searchKeys": []
     }
 }
diff --git a/src/events/viewEvent.js b/src/events/viewEvent.js
index 2398b4721098cf941bbbaf091bf7de503c5bb5f8..7e9e7d4c7f523058958ce4e9a0780cdcf9eb5db2 100644
--- a/src/events/viewEvent.js
+++ b/src/events/viewEvent.js
@@ -19,57 +19,41 @@ import { ResourceHandler } from '../auth';
 
 const viewLayout = [
     {
-        '.eventViewContainer': {
-            display: 'grid',
-            'grid-template-columns': '40% 55%',
-            'grid-gap': '50px',
-        },
-        '.propertyTitle': {
-            color: 'rgba(0, 0, 0, 0.54)',
-        },
-        '.propertyText': {
-            color: 'rgba(0, 0, 0, 0.87)',
-        },
-        '.propertyLangIndicator': {
-            width: '30px',
-            height: '20px',
-            float: 'left',
-            'background-color': 'rgb(031,045,084)',
-            'border-radius': '10px',
-            'text-align': 'center',
-            'line-height': '20px',
-            color: 'rgb(255,255,255)',
-            'margin-right': '10px',
-            'font-size' : '11px',
-        },
-        '.eventInfoCard': {
-          padding: '10px',
-            'font-size': '15sp',
-        },
-        '.eventViewLeft': {
-            'grid-column': 1,
-        },
-        '.eventViewRight': {
-            'grid-column': 2,
-        },
-        '.eventViewRight h4': {
-                'margin-top': '0px',
-        }
-    },
-  {
     '.eventViewContainer': {
-      display: 'grid',
-      'grid-template-columns': '40% 60%',
-      'grid-gap': '50px',
+        display: 'grid',
+        'grid-template-columns': '40% 55%',
+        'grid-gap': '50px',
+    },
+    '.propertyTitle': {
+        color: 'rgba(0, 0, 0, 0.54)',
+    },
+    '.propertyText': {
+        color: 'rgba(0, 0, 0, 0.87)',
+    },
+    '.propertyLangIndicator': {
+        width: '30px',
+        height: '20px',
+        float: 'left',
+        'background-color': 'rgb(031,045,084)',
+        'border-radius': '10px',
+        'text-align': 'center',
+        'line-height': '20px',
+        color: 'rgb(255,255,255)',
+        'margin-right': '10px',
+        'font-size' : '11px',
+    },
+    '.eventInfoCard': {
+      padding: '10px',
+        'font-size': '15sp',
     },
     '.eventViewLeft': {
-      'grid-column': 1,
+        'grid-column': 1,
     },
     '.eventViewRight': {
-      'grid-column': 2,
+        'grid-column': 2,
     },
     '.eventViewRight h4': {
-      'margin-top': '2px',
+            'margin-top': '0px',
     },
   },
 ];
@@ -77,6 +61,8 @@ styler.add('eventView', viewLayout);
 
 class PropertyInfo {
     view({ attrs: { title, de, en } }) {
+        //const text = '';
+
         if(de && en) {
             return m('div',
                 m('p.propertyTitle', {style: { 'margin-top': '10px', 'margin-bottom': '3px' } }, [title]),
@@ -111,10 +97,18 @@ class PropertyInfo {
 
 class ParticipantsTable {
   constructor({ attrs: { where } }) {
-    this.ctrl = new DatalistController('eventsignups', {
-      embedded: { user: 1 },
-      where,
-    }, signupConfig.tableKeys);
+    this.ctrl = new DatalistController(
+      'eventsignups', {
+        embedded: { user: 1 },
+        where,
+      },
+      [
+        'email',
+        'user.firstname',
+        'user.lastname',
+      ],
+      false,
+    );
   }
 
   getItemData(data) {
@@ -394,4 +388,4 @@ export default class viewEvent extends ItemView {
 
         ])
     }
-}
\ No newline at end of file
+}
diff --git a/src/listcontroller.js b/src/listcontroller.js
index bc759b307e92a02d5522e68b65014274b5bb75de..1d871958e6b962ce77e83a49e3d59d2bfb16c5f2 100644
--- a/src/listcontroller.js
+++ b/src/listcontroller.js
@@ -2,10 +2,16 @@ import Stream from 'mithril/stream';
 import { ResourceHandler } from './auth';
 
 export default class DatalistController {
-  constructor(resource, query = {}, searchKeys = false) {
-    this.handler = new ResourceHandler(resource, searchKeys);
+  constructor(resource, query = {}, searchKeys = false, onlineSearch = true) {
+    this.onlineSearch = onlineSearch;
+    if (onlineSearch) {
+      this.handler = new ResourceHandler(resource, searchKeys);
+    } else {
+      this.handler = new ResourceHandler(resource, false);
+      this.clientSearchKeys = searchKeys || [];
+    }
     this.query = query || {};
-    this.items = [];
+    this.search = null;
     // state pointer that is counted up every time the table is refreshed so
     // we can tell infinite scroll that the data-version has changed.
     this.stateCounter = Stream(0);
@@ -27,25 +33,66 @@ export default class DatalistController {
   getPageData(pageNum) {
     // for some reason this is called before the object is instantiated.
     // check this and return nothing
-    const query = {};
-    Object.keys(this.query).forEach((key) => { query[key] = this.query[key]; });
+    const query = Object.assign({}, this.query);
     query.max_results = 10;
     query.page = pageNum;
 
     return new Promise((resolve, reject) => {
       this.handler.get(query).then((data) => {
-        resolve(data._items);
+        // If onlineSearch is false, we filter the page-results at the client
+        // because the API would not understand the search pattern, e.g. for
+        // embedded keys like user.firstname
+        if (!this.onlineSearch && this.clientSearchKeys.length > 0 && this.search) {
+          const response = [];
+          // We go through all response items and will add them to response if
+          // they match the query.
+          data._items.forEach((item) => {
+            // Try every search Key seperately, such that any match with any
+            // key is sufficient
+            this.clientSearchKeys.some((key) => {
+              if (key.match(/.*\..*/)) {
+                // traverse the key, this is a key pointing to a sub-object
+                let intermediateObject = Object.assign({}, item);
+                key.split('.').forEach((subKey) => {
+                  intermediateObject = intermediateObject[subKey];
+                });
+                if (intermediateObject.includes(this.search)) {
+                  response.push(item);
+                  // return true to end the search of this object, it is already
+                  // matched
+                  return true;
+                }
+              } else if (item[key] && item[key].includes(this.search)) {
+                response.push(item);
+                // return true to end the search of this object, it is already
+                // matched
+                return true;
+              }
+              return false;
+            });
+          });
+          resolve(response);
+        } else {
+          resolve(data._items);
+        }
       });
     });
   }
 
   setSearch(search) {
-    this.query.search = search;
-    this.refresh();
+    if (this.onlineSearch) {
+      this.search = search;
+      this.query.search = search;
+      this.refresh();
+    } else if (this.clientSearchKeys.length > 0) {
+      this.search = search;
+      this.refresh();
+    }
   }
 
   setQuery(query) {
     this.query = query;
+    this.query.search = this.search;
     this.refresh();
   }
 }