Ajout classe .std-focusbox.
[Plinn.git] / skins / ajax_scripts / ajax_form_manager.js
index d91c440..acca796 100644 (file)
@@ -1,4 +1,4 @@
-// (c) Benoît PIN 2006-2007
+// (c) Benoît PIN 2006-2014
 // http://plinn.org
 // Licence GPL
 // 
 // http://plinn.org
 // Licence GPL
 // 
@@ -8,16 +8,16 @@ var FormManager;
 
 (function(){
        
 
 (function(){
        
-FormManager = function(form, responseTextDest, lazy) {
+FormManager = function(form, responseTextDest, lazy, noHistory) {
        if (form.elements.namedItem("noAjax")) {return;}
        
        this.form = form;
        this.responseTextDest = responseTextDest;
        this.lazy = lazy;
        if (form.elements.namedItem("noAjax")) {return;}
        
        this.form = form;
        this.responseTextDest = responseTextDest;
        this.lazy = lazy;
+       this.noHistory = noHistory;
        var thisManager = this;
        this.form.onsubmit = function(evt) { thisManager.submit(evt); };
        this.form.onclick = function(evt) { thisManager.click(evt); };
        var thisManager = this;
        this.form.onsubmit = function(evt) { thisManager.submit(evt); };
        this.form.onclick = function(evt) { thisManager.click(evt); };
-       this.submitButton = null;
        
        /* raised on form submit */
        this.onBeforeSubmit = null;
        
        /* raised on form submit */
        this.onBeforeSubmit = null;
@@ -55,6 +55,7 @@ FormManager.prototype.submit = function(evt) {
                        if (onBeforeSubmit.length) {
                                onBeforeSubmit = onBeforeSubmit[0];
                        }
                        if (onBeforeSubmit.length) {
                                onBeforeSubmit = onBeforeSubmit[0];
                        }
+                       /*jslint evil: true */
                        this.onBeforeSubmit = eval(onBeforeSubmit.value);
                        bsMessage = this.onBeforeSubmit(thisManager, evt);
                }
                        this.onBeforeSubmit = eval(onBeforeSubmit.value);
                        bsMessage = this.onBeforeSubmit(thisManager, evt);
                }
@@ -99,7 +100,7 @@ FormManager.prototype.submit = function(evt) {
                query += submitButton.name + '=' + submitButton.value + '&';
        }
        
                query += submitButton.name + '=' + submitButton.value + '&';
        }
        
-       if (window.AJAX_CONFIG && (AJAX_CONFIG & 1 === 1)) {
+       if (window.AJAX_CONFIG && ((AJAX_CONFIG & 1) === 1)) {
                if (form.method.toLowerCase() === 'post') {
                        this._post(query);
                }
                if (form.method.toLowerCase() === 'post') {
                        this._post(query);
                }
@@ -175,10 +176,10 @@ FormManager.prototype.replaceElementByField = function(evt) {
                var tabIndex = ob.tabIndex;
                var text;
                if (ob.firstChild && ob.firstChild.className === 'hidden_value') {
                var tabIndex = ob.tabIndex;
                var text;
                if (ob.firstChild && ob.firstChild.className === 'hidden_value') {
-                   text = ob.firstChild.innerHTML;
+                       text = ob.firstChild.innerHTML;
                }
                else {
                }
                else {
-                   text = ob.innerHTML;
+                       text = ob.innerHTML;
                }
                disablePropagation(evt);
                var parent;
                }
                disablePropagation(evt);
                var parent;
@@ -391,19 +392,30 @@ FormManager.prototype.loadResponse = function(req) {
                                        return;
                                }
                                var fragments = req.responseXML.documentElement.childNodes;
                                        return;
                                }
                                var fragments = req.responseXML.documentElement.childNodes;
-                               var fragment, dest;
-                               var i;
-                               for (i=0 ; i<fragments.length ; i++) {
-                                       fragment = fragments[i];
-                                       if (fragment.nodeName === 'fragment') {
-                                               dest = document.getElementById(fragment.getAttribute('id'));
-                                               dest.innerHTML = fragment.firstChild.nodeValue;
-                       
-                                               scripts = dest.getElementsByTagName('script');
-                                               var j;
-                                               for (j=0 ; j < scripts.length ; j++) {
-                                                       globalScriptRegistry.loadScript(scripts[j]);
-                                               }
+                               var element, dest, i, j;
+                               for (i=0 ; i < fragments.length ; i++) {
+                                       element = fragments[i];
+                                       switch (element.nodeName) {
+                                               case 'fragment' :
+                                                       dest = document.getElementById(element.getAttribute('id'));
+                                                       if(dest) {
+                                                               dest.innerHTML = element.firstChild.nodeValue;
+                                                               scripts = dest.getElementsByTagName('script');
+                                                               for (j=0 ; j < scripts.length ; j++) {
+                                                                       globalScriptRegistry.loadScript(scripts[j]); }
+                                                       }
+                                                       break;
+                                               case 'base' :
+                                                       var headBase = document.getElementsByTagName('base');
+                                                       if (headBase.length > 0) {
+                                                               headBase[0].setAttribute('href', element.getAttribute('href'));
+                                                       }
+                                                       else {
+                                                               headBase = document.createElement('base');
+                                                               headBase.setAttribute('href', element.getAttribute('href'));
+                                                               document.head.appendChild(headBase);
+                                                       }
+                                                       break;
                                        }
                                }
                                break;
                                        }
                                }
                                break;
@@ -422,13 +434,19 @@ FormManager.prototype.loadResponse = function(req) {
        }
        
        var onAfterPopulate = this.onAfterPopulate;
        }
        
        var onAfterPopulate = this.onAfterPopulate;
-       if (typeof(onAfterPopulate) === "string") {
-               if (window.console) {
-                       console.warn('Deprecation WARNING onAfterPopulate: ' + onAfterPopulate);
-               }
-               onAfterPopulate = eval(onAfterPopulate);
-       }
        onAfterPopulate();
        onAfterPopulate();
+       this.scrollToPortalMessage();
+       var url = this.form.action;
+       if (!this.noHistory){ history.pushState(url, document.title, url); }
+};
+
+FormManager.prototype.scrollToPortalMessage = function() {
+       var psm = document.getElementById('DesktopStatusBar');
+       if (psm) {
+               var msgOffset = psm.offsetTop;
+               smoothScroll(window.scrollY, msgOffset);
+               shake(psm, 10, 1000);
+       }
 };
 
 FormManager.prototype._fitField = function(evt) {
 };
 
 FormManager.prototype._fitField = function(evt) {
@@ -450,4 +468,69 @@ function initForms(baseElement, lazy) {
        }
 }
 
        }
 }
 
+function smoothScroll(from, to) {
+       var intervalId;
+       var step = 25;
+       var pos = from;
+       var dir;
+       if (to > from) {
+               dir = 1;
+       }
+       else {
+               dir = -1;
+       }
+
+       var jump = function() {
+               window.scroll(0, pos);
+               pos = pos + step * dir;
+               if ((dir === 1 && pos >= to) ||
+                       (dir === -1 && pos <= to)) {
+                       window.clearInterval(intervalId);
+                       window.scroll(0, to);
+               }
+       };
+       intervalId = window.setInterval(jump, 10);
+}
+
+/* adapted from http://xahlee.info/js/js_shake_box.html */
+function shake(e, distance, time) {
+       // Handle arguments
+       if (!time) { time = 500; }
+       if (!distance) { distance = 5; }
+
+       // Save the original style of e, Make e relatively positioned, Note the animation start time, Start the animation
+       var originalStyle = e.style.cssText;
+       e.style.position = "relative";
+       var start = (new Date()).getTime();
+
+       // This function checks the elapsed time and updates the position of e.
+       // If the animation is complete, it restores e to its original state.
+       // Otherwise, it updates e's position and schedules itself to run again.
+       function animate() {
+               var now = (new Date()).getTime();
+               // Get current time
+               var elapsed = now-start;
+               // How long since we started
+               var fraction = elapsed/time;
+               // What fraction of total time?
+               if (fraction < 1) {
+                       // If the animation is not yet complete
+                       // Compute the x position of e as a function of animation
+                       // completion fraction. We use a sinusoidal function, and multiply
+                       // the completion fraction by 4pi, so that it shakes back and
+                       // forth twice.
+                       var x = distance * Math.sin(fraction*8*Math.PI);
+                       e.style.left = x + "px";
+                       // Try to run again in 25ms or at the end of the total time.
+                       // We're aiming for a smooth 40 frames/second animation.
+                       setTimeout(animate, Math.min(25, time-elapsed));
+               }
+               else {
+                       // Otherwise, the animation is complete
+                       e.style.cssText = originalStyle; // Restore the original style
+               }
+       }
+       animate();
+}
+
 }());
 }());