Hotkey support for viewer links.
[fa-stable.git] / js / inserts.js
1 var _focus;
2 var _hotkeys = {
3         'alt': false,   // whether is the Alt key pressed
4         'focus': -1     // currently selected indeks of document.links
5 };
6
7 function debug(msg) {
8     box = document.getElementById('msgbox')
9         box.innerHTML= box.innerHTML+'<br>'+msg
10 }
11
12 function progbar() {
13         box = document.getElementById('msgbox');
14     box.innerHTML= "<center><table width='98%' border='1' cellpadding=3 "
15         +"bordercolor='#007700' style='border-collapse: collapse'>"
16         +"<tr><td align='center' bgcolor='#ccffcc' >"
17                 +"<img src='"+user.theme+"images/progressbar.gif' alt='"
18                 +user.loadtxt+"' /></td></tr></table></center><br>";
19         box.style.display = 'block';
20 }
21
22 function save_focus(e) {
23   _focus = e.name||e.id;
24   var h = document.getElementById('hints');
25   if (h) {
26         h.style.display = e.title && e.title.length ? 'inline' : 'none';
27         h.innerHTML = e.title ? e.title : '';
28   }
29 }
30
31 function _expand(tabobj) {
32
33   var ul = tabobj.parentNode.parentNode;
34   var alltabs=ul.getElementsByTagName("input");
35   var frm = tabobj.form;
36
37   if (ul.getAttribute("rel")){
38         for (var i=0; i<alltabs.length; i++){
39           alltabs[i].className = "ajaxbutton"  //deselect all tabs
40         }
41         tabobj.className = "current";
42         JsHttpRequest.request(tabobj)
43   }
44 }
45
46 //interface for selecting a tab (plus expand corresponding content)
47 function expandtab(tabcontentid, tabnumber) {
48   var tabs = document.getElementById(tabcontentid);
49  _expand(tabs.getElementsByTagName("input")[tabnumber]);
50 }
51
52 function _set_combo_input(e) {
53                 e.setAttribute('_last', e.value);
54                 e.onblur=function() { 
55                   var but_name = this.name.substring(0, this.name.length-4)+'button';
56                   var button = document.getElementsByName(but_name)[0];
57                   var select = document.getElementsByName(this.getAttribute('rel'))[0];
58                   save_focus(select);
59 // submit request if there is submit_on_change option set and 
60 // search field has changed.
61                   if (button && (this.value != this.getAttribute('_last'))) {
62                         JsHttpRequest.request(button);
63                   } else if(this.className=='combo2') {
64                                 this.style.display = 'none';
65                                 select.style.display = 'inline';
66                                 setFocus(select.name);
67                   }
68                   return false;
69                 };
70                 e.onkeyup = function(ev) {
71                         var select = document.getElementsByName(this.getAttribute('rel'))[0];
72                         if(select && select.selectedIndex>=0) {
73                           var len = select.length;
74                           var byid = this.className=='combo';
75                           var ac = this.value.toUpperCase();
76                           select.options[select.selectedIndex].selected = false;
77                           for (i = 0; i < len; i++) {
78                                 var txt = byid ? select.options[i].value : select.options[i].text;
79                                 if (txt.toUpperCase().indexOf(ac) >= 0) {
80                                   select.options[i].selected = true;
81                                   break;
82                                 }
83                           }
84                         }
85                 };
86         e.onkeydown = function(ev) { 
87                         ev = ev||window.event;
88                         key = ev.keyCode||ev.which;
89                         if(key == 13) {
90                           this.blur();
91                           return false;
92                         }
93                 }
94 }
95
96 function _update_box(s) {
97         var byid = s.className=='combo';
98         var rel = s.getAttribute('rel');
99         var box = document.getElementsByName(rel)[0];
100                 if(box && s.selectedIndex>=0) {
101                           var opt = s.options[s.selectedIndex];
102                                 if(box) {
103                                   box.value = byid ? opt.value : opt.text;
104                                   box.setAttribute('_last', box.value);
105                                 }
106                 }
107 }
108
109 function _set_combo_select(e) {
110                 // When combo position is changed via js (eg from searchbox)
111                 // no onchange event is generated. To ensure proper change 
112                 // signaling we must track selectedIndex in onblur handler.
113                 e.setAttribute('_last', e.selectedIndex);
114                 e.onblur = function() {
115                         if(this.className=='combo')
116                             _update_box(this);
117                         if (this.selectedIndex != this.getAttribute('_last'))
118                                 this.onchange();
119                 }
120                 e.onchange = function() {
121                         var s = this;
122                         this.setAttribute('_last', this.selectedIndex);                 
123                         if(s.className=='combo')
124                             _update_box(s);
125                         if(s.selectedIndex>=0) {
126                                  var sname = '_'+s.name+'_update';
127                                  var update = document.getElementsByName(sname)[0];
128                                  if(update) {
129                                             JsHttpRequest.request(update);
130                                 } 
131                         }
132                         return true;
133                 }
134                 e.onkeydown = function(event) {
135                     event = event||window.event;
136                     key = event.keyCode||event.which;
137                     var box = document.getElementsByName(this.getAttribute('rel'))[0];
138                     if (box && key == 32 && this.className == 'combo2') {
139                             this.style.display = 'none';
140                             box.style.display = 'inline';
141                                 box.value='';
142                                 setFocus(box.name);
143                             return false;
144                          }
145                         if (this.getAttribute('aspect') == 'editable' && key==115) {
146                                 // F4: call related database editor - not available in non-js fallback mode
147                                 JsHttpRequest.request('_'+this.name+'_editor', this.form);
148                                 return false; // prevent default binding
149                                 // TODO: stopPropagation when needed
150                         }
151                 }
152 }               
153
154 /*
155  Behaviour definitions
156 */
157 var inserts = {
158         'form': function(e) {
159                 e.onkeydown = function(ev) { 
160                         ev = ev||window.event;
161                         key = ev.keyCode||ev.which;
162                         if((ev.ctrlKey && key == 13) || key == 27) {
163                                 ev.cancelBubble = true;
164                         if(ev.stopPropagation) ev.stopPropagation();
165 // here ctrl-enter/escape support
166                                 ev.returnValue = false;
167                                 return false;
168                         } 
169                         return true;
170                 }
171         },
172         'input': function(e) {
173                 if(e.onfocus==undefined) {
174                         e.onfocus = function() {
175                             save_focus(this);
176                                 if (this.className == 'combo') 
177                                         this.select();
178                         };
179                 }
180                 if (e.className == 'combo' || e.className == 'combo2') {
181                                 _set_combo_input(e);
182                 } 
183                 else
184                 if(e.type == 'text' ) {
185                                 e.onkeydown = function(ev) { 
186                                         ev = ev||window.event;
187                                         key = ev.keyCode||ev.which;
188                                         if(key == 13) {
189                                                 if(e.className == 'searchbox') e.onblur();
190                                                 return false;
191                                         } 
192                                         return true;
193                                 }
194                         }
195         },
196         'input.combo2,input[aspect="fallback"]': 
197         function(e) {
198             // this hides search button for js enabled browsers
199             e.style.display = 'none';
200         },
201         'div.js_only': 
202         function(e) {
203             // this shows divs for js enabled browsers only
204             e.style.display = 'block';
205         },
206 //      '.ajaxsubmit,.editbutton,.navibutton': // much slower on IE7
207         'button.ajaxsubmit,submit.ajaxsubmit,submit.editbutton,submit.navibutton': 
208         function(e) {
209             e.onclick = function() {
210                         if (this.getAttribute('aspect') == 'process')
211                                 progbar();
212                         JsHttpRequest.request(this);
213                         return false;
214             }
215         },
216     '.amount': function(e) {
217                 if(e.onblur==undefined) {
218                   e.onblur = function() {
219                         var dec = this.getAttribute("dec");
220                         price_format(this.name, get_amount(this.name), dec);
221                   };
222                 }
223         },
224         '.searchbox': // emulated onchange event handling for text inputs
225                 function(e) {
226                         e.setAttribute('_last_val', e.value);
227                         e.setAttribute('autocomplete', 'off'); //must be off when calling onblur
228                         e.onblur = function() {
229                                 var val = this.getAttribute('_last_val');
230                                 if (val != this.value) {
231                                         this.setAttribute('_last_val', this.value);
232                                         JsHttpRequest.request('_'+this.name+'_changed', this.form);
233                                 }
234                         }
235 /*              e.onkeydown = function(ev) { 
236                                 ev = ev||window.event;
237                                 key = ev.keyCode||ev.which;
238                                 if (key == 13 && (this.value != this.getAttribute('_last_val'))) {
239                                         this.blur();
240                                         return false;
241                                 }
242                         }
243 */              },
244         'select': function(e) {
245                 if(e.onfocus==undefined) {
246                         e.onfocus = function() {
247                             save_focus(this);
248                         };
249                   var c = e.className;
250                   if (c == 'combo' || c == 'combo2')
251                         _set_combo_select(e);
252                 }
253         },
254         'textarea,a': function(e) {
255                 if(e.onfocus==undefined) {
256                         e.onfocus = function() {
257                             save_focus(this);
258                         };
259                 }
260         },
261         'a.printlink':  function(l) {
262                 l.onclick = function() {
263                     save_focus(this);
264                         JsHttpRequest.request(this);
265                         return false;
266                 }
267         },
268         'ul.ajaxtabs':  function(ul) {
269             var ulist=ul.getElementsByTagName("li");
270             for (var x=0; x<ulist.length; x++){ //loop through each LI e
271                 var ulistlink=ulist[x].getElementsByTagName("input")[0];
272                 if(ulistlink.onclick==undefined) {
273 // ?  var modifiedurl=ulistlink.getAttribute("href").replace(/^http:\/\/[^\/]+\//i, "http://"+window.location.hostname+"/")
274                     var url = ulistlink.form.action
275                     ulistlink.onclick=function(){
276                         _expand(this);
277                         return false;
278                     }
279                 }
280             }
281         },
282         '#msgbox': function(e) {
283         // this is to avoid changing div height after ajax update in IE7
284           e.style.display = e.innerHTML.length ? 'block' : 'none';
285         }
286 /* TODO
287         'a.date_picker':  function(e) {
288             // this un-hides data picker for js enabled browsers
289             e.href = date_picker(this.getAttribute('rel'));
290             e.style.display = '';
291             e.tabindex = -1; // skip in tabbing order
292         }
293 */
294 };
295 function stopEv(ev) {
296                         ev.returnValue = false;
297                         ev.cancelBubble = true;
298                         if(ev.preventDefault) ev.preventDefault();
299                         return false;
300 }
301 /*
302         Modified accesskey system. While Alt key is pressed letter keys moves 
303         focus to next marked link. Alt key release activates focused link.
304 */
305 function setHotKeys() {
306         document.onkeydown = function(ev) {
307                 ev = ev||window.event;
308                 key = ev.keyCode||ev.which;
309                 if (key == 18) {        // start selection
310                         _hotkeys.alt = true;
311                         _hotkeys.focus = -1;
312                         return stopEv(ev);
313                 } else
314                 if (key == 27) { // cancel selection
315                         _hotkeys.alt = false;
316                         _hotkeys.focus = -1;
317                         return stopEv(ev);
318                 } 
319                 else if (_hotkeys.alt && ((key>47 && key<58) || (key>64 && key<91))) {
320                         var n = _hotkeys.focus;
321                         var l = document.links;
322                         var cnt = l.length;
323                         key = String.fromCharCode(key);
324                         for (var i=0; i<cnt; i++) { 
325                                 n = (n+1)%cnt;
326                                 // check also if the link is visible
327                                 if (l[n].accessKey==key && l[n].scrollWidth) {
328                                         _hotkeys.focus = n;
329             // The timeout is needed to prevent unpredictable behaviour on IE.
330                                         var tmp = function() {document.links[_hotkeys.focus].focus();};
331                                         setTimeout(tmp, 0);
332                                         break;
333                                 }
334                         }
335                         return stopEv(ev);
336                 }
337                 return true;
338         };
339         document.onkeyup = function(ev) {
340                 if (_hotkeys.alt==true) {
341                         ev = ev||window.event;
342                         key = ev.keyCode||ev.which;
343
344                         if (key == 18) {
345                                 _hotkeys.alt = false;
346                                 if (_hotkeys.focus>=0) {
347                                         var link = document.links[_hotkeys.focus];
348                                         if (link.target=='_blank') {
349 //                                              window.open(link.href,'','toolbar=no,scrollbar=no,resizable=yes,menubar=no,width=900,height=500');
350                                                 openWindow(link.href,'_blank');
351                                         } else
352                                                 window.location = link.href;
353                                 }
354                         } 
355                         return stopEv(ev);
356                 }
357                 return true;
358         }
359 }
360
361 Behaviour.register(inserts);
362
363 Behaviour.addLoadEvent(setFocus);
364 Behaviour.addLoadEvent(setHotKeys);