From aa7f4d5e55f9dafc4343b4038561aaaab07184de Mon Sep 17 00:00:00 2001
From: Hermann Blum <hermannsblum@yahoo.de>
Date: Fri, 1 Dec 2017 23:53:44 +0100
Subject: [PATCH] define more general active/inactive submit button

---
 src/userTool.js       | 40 +++++++++++-------------
 src/views/editView.js | 73 ++++++++++++++++++++++---------------------
 2 files changed, 56 insertions(+), 57 deletions(-)

diff --git a/src/userTool.js b/src/userTool.js
index f88584f..0e0f5dc 100644
--- a/src/userTool.js
+++ b/src/userTool.js
@@ -1,5 +1,5 @@
 import { ItemView } from './views/itemView';
-import { EditView, inputGroup, selectGroup } from './views/editView';
+import { EditView, inputGroup, selectGroup, submitButton } from './views/editView';
 import TableView from './views/tableView';
 
 const m = require('mithril');
@@ -105,18 +105,17 @@ class UserEdit extends EditView {
     // 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,
+      m(submitButton, {
+        active: this.valid,
+        args: {
+          onclick: this.submit('PATCH', [
+            'lastname', 'firstname', 'email', 'membership', 'gender']),
+          class: 'btn-warning',
+        },
+        text: 'Update',
+      }),
     ]);
   }
 }
@@ -135,18 +134,17 @@ export class NewUser extends UserEdit {
   }
 
   view() {
-    // UPDATE button is inactive if form is not valid
-    const buttonArgs = this.createOnClick([
-      'lastname', 'firstname', 'email', 'membership', 'gender']);
-    const postButton = m(
-      'div.btn.btn-warning',
-      this.valid ? buttonArgs : { disabled: 'disabled' },
-      'Create',
-    );
-
     return m('form', [
       this.getForm(),
-      postButton,
+      m(submitButton, {
+        active: this.valid,
+        args: {
+          onclick: this.submit('POST', [
+            'lastname', 'firstname', 'email', 'membership', 'gender']),
+          class: 'btn-warning',
+        },
+        text: 'Create',
+      }),
     ]);
   }
 }
diff --git a/src/views/editView.js b/src/views/editView.js
index 727a5f4..182659e 100644
--- a/src/views/editView.js
+++ b/src/views/editView.js
@@ -99,46 +99,37 @@ export class EditView extends ItemView {
     return boundFormelement;
   }
 
-  patchOnClick(patchableFields) {
-    return {
-      onclick: () => {
-        if (this.changed) {
-          getSession().then((apiSession) => {
-            // fields like `_id` are not patchable and would lead to an error
+  submit(method, fields) {
+    return () => {
+      if (this.changed) {
+        getSession().then((apiSession) => {
+          // build request
+          const request = { method };
+          if (method === 'POST' || method === 'PATCH') {
+            // fields like `_id` are not post/patchable
             // We therefore only send patchable fields
-            const patchData = {};
-            patchableFields.forEach((key) => {
-              patchData[key] = this.data[key];
-            });
-
-            apiSession.patch(`${this.resource}/${this.id}`, patchData, {
-              headers: { 'If-Match': this.data._etag },
-            }).then((response) => {
-              this.callback(response);
+            const submitData = {};
+            fields.forEach((key) => {
+              submitData[key] = this.data[key];
             });
+            request.data = submitData;
+          }
+
+          // if request is PATCH or DELETE, add If-Match header and set url
+          if (method === 'PATCH' || method === 'DELETE') {
+            request.headers = { 'If-Match': this.data._etag };
+            request.url = `${this.resource}/${this.id}`;
+          } else {
+            request.url = this.resource;
+          }
+
+          apiSession(request).then((response) => {
+            this.callback(response);
           });
-        } else {
-          this.callback();
-        }
-      },
-    };
-  }
-
-  createOnClick(fields) {
-    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) => { this.callback(response); });
         });
-      },
+      } else {
+        this.callback();
+      }
     };
   }
 }
@@ -184,3 +175,13 @@ export class selectGroup {
     ]);
   }
 }
+
+export class submitButton {
+  view(vnode) {
+    const args = vnode.attrs.args;
+    if (!vnode.attrs.active) {
+      args.disabled = 'disabled';
+    }
+    return m('div.btn', args, vnode.attrs.text);
+  }
+}
-- 
GitLab