]> dev.renevier.net Git - syp.git/blobdiff - js/admin.js
detects when server sends a bad formed html page
[syp.git] / js / admin.js
index e0a27ea58570c14b946ff4a84f6f7e85659f5e7d..85a28ddca09ee94712d9ba3e547bd01a6745a30f 100644 (file)
@@ -55,13 +55,11 @@ OpenLayers.Control.SypDragFeature = OpenLayers.Class (OpenLayers.Control.DragFea
 });
 
 var Admin = {
-    Settings: {
-        MARKER_ICON: "openlayers/img/marker-blue.png",
-        MARKER_ICON_HEIGHT: 25,
-        MARKER_SELECT_ICON: "openlayers/img/marker-green.png",
-        MARKER_SELECT_ICON_HEIGHT: 25,
-        MARKER_TEMPORARY_ICON: "openlayers/img/marker-gold.png",
-        MARKER_TEMPORARY_ICON_HEIGHT: 25
+    Markers: {
+        ICON: "media/marker-normal.png",
+        SELECT_ICON: "media/marker-selected.png",
+        TEMPORARY_ICON: "media/marker-temp.png",
+        HEIGHT: 25
     },
 
     map: null,
@@ -85,37 +83,14 @@ var Admin = {
          });
 
          this.baseLayer = this.createBaseLayer ();
-         this.dataLayer = this.createDataLayer ();
-         this.map.addLayers([this.baseLayer, this.dataLayer]);
-
-         // controls
-         this.selFeatureControl = this.createSelectFeatureControl();
-         this.map.addControl(this.selFeatureControl);
-         this.moveFeatureControl = this.createMoveFeatureControl();
-         this.map.addControl(this.moveFeatureControl);
-         this.addFeatureControl = this.createNewfeatureControl();
-         this.map.addControl(this.addFeatureControl);
-
-         // position
-         var centerBounds = new OpenLayers.Bounds();
-
-         var mapProj = this.map.getProjectionObject();
-         var sypOrigProj = new OpenLayers.Projection("EPSG:4326");
-
-         var bottomLeft = new OpenLayers.LonLat(sypOrig[0],sypOrig[1]);
-         bottomLeft = bottomLeft.transform(sypOrigProj, mapProj);
-         var topRight = new OpenLayers.LonLat(sypOrig[2],sypOrig[3])
-         topRight = topRight.transform(sypOrigProj, mapProj);
-
-         centerBounds.extend(bottomLeft);
-         centerBounds.extend(topRight);
-
-         // at that moment, ie does not know size of the map, we need to update
-         // manually
-         this.map.updateSize();
-         this.map.zoomToExtent(centerBounds);
-
-         this.reset();
+         this.map.addLayer(this.baseLayer);
+
+         this.map.setCenter(new OpenLayers.LonLat(0, 0), 0);
+         if (sypSettings.loggedUser) {
+            this.dataLayer = this.createDataLayer (sypSettings.loggedUser);
+            this.map.addLayer(this.dataLayer);
+            this.reset();
+         }
     },
 
     reset: function() {
@@ -133,47 +108,52 @@ var Admin = {
         return new OpenLayers.Layer.OSM("OSM");
     },
 
-    createDataLayer: function () {
+    createDataLayer: function (user) {
         var styleMap = new OpenLayers.StyleMap (
                         {"default": {
-                             externalGraphic: this.Settings.MARKER_ICON,
-                             graphicHeight: this.Settings.MARKER_ICON_HEIGHT
-                                                  || 32 
+                             externalGraphic: this.Markers.ICON,
+                             graphicHeight: this.Markers.HEIGHT || 32 
                                 },
                          "temporary": { 
-                             externalGraphic: this.Settings.MARKER_TEMPORARY_ICON,
-                             graphicHeight: this.Settings.MARKER_TEMPORARY_ICON_HEIGHT
-                                                  || 32 
+                             externalGraphic: this.Markers.TEMPORARY_ICON,
+                             graphicHeight: this.Markers.HEIGHT || 32 
                          },
                          "select": { 
-                             externalGraphic: this.Settings.MARKER_SELECT_ICON,
-                             graphicHeight: this.Settings.MARKER_SELECT_ICON_HEIGHT
-                                                  || 32 
+                             externalGraphic: this.Markers.SELECT_ICON,
+                             graphicHeight: this.Markers.HEIGHT || 32 
                     }});
 
-        var layer = new OpenLayers.Layer.GML("KML", "items.php", 
+        var layer = new OpenLayers.Layer.GML("KML", "items.php?from_user=" + encodeURIComponent(user),
            {
             styleMap: styleMap,
             format: OpenLayers.Format.KML, 
             projection: this.map.displayProjection,
             eventListeners: { scope: this,
-                loadend: this.checkForFeatures
+                loadend: this.dataLayerEndLoad
             }
        });
 
+        // controls
+        this.selFeatureControl = this.createSelectFeatureControl(layer)
+        this.map.addControl(this.selFeatureControl);
+        this.moveFeatureControl = this.createMoveFeatureControl(layer)
+        this.map.addControl(this.moveFeatureControl);
+        this.addFeatureControl = this.createNewfeatureControl();
+        this.map.addControl(this.addFeatureControl);
+
         return layer;
     },
 
-    createMoveFeatureControl: function () {
+    createMoveFeatureControl: function (layer) {
         var control = new OpenLayers.Control.SypDragFeature(
-                this.dataLayer, {
+                layer, {
                          });
         return control;
     },
 
-    createSelectFeatureControl: function () {
+    createSelectFeatureControl: function (layer) {
         var control = new OpenLayers.Control.SelectFeature(
-                this.dataLayer, {
+                layer, {
                         onSelect: OpenLayers.Function.bind(this.onFeatureSelect, this)
                          });
         return control;
@@ -196,6 +176,9 @@ var Admin = {
     },
 
     closeEditor: function() {
+        if ($("#editor").css("display") == "none") {
+            return;
+        }
         if (this.currentFeature && this.currentFeature.layer) {
             this.selFeatureControl.unselect(this.currentFeature);
         }
@@ -216,6 +199,8 @@ var Admin = {
 
     showEditor: function (feature) {
         $("#newfeature_button").hide();
+        userMgr.close();
+
         if (feature.fid) {
             $("#delete").show();
         } else {
@@ -248,13 +233,43 @@ var Admin = {
         $("#title").select().focus(); 
     },
 
+    dataLayerEndLoad: function() {
+        // only set zoom extent once
+        this.dataLayer.events.unregister('loadend', this, this.dataLayerEndLoad);
+        this.dataLayer.events.register('loadend', this, this.checkForFeatures);
+
+        if (!this.checkForFeatures()) {
+            return;
+        }
+
+        var map = this.map;
+        var orig = this.Utils.mbr (this.dataLayer);
+        var centerBounds = new OpenLayers.Bounds();
+
+        var mapProj = map.getProjectionObject();
+        var sypOrigProj = new OpenLayers.Projection("EPSG:4326");
+
+        var bottomLeft = new OpenLayers.LonLat(orig[0],orig[1]);
+        bottomLeft = bottomLeft.transform(sypOrigProj, mapProj);
+        var topRight = new OpenLayers.LonLat(orig[2],orig[3])
+        topRight = topRight.transform(sypOrigProj, mapProj);
+
+        centerBounds.extend(bottomLeft);
+        centerBounds.extend(topRight);
+        map.zoomToExtent(centerBounds);
+    },
+
     checkForFeatures: function () {
-        if (this.dataLayer.features.length != 0) {
+        var features = this.dataLayer.features;
+        if (features.length != 0) {
             $("#instructions").text(SypStrings.SelectHowto);
         }
+        return !!features.length;
     },
 
     addNewFeature: function () {
+        userMgr.close();
+
         function cancel() {
             $(document).unbind("keydown");
             Admin.reset()
@@ -277,15 +292,18 @@ var Admin = {
 
     cancelCurrentFeature: function() {
         if (AjaxMgr.running) {
-            return;
+            return false;
         }
         var feature = this.currentFeature;
-        if (feature.fid) {
-            FeatureMgr.move (feature, this.currentFeatureLocation);
-        } else {
-            this.dataLayer.removeFeatures([feature]);
+        if (feature) {
+            if (feature.fid) {
+                FeatureMgr.move (feature, this.currentFeatureLocation);
+            } else {
+                this.dataLayer.removeFeatures([feature]);
+            }
         }
         this.closeEditor();
+        return true;
     },
 
     reloadLayer: function (layer) {
@@ -295,6 +313,59 @@ var Admin = {
     },
 
     Utils: {
+        /* minimum bounds rectangle containing all feature locations.
+         * FIXME: if two features are close, but separated by 180th meridian,
+         * their mbr will span the whole earth. Actually, 179° lon and -170°
+         * lon are considerated very near.
+         */
+        mbr: function (layer) {
+            var features = [];
+            var map = layer.map;
+
+            var mapProj = map.getProjectionObject();
+            var sypOrigProj = new OpenLayers.Projection("EPSG:4326");
+
+            for (var i =0; i < layer.features.length; i++) {
+                if (layer.features[i].cluster) {
+                    features = features.concat(layer.features[i].cluster);
+                } else {
+                    features = features.concat(layer.features);
+                }
+            }
+
+            var minlon = 180;
+            var minlat = 88;
+            var maxlon = -180;
+            var maxlat = -88;
+
+            if (features.length == 0) {
+                // keep default values
+            } else if (features.length == 1) {
+                // in case there's only one feature, we show an area of at least 
+                // 4 x 4 degrees
+                var pos = features[0].geometry.getBounds().getCenterLonLat().clone();
+                var lonlat = pos.transform(mapProj, sypOrigProj);
+
+                minlon = Math.max (lonlat.lon - 2, -180);
+                maxlon = Math.min (lonlat.lon + 2, 180);
+                minlat = Math.max (lonlat.lat - 2, -90);
+                maxlat = Math.min (lonlat.lat + 2, 90);
+            } else {
+                for (var i = 0; i < features.length; i++) {
+                    var pos = features[i].geometry.getBounds().getCenterLonLat().clone();
+                    var lonlat = pos.transform(mapProj, sypOrigProj);
+                    minlon = Math.min (lonlat.lon, minlon);
+                    minlat = Math.min (lonlat.lat, minlat);
+                    maxlon = Math.max (lonlat.lon, maxlon);
+                    maxlat = Math.max (lonlat.lat, maxlat);
+                }
+            }
+
+            return [minlon, minlat, maxlon, maxlat];
+
+        },
+
+
         escapeHTML: function (str) {
             if (!str) {
                 return "";
@@ -362,7 +433,8 @@ var FeatureMgr = {
         form.find('input[name="fid"]').val(feature.fid);
         AjaxMgr.add({
             form: form,
-            oncomplete: OpenLayers.Function.bind(this.ajaxReply, this)
+            oncomplete: OpenLayers.Function.bind(this.ajaxReply, this),
+            throbberid: "editor_throbber"
         });
     },
 
@@ -389,7 +461,8 @@ var FeatureMgr = {
         }
         AjaxMgr.add({
             form: form,
-            oncomplete: OpenLayers.Function.bind(this.ajaxReply, this)
+            oncomplete: OpenLayers.Function.bind(this.ajaxReply, this),
+            throbberid: "editor_throbber"
         });
     },
 
@@ -400,14 +473,22 @@ var FeatureMgr = {
         }
 
         var xml = new OpenLayers.Format.XML().read(data);
+        if (!xml.documentElement) {
+            this.commError(SypStrings.UnconsistentError);
+            $("title").focus();
+            return;
+        }
 
         switch (xml.documentElement.nodeName.toLowerCase()) {
             case "error":
                 switch (xml.documentElement.getAttribute("reason")) {
                     case "unauthorized":
-                        $("#login_area").show();
+                        pwdMgr.reset();
+                        $("#cookie_warning").show();
                         this.reset();
+                        Admin.cancelCurrentFeature();
                         Admin.reset();
+                        userMgr.uninit();
                     break;
                     case "server":
                         this.commError(SypStrings.ServerError);
@@ -437,7 +518,7 @@ var FeatureMgr = {
                         $("#image_file").focus();
                     break;
                     default:
-                        this.commError(SypStrings.UnknownError);
+                        this.commError(SypStrings.UnconsistentError);
                         $("title").focus();
                     break;
                 }
@@ -523,12 +604,12 @@ var FeatureMgr = {
 
     commSuccess: function (message) {
         $("#server_comm").text(message);
-        $("#server_comm").removeClass().addClass("success");
+        $("#server_comm").removeClass("error success").addClass("success");
     },
 
     commError: function (message) {
         $("#server_comm").text(message);
-        $("#server_comm").removeClass().addClass("error");
+        $("#server_comm").removeClass("error success").addClass("error");
     }
 }
 
@@ -553,6 +634,9 @@ var AjaxMgr = {
         $('#api_frame').one("load", function() {
             self.running = false;
             self._reqEnd();
+            if (query.throbberid) {
+                $("#" + query.throbberid).css("visibility", "hidden");
+            }
             if (typeof (query.oncomplete) == "function") {
                 var body = null;
                 try {
@@ -576,6 +660,9 @@ var AjaxMgr = {
         query.form.attr("method", "post");
         this.running = true;
         query.form.get(0).submit();
+        if (query.throbberid) {
+            $("#" + query.throbberid).css("visibility", "visible");
+        }
         if (typeof (query.onsend) == "function") {
             query.onsend();
         }
@@ -593,11 +680,14 @@ var pwdMgr = {
 
     init: function () {
         $("#login_form").submit(this.submit);
-        $("#password").focus().select();
+        $("#user").focus().select();
     },
 
     reset: function() {
         this.commError ("");
+        $("#login_area").show();
+        $("#password").val("");
+        $("#user").val(sypSettings.loggedUser).focus().select();
     },
 
     submit: function () {
@@ -605,16 +695,16 @@ var pwdMgr = {
             pwdMgr.commError("");
             var req = {
                 form:  $("#login_form"),
+                throbberid: "pwd_throbber",
                 onsend: function() {
-                    $("#pwd_throbber").css("visibility", "visible");
                     $("#login_error").hide();
 
                     // we need a timeout; otherwise those fields will not be submitted
                     window.setTimeout(function() { 
                             // removes focus from #password before disabling it. Otherwise, opera
                             // prevents re-focusing it after re-enabling it.
-                            $("#password").blur(); 
-                            $("#login_submit, #password").attr("disabled", "disabled");
+                            $("#user, #password").blur(); 
+                            $("#login_submit, #user, #password").attr("disabled", "disabled");
                     }, 0)
                 },
                 oncomplete: OpenLayers.Function.bind(pwdMgr.ajaxReply, pwdMgr)
@@ -625,22 +715,28 @@ var pwdMgr = {
     },
 
     ajaxReply: function (data) {
-
-        $("#pwd_throbber").css("visibility", "hidden");
         // here, we need a timeout because onsend timeout sometimes has not been triggered yet
         window.setTimeout(function() {
-            $("#login_submit, #password").removeAttr("disabled");
+            $("#login_submit, #user, #password").removeAttr("disabled");
         }, 0);
 
         if (!data) {
             this.commError(SypStrings.ServerError);
             $("#login_error").show();
             window.setTimeout(function() {
-                    $("#password").focus().select();
+                    $("#user").focus().select();
             }, 0);
             return;
         }
+
         var xml = new OpenLayers.Format.XML().read(data);
+        if (!xml.documentElement) {
+            this.commError(SypStrings.UnconsistentError);
+            $("#login_error").show();
+            window.setTimeout(function() {
+                    $("#user").focus().select();
+            }, 0);
+        }
 
         switch (xml.documentElement.nodeName.toLowerCase()) {
             case "error":
@@ -655,17 +751,41 @@ var pwdMgr = {
                         this.commError(SypStrings.RequestError);
                     break;
                     default:
-                        this.commError(SypStrings.UnknownError);
+                        this.commError(SypStrings.UnconsistentError);
                     break;
                 }
                 $("#login_error").show();
                 window.setTimeout(function() {
-                        $("#password").focus().select();
+                        $("#user").focus().select();
                 }, 0);
             break;
             case "success":
-                this.reset();
                 $("#login_area").hide();
+
+                user = $(xml).find("USER,user").text();
+                sypSettings.loggedUser = user;
+
+                if (sypSettings.loggedUser == "admin")  {
+                    userMgr.init();
+                }
+
+                if (Admin.selFeatureControl) {
+                    Admin.selFeatureControl.destroy();
+                }
+                if (Admin.moveFeatureControl) {
+                    Admin.moveFeatureControl.destroy();
+                }
+                if (Admin.addFeatureControl) {
+                    Admin.addFeatureControl.destroy();
+                }
+                if (Admin.dataLayer) {
+                    Admin.dataLayer.destroy();
+                }
+
+                Admin.dataLayer = Admin.createDataLayer(user);
+                Admin.map.addLayer(Admin.dataLayer);
+                Admin.reset();
+
             break;
             default:
                 this.commError(SypStrings.UnconsistentError);
@@ -683,6 +803,347 @@ var pwdMgr = {
     }
 }
 
+var userMgr = {
+    _adduserDisplayed: false,
+    _changepassDisplayed: false,
+
+    init: function() {
+        $("#user_close").unbind("click").click(function () {
+            userMgr.close()
+        });
+
+        $("#change_pass").unbind("click").click(function() {
+            userMgr.toggleChangePass();
+            return false;
+        });
+        $("#changepass").unbind("submit").submit(function() {
+            try {
+                userMgr.changepass();
+            } catch(e) {}
+            return false;
+        });
+
+        if (sypSettings.loggedUser != "admin") {
+            return;
+        }
+
+        $("#add_user").show();
+        $("#add_user").unbind("click").click(function () {
+            userMgr.toggleAddUser();
+            return false;
+        });
+        $("#newuser").unbind("submit").submit(function() {
+            try {
+                userMgr.add();
+            } catch(e) {}
+            return false;
+        });
+
+    },
+
+    disableForms: function() {
+        $("#newuser_name, #newuser_password, #newuser_password_confirm, #newuser_submit").attr("disabled", "disabled");
+        $("#pass_current, #pass_new, #pass_new_confirm, #pass_submit").attr("disabled", "disabled");
+    },
+
+    enableForms: function() {
+        $("#newuser_name, #newuser_password, #newuser_password_confirm, #newuser_submit").removeAttr("disabled");
+        $("#pass_current, #pass_new, #pass_new_confirm, #pass_submit").removeAttr("disabled");
+    },
+
+    resetForms: function() {
+        $("#newuser_name, #newuser_password, #newuser_password_confirm").val("");
+        $("#pass_current, #pass_new, #pass_new_confirm").val("");
+    },
+
+    uninit: function() {
+        this.close();
+        $("#add_user").unbind("click");
+        $("#add_user").hide();
+        $("#change_pass").unbind("click");
+        $("#user_close").unbind("click");
+        $("#newuser").unbind("submit");
+        $("#changepass").unbind("submit");
+    },
+
+    close: function() {
+        this.closeChangePass();
+        this.closeAddUser();
+    },
+
+    toggleChangePass: function() {
+        if (this._changepassDisplayed) {
+            this.closeChangePass();
+        } else {
+            this.showChangePass();
+        }
+    },
+
+    showChangePass: function() {
+        if (!Admin.cancelCurrentFeature()) {
+            return;
+        }
+        this.closeAddUser();
+
+        $(document).unbind("keydown").keydown(function(e) { 
+            if (e.keyCode == 27) {
+                userMgr.closeChangePass()
+                e.preventDefault();
+            }
+        });
+
+        this.resetForms();
+        this.enableForms();
+        $("#user_area, #changepass").show();
+        this.commError("");
+
+        // XXX: setTimeout needed because otherwise, map becomes hidden in IE. Why ??
+        window.setTimeout(function() { 
+            $("#pass_current").focus();
+        }, 0);
+
+        this._changepassDisplayed = true;
+    },
+
+    closeChangePass: function() {
+        if (!this._changepassDisplayed) {
+            return;
+        }
+        $("#user_area, #changepass").hide();
+        $(document).unbind("keydown");
+        this._changepassDisplayed = false;
+    },
+
+    changepass: function() {
+        var newpass = $("#pass_new").val();
+        var newpass_confirm = $("#pass_new_confirm").val();
+        if (newpass != newpass_confirm) {
+            this.commError(SypStrings.userPasswordmatchError);
+            $("#pass_new").focus().select();
+            return;
+        }
+
+        var curpass = $("#pass_current").val();
+        if (newpass == curpass) {
+            this.commError(SypStrings.changeSamePass);
+            $("#pass_new").focus().select();
+            return;
+        }
+
+        this.commError("");
+
+        AjaxMgr.add({
+            form: $("#changepass"),
+            oncomplete: OpenLayers.Function.bind(this.ajaxReply, this),
+            throbberid: "user_throbber",
+            onsend: function() { 
+                // we need a timeout; otherwise those fields will not be submitted
+                window.setTimeout(function() {
+                    // removes focus from #password before disabling it. Otherwise, opera
+                    // prevents re-focusing it after re-enabling it.
+                    $("#pass_current, #pass_new, #pass_new_confirm").blur(); 
+                    userMgr.disableForms();
+                }, 0);
+            }
+        });
+    },
+
+    toggleAddUser: function() {
+        if (this._adduserDisplayed) {
+            this.closeAddUser();
+        } else {
+            this.showAddUser();
+        }
+    },
+
+    showAddUser: function() {
+        if (!Admin.cancelCurrentFeature()) {
+            return;
+        }
+
+        this.closeChangePass();
+
+        $(document).unbind("keydown").keydown(function(e) { 
+            if (e.keyCode == 27) {
+                userMgr.closeAddUser()
+                e.preventDefault();
+            }
+        });
+
+        $("#user_area, #newuser").show();
+        this.resetForms();
+        this.enableForms();
+        this.commError("");
+
+        // XXX: setTimeout needed because otherwise, map becomes hidden in IE. Why ??
+        window.setTimeout(function() { 
+            $("#newuser_name").focus();
+        }, 0);
+
+        this._adduserDisplayed = true;
+    },
+
+    closeAddUser: function() {
+        if (!this._adduserDisplayed) {
+            return;
+        }
+        $("#user_area, #newuser").hide();
+        $(document).unbind("keydown");
+        this._adduserDisplayed = false;
+    },
+
+    add: function() {
+        var newuser_name = $("#newuser_name").val();
+        if (!newuser_name) {
+            this.commError(SypStrings.newUserNonameError);
+            $("#newuser_name").focus();
+            return;
+        }
+
+        var newuser_pass = $("#newuser_password").val();
+        var newuser_pass_confirm = $("#newuser_password_confirm").val();
+        if (newuser_pass != newuser_pass_confirm) {
+            this.commError(SypStrings.userPasswordmatchError);
+            $("#newuser_password").focus().select();
+            return;
+        }
+
+        this.commError("");
+
+        AjaxMgr.add({
+            form: $("#newuser"),
+            oncomplete: OpenLayers.Function.bind(this.ajaxReply, this),
+            throbberid: "user_throbber",
+            onsend: function() { 
+                // we need a timeout; otherwise those fields will not be submitted
+                window.setTimeout(function() {
+                    // removes focus from #password before disabling it. Otherwise, opera
+                    // prevents re-focusing it after re-enabling it.
+                    $("#newuser_name, #newuser_password, #newuser_password_confirm").blur(); 
+                    userMgr.disableForms();
+                }, 0);
+            }
+        });
+    },
+
+    ajaxReply: function (data) {
+        if (!data) {
+            // here, we need a timeout because onsend timeout sometimes has not been triggered yet
+            var self = this;
+            window.setTimeout(function() {
+                self.enableForms();
+             }, 0);
+            this.commError(SypStrings.ServerError);
+            return;
+        }
+
+        var xml = new OpenLayers.Format.XML().read(data);
+        if (!xml.documentElement) {
+            // here, we need a timeout because onsend timeout sometimes has not been triggered yet
+            var self = this;
+            window.setTimeout(function() {
+                self.enableForms();
+             }, 0);
+            this.commError(SypStrings.UnconsistentError);
+            return;
+        }
+
+        var needFormEnabling = true;
+        var focusEl = null;
+
+        switch (xml.documentElement.nodeName.toLowerCase()) {
+            case "error":
+                switch (xml.documentElement.getAttribute("reason")) {
+                    case "unauthorized":
+                        pwdMgr.reset();
+                        $("#cookie_warning").show();
+                        Admin.reset();
+                        this.uninit();
+                    break;
+                    case "server":
+                        this.commError(SypStrings.ServerError);
+                        if (this._adduserDisplayed) {
+                            focusEl = $("#newuser_name");
+                        } else if (this._changepassDisplayed) {
+                            focusEl = $("#pass_current");
+                        }
+                    break;
+                    case "request":
+                        this.commError(SypStrings.RequestError);
+                        if (this._adduserDisplayed) {
+                            focusEl = $("#newuser_name");
+                        } else if (this._changepassDisplayed) {
+                            focusEl = $("#pass_current");
+                        }
+                    break;
+                    case "wrongpass":
+                        this.commError(SypStrings.changePassBadPass);
+                        focusEl = $("#pass_current");
+                    break;
+                    case "newuser_exists":
+                        this.commError(SypStrings.newUserExistsError);
+                        focusEl = $("#newuser_name");
+                    break;
+                    default:
+                        this.commError(SypStrings.UnconsistentError);
+                        if (this._adduserDisplayed) {
+                            focusEl = $("#newuser_name");
+                        } else if (this._changepassDisplayed) {
+                            focusEl = $("#pass_current");
+                        }
+                    break;
+                }
+            break;
+            case "success":
+                switch (xml.documentElement.getAttribute("request")) {
+                    case "newuser":
+                        this.commSuccess(SypStrings.newUserSuccess);
+                        needFormEnabling = false;
+                    break;
+                    case "changepass":
+                        this.commSuccess(SypStrings.changePassSuccess);
+                        needFormEnabling = false;
+                    break;
+                    default:
+                        this.commError(SypStrings.UnconsistentError);
+                        focusEl = $("newuser_name");
+                    break;
+                }
+            break;
+            default:
+                this.commError(SypStrings.UnconsistentError);
+                focusEl = $("newuser_name");
+            break;
+        }
+
+        if (needFormEnabling) {
+            // here, we need a timeout because onsend timeout sometimes has not been triggered yet
+            var self = this;
+            window.setTimeout(function() {
+                self.enableForms();
+                if (focusEl) {
+                    focusEl.select().focus();
+                }
+             }, 0);
+        } else {
+            if (focusEl) {
+                focusEl.focus().select();
+            }
+        }
+
+    },
+
+    commSuccess: function (message) {
+        $("#user_comm").text(message);
+        $("#user_comm").removeClass("error success").addClass("success");
+    },
+
+    commError: function (message) {
+        $("#user_comm").text(message);
+        $("#user_comm").removeClass("error success").addClass("error");
+    }
+}
+
 $(window).load(function () {
     // if using .ready, ie triggers an error when trying to access
     // document.namespaces
@@ -715,5 +1176,6 @@ $(window).load(function () {
             $("#image_file").parent().show();
     });
 
+    userMgr.init();
     Admin.init();
 });