diff --git a/src/index.js b/src/index.js
index ce76ae1ecafd786cf01108b6d0256ddfbd8e0eb9..e3c3fee4bf026a057c442bbef457265148bfc939 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,6 +1,6 @@
 import { LoginScreen } from './login';
 import TableView from './views/tableView';
-import { UserModal, UserTable } from './userTool';
+import { UserModal, UserTable, NewUser } from './userTool';
 import Sidebar from './sidebar';
 
 const m = require('mithril');
@@ -31,6 +31,7 @@ function layoutWith(view) {
 m.route(root, '/users', {
   '/users': layoutWith(UserTable),
   '/users/:id': layoutWith(UserModal),
+  '/newusers': layoutWith(NewUser),
   '/events': layoutWith({
     view() {
       return m(TableView, {
diff --git a/src/userTool.js b/src/userTool.js
index df07a7e9b3c9d161c69f01de3865b905c920f1ee..64a5eb031b4357ae473722d222c726e8d78bb7f9 100644
--- a/src/userTool.js
+++ b/src/userTool.js
@@ -73,19 +73,7 @@ class UserEdit extends EditView {
     super(vnode, 'users');
   }
 
-  view() {
-    // do not render anything if there is no data yet
-    if (!this.data) return m.trust('');
-
-    // UPDATE button is inactive if form is not valid
-    const buttonArgs = this.patchOnClick([
-      'lastname', 'firstname', 'email', 'membership', 'gender']);
-    const updateButton = m(
-      'div.btn.btn-warning',
-      this.valid ? buttonArgs : { disabled: 'disabled' },
-      'Update',
-    );
-
+  getForm() {
     return m('form', [
       m('div.row', [
         m(inputGroup, this.bind({
@@ -109,12 +97,59 @@ class UserEdit extends EditView {
         })),
       ]),
       m('span', JSON.stringify(this.data)),
-      m('span', JSON.stringify(this.errorLists)),
+      m('span', JSON.stringify(this.errors)),
+    ]);
+  }
+
+  view() {
+    // do not render anything if there is no data yet
+    if (!this.data) return m.trust('');
+
+    // UPDATE button is inactive if form is not valid
+    const buttonArgs = this.patchOnClick([
+      'lastname', 'firstname', 'email', 'membership', 'gender']);
+    const updateButton = m(
+      'div.btn.btn-warning',
+      this.valid ? buttonArgs : { disabled: 'disabled' },
+      'Update',
+    );
+
+    return m('form', [
+      this.getForm(),
       updateButton,
     ]);
   }
 }
 
+export class NewUser extends UserEdit {
+  constructor(vnode) {
+    super(vnode);
+    this.data = {
+      gender: 'male',
+      membership: 'regular',
+    };
+    this.valid = false;
+  }
+
+  view() {
+    // UPDATE button is inactive if form is not valid
+    const buttonArgs = this.createOnClick(
+      ['lastname', 'firstname', 'email', 'membership', 'gender'],
+      (response) => { m.route.set(`/users/${response.data._id}`); },
+    );
+    const postButton = m(
+      'div.btn.btn-warning',
+      this.valid ? buttonArgs : { disabled: 'disabled' },
+      'Create',
+    );
+
+    return m('form', [
+      this.getForm(),
+      postButton,
+    ]);
+  }
+}
+
 export class UserModal {
   constructor() {
     this.edit = false;
diff --git a/src/views/editView.js b/src/views/editView.js
index 46d07d7f4c0dd6c40dffd7151e405481903ebe24..61805ac0516ea22b6667d50b3eae18f5caed53e8 100644
--- a/src/views/editView.js
+++ b/src/views/editView.js
@@ -16,7 +16,11 @@ export class EditView extends ItemView {
 
     // state for validation
     this.valid = valid;
-    this.ajv = new Ajv({ missingRefs: 'ignore' });
+    this.ajv = new Ajv({
+      missingRefs: 'ignore',
+      errorDataPath: 'property',
+      allErrors: true,
+    });
     this.errors = {};
 
     // callback when edit is finished
@@ -24,12 +28,14 @@ export class EditView extends ItemView {
   }
 
   oninit() {
-    // load data for item
-    getSession().then((apiSession) => {
-      this.loadItemData(apiSession);
-    }).catch(() => {
-      m.route.set('/login');
-    });
+    if (this.id) {
+      // load data for item
+      getSession().then((apiSession) => {
+        this.loadItemData(apiSession);
+      }).catch(() => {
+        m.route.set('/login');
+      });
+    }
     // load schema
     m.request('http://amiv-api.ethz.ch/docs/api-docs').then((schema) => {
       const objectSchema = schema.definitions[
@@ -52,15 +58,21 @@ export class EditView extends ItemView {
         // validate against schema
         const validate = this.ajv.getSchema('schema');
         this.valid = validate(this.data);
+        console.log(validate.schema);
 
-        // get errors of this field
-        let errors = [];
-        if (!this.valid) {
-          errors = validate.errors.filter(error =>
-            `.${e.target.name}` === error.dataPath);
-          errors = errors.map(error => error.message);
+        console.log(validate.errors);
+        if (this.valid) {
+          Object.keys(this.errors).forEach((field) => {
+            this.errors[field] = [];
+          });
+        } else {
+          // get errors for respective fields
+          Object.keys(this.errors).forEach((field) => {
+            const errors = validate.errors.filter(error =>
+              `.${field}` === error.dataPath);
+            this.errors[field] = errors.map(error => error.message);
+          });
         }
-        this.errors[e.target.name] = errors;
       },
       getErrors: () => this.errors[attrs.name],
       value: this.data[attrs.name],
@@ -71,7 +83,7 @@ export class EditView extends ItemView {
     return boundFormelement;
   }
 
-  patchOnClick(patchableFields) {
+  patchOnClick(patchableFields, callback) {
     return {
       onclick: () => {
         if (this.changed) {
@@ -85,14 +97,32 @@ export class EditView extends ItemView {
 
             apiSession.patch(`${this.resource}/${this.id}`, patchData, {
               headers: { 'If-Match': this.data._etag },
-            }).then(() => { this.callback(); });
+            }).then(() => { callback(); });
           });
         } else {
-          this.callback();
+          callback();
         }
       },
     };
   }
+
+  createOnClick(fields, callback) {
+    return {
+      onclick: () => {
+        getSession().then((apiSession) => {
+          // fields like `_id` are not patchable and would lead to an error
+          // We therefore only send patchable fields
+          const postData = {};
+          fields.forEach((key) => {
+            postData[key] = this.data[key];
+          });
+
+          apiSession.post(this.resource, postData)
+            .then(response => { callback(response); });
+        });
+      },
+    };
+  }
 }
 
 export class inputGroup {
@@ -107,11 +137,12 @@ export class inputGroup {
   view(vnode) {
     // set display-settings accoridng to error-state
     let errorField = null;
-    const groupClasses = vnode.attrs.classes ? vnode.attrs.classes : [];
+    let groupClasses = vnode.attrs.classes ? vnode.attrs.classes : '';
+    console.log(groupClasses)
     const errors = this.getErrors();
     if (errors.length > 0) {
       errorField = m('span.help-block', `Error: ${errors.join(', ')}`);
-      groupClasses.push('has-error');
+      groupClasses += ' has-error';
     }
 
     return m('div.form-group', { class: groupClasses }, [