X-Git-Url: https://scm.cri.ensmp.fr/git/Plinn.git/blobdiff_plain/3e0a2c257d49fb162da9c70d2f70194036235166..8f40b26abe44b2589a48b70865a1d4260f041ed4:/skins/ajax_scripts/ajax_form_manager.js

diff --git a/skins/ajax_scripts/ajax_form_manager.js b/skins/ajax_scripts/ajax_form_manager.js
index 9caf6e4..508a4f9 100644
--- a/skins/ajax_scripts/ajax_form_manager.js
+++ b/skins/ajax_scripts/ajax_form_manager.js
@@ -1,12 +1,15 @@
 // (c) Benoît PIN 2006-2007
 // http://plinn.org
 // Licence GPL
-// $Id: ajax_form_manager.js 1470 2009-02-18 16:42:02Z pin $
-// $URL: http://svn.cri.ensmp.fr/svn/Plinn/branches/CMF-2.1/skins/ajax_scripts/ajax_form_manager.js $
+// 
+// 
 
+var FormManager;
 
-function FormManager(form, responseTextDest, lazy) {
-	if (form.elements.namedItem("noAjax")) return;
+(function(){
+	
+FormManager = function(form, responseTextDest, lazy) {
+	if (form.elements.namedItem("noAjax")) {return;}
 	
 	this.form = form;
 	this.responseTextDest = responseTextDest;
@@ -14,7 +17,6 @@ function FormManager(form, responseTextDest, lazy) {
 	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;
@@ -26,21 +28,20 @@ function FormManager(form, responseTextDest, lazy) {
 	this.submitButton = null;
 	
 	if (this.lazy) {
-		this.fieldTagName;
-		this.liveFormField;
-		this.pendingEvent;
 		this.form.onclick = function(evt){
 			thisManager.replaceElementByField(evt);
 			thisManager.click(evt);
 		};
-		if (browser.isDOM2Event)
+		if (browser.isDOM2Event) {
 			this.form.onfocus = this.form.onclick;
-		else if (browser.isIE6up)
+		}
+		else if (browser.isIE6up) {
 			this.form.onfocusin = this.form.onclick;
+		}
 		this.onResponseLoad = function(req){ thisManager.restoreField(req); };
-		this.lazyListeners = new Array();
+		this.lazyListeners = [];
 	}
-}
+};
 	
 FormManager.prototype.submit = function(evt) {
 	var form = this.form;
@@ -50,16 +51,19 @@ FormManager.prototype.submit = function(evt) {
 	if (!this.onBeforeSubmit) {
 		var onBeforeSubmit = form.elements.namedItem("onBeforeSubmit");
 		if (onBeforeSubmit) {
-			if (onBeforeSubmit.length)
+			if (onBeforeSubmit.length) {
 				onBeforeSubmit = onBeforeSubmit[0];
+			}
+			/*jslint evil: true */
 			this.onBeforeSubmit = eval(onBeforeSubmit.value);
 			bsMessage = this.onBeforeSubmit(thisManager, evt);
 		}
 	}
-	else
+	else {
 		bsMessage = this.onBeforeSubmit(thisManager, evt);
+	}
 	
-	if (bsMessage == 'cancelSubmit') {
+	if (bsMessage === 'cancelSubmit') {
 		try {disableDefault(evt);}
 		catch (e){}
 		return;
@@ -67,41 +71,48 @@ FormManager.prototype.submit = function(evt) {
 
 	if (!this.onResponseLoad) {
 		var onResponseLoad = form.elements.namedItem("onResponseLoad");
-		if (onResponseLoad)
+		if (onResponseLoad) {
 			this.onResponseLoad = eval(onResponseLoad.value);
-		else
+		}
+		else {
 			this.onResponseLoad = this.loadResponse;
+		}
 	}
 
 	var submitButton = this.submitButton;
 	var queryInfo = this.formData2QueryString();
-	var query = queryInfo['query'];
-	this.hasFile = queryInfo['hasFile'];
+	var query = queryInfo.query;
+	this.hasFile = queryInfo.hasFile;
 	
 	
 	if (!this.onAfterPopulate) {
 		var onAfterPopulate = form.elements.namedItem("onAfterPopulate");
-		if (onAfterPopulate)
+		if (onAfterPopulate) {
 			this.onAfterPopulate = onAfterPopulate.value;
-		else
+		}
+		else {
 			this.onAfterPopulate = function() {};
+		}
 	}
 	
 	if (submitButton) {
 		query += submitButton.name + '=' + submitButton.value + '&';
 	}
 	
-	if (window.AJAX_CONFIG && (AJAX_CONFIG & 1 == 1)) {
-		if (form.method.toLowerCase() == 'post')
+	if (window.AJAX_CONFIG && ((AJAX_CONFIG & 1) === 1)) {
+		if (form.method.toLowerCase() === 'post') {
 			this._post(query);
-		else
-			this._get(query)
+		}
+		else {
+			this._get(query);
+		}
 	}
-	else
+	else {
 		this._post(query);
+	}
 	
 	try {disableDefault(evt);}
-	catch (e){}
+	catch (e2){}
 };
 
 FormManager.prototype._post = function(query) {
@@ -117,11 +128,14 @@ FormManager.prototype._post = function(query) {
 				break;
 			case 4 :
 				hideProgressImage();
-				if (req.status == 200 || req.status == 204)
+				if (req.status === 200 || req.status === 204) {
 					thisManager.onResponseLoad(req);
-				else
+				}
+				else {
 					alert('Error: ' + req.status);
-		};
+				}
+				break;
+		}
 	};
 	var url = this.form.action;
 	req.open("POST", url, true);
@@ -132,14 +146,14 @@ FormManager.prototype._post = function(query) {
 FormManager.prototype._get = function(query) {
 	// send form by browser location
 	var url = this.form.action;
-	url += '?' + query
+	url += '?' + query;
 	linkHandler.loadUrl(url);
 };
 
 
 FormManager.prototype.click = function(evt) {
 	var target = getTargetedObject(evt);
-	if(target.type == "submit" || target.type == "image") {
+	if(target.type === "submit" || target.type === "image") {
 		this.submitButton = target;
 		disablePropagation(evt);
 	}
@@ -149,9 +163,10 @@ FormManager.prototype.replaceElementByField = function(evt) {
 	evt = getEventObject(evt);
 	var ob = getTargetedObject(evt);
 	var eventType = evt.type;
-	if (eventType == 'focus' || eventType == 'focusin') {
-		if (this.liveFormField && ob.tagName != 'INPUT')
+	if (eventType === 'focus' || eventType === 'focusin') {
+		if (this.liveFormField && ob.tagName !== 'INPUT') {
 			this.pendingEvent = [ob, 'click'];
+		}
 		return;
 	}
 	var fieldName = ob.getAttribute('id');
@@ -159,11 +174,15 @@ FormManager.prototype.replaceElementByField = function(evt) {
 		this.fieldTagName = ob.tagName;
 		var tabIndex = ob.tabIndex;
 		var text;
-		if (ob.firstChild && ob.firstChild.className == 'hidden_value')
+		if (ob.firstChild && ob.firstChild.className === 'hidden_value') {
 		    text = ob.firstChild.innerHTML;
-		else
+		}
+		else {
 		    text = ob.innerHTML;
+		}
 		disablePropagation(evt);
+		var parent;
+		thisManager = this;
 		switch (ob.tagName) {
 			case 'SPAN' :
 				// create input element
@@ -180,7 +199,7 @@ FormManager.prototype.replaceElementByField = function(evt) {
 				//inputText.setAttribute("size", text.length);
 
 				// replacement
-				var parent = ob.parentNode;
+				parent = ob.parentNode;
 				parent.replaceChild(inputText, ob);
 
 				inputText.focus();
@@ -189,7 +208,6 @@ FormManager.prototype.replaceElementByField = function(evt) {
 				inputText.tabIndex = tabIndex;
 				inputText.className = 'live_field';
 				this.liveFormField = inputText;
-				var thisManager = this;
 				this.lazyListeners.push({'element': inputText, 'eventName' : 'blur', 'handler': function(){ thisManager.submit();}});
 				this.lazyListeners.push({'element': inputText, 'eventName' : 'keypress', 'handler': function(evt){ thisManager._fitField(evt);}});
 				this._addLazyListeners();
@@ -206,7 +224,7 @@ FormManager.prototype.replaceElementByField = function(evt) {
 				ta.value = text;
 
 				// replacement
-				var parent = ob.parentNode;
+				parent = ob.parentNode;
 				parent.replaceChild(ta, ob);
 
 				ta.focus();
@@ -214,27 +232,26 @@ FormManager.prototype.replaceElementByField = function(evt) {
 				ta.setAttribute('name', fieldName);
 				ta.tabIndex = tabIndex;
 				this.liveFormField = ta;
-				var thisManager = this;
 				this.lazyListeners.push({'element': ta, 'eventName' : 'blur', 'handler': function(){ thisManager.submit();}});
 				this._addLazyListeners();
 				break;
-				
-				
-		};
+		}
 	}
 };
 
 FormManager.prototype._addLazyListeners = function() {
-	for (var i=0 ; i<this.lazyListeners.length ; i++) {
-		var handlerInfo = this.lazyListeners[i];
-		addListener(handlerInfo['element'], handlerInfo['eventName'], handlerInfo['handler']);
+	var i, handlerInfo;
+	for (i=0 ; i<this.lazyListeners.length ; i++) {
+		handlerInfo = this.lazyListeners[i];
+		addListener(handlerInfo.element, handlerInfo.eventName, handlerInfo.handler);
 	}
 };
 
 FormManager.prototype._removeLazyListeners = function() {
-	for (var i=0 ; i<this.lazyListeners.length ; i++) {
-		var handlerInfo = this.lazyListeners[i];
-		removeListener(handlerInfo['element'], handlerInfo['eventName'], handlerInfo['handler']);
+	var i, handlerInfo;
+	for (i=0 ; i<this.lazyListeners.length ; i++) {
+		handlerInfo = this.lazyListeners[i];
+		removeListener(handlerInfo.element, handlerInfo.eventName, handlerInfo.handler);
 	}
 };
 
@@ -242,11 +259,12 @@ FormManager.prototype._removeLazyListeners = function() {
 FormManager.prototype.restoreField = function(req) {
 	var text;
 	var input = this.liveFormField;
-	if (req.status == 200) {
-		if (req.getResponseHeader('Content-Type').indexOf('text/xml') != -1) {
+	if (req.status === 200) {
+		if (req.getResponseHeader('Content-Type').indexOf('text/xml') !== -1) {
 			var out = '..........';
-			if (req.responseXML.documentElement.firstChild)
+			if (req.responseXML.documentElement.firstChild) {
 				out = req.responseXML.documentElement.firstChild.nodeValue;
+			}
 			
 			switch (req.responseXML.documentElement.nodeName) {
 				case 'computedField':
@@ -259,18 +277,19 @@ FormManager.prototype.restoreField = function(req) {
 					input.focus();
 					this._addLazyListeners();
 					return false;
-					break;
 			}
 		}
 		else {
 			text = req.responseText;
 		}
 	}
-	else
+	else {
 		text = '';
+	}
 	
-	if (!text.match(/\w/))
+	if (!text.match(/\w/)) {
 		text = '..........';
+	}
 	
 	var field = document.createElement(this.fieldTagName);
 	field.innerHTML = text;
@@ -282,8 +301,9 @@ FormManager.prototype.restoreField = function(req) {
 	parent.replaceChild(field, input);
 	this.liveFormField = null;
 	
-	if (this.pendingEvent)
+	if (this.pendingEvent) {
 		raiseMouseEvent(this.pendingEvent[0], this.pendingEvent[1]);
+	}
 	return true;
 };
 
@@ -293,26 +313,29 @@ FormManager.prototype.formData2QueryString = function() {
 	var form = this.form;
 	var strSubmit = '', formElem, elements;
 	var hasFile = false;
+	var i;
 
-	if (!this.lazy)
+	if (!this.lazy) {
 		elements = form.elements;
+	}
 	else {
-		elements = new Array();
+		elements = [];
 		var formElements = form.elements;
-		for (var i = 0; i < formElements.length; i++) {
+		for (i = 0; i < formElements.length; i++) {
 			formElem = formElements[i];
 			switch (formElem.type) {
 				case 'hidden':
 					elements.push(formElem);
 					break;
 				default :
-					if (formElem == this.liveFormField)
+					if (formElem === this.liveFormField) {
 						elements.push(formElem);
-			};
+					}
+			}
 		}
 	}
-	
-	for (var i = 0; i < elements.length; i++) {
+
+	for (i = 0; i < elements.length; i++) {
 		formElem = elements[i];
 		switch (formElem.type) {
 			// text, select, hidden, password, textarea elements
@@ -325,28 +348,33 @@ FormManager.prototype.formData2QueryString = function() {
 				break;
 			case 'radio':
 			case 'checkbox':
-				if (formElem.checked)
+				if (formElem.checked) {
 					strSubmit += formElem.name + '=' + encodeURIComponent(formElem.value) + '&';
+				}
 				break;
 			case 'select-multiple':
 				var options = formElem.getElementsByTagName("OPTION"), option;
-				for (var j = 0 ; j < options.length ; j++) {
+				var j;
+				for (j = 0 ; j < options.length ; j++) {
 					option = options[j];
-					if (option.selected)
+					if (option.selected) {
 						strSubmit += formElem.name + '=' + encodeURIComponent(option.value) + '&';
+					}
 				}
 				break;
 			case 'file':
-				if (formElem.value)
+				if (formElem.value) {
 					hasFile = true;
+				}
 				break;
-		};
+		}
 	}
 	return {'query' : strSubmit, 'hasFile' : hasFile};
 };
 
 FormManager.prototype.loadResponse = function(req) {
-	if (req.getResponseHeader('Content-Type').indexOf('text/xml') != -1) {
+	var scripts;
+	if (req.getResponseHeader('Content-Type').indexOf('text/xml') !== -1) {
 		switch(req.responseXML.documentElement.nodeName) {
 			case 'fragments' :
 				if (this.hasFile) {
@@ -363,16 +391,19 @@ FormManager.prototype.loadResponse = function(req) {
 					return;
 				}
 				var fragments = req.responseXML.documentElement.childNodes;
-				var fragment, dest, scripts;
-				for (var i=0 ; i<fragments.length ; i++) {
+				var fragment, dest;
+				var i;
+				for (i=0 ; i<fragments.length ; i++) {
 					fragment = fragments[i];
-					if (fragment.nodeName == 'fragment') {
+					if (fragment.nodeName === 'fragment') {
 						dest = document.getElementById(fragment.getAttribute('id'));
 						dest.innerHTML = fragment.firstChild.nodeValue;
 			
 						scripts = dest.getElementsByTagName('script');
-						for (var j=0 ; j < scripts.length ; j++)
+						var j;
+						for (j=0 ; j < scripts.length ; j++) {
 							globalScriptRegistry.loadScript(scripts[j]);
+						}
 					}
 				}
 				break;
@@ -383,18 +414,26 @@ FormManager.prototype.loadResponse = function(req) {
 	}
 	else {
 		this.responseTextDest.innerHTML = req.responseText;
-		var scripts = this.responseTextDest.getElementsByTagName('script');
-		for (var j=0 ; j < scripts.length ; j++)
-			globalScriptRegistry.loadScript(scripts[j]);
+		scripts = this.responseTextDest.getElementsByTagName('script');
+		var k;
+		for (k=0 ; k < scripts.length ; k++) {
+			globalScriptRegistry.loadScript(scripts[k]);
+		}
 	}
 	
 	var onAfterPopulate = this.onAfterPopulate;
-	if (typeof(onAfterPopulate) == "string") {
-		if (window.console)
-			console.warn('Deprecation WARNING onAfterPopulate: ' + onAfterPopulate);
-		onAfterPopulate = eval(onAfterPopulate);
-	}
 	onAfterPopulate();
+	this.scrollToPortalMessage();
+  history.pushState(absolute_url(), document.title, absolute_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) {
@@ -405,14 +444,80 @@ FormManager.prototype._fitField = function(evt) {
 };
 
 function initForms(baseElement, lazy) {
-	if (!baseElement)
+	if (!baseElement) {
 		baseElement = document;
+	}
 	var dest = document.getElementById("mainCell");
 	var forms = baseElement.getElementsByTagName("form");
-	var f;
-	for (var i = 0 ; i < forms.length ; i++ )
+	var f, i;
+	for (i = 0 ; i < forms.length ; i++ ) {
 		f = new FormManager(forms[i], dest, 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();
+}
 
-//registerStartupFunction(initForms);
\ No newline at end of file
+}());