// (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;
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;
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;
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;
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) {
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);
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);
}
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');
this.fieldTagName = ob.tagName;
var tabIndex = ob.tabIndex;
var text;
- if (ob.firstChild && ob.firstChild.className == 'hidden_value')
- text = ob.firstChild.innerHTML;
- else
- text = ob.innerHTML;
+ if (ob.firstChild && ob.firstChild.className === 'hidden_value') {
+ text = ob.firstChild.innerHTML;
+ }
+ else {
+ text = ob.innerHTML;
+ }
disablePropagation(evt);
+ var parent;
+ thisManager = this;
switch (ob.tagName) {
case 'SPAN' :
// create input element
//inputText.setAttribute("size", text.length);
// replacement
- var parent = ob.parentNode;
+ parent = ob.parentNode;
parent.replaceChild(inputText, ob);
inputText.focus();
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();
ta.value = text;
// replacement
- var parent = ob.parentNode;
+ parent = ob.parentNode;
parent.replaceChild(ta, ob);
ta.focus();
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);
}
};
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':
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;
parent.replaceChild(field, input);
this.liveFormField = null;
- if (this.pendingEvent)
+ if (this.pendingEvent) {
raiseMouseEvent(this.pendingEvent[0], this.pendingEvent[1]);
+ }
return true;
};
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
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) {
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;
}
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) {
};
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
+}());