1 // (c) Benoît PIN 2006-2007
8 function FormManager(form
, responseTextDest
, lazy
) {
9 if (form
.elements
.namedItem("noAjax")) return;
12 this.responseTextDest
= responseTextDest
;
14 var thisManager
= this;
15 this.form
.onsubmit = function(evt
) { thisManager
.submit(evt
); };
16 this.form
.onclick = function(evt
) { thisManager
.click(evt
); };
17 this.submitButton
= null;
19 /* raised on form submit */
20 this.onBeforeSubmit
= null;
21 /* raised after xmlhttp response */
22 this.onResponseLoad
= null;
23 /* raised when the responseText is added inside the main element.
24 * (onResponseLoad may have the default value) */
25 this.onAfterPopulate
= null;
26 this.submitButton
= null;
32 this.form
.onclick = function(evt
){
33 thisManager
.replaceElementByField(evt
);
34 thisManager
.click(evt
);
36 if (browser
.isDOM2Event
)
37 this.form
.onfocus
= this.form
.onclick
;
38 else if (browser
.isIE6up
)
39 this.form
.onfocusin
= this.form
.onclick
;
40 this.onResponseLoad = function(req
){ thisManager
.restoreField(req
); };
41 this.lazyListeners
= new Array();
45 FormManager
.prototype.submit = function(evt
) {
47 var thisManager
= this;
49 var bsMessage
; // before submit message
50 if (!this.onBeforeSubmit
) {
51 var onBeforeSubmit
= form
.elements
.namedItem("onBeforeSubmit");
53 if (onBeforeSubmit
.length
)
54 onBeforeSubmit
= onBeforeSubmit
[0];
55 this.onBeforeSubmit
= eval(onBeforeSubmit
.value
);
56 bsMessage
= this.onBeforeSubmit(thisManager
, evt
);
60 bsMessage
= this.onBeforeSubmit(thisManager
, evt
);
62 if (bsMessage
== 'cancelSubmit') {
63 try {disableDefault(evt
);}
68 if (!this.onResponseLoad
) {
69 var onResponseLoad
= form
.elements
.namedItem("onResponseLoad");
71 this.onResponseLoad
= eval(onResponseLoad
.value
);
73 this.onResponseLoad
= this.loadResponse
;
76 var submitButton
= this.submitButton
;
77 var queryInfo
= this.formData2QueryString();
78 var query
= queryInfo
['query'];
79 this.hasFile
= queryInfo
['hasFile'];
82 if (!this.onAfterPopulate
) {
83 var onAfterPopulate
= form
.elements
.namedItem("onAfterPopulate");
85 this.onAfterPopulate
= onAfterPopulate
.value
;
87 this.onAfterPopulate = function() {};
91 query
+= submitButton
.name
+ '=' + submitButton
.value
+ '&';
94 if (window
.AJAX_CONFIG
&& (AJAX_CONFIG
& 1 == 1)) {
95 if (form
.method
.toLowerCase() == 'post')
103 try {disableDefault(evt
);}
107 FormManager
.prototype._post = function(query
) {
108 // send form by XmlHttpRequest
111 var req
= new XMLHttpRequest();
112 var thisManager
= this;
113 req
.onreadystatechange = function() {
114 switch (req
.readyState
) {
120 if (req
.status
== 200 || req
.status
== 204)
121 thisManager
.onResponseLoad(req
);
123 alert('Error: ' + req
.status
);
126 var url
= this.form
.action
;
127 req
.open("POST", url
, true);
128 req
.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
132 FormManager
.prototype._get = function(query
) {
133 // send form by browser location
134 var url
= this.form
.action
;
136 linkHandler
.loadUrl(url
);
140 FormManager
.prototype.click = function(evt
) {
141 var target
= getTargetedObject(evt
);
142 if(target
.type
== "submit" || target
.type
== "image") {
143 this.submitButton
= target
;
144 disablePropagation(evt
);
148 FormManager
.prototype.replaceElementByField = function(evt
) {
149 evt
= getEventObject(evt
);
150 var ob
= getTargetedObject(evt
);
151 var eventType
= evt
.type
;
152 if (eventType
== 'focus' || eventType
== 'focusin') {
153 if (this.liveFormField
&& ob
.tagName
!= 'INPUT')
154 this.pendingEvent
= [ob
, 'click'];
157 var fieldName
= ob
.getAttribute('id');
159 this.fieldTagName
= ob
.tagName
;
160 var tabIndex
= ob
.tabIndex
;
162 if (ob
.firstChild
&& ob
.firstChild
.className
== 'hidden_value')
163 text
= ob
.firstChild
.innerHTML
;
166 disablePropagation(evt
);
167 switch (ob
.tagName
) {
169 // create input element
170 var inputText
= document
.createElement("input");
171 inputText
.setAttribute("type", "text");
172 text
= text
.replace(/\n/g, ' ');
173 text
= text
.replace(/\s+/g, ' ');
174 text
= text
.replace(/^ /, '');
175 text
= text
.replace(/ $/, '');
176 inputText
.setAttribute("value", text
);
177 var inputWidth
= text
.length
/ 1.9;
178 inputWidth
= (inputWidth
> 5) ? inputWidth
: 5;
179 inputText
.style
.width
= inputWidth
+ 'em';
180 //inputText.setAttribute("size", text.length);
183 var parent
= ob
.parentNode
;
184 parent
.replaceChild(inputText
, ob
);
188 inputText
.setAttribute('name', fieldName
);
189 inputText
.tabIndex
= tabIndex
;
190 inputText
.className
= 'live_field';
191 this.liveFormField
= inputText
;
192 var thisManager
= this;
193 this.lazyListeners
.push({'element': inputText
, 'eventName' : 'blur', 'handler': function(){ thisManager
.submit();}});
194 this.lazyListeners
.push({'element': inputText
, 'eventName' : 'keypress', 'handler': function(evt
){ thisManager
._fitField(evt
);}});
195 this._addLazyListeners();
201 var ta
= document
.createElement('textarea');
202 ta
.style
.display
= 'block';
203 ta
.className
= 'live_field';
204 text
= text
.replace(/^\s*/, '');
205 text
= text
.replace(/\s*$/, '');
209 var parent
= ob
.parentNode
;
210 parent
.replaceChild(ta
, ob
);
214 ta
.setAttribute('name', fieldName
);
215 ta
.tabIndex
= tabIndex
;
216 this.liveFormField
= ta
;
217 var thisManager
= this;
218 this.lazyListeners
.push({'element': ta
, 'eventName' : 'blur', 'handler': function(){ thisManager
.submit();}});
219 this._addLazyListeners();
227 FormManager
.prototype._addLazyListeners = function() {
228 for (var i
=0 ; i
<this.lazyListeners
.length
; i
++) {
229 var handlerInfo
= this.lazyListeners
[i
];
230 addListener(handlerInfo
['element'], handlerInfo
['eventName'], handlerInfo
['handler']);
234 FormManager
.prototype._removeLazyListeners = function() {
235 for (var i
=0 ; i
<this.lazyListeners
.length
; i
++) {
236 var handlerInfo
= this.lazyListeners
[i
];
237 removeListener(handlerInfo
['element'], handlerInfo
['eventName'], handlerInfo
['handler']);
242 FormManager
.prototype.restoreField = function(req
) {
244 var input
= this.liveFormField
;
245 if (req
.status
== 200) {
246 if (req
.getResponseHeader('Content-Type').indexOf('text/xml') != -1) {
247 var out
= '..........';
248 if (req
.responseXML
.documentElement
.firstChild
)
249 out
= req
.responseXML
.documentElement
.firstChild
.nodeValue
;
251 switch (req
.responseXML
.documentElement
.nodeName
) {
252 case 'computedField':
256 this._removeLazyListeners();
258 this.pendingEvent
= null;
260 this._addLazyListeners();
266 text
= req
.responseText
;
272 if (!text
.match(/\w/))
275 var field
= document
.createElement(this.fieldTagName
);
276 field
.innerHTML
= text
;
277 field
.setAttribute('id', input
.getAttribute('name'));
278 field
.className
= 'editable';
279 field
.tabIndex
= input
.tabIndex
;
281 var parent
= input
.parentNode
;
282 parent
.replaceChild(field
, input
);
283 this.liveFormField
= null;
285 if (this.pendingEvent
)
286 raiseMouseEvent(this.pendingEvent
[0], this.pendingEvent
[1]);
291 FormManager
.prototype.formData2QueryString = function() {
292 // http://www.onlamp.com/pub/a/onlamp/2005/05/19/xmlhttprequest.html
293 var form
= this.form
;
294 var strSubmit
= '', formElem
, elements
;
298 elements
= form
.elements
;
300 elements
= new Array();
301 var formElements
= form
.elements
;
302 for (var i
= 0; i
< formElements
.length
; i
++) {
303 formElem
= formElements
[i
];
304 switch (formElem
.type
) {
306 elements
.push(formElem
);
309 if (formElem
== this.liveFormField
)
310 elements
.push(formElem
);
315 for (var i
= 0; i
< elements
.length
; i
++) {
316 formElem
= elements
[i
];
317 switch (formElem
.type
) {
318 // text, select, hidden, password, textarea elements
324 strSubmit
+= formElem
.name
+ '=' + encodeURIComponent(formElem
.value
) + '&';
328 if (formElem
.checked
)
329 strSubmit
+= formElem
.name
+ '=' + encodeURIComponent(formElem
.value
) + '&';
331 case 'select-multiple':
332 var options
= formElem
.getElementsByTagName("OPTION"), option
;
333 for (var j
= 0 ; j
< options
.length
; j
++) {
336 strSubmit
+= formElem
.name
+ '=' + encodeURIComponent(option
.value
) + '&';
345 return {'query' : strSubmit
, 'hasFile' : hasFile
};
348 FormManager
.prototype.loadResponse = function(req
) {
349 if (req
.getResponseHeader('Content-Type').indexOf('text/xml') != -1) {
350 switch(req
.responseXML
.documentElement
.nodeName
) {
353 var sb
= this.submitButton
;
355 var h
= document
.createElement('input');
359 this.form
.appendChild(h
);
365 var fragments
= req
.responseXML
.documentElement
.childNodes
;
366 var fragment
, dest
, scripts
;
367 for (var i
=0 ; i
<fragments
.length
; i
++) {
368 fragment
= fragments
[i
];
369 if (fragment
.nodeName
== 'fragment') {
370 dest
= document
.getElementById(fragment
.getAttribute('id'));
371 dest
.innerHTML
= fragment
.firstChild
.nodeValue
;
373 scripts
= dest
.getElementsByTagName('script');
374 for (var j
=0 ; j
< scripts
.length
; j
++)
375 globalScriptRegistry
.loadScript(scripts
[j
]);
380 alert(req
.responseXML
.documentElement
.firstChild
.nodeValue
);
385 this.responseTextDest
.innerHTML
= req
.responseText
;
386 var scripts
= this.responseTextDest
.getElementsByTagName('script');
387 for (var j
=0 ; j
< scripts
.length
; j
++)
388 globalScriptRegistry
.loadScript(scripts
[j
]);
391 var onAfterPopulate
= this.onAfterPopulate
;
392 if (typeof(onAfterPopulate
) == "string") {
394 console
.warn('Deprecation WARNING onAfterPopulate: ' + onAfterPopulate
);
395 onAfterPopulate
= eval(onAfterPopulate
);
400 FormManager
.prototype._fitField = function(evt
) {
401 var ob
= getTargetedObject(evt
);
402 var inputWidth
= ob
.value
.length
/ 1.9;
403 inputWidth
= (inputWidth
> 5) ? inputWidth
: 5;
404 ob
.style
.width
= inputWidth
+ 'em';
407 function initForms(baseElement
, lazy
) {
409 baseElement
= document
;
410 var dest
= document
.getElementById("mainCell");
411 var forms
= baseElement
.getElementsByTagName("form");
413 for (var i
= 0 ; i
< forms
.length
; i
++ )
414 f
= new FormManager(forms
[i
], dest
, lazy
);
418 //registerStartupFunction(initForms);