Index: TFP-WebServer/bin/Mods/Xample_MarkersMod/WebMod/bundle.js
===================================================================
--- TFP-WebServer/bin/Mods/Xample_MarkersMod/WebMod/bundle.js	(revision 485)
+++ TFP-WebServer/bin/Mods/Xample_MarkersMod/WebMod/bundle.js	(revision 487)
@@ -15,4 +15,5 @@
   LayersControl,
   Marker,
+  Tooltip,
   HideBasedOnAuth,
   L
@@ -45,5 +46,5 @@
               lng: y
             }
-          });
+          }, /*#__PURE__*/React.createElement(Tooltip, null, marker.name));
         });
         setMarkers(markerComponents);
@@ -82,5 +83,6 @@
     formState: {
       errors
-    }
+    },
+    setValue
   } = useForm();
   const {
@@ -91,4 +93,5 @@
     mutate: createMarker
   } = useMutation('createMarker', data => HTTP.post('/api/markers', {
+    name: data.name,
     x: parseInt(data.x, 10),
     y: parseInt(data.y, 10)
@@ -104,4 +107,5 @@
     mutate: updateMarker
   } = useMutation('updateMarker', data => HTTP.put(`/api/markers/${data.id}`, {
+    name: data.name,
     x: parseInt(data.x, 10),
     y: parseInt(data.y, 10),
@@ -114,63 +118,71 @@
     method: 'PUT'
   });
+  const canDeleteRows = checkPermission({
+    module: 'webapi.Markers',
+    method: 'DELETE'
+  });
   const columnDef = [{
     field: 'id',
     filter: 'agTextColumnFilter',
-    checkboxSelection: true,
-    width: 300,
-    flex: 0
+    flex: 1
+  }, {
+    field: 'name',
+    filter: 'agTextColumnFilter',
+    flex: 1
   }, {
     field: 'x',
     filter: 'agNumberColumnFilter',
-    editable: canEditRows,
-    cellEditorPopup: true,
-    width: 50,
-    flex: 0
+    flex: 0.25,
+    sort: 'asc'
   }, {
     field: 'y',
     filter: 'agNumberColumnFilter',
-    editable: canEditRows,
-    cellEditorPopup: true,
-    width: 50,
-    flex: 0
+    flex: 0.25,
+    sort: 'asc'
   }, {
     field: 'icon',
     filter: 'agTextColumnFilter',
-    editable: canEditRows,
-    cellEditorPopup: true,
     flex: 1
   }];
-  const CreateMarker = () => {
+  const Form = /*#__PURE__*/React.createElement(TfpForm, {
+    id: "markers-form",
+    error: errors
+  }, /*#__PURE__*/React.createElement(FormElements.StyledFormItem, null, /*#__PURE__*/React.createElement(FormElements.FormLabel, {
+    htmlFor: "input-id"
+  }, "ID"), /*#__PURE__*/React.createElement(FormElements.FormInput, _extends({
+    key: "id",
+    id: "input-id"
+  }, register('id'), {
+    disabled: true
+  }))), /*#__PURE__*/React.createElement(FormElements.StyledFormItem, null, /*#__PURE__*/React.createElement(FormElements.FormLabel, {
+    htmlFor: "input-name"
+  }, "Name"), /*#__PURE__*/React.createElement(FormElements.FormInput, _extends({
+    key: "name",
+    id: "input-name"
+  }, register('name')))), /*#__PURE__*/React.createElement(FormElements.StyledFormItem, null, /*#__PURE__*/React.createElement(FormElements.FormLabel, {
+    htmlFor: "input-x"
+  }, "X"), /*#__PURE__*/React.createElement(FormElements.FormInput, _extends({
+    key: "x",
+    id: "input-x"
+  }, register('x', {
+    required: true
+  })))), /*#__PURE__*/React.createElement(FormElements.StyledFormItem, null, /*#__PURE__*/React.createElement(FormElements.FormLabel, {
+    htmlFor: "input-y"
+  }, "Y"), /*#__PURE__*/React.createElement(FormElements.FormInput, _extends({
+    key: "y",
+    id: "input-y"
+  }, register('y', {
+    required: true
+  })))));
+  async function handleCreate(data) {
     if (!checkPermission({
       module: 'webapi.Markers',
       method: 'POST'
     })) {
-      return null;
-    }
-    return /*#__PURE__*/React.createElement(TfpForm, {
-      id: "markers-form",
-      handleSubmit: handleSubmit(createMarker),
-      error: errors
-    }, /*#__PURE__*/React.createElement(FormElements.StyledFormItem, null, /*#__PURE__*/React.createElement(FormElements.FormLabel, {
-      htmlFor: "input-x"
-    }, "X"), /*#__PURE__*/React.createElement(FormElements.FormInput, _extends({
-      key: "x",
-      id: "input-x"
-    }, register('x', {
-      required: true
-    })))), /*#__PURE__*/React.createElement(FormElements.StyledFormItem, null, /*#__PURE__*/React.createElement(FormElements.FormLabel, {
-      htmlFor: "input-y"
-    }, "Y"), /*#__PURE__*/React.createElement(FormElements.FormInput, _extends({
-      key: "y",
-      id: "input-y"
-    }, register('y', {
-      required: true
-    })))));
-  };
-  async function cellEdited({
-    data,
-    newValue,
-    column
-  }) {
+      return;
+    }
+    createMarker(data);
+  }
+  async function handleEdit(data) {
     if (!checkPermission({
       module: 'webapi.Markers',
@@ -179,9 +191,5 @@
       return;
     }
-    const changedField = column.colId;
-    updateMarker({
-      ...data,
-      [changedField]: newValue
-    });
+    updateMarker(data);
   }
   async function cellDeleted(row) {
@@ -194,4 +202,10 @@
     deleteMarker(row.id);
   }
+  const setDefaultValues = data => {
+    setValue('id', data.id);
+    setValue('name', data.name);
+    setValue('x', data.x);
+    setValue('y', data.y);
+  };
   return /*#__PURE__*/React.createElement("div", {
     style: {
@@ -199,11 +213,17 @@
       height: '80vh'
     }
-  }, /*#__PURE__*/React.createElement(CreateMarker, null), /*#__PURE__*/React.createElement(EditableTable, {
+  }, /*#__PURE__*/React.createElement(EditableTable, {
     columnDef: columnDef,
     rowData: data,
     reloadFn: refetch,
-    editRowFn: cellEdited,
     deleteRowFn: cellDeleted,
-    height: '90%'
+    canDeleteRows: canDeleteRows,
+    height: '90%',
+    editRowFn: handleSubmit(handleEdit),
+    editForm: Form,
+    setDefaultValues: setDefaultValues,
+    canEditRows: canEditRows,
+    canCreateRows: canEditRows,
+    createRowFn: handleSubmit(handleCreate)
   }));
 }
