d942234600c18e5f9ab15bcd7e48015d0e40f9bf
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;
29 this.form
.onclick = function(evt
){
30 thisManager
.replaceElementByField(evt
);
31 thisManager
.click(evt
);
33 if (browser
.isDOM2Event
) {
34 this.form
.onfocus
= this.form
.onclick
;
36 else if (browser
.isIE6up
) {
37 this.form
.onfocusin
= this.form
.onclick
;
39 this.onResponseLoad = function(req
){ thisManager
.restoreField(req
); };
40 this.lazyListeners
= [];
44 FormManager
.prototype.submit = function(evt
) {
46 var thisManager
= this;
48 var bsMessage
; // before submit message
49 if (!this.onBeforeSubmit
) {
50 var onBeforeSubmit
= form
.elements
.namedItem("onBeforeSubmit");
52 if (onBeforeSubmit
.length
) {
53 onBeforeSubmit
= onBeforeSubmit
[0];
55 this.onBeforeSubmit
= eval(onBeforeSubmit
.value
);
56 bsMessage
= this.onBeforeSubmit(thisManager
, evt
);
60 bsMessage
= this.onBeforeSubmit(thisManager
, evt
);
63 if (bsMessage
=== 'cancelSubmit') {
64 try {disableDefault(evt
);}
69 if (!this.onResponseLoad
) {
70 var onResponseLoad
= form
.elements
.namedItem("onResponseLoad");
72 this.onResponseLoad
= eval(onResponseLoad
.value
);
75 this.onResponseLoad
= this.loadResponse
;
79 var submitButton
= this.submitButton
;
80 var queryInfo
= this.formData2QueryString();
81 var query
= queryInfo
.query
;
82 this.hasFile
= queryInfo
.hasFile
;
85 if (!this.onAfterPopulate
) {
86 var onAfterPopulate
= form
.elements
.namedItem("onAfterPopulate");
87 if (onAfterPopulate
) {
88 this.onAfterPopulate
= onAfterPopulate
.value
;
91 this.onAfterPopulate = function() {};
96 query
+= submitButton
.name
+ '=' + submitButton
.value
+ '&';
99 if (window
.AJAX_CONFIG
&& (AJAX_CONFIG
& 1 === 1)) {
100 if (form
.method
.toLowerCase() === 'post') {
111 try {disableDefault(evt
);}
115 FormManager
.prototype._post = function(query
) {
116 // send form by XmlHttpRequest
119 var req
= new XMLHttpRequest();
120 var thisManager
= this;
121 req
.onreadystatechange = function() {
122 switch (req
.readyState
) {
128 if (req
.status
=== 200 || req
.status
=== 204) {
129 thisManager
.onResponseLoad(req
);
132 alert('Error: ' + req
.status
);
137 var url
= this.form
.action
;
138 req
.open("POST", url
, true);
139 req
.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
143 FormManager
.prototype._get = function(query
) {
144 // send form by browser location
145 var url
= this.form
.action
;
147 linkHandler
.loadUrl(url
);
151 FormManager
.prototype.click = function(evt
) {
152 var target
= getTargetedObject(evt
);
153 if(target
.type
=== "submit" || target
.type
=== "image") {
154 this.submitButton
= target
;
155 disablePropagation(evt
);
159 FormManager
.prototype.replaceElementByField = function(evt
) {
160 evt
= getEventObject(evt
);
161 var ob
= getTargetedObject(evt
);
162 var eventType
= evt
.type
;
163 if (eventType
=== 'focus' || eventType
=== 'focusin') {
164 if (this.liveFormField
&& ob
.tagName
!== 'INPUT') {
165 this.pendingEvent
= [ob
, 'click'];
169 var fieldName
= ob
.getAttribute('id');
171 this.fieldTagName
= ob
.tagName
;
172 var tabIndex
= ob
.tabIndex
;
174 if (ob
.firstChild
&& ob
.firstChild
.className
=== 'hidden_value') {
175 text
= ob
.firstChild
.innerHTML
;
180 disablePropagation(evt
);
183 switch (ob
.tagName
) {
185 // create input element
186 var inputText
= document
.createElement("input");
187 inputText
.setAttribute("type", "text");
188 text
= text
.replace(/\n/g, ' ');
189 text
= text
.replace(/\s+/g, ' ');
190 text
= text
.replace(/^ /, '');
191 text
= text
.replace(/ $/, '');
192 inputText
.setAttribute("value", text
);
193 var inputWidth
= text
.length
/ 1.9;
194 inputWidth
= (inputWidth
> 5) ? inputWidth
: 5;
195 inputText
.style
.width
= inputWidth
+ 'em';
196 //inputText.setAttribute("size", text.length);
199 parent
= ob
.parentNode
;
200 parent
.replaceChild(inputText
, ob
);
204 inputText
.setAttribute('name', fieldName
);
205 inputText
.tabIndex
= tabIndex
;
206 inputText
.className
= 'live_field';
207 this.liveFormField
= inputText
;
208 this.lazyListeners
.push({'element': inputText
, 'eventName' : 'blur', 'handler': function(){ thisManager
.submit();}});
209 this.lazyListeners
.push({'element': inputText
, 'eventName' : 'keypress', 'handler': function(evt
){ thisManager
._fitField(evt
);}});
210 this._addLazyListeners();
216 var ta
= document
.createElement('textarea');
217 ta
.style
.display
= 'block';
218 ta
.className
= 'live_field';
219 text
= text
.replace(/^\s*/, '');
220 text
= text
.replace(/\s*$/, '');
224 parent
= ob
.parentNode
;
225 parent
.replaceChild(ta
, ob
);
229 ta
.setAttribute('name', fieldName
);
230 ta
.tabIndex
= tabIndex
;
231 this.liveFormField
= ta
;
232 this.lazyListeners
.push({'element': ta
, 'eventName' : 'blur', 'handler': function(){ thisManager
.submit();}});
233 this._addLazyListeners();
239 FormManager
.prototype._addLazyListeners = function() {
241 for (i
=0 ; i
<this.lazyListeners
.length
; i
++) {
242 handlerInfo
= this.lazyListeners
[i
];
243 addListener(handlerInfo
.element
, handlerInfo
.eventName
, handlerInfo
.handler
);
247 FormManager
.prototype._removeLazyListeners = function() {
249 for (i
=0 ; i
<this.lazyListeners
.length
; i
++) {
250 handlerInfo
= this.lazyListeners
[i
];
251 removeListener(handlerInfo
.element
, handlerInfo
.eventName
, handlerInfo
.handler
);
256 FormManager
.prototype.restoreField = function(req
) {
258 var input
= this.liveFormField
;
259 if (req
.status
=== 200) {
260 if (req
.getResponseHeader('Content-Type').indexOf('text/xml') !== -1) {
261 var out
= '..........';
262 if (req
.responseXML
.documentElement
.firstChild
) {
263 out
= req
.responseXML
.documentElement
.firstChild
.nodeValue
;
266 switch (req
.responseXML
.documentElement
.nodeName
) {
267 case 'computedField':
271 this._removeLazyListeners();
273 this.pendingEvent
= null;
275 this._addLazyListeners();
280 text
= req
.responseText
;
287 if (!text
.match(/\w/)) {
291 var field
= document
.createElement(this.fieldTagName
);
292 field
.innerHTML
= text
;
293 field
.setAttribute('id', input
.getAttribute('name'));
294 field
.className
= 'editable';
295 field
.tabIndex
= input
.tabIndex
;
297 var parent
= input
.parentNode
;
298 parent
.replaceChild(field
, input
);
299 this.liveFormField
= null;
301 if (this.pendingEvent
) {
302 raiseMouseEvent(this.pendingEvent
[0], this.pendingEvent
[1]);
308 FormManager
.prototype.formData2QueryString = function() {
309 // http://www.onlamp.com/pub/a/onlamp/2005/05/19/xmlhttprequest.html
310 var form
= this.form
;
311 var strSubmit
= '', formElem
, elements
;
316 elements
= form
.elements
;
320 var formElements
= form
.elements
;
321 for (i
= 0; i
< formElements
.length
; i
++) {
322 formElem
= formElements
[i
];
323 switch (formElem
.type
) {
325 elements
.push(formElem
);
328 if (formElem
=== this.liveFormField
) {
329 elements
.push(formElem
);
335 for (i
= 0; i
< elements
.length
; i
++) {
336 formElem
= elements
[i
];
337 switch (formElem
.type
) {
338 // text, select, hidden, password, textarea elements
344 strSubmit
+= formElem
.name
+ '=' + encodeURIComponent(formElem
.value
) + '&';
348 if (formElem
.checked
) {
349 strSubmit
+= formElem
.name
+ '=' + encodeURIComponent(formElem
.value
) + '&';
352 case 'select-multiple':
353 var options
= formElem
.getElementsByTagName("OPTION"), option
;
355 for (j
= 0 ; j
< options
.length
; j
++) {
357 if (option
.selected
) {
358 strSubmit
+= formElem
.name
+ '=' + encodeURIComponent(option
.value
) + '&';
363 if (formElem
.value
) {
369 return {'query' : strSubmit
, 'hasFile' : hasFile
};
372 FormManager
.prototype.loadResponse = function(req
) {
374 if (req
.getResponseHeader('Content-Type').indexOf('text/xml') !== -1) {
375 switch(req
.responseXML
.documentElement
.nodeName
) {
378 var sb
= this.submitButton
;
380 var h
= document
.createElement('input');
384 this.form
.appendChild(h
);
390 var fragments
= req
.responseXML
.documentElement
.childNodes
;
393 for (i
=0 ; i
<fragments
.length
; i
++) {
394 fragment
= fragments
[i
];
395 if (fragment
.nodeName
=== 'fragment') {
396 dest
= document
.getElementById(fragment
.getAttribute('id'));
397 dest
.innerHTML
= fragment
.firstChild
.nodeValue
;
399 scripts
= dest
.getElementsByTagName('script');
401 for (j
=0 ; j
< scripts
.length
; j
++) {
402 globalScriptRegistry
.loadScript(scripts
[j
]);
408 alert(req
.responseXML
.documentElement
.firstChild
.nodeValue
);
413 this.responseTextDest
.innerHTML
= req
.responseText
;
414 scripts
= this.responseTextDest
.getElementsByTagName('script');
416 for (k
=0 ; k
< scripts
.length
; k
++) {
417 globalScriptRegistry
.loadScript(scripts
[k
]);
421 var onAfterPopulate
= this.onAfterPopulate
;
422 if (typeof(onAfterPopulate
) === "string") {
423 if (window
.console
) {
424 console
.warn('Deprecation WARNING onAfterPopulate: ' + onAfterPopulate
);
426 onAfterPopulate
= eval(onAfterPopulate
);
431 FormManager
.prototype._fitField = function(evt
) {
432 var ob
= getTargetedObject(evt
);
433 var inputWidth
= ob
.value
.length
/ 1.9;
434 inputWidth
= (inputWidth
> 5) ? inputWidth
: 5;
435 ob
.style
.width
= inputWidth
+ 'em';
438 function initForms(baseElement
, lazy
) {
440 baseElement
= document
;
442 var dest
= document
.getElementById("mainCell");
443 var forms
= baseElement
.getElementsByTagName("form");
445 for (i
= 0 ; i
< forms
.length
; i
++ ) {
446 f
= new FormManager(forms
[i
], dest
, lazy
);
451 //registerStartupFunction(initForms);