1 /** |
1 /** |
2 * Javascript auto-completion for form fields. This supercedes the code in autocomplete.js for MOZILLA ONLY. It doesn't seem to work real |
2 * Javascript auto-completion for form fields. This supercedes the code in autocomplete.js for MOZILLA ONLY. It doesn't seem to work real |
3 * well with other browsers yet. |
3 * well with other browsers yet. |
4 */ |
4 */ |
5 |
5 |
6 var af_current = false; |
6 // fill schemas |
7 |
7 var autofill_schemas = {}; |
8 function AutofillUsername(parent, event, allowanon) |
8 |
|
9 // default, generic schema |
|
10 autofill_schemas.generic = { |
|
11 template: '<div id="--ID--_region" spry:region="autofill_region_--ID--" class="tblholder">' + "\n" + |
|
12 ' <table border="0" cellspacing="1" cellpadding="3" style="font-size: smaller;">' + "\n" + |
|
13 ' <tr spry:repeat="autofill_region_--ID--">' + "\n" + |
|
14 ' <td class="row1" spry:suggest="{name}">{name}</td>' + "\n" + |
|
15 ' </tr>' + "\n" + |
|
16 ' </table>' + "\n" + |
|
17 '</div>', |
|
18 |
|
19 init: function(element, fillclass) |
|
20 { |
|
21 // setup the dataset |
|
22 window["autofill_region_" + element.id] = new Spry.Data.JSONDataSet(makeUrlNS('Special', 'Autofill', 'type=' + fillclass)); |
|
23 |
|
24 // inject our HTML wrapper |
|
25 var template = this.template.replace(new RegExp('--ID--', 'g'), element.id); |
|
26 var wrapper = element.parentNode; // document.createElement('div'); |
|
27 wrapper.id = 'autofill_wrap_' + element.id; |
|
28 |
|
29 // a bunch of hacks to add a spry wrapper |
|
30 // var el2 = element.cloneNode(false); |
|
31 // wrapper.appendChild(el2); |
|
32 wrapper.innerHTML += template; |
|
33 // insertAfter(element.parentNode, wrapper, element); |
|
34 // element.parentNode.removeChild(element); |
|
35 // element = el2; |
|
36 |
|
37 var autosuggest = new Spry.Widget.AutoSuggest("autofill_wrap_" + element.id, element.id + '_region', window["autofill_region_" + element.id], 'name', {loadFromServer: true, urlParam: 'userinput', hoverSuggestClass: 'row2', minCharsType: 3}); |
|
38 } |
|
39 }; |
|
40 |
|
41 function autofill_init_element(element, params) |
9 { |
42 { |
10 // if this is IE, use the old code |
43 if ( element.parentNode.id.match(/^autofill_wrap_/) ) |
11 if ( IE ) |
44 return false; |
|
45 |
|
46 params = params || {}; |
|
47 // assign an ID if it doesn't have one yet |
|
48 if ( !element.id ) |
12 { |
49 { |
13 ajaxUserNameComplete(parent); |
50 element.id = 'autofill_' + Math.floor(Math.random() * 100000); |
14 return false; |
|
15 } |
51 } |
16 if ( parent.afobj ) |
52 var id = element.id; |
|
53 |
|
54 // get the fill type |
|
55 var fillclass = element.className; |
|
56 fillclass = fillclass.split(' '); |
|
57 fillclass = fillclass[1]; |
|
58 |
|
59 var schema = ( autofill_schemas[fillclass] ) ? autofill_schemas[fillclass] : autofill_schemas['generic']; |
|
60 if ( typeof(schema.init) != 'function' ) |
17 { |
61 { |
18 parent.afobj.go(); |
62 schema.init = autofill_schemas.generic.init; |
19 return true; |
63 } |
|
64 schema.init(element, fillclass, params); |
|
65 |
|
66 element.af_initted = true; |
|
67 } |
|
68 |
|
69 var autofill_onload = function() |
|
70 { |
|
71 autofill_schemas.username = { |
|
72 template: '<div id="--ID--_region" spry:region="autofill_region_--ID--" class="tblholder">' + "\n" + |
|
73 ' <table border="0" cellspacing="1" cellpadding="3" style="font-size: smaller;">' + "\n" + |
|
74 ' <tr>' + "\n" + |
|
75 ' <th>' + $lang.get('user_autofill_heading_suggestions') + '</th>' + "\n" + |
|
76 ' </tr>' + "\n" + |
|
77 ' <tr spry:repeat="autofill_region_--ID--">' + "\n" + |
|
78 ' <td class="row1" spry:suggest="{name}">{name_highlight}<br /><small style="{rank_style}">{rank_title}</small></td>' + "\n" + |
|
79 ' </tr>' + "\n" + |
|
80 ' </table>' + "\n" + |
|
81 '</div>', |
|
82 |
|
83 init: function(element, fillclass, params) |
|
84 { |
|
85 // calculate positions before spry f***s everything up |
|
86 var top = $dynano(element).Top() + $dynano(element).Height() - 10; // tblholder has 10px top margin |
|
87 var left = $dynano(element).Left(); |
|
88 |
|
89 var allow_anon = ( params.allow_anon ) ? '1' : '0'; |
|
90 // setup the dataset |
|
91 window["autofill_region_" + element.id] = new Spry.Data.JSONDataSet(makeUrlNS('Special', 'Autofill', 'type=' + fillclass + '&allow_anon' + allow_anon)); |
|
92 Spry.Data.initRegions(document.body); |
|
93 (window["autofill_region_" + element.id]).loadData(); |
|
94 |
|
95 // inject our HTML wrapper |
|
96 var template = this.template.replace(new RegExp('--ID--', 'g'), element.id); |
|
97 var wrapper = element.parentNode; // document.createElement('div'); |
|
98 wrapper.id = 'autofill_wrap_' + element.id; |
|
99 |
|
100 // a bunch of hacks to add a spry wrapper |
|
101 wrapper.innerHTML = template + wrapper.innerHTML; |
|
102 |
|
103 var autosuggest = new Spry.Widget.AutoSuggest("autofill_wrap_" + element.id, element.id + '_region', window["autofill_region_" + element.id], 'name', {loadFromServer: true, urlParam: 'userinput', hoverSuggestClass: 'row2', minCharsType: 3}); |
|
104 var regiondiv = document.getElementById(element.id + '_region'); |
|
105 regiondiv.style.position = 'absolute'; |
|
106 regiondiv.style.top = top + 'px'; |
|
107 regiondiv.style.left = left + 'px'; |
|
108 } |
|
109 }; |
|
110 |
|
111 autofill_schemas.page = { |
|
112 template: '<div id="--ID--_region" spry:region="autofill_region_--ID--" class="tblholder">' + "\n" + |
|
113 ' <table border="0" cellspacing="1" cellpadding="3" style="font-size: smaller;">' + "\n" + |
|
114 ' <tr>' + "\n" + |
|
115 ' <th colspan="2">' + $lang.get('page_autosuggest_heading') + '</th>' + "\n" + |
|
116 ' </tr>' + "\n" + |
|
117 ' <tr spry:repeat="autofill_region_--ID--">' + "\n" + |
|
118 ' <td class="row1" spry:suggest="{page_id}">{pid_highlight}<br /><small>{name_highlight}</small></td>' + "\n" + |
|
119 ' </tr>' + "\n" + |
|
120 ' </table>' + "\n" + |
|
121 '</div>' |
20 } |
122 } |
21 |
123 |
22 parent.autocomplete = 'off'; |
124 var inputs = document.getElementsByClassName('input', 'autofill'); |
23 parent.setAttribute('autocomplete', 'off'); |
|
24 |
125 |
25 this.repeat = false; |
126 for ( var i = 0; i < inputs.length; i++ ) |
26 this.event = event; |
127 { |
27 this.box_id = false; |
128 autofill_init_element(inputs[i]); |
28 this.boxes = new Array(); |
129 } |
29 this.state = false; |
130 } |
30 this.allowanon = ( allowanon ) ? true : false; |
131 |
|
132 addOnloadHook(autofill_onload); |
|
133 |
|
134 function AutofillUsername(element, event, allowanon) |
|
135 { |
|
136 element.onkeyup = element.onkeydown = element.onkeypress = function(e) {}; |
31 |
137 |
32 if ( !parent.id ) |
138 element.className = 'autofill username'; |
33 parent.id = 'afuser_' + Math.floor(Math.random() * 1000000); |
|
34 |
139 |
35 this.field_id = parent.id; |
140 allowanon = allowanon ? true : false; |
36 |
141 autofill_init_element(element, { |
37 // constants |
142 allow_anon: allowanon |
38 this.KEY_UP = 38; |
143 }); |
39 this.KEY_DOWN = 40; |
|
40 this.KEY_ESC = 27; |
|
41 this.KEY_TAB = 9; |
|
42 this.KEY_ENTER = 13; |
|
43 |
|
44 // response cache |
|
45 this.responses = new Object(); |
|
46 |
|
47 // ajax placeholder |
|
48 this.process_dataset = function(resp_json) |
|
49 { |
|
50 // window.console.info('Processing the following dataset.'); |
|
51 // window.console.debug(resp_json); |
|
52 var autofill = this; |
|
53 |
|
54 if ( typeof(autofill.event) == 'object' ) |
|
55 { |
|
56 if ( autofill.event.keyCode ) |
|
57 { |
|
58 if ( autofill.event.keyCode == autofill.KEY_ENTER && autofill.boxes.length < 1 && !autofill.box_id ) |
|
59 { |
|
60 // user hit enter after accepting a suggestion - submit the form |
|
61 var frm = findParentForm($dynano(autofill.field_id).object); |
|
62 frm._af_acting = false; |
|
63 frm.submit(); |
|
64 // window.console.info('Submitting form'); |
|
65 return false; |
|
66 } |
|
67 if ( autofill.event.keyCode == autofill.KEY_UP || autofill.event.keyCode == autofill.KEY_DOWN || autofill.event.keyCode == autofill.KEY_ESC || autofill.event.keyCode == autofill.KEY_TAB || autofill.event.keyCode == autofill.KEY_ENTER ) |
|
68 { |
|
69 autofill.keyhandler(); |
|
70 // window.console.info('Control key detected, called keyhandler and exiting'); |
|
71 return true; |
|
72 } |
|
73 } |
|
74 } |
|
75 |
|
76 if ( this.box_id ) |
|
77 { |
|
78 this.destroy(); |
|
79 // window.console.info('already have a box open - destroying and exiting'); |
|
80 //return false; |
|
81 } |
|
82 |
|
83 var users = new Array(); |
|
84 for ( var i = 0; i < resp_json.users_real.length; i++ ) |
|
85 { |
|
86 try |
|
87 { |
|
88 var user = resp_json.users_real[i].toLowerCase(); |
|
89 var inp = $dynano(autofill.field_id).object.value; |
|
90 inp = inp.toLowerCase(); |
|
91 if ( user.indexOf(inp) > -1 ) |
|
92 { |
|
93 users.push(resp_json.users_real[i]); |
|
94 } |
|
95 } |
|
96 catch(e) |
|
97 { |
|
98 users.push(resp_json.users_real[i]); |
|
99 } |
|
100 } |
|
101 |
|
102 // This was used ONLY for debugging the DOM and list logic |
|
103 // resp_json.users = resp_json.users_real; |
|
104 |
|
105 // construct table |
|
106 var div = document.createElement('div'); |
|
107 div.className = 'tblholder'; |
|
108 div.style.clip = 'rect(0px,auto,auto,0px)'; |
|
109 div.style.maxHeight = '200px'; |
|
110 div.style.overflow = 'auto'; |
|
111 div.style.zIndex = '9999'; |
|
112 var table = document.createElement('table'); |
|
113 table.border = '0'; |
|
114 table.cellSpacing = '1'; |
|
115 table.cellPadding = '3'; |
|
116 |
|
117 var tr = document.createElement('tr'); |
|
118 var th = document.createElement('th'); |
|
119 th.appendChild(document.createTextNode($lang.get('user_autofill_heading_suggestions'))); |
|
120 tr.appendChild(th); |
|
121 table.appendChild(tr); |
|
122 |
|
123 if ( users.length < 1 ) |
|
124 { |
|
125 var tr = document.createElement('tr'); |
|
126 var td = document.createElement('td'); |
|
127 td.className = 'row1'; |
|
128 td.appendChild(document.createTextNode($lang.get('user_autofill_msg_no_suggestions'))); |
|
129 td.afobj = autofill; |
|
130 tr.appendChild(td); |
|
131 table.appendChild(tr); |
|
132 } |
|
133 else |
|
134 |
|
135 for ( var i = 0; i < users.length; i++ ) |
|
136 { |
|
137 var user = users[i]; |
|
138 var tr = document.createElement('tr'); |
|
139 var td = document.createElement('td'); |
|
140 td.className = ( i == 0 ) ? 'row2' : 'row1'; |
|
141 td.appendChild(document.createTextNode(user)); |
|
142 td.afobj = autofill; |
|
143 td.style.cursor = 'pointer'; |
|
144 td.onclick = function() |
|
145 { |
|
146 this.afobj.set(this.firstChild.nodeValue); |
|
147 } |
|
148 tr.appendChild(td); |
|
149 table.appendChild(tr); |
|
150 } |
|
151 |
|
152 // Finalize div |
|
153 var tb_top = $dynano(autofill.field_id).Top(); |
|
154 var tb_height = $dynano(autofill.field_id).Height(); |
|
155 var af_top = tb_top + tb_height - 9; |
|
156 var tb_left = $dynano(autofill.field_id).Left(); |
|
157 var af_left = tb_left; |
|
158 |
|
159 div.style.position = 'absolute'; |
|
160 div.style.left = af_left + 'px'; |
|
161 div.style.top = af_top + 'px'; |
|
162 div.style.width = '200px'; |
|
163 div.style.fontSize = '7pt'; |
|
164 div.style.fontFamily = 'Trebuchet MS, arial, helvetica, sans-serif'; |
|
165 div.id = 'afuserdrop_' + Math.floor(Math.random() * 1000000); |
|
166 div.appendChild(table); |
|
167 |
|
168 autofill.boxes.push(div.id); |
|
169 autofill.box_id = div.id; |
|
170 if ( users.length > 0 ) |
|
171 autofill.state = users[0]; |
|
172 |
|
173 var body = document.getElementsByTagName('body')[0]; |
|
174 body.appendChild(div); |
|
175 |
|
176 autofill.repeat = true; |
|
177 } |
|
178 |
|
179 // perform ajax call |
|
180 this.fetch_and_process = function() |
|
181 { |
|
182 af_current = this; |
|
183 var processResponse = function() |
|
184 { |
|
185 if ( ajax.readyState == 4 && ajax.status == 200 ) |
|
186 { |
|
187 var afobj = af_current; |
|
188 af_current = false; |
|
189 // parse the JSON response |
|
190 var response = String(ajax.responseText) + ' '; |
|
191 if ( response.substr(0,1) != '{' ) |
|
192 { |
|
193 new MessageBox(MB_OK|MB_ICONSTOP, 'Invalid response', 'Invalid or unexpected JSON response from server:<pre>' + ajax.responseText + '</pre>'); |
|
194 return false; |
|
195 } |
|
196 if ( $dynano(afobj.field_id).object.value.length < 3 ) |
|
197 return false; |
|
198 var resp_json = parseJSON(response); |
|
199 var resp_code = $dynano(afobj.field_id).object.value.toLowerCase().substr(0, 3); |
|
200 afobj.responses[resp_code] = resp_json; |
|
201 afobj.process_dataset(resp_json); |
|
202 } |
|
203 } |
|
204 var usernamefragment = ajaxEscape($dynano(this.field_id).object.value); |
|
205 ajaxGet(stdAjaxPrefix + '&_mode=fillusername&name=' + usernamefragment + '&allowanon=' + ( this.allowanon ? '1' : '0' ), processResponse); |
|
206 } |
|
207 |
|
208 this.go = function() |
|
209 { |
|
210 if ( document.getElementById(this.field_id).value.length < 3 ) |
|
211 { |
|
212 this.destroy(); |
|
213 return false; |
|
214 } |
|
215 |
|
216 if ( af_current ) |
|
217 return false; |
|
218 |
|
219 var resp_code = $dynano(this.field_id).object.value.toLowerCase().substr(0, 3); |
|
220 if ( this.responses.length < 1 || ! this.responses[ resp_code ] ) |
|
221 { |
|
222 // window.console.info('Cannot find dataset ' + resp_code + ' in cache, sending AJAX request'); |
|
223 this.fetch_and_process(); |
|
224 } |
|
225 else |
|
226 { |
|
227 // window.console.info('Using cached dataset: ' + resp_code); |
|
228 var resp_json = this.responses[ resp_code ]; |
|
229 this.process_dataset(resp_json); |
|
230 } |
|
231 document.getElementById(this.field_id).onkeyup = function(event) |
|
232 { |
|
233 this.afobj.event = event; |
|
234 this.afobj.go(); |
|
235 } |
|
236 document.getElementById(this.field_id).onkeydown = function(event) |
|
237 { |
|
238 var form = findParentForm(this); |
|
239 if ( typeof(event) != 'object' ) |
|
240 var event = window.event; |
|
241 if ( typeof(event) == 'object' ) |
|
242 { |
|
243 if ( event.keyCode == this.afobj.KEY_ENTER && this.afobj.boxes.length < 1 && !this.afobj.box_id ) |
|
244 { |
|
245 // user hit enter after accepting a suggestion - submit the form |
|
246 form._af_acting = false; |
|
247 return true; |
|
248 } |
|
249 else |
|
250 { |
|
251 form._af_acting = true; |
|
252 return true; |
|
253 } |
|
254 } |
|
255 } |
|
256 } |
|
257 |
|
258 this.keyhandler = function() |
|
259 { |
|
260 var key = this.event.keyCode; |
|
261 if ( key == this.KEY_ENTER && !this.repeat ) |
|
262 { |
|
263 submitAuthorized = true; |
|
264 var form = findParentForm($dynano(this.field_id).object); |
|
265 form._af_acting = false; |
|
266 return true; |
|
267 } |
|
268 switch(key) |
|
269 { |
|
270 case this.KEY_UP: |
|
271 this.focus_up(); |
|
272 break; |
|
273 case this.KEY_DOWN: |
|
274 this.focus_down(); |
|
275 break; |
|
276 case this.KEY_ESC: |
|
277 this.destroy(); |
|
278 break; |
|
279 case this.KEY_TAB: |
|
280 this.destroy(); |
|
281 break; |
|
282 case this.KEY_ENTER: |
|
283 this.set(); |
|
284 break; |
|
285 } |
|
286 |
|
287 var form = findParentForm($dynano(this.field_id).object); |
|
288 form._af_acting = false; |
|
289 } |
|
290 |
|
291 this.get_state_td = function() |
|
292 { |
|
293 var div = document.getElementById(this.box_id); |
|
294 if ( !div ) |
|
295 return false; |
|
296 if ( !this.state ) |
|
297 return false; |
|
298 var table = div.firstChild; |
|
299 for ( var i = 1; i < table.childNodes.length; i++ ) |
|
300 { |
|
301 // the table is DOM-constructed so no cruddy HTML hacks :-) |
|
302 var child = table.childNodes[i]; |
|
303 var tn = child.firstChild.firstChild; |
|
304 if ( tn.nodeValue == this.state ) |
|
305 return child.firstChild; |
|
306 } |
|
307 return false; |
|
308 } |
|
309 |
|
310 this.focus_down = function() |
|
311 { |
|
312 var state_td = this.get_state_td(); |
|
313 if ( !state_td ) |
|
314 return false; |
|
315 if ( state_td.parentNode.nextSibling ) |
|
316 { |
|
317 // Ooh boy, DOM stuff can be so complicated... |
|
318 // <tr> → <tr> |
|
319 // ↑ <td> <td> ↓ |
|
320 // user user |
|
321 |
|
322 var newstate = state_td.parentNode.nextSibling.firstChild.firstChild.nodeValue; |
|
323 if ( !newstate ) |
|
324 return false; |
|
325 this.state = newstate; |
|
326 state_td.className = 'row1'; |
|
327 state_td.parentNode.nextSibling.firstChild.className = 'row2'; |
|
328 |
|
329 // Exception - automatically scroll around if the item is off-screen |
|
330 var height = $dynano(this.box_id).Height(); |
|
331 var top = $dynano(this.box_id).object.scrollTop; |
|
332 var scroll_bottom = height + top; |
|
333 |
|
334 var td_top = $dynano(state_td.parentNode.nextSibling.firstChild).Top() - $dynano(this.box_id).Top(); |
|
335 var td_height = $dynano(state_td.parentNode.nextSibling.firstChild).Height(); |
|
336 var td_bottom = td_top + td_height; |
|
337 |
|
338 if ( td_bottom > scroll_bottom ) |
|
339 { |
|
340 var scrollY = td_top - height + 2*td_height - 7; |
|
341 // window.console.debug(scrollY); |
|
342 $dynano(this.box_id).object.scrollTop = scrollY; |
|
343 /* |
|
344 var newtd = state_td.parentNode.nextSibling.firstChild; |
|
345 var a = document.createElement('a'); |
|
346 var id = 'autofill' + Math.floor(Math.random() * 100000); |
|
347 a.name = id; |
|
348 a.id = id; |
|
349 newtd.appendChild(a); |
|
350 window.location.hash = '#' + id; |
|
351 */ |
|
352 |
|
353 // In firefox, scrolling like that makes the field get unfocused |
|
354 $dynano(this.field_id).object.focus(); |
|
355 } |
|
356 } |
|
357 else |
|
358 { |
|
359 return false; |
|
360 } |
|
361 } |
|
362 |
|
363 this.focus_up = function() |
|
364 { |
|
365 var state_td = this.get_state_td(); |
|
366 if ( !state_td ) |
|
367 return false; |
|
368 if ( state_td.parentNode.previousSibling && state_td.parentNode.previousSibling.firstChild.tagName != 'TH' ) |
|
369 { |
|
370 // Ooh boy, DOM stuff can be so complicated... |
|
371 // <tr> ← <tr> |
|
372 // ↓ <td> <td> ↑ |
|
373 // user user |
|
374 |
|
375 var newstate = state_td.parentNode.previousSibling.firstChild.firstChild.nodeValue; |
|
376 if ( !newstate ) |
|
377 { |
|
378 return false; |
|
379 } |
|
380 this.state = newstate; |
|
381 state_td.className = 'row1'; |
|
382 state_td.parentNode.previousSibling.firstChild.className = 'row2'; |
|
383 |
|
384 // Exception - automatically scroll around if the item is off-screen |
|
385 var top = $dynano(this.box_id).object.scrollTop; |
|
386 |
|
387 var td_top = $dynano(state_td.parentNode.previousSibling.firstChild).Top() - $dynano(this.box_id).Top(); |
|
388 |
|
389 if ( td_top < top ) |
|
390 { |
|
391 $dynano(this.box_id).object.scrollTop = td_top - 10; |
|
392 /* |
|
393 var newtd = state_td.parentNode.previousSibling.firstChild; |
|
394 var a = document.createElement('a'); |
|
395 var id = 'autofill' + Math.floor(Math.random() * 100000); |
|
396 a.name = id; |
|
397 a.id = id; |
|
398 newtd.appendChild(a); |
|
399 window.location.hash = '#' + id; |
|
400 */ |
|
401 |
|
402 // In firefox, scrolling like that makes the field get unfocused |
|
403 $dynano(this.field_id).object.focus(); |
|
404 } |
|
405 } |
|
406 else |
|
407 { |
|
408 $dynano(this.box_id).object.scrollTop = 0; |
|
409 return false; |
|
410 } |
|
411 } |
|
412 |
|
413 this.destroy = function() |
|
414 { |
|
415 this.repeat = false; |
|
416 var body = document.getElementsByTagName('body')[0]; |
|
417 var div = document.getElementById(this.box_id); |
|
418 if ( !div ) |
|
419 return false; |
|
420 setTimeout('var body = document.getElementsByTagName("body")[0]; body.removeChild(document.getElementById("'+div.id+'"));', 20); |
|
421 // hackish workaround for divs that stick around past their welcoming period |
|
422 for ( var i = 0; i < this.boxes.length; i++ ) |
|
423 { |
|
424 var div = document.getElementById(this.boxes[i]); |
|
425 if ( div ) |
|
426 setTimeout('var body = document.getElementsByTagName("body")[0]; var div = document.getElementById("'+div.id+'"); if ( div ) body.removeChild(div);', 20); |
|
427 delete(this.boxes[i]); |
|
428 } |
|
429 this.boxes = new Array(); |
|
430 this.box_id = false; |
|
431 this.state = false; |
|
432 } |
|
433 |
|
434 this.set = function(val) |
|
435 { |
|
436 var ta = document.getElementById(this.field_id); |
|
437 if ( val ) |
|
438 ta.value = val; |
|
439 else if ( this.state ) |
|
440 ta.value = this.state; |
|
441 this.destroy(); |
|
442 findParentForm($dynano(this.field_id.object))._af_acting = false; |
|
443 } |
|
444 |
|
445 this.sleep = function() |
|
446 { |
|
447 if ( this.box_id ) |
|
448 { |
|
449 var div = document.getElementById(this.box_id); |
|
450 div.style.display = 'none'; |
|
451 } |
|
452 var el = $dynano(this.field_id).object; |
|
453 var fr = findParentForm(el); |
|
454 el._af_acting = false; |
|
455 } |
|
456 |
|
457 this.wake = function() |
|
458 { |
|
459 if ( this.box_id ) |
|
460 { |
|
461 var div = document.getElementById(this.box_id); |
|
462 div.style.display = 'block'; |
|
463 } |
|
464 } |
|
465 |
|
466 parent.onblur = function() |
|
467 { |
|
468 af_current = this.afobj; |
|
469 window.setTimeout('if ( af_current ) af_current.sleep(); af_current = false;', 50); |
|
470 } |
|
471 |
|
472 parent.onfocus = function() |
|
473 { |
|
474 af_current = this.afobj; |
|
475 window.setTimeout('if ( af_current ) af_current.wake(); af_current = false;', 50); |
|
476 } |
|
477 |
|
478 parent.afobj = this; |
|
479 var frm = findParentForm(parent); |
|
480 if ( frm.onsubmit ) |
|
481 { |
|
482 frm.orig_onsubmit = frm.onsubmit; |
|
483 frm.onsubmit = function(e) |
|
484 { |
|
485 if ( this._af_acting ) |
|
486 return false; |
|
487 this.orig_onsubmit(e); |
|
488 } |
|
489 } |
|
490 else |
|
491 { |
|
492 frm.onsubmit = function() |
|
493 { |
|
494 if ( this._af_acting ) |
|
495 return false; |
|
496 } |
|
497 } |
|
498 |
|
499 if ( parent.value.length < 3 ) |
|
500 { |
|
501 this.destroy(); |
|
502 return false; |
|
503 } |
|
504 } |
144 } |
505 |
145 |
506 function findParentForm(o) |
146 function findParentForm(o) |
507 { |
147 { |
508 if ( o.tagName == 'FORM' ) |
148 if ( o.tagName == 'FORM' ) |