diff --git a/bower.json b/bower.json
index 35aaa612a0a8e199d20f5dafffe38282a6180da4..8667a9f5d9573eaf9d9827aba29159d88ec4bd73 100644
--- a/bower.json
+++ b/bower.json
@@ -23,7 +23,8 @@
     "leaflet.loading": "Leaflet.loading#^0.1.24",
     "ui-leaflet": "^2.0.0",
     "leaflet.markercluster": "0.5",
-    "Leaflet.FeatureGroup.SubGroup": "0.1.2"
+    "Leaflet.FeatureGroup.SubGroup": "0.1.2",
+    "ion-digit-keyboard": "skol-pro/ion-digit-keyboard"
   },
   "resolutions": {
     "angular-sanitize": "1.5.3",
diff --git a/www/index.html b/www/index.html
index bf185d8ae82b9a3f14157cd1da6e80a828179352..083030e623203637c1be132939dc75d721820033 100644
--- a/www/index.html
+++ b/www/index.html
@@ -69,6 +69,7 @@
 <script src="lib/ionic/js/angular/angular-idle.js"></script>
 <script src="lib/ionic/js/angular/angular-simple-logger.light.js"></script>
 <script src="lib/ionic/js/angular/ui-leaflet.js"></script>
+<script src="lib/ion-digit-keyboard/dist/ion-digit-keyboard.min.js"></script>
 
 <!--removeIf(ubuntu)--> <!-- FIXME: issue #463 under ubuntu OS -->
 <script src="lib/ionic/js/angular/angular-chart.min.js"></script>
diff --git a/www/js/app.js b/www/js/app.js
index 7497c864ffc0d435937906477ab1d20984cc514f..ae3b11533a95fd58b83c51db4c8e0b2a817bd751 100644
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -5,7 +5,7 @@
 // the 2nd parameter is an array of 'requires'
 // 'starter.controllers' is found in controllers.js
 angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht.translate',
-  'ngApi', 'angular-cache', 'angular.screenmatch', 'angular.bind.notifier', 'ImageCropper',
+  'ngApi', 'angular-cache', 'angular.screenmatch', 'angular.bind.notifier', 'ImageCropper', 'ion-digit-keyboard',
   // removeIf(no-device)
   'ngCordova',
   // endRemoveIf(no-device)
diff --git a/www/js/services/device-services.js b/www/js/services/device-services.js
index f5198edc9b9598ef1525c62d9b55c6c0a390ec0e..5ffe61da021a01d0ac810b47b61d6980af32f2b1 100644
--- a/www/js/services/device-services.js
+++ b/www/js/services/device-services.js
@@ -2,7 +2,7 @@
 angular.module('cesium.device.services', ['cesium.utils.services', 'cesium.settings.services'])
 
   .factory('Device',
-    function($translate, $ionicPopup, $q,
+    function($rootScope, $translate, $ionicPopup, $q,
       // removeIf(no-device)
       $cordovaClipboard, $cordovaBarcodeScanner, $cordovaCamera,
       // endRemoveIf(no-device)
@@ -141,6 +141,63 @@ angular.module('cesium.device.services', ['cesium.utils.services', 'cesium.setti
         }
       };
 
+      // Numerical keyboard - fix #30
+      exports.keyboard.digit = {
+        settings: {
+          bindModel: function(modelScope, modelPath, settings) {
+            settings = settings || {};
+            modelScope = modelScope || $rootScope;
+            var getModelValue = function() {
+              return (modelPath||'').split('.').reduce(function(res, path) {
+                return res ? res[path] : undefined;
+              }, modelScope);
+            };
+            var setModelValue = function(value) {
+              var paths = (modelPath||'').split('.');
+              var property = paths.length && paths[paths.length-1];
+              paths.reduce(function(res, path) {
+                if (path == property) {
+                  res[property] = value;
+                  return;
+                }
+                return res[path];
+              }, modelScope);
+            };
+
+            settings.action = settings.action || function(number) {
+                setModelValue((getModelValue() ||'') + number);
+              };
+            if (settings.decimal) {
+              settings.decimalSeparator = settings.decimalSeparator || '.';
+              settings.leftButton = settings.leftButton = {
+                html: '<span>.</span>',
+                action: function () {
+                  var text = getModelValue() || '';
+                  // only one '.' allowed
+                  if (text.indexOf(settings.decimalSeparator) >= 0) return;
+                  // Auto add zero when started with '.'
+                  if (!text.trim().length) {
+                    text = '0';
+                  }
+                  setModelValue(text + settings.decimalSeparator);
+                }
+              };
+            }
+            settings.rightButton = settings.rightButton || {
+                html: '<i class="icon ion-backspace-outline"></i>',
+                action: function() {
+                  var text = getModelValue();
+                  if (text && text.length) {
+                    text = text.slice(0, -1);
+                    setModelValue(text);
+                  }
+                }
+              };
+            return settings;
+          }
+        }
+      };
+
       exports.isIOS = function() {
         return !!navigator.userAgent.match(/iPhone | iPad | iPod/i) || ionic.Platform.isIOS();
       };
diff --git a/www/js/services/http-services.js b/www/js/services/http-services.js
index 52561f25ac0176dc7fc71addd09e37ea15f99264..035d86ec764cec7fb5252961980ae443131e9d51 100644
--- a/www/js/services/http-services.js
+++ b/www/js/services/http-services.js
@@ -132,27 +132,7 @@ angular.module('cesium.http.services', ['cesium.cache.services'])
       return $q(function(resolve, reject) {
         var config = {
           timeout: forcedTimeout || timeout,
-          headers : {'Content-Type' : 'application/json;charset=UTF-8'},
-          eventHandlers: {
-            readystatechange: function(event) {
-              if(event.currentTarget.readyState === 4) {
-                console.log("readyState=4: Server has finished extra work!");
-              }
-            }
-          },
-
-          uploadEventHandlers: {
-            progress: function(e) {
-              if (e.lengthComputable) {
-                progress = Math.round(e.loaded * 100 / e.total);
-                console.log("progress: " + progress + "%");
-                if (e.loaded == e.total) {
-                  console.log("File upload finished!");
-                  console.log("Server will perform extra work now...");
-                }
-              }
-            }
-          }
+          headers : {'Content-Type' : 'application/json;charset=UTF-8'}
         };
 
         prepare(url, params, config, function(url, config) {