Further fixes to javascript multiple class handling.
[fa-stable.git] / js / inserts.js
index e15da1efe2ee42485a6dab5d67ce153f9501c6cd..0dd141650f64203d2f864004ae8fd926f0d11728 100644 (file)
@@ -1,11 +1,11 @@
 /**********************************************************************
     Copyright (C) FrontAccounting, LLC.
 /**********************************************************************
     Copyright (C) FrontAccounting, LLC.
-       Released under the terms of the GNU General Public License, GPL, 
-       as published by the Free Software Foundation, either version 3 
+       Released under the terms of the GNU General Public License, GPL,
+       as published by the Free Software Foundation, either version 3
        of the License, or (at your option) any later version.
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
        of the License, or (at your option) any later version.
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
 ***********************************************************************/
 var _focus;
     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
 ***********************************************************************/
 var _focus;
@@ -46,7 +46,7 @@ function _expand(tabobj) {
 
   if (ul.getAttribute("rel")){
        for (var i=0; i<alltabs.length; i++){
 
   if (ul.getAttribute("rel")){
        for (var i=0; i<alltabs.length; i++){
-         alltabs[i].className = "ajaxbutton"  //deselect all tabs
+         alltabs[i].className = "ajaxbutton"  //deselect all tabs // Review CP 2014-11 This will remove all other classes from the element.
        }
        tabobj.className = "current";
        JsHttpRequest.request(tabobj)
        }
        tabobj.className = "current";
        JsHttpRequest.request(tabobj)
@@ -61,17 +61,17 @@ function expandtab(tabcontentid, tabnumber) {
 
 function _set_combo_input(e) {
                e.setAttribute('_last', e.value);
 
 function _set_combo_input(e) {
                e.setAttribute('_last', e.value);
-               e.onblur=function() { 
+               e.onblur=function() {
                  var but_name = this.name.substring(0, this.name.length-4)+'button';
                  var button = document.getElementsByName(but_name)[0];
                  var select = document.getElementsByName(this.getAttribute('rel'))[0];
                  save_focus(select);
                  var but_name = this.name.substring(0, this.name.length-4)+'button';
                  var button = document.getElementsByName(but_name)[0];
                  var select = document.getElementsByName(this.getAttribute('rel'))[0];
                  save_focus(select);
-// submit request if there is submit_on_change option set and 
+// submit request if there is submit_on_change option set and
 // search field has changed.
 // search field has changed.
-               
+
                  if (button && (this.value != this.getAttribute('_last'))) {
                        JsHttpRequest.request(button);
                  if (button && (this.value != this.getAttribute('_last'))) {
                        JsHttpRequest.request(button);
-                 } else if(this.className=='combo2') {
+                 } else if(string_contains(this.className, 'combo2')) {
                                this.style.display = 'none';
                                select.style.display = 'inline';
                                setFocus(select);
                                this.style.display = 'none';
                                select.style.display = 'inline';
                                setFocus(select);
@@ -82,12 +82,12 @@ function _set_combo_input(e) {
                        var select = document.getElementsByName(this.getAttribute('rel'))[0];
                        if(select && select.selectedIndex>=0) {
                          var len = select.length;
                        var select = document.getElementsByName(this.getAttribute('rel'))[0];
                        if(select && select.selectedIndex>=0) {
                          var len = select.length;
-                         var byid = this.className=='combo' || this.className=='combo3';
+                         var byid = string_contains(this.className, 'combo') || string_contains(this.className, 'combo3');
                          var ac = this.value.toUpperCase();
                          select.options[select.selectedIndex].selected = false;
                          for (i = 0; i < len; i++) {
                                var txt = byid ? select.options[i].value : select.options[i].text;
                          var ac = this.value.toUpperCase();
                          select.options[select.selectedIndex].selected = false;
                          for (i = 0; i < len; i++) {
                                var txt = byid ? select.options[i].value : select.options[i].text;
-                               if (this.className=='combo3') {
+                               if (string_contains(this.className, 'combo3')) {
                                  if(txt.toUpperCase().indexOf(ac) == 0) {
                                        select.options[i].selected = true;
                                        break;
                                  if(txt.toUpperCase().indexOf(ac) == 0) {
                                        select.options[i].selected = true;
                                        break;
@@ -101,7 +101,7 @@ function _set_combo_input(e) {
                          }
                        }
                };
                          }
                        }
                };
-       e.onkeydown = function(ev) { 
+       e.onkeydown = function(ev) {
                        ev = ev||window.event;
                        key = ev.keyCode||ev.which;
                        if(key == 13) {
                        ev = ev||window.event;
                        key = ev.keyCode||ev.which;
                        if(key == 13) {
@@ -112,7 +112,7 @@ function _set_combo_input(e) {
 }
 
 function _update_box(s) {
 }
 
 function _update_box(s) {
-       var byid = s.className=='combo' || s.className=='combo3';
+       var byid = string_contains(s.className, 'combo') || string_contains(s.className, 'combo3');
        var rel = s.getAttribute('rel');
        var box = document.getElementsByName(rel)[0];
                if(box && s.selectedIndex>=0) {
        var rel = s.getAttribute('rel');
        var box = document.getElementsByName(rel)[0];
                if(box && s.selectedIndex>=0) {
@@ -128,29 +128,29 @@ function _update_box(s) {
 
 function _set_combo_select(e) {
                // When combo position is changed via js (eg from searchbox)
 
 function _set_combo_select(e) {
                // When combo position is changed via js (eg from searchbox)
-               // no onchange event is generated. To ensure proper change 
+               // no onchange event is generated. To ensure proper change
                // signaling we must track selectedIndex in onblur handler.
                e.setAttribute('_last', e.selectedIndex);
                e.onblur = function() {
                    var box = document.getElementsByName(this.getAttribute('rel'))[0];
                // signaling we must track selectedIndex in onblur handler.
                e.setAttribute('_last', e.selectedIndex);
                e.onblur = function() {
                    var box = document.getElementsByName(this.getAttribute('rel'))[0];
-//                     if(this.className=='combo')
+//                     if(string_contains(this.className, 'combo'))
 //                         _update_box(this);
                        if ((this.selectedIndex != this.getAttribute('_last'))
 //                         _update_box(this);
                        if ((this.selectedIndex != this.getAttribute('_last'))
-                               ||((this.className=='combo' || this.className=='combo3') && _update_box(this))
+                               ||((string_contains(this.className, 'combo') || string_contains(this.className, 'combo3')) && _update_box(this))
                                )
                                        this.onchange();
                }
                e.onchange = function() {
                        var s = this;
                        this.setAttribute('_last', this.selectedIndex);
                                )
                                        this.onchange();
                }
                e.onchange = function() {
                        var s = this;
                        this.setAttribute('_last', this.selectedIndex);
-                       if(s.className=='combo' || this.className=='combo3')
+                       if(string_contains(s.className, 'combo') || string_contains(this.className, 'combo3'))
                            _update_box(s);
                        if(s.selectedIndex>=0) {
                                 var sname = '_'+s.name+'_update';
                                 var update = document.getElementsByName(sname)[0];
                                 if(update) {
                                            JsHttpRequest.request(update);
                            _update_box(s);
                        if(s.selectedIndex>=0) {
                                 var sname = '_'+s.name+'_update';
                                 var update = document.getElementsByName(sname)[0];
                                 if(update) {
                                            JsHttpRequest.request(update);
-                               } 
+                               }
                        }
                        return true;
                }
                        }
                        return true;
                }
@@ -162,7 +162,7 @@ function _set_combo_select(e) {
                                event.returnValue = false;
                                return false;
                        }
                                event.returnValue = false;
                                return false;
                        }
-                   if (box && (key == 32) && (this.className == 'combo2')) {
+                   if (box && (key == 32) && (string_contains(this.className, 'combo2'))) {
                            this.style.display = 'none';
                            box.style.display = 'inline';
                                box.value='';
                            this.style.display = 'none';
                            box.style.display = 'inline';
                                box.value='';
@@ -178,7 +178,7 @@ function _set_combo_select(e) {
 var _w;
 
 function callEditor(key) {
 var _w;
 
 function callEditor(key) {
-  var el = document.getElementsByName(editors[key][1])[0]; 
+  var el = document.getElementsByName(editors[key][1])[0];
   if(_w) _w.close(); // this is really necessary to have window on top in FF2 :/
   var left = (screen.width - editors[key][2]) / 2;
   var top = (screen.height - editors[key][3]) / 2;
   if(_w) _w.close(); // this is really necessary to have window on top in FF2 :/
   var left = (screen.width - editors[key][2]) / 2;
   var top = (screen.height - editors[key][3]) / 2;
@@ -186,7 +186,7 @@ function callEditor(key) {
          "edit","scrollbars=yes,resizable=0,width="+editors[key][2]+",height="+editors[key][3]+",left="+left+",top="+top+",screenX="+left+",screenY="+top);
   if (_w.opener == null)
          _w.opener = self;
          "edit","scrollbars=yes,resizable=0,width="+editors[key][2]+",height="+editors[key][3]+",left="+left+",top="+top+",screenX="+left+",screenY="+top);
   if (_w.opener == null)
          _w.opener = self;
-  editors._call = key; // store call point for passBack 
+  editors._call = key; // store call point for passBack
   _w.focus();
 }
 
   _w.focus();
 }
 
@@ -196,7 +196,7 @@ function passBack(value) {
                var back = o.editors[o.editors._call]; // form input bindings
                var to = o.document.getElementsByName(back[1])[0];
                if (to) {
                var back = o.editors[o.editors._call]; // form input bindings
                var to = o.document.getElementsByName(back[1])[0];
                if (to) {
-                       if (to[0] != undefined) 
+                       if (to[0] != undefined)
                                to[0].value = value; // ugly hack to set selector to any value
                        to.value = value;
                        // update page after item selection
                                to[0].value = value; // ugly hack to set selector to any value
                        to.value = value;
                        // update page after item selection
@@ -207,6 +207,67 @@ function passBack(value) {
        close();
 }
 
        close();
 }
 
+/*
+       Normalize date format using previous input value to guess missing date elements.
+       Helps fast date input field change with only single or double numbers (for day or day-and-month fragments)
+*/
+function fix_date(date, last)
+{
+       var dat = last.split(user.datesep);
+       var cur = date.split(user.datesep);
+       var day, month, year;
+
+// TODO: user.date as default?
+// TODO: user.datesys
+       if (date == "" || date == last) // should we return an empty date or should we return last?
+               return date;
+       if (user.datefmt == 0 || user.datefmt == 3) // set defaults
+       {
+               day = dat[1]; month = dat[0]; year = dat[2];
+       } else if (user.datefmt == 1 || user.datefmt == 4){
+               day = dat[0]; month = dat[1]; year = dat[2];
+       } else {
+               day = dat[2]; month = dat[1]; year = dat[0];
+       }
+       if (cur[1] != undefined && cur[1] != "") // day or month entered, could be string 3
+       {
+               if (user.datefmt == 0 || user.datefmt == 3 || ((user.datefmt == 2 || user.datefmt == 5) && (cur[2] == undefined || cur[2] == "")))
+                       day = cur[1];
+               else
+                       month = cur[1];
+       }
+       if (cur[0] != undefined && cur[0] != "") // day or month entered. could be string 3
+       {
+               if (cur[1] == undefined || cur[1] == "")
+                       day = cur[0];
+               else if (user.datefmt == 0 || user.datefmt == 3 || ((user.datefmt == 2 || user.datefmt == 5) && (cur[2] == undefined || cur[2] == "")))
+                       month = cur[0];
+               else if (user.datefmt == 2 || user.datefmt == 5)
+                       year = cur[0];
+               else
+                       day = cur[0];
+       }
+       if (cur[2] != undefined && cur[2] != "") // year,
+       {
+               if (user.datefmt == 2 || user.datefmt == 5)
+                       day = cur[2];
+               else
+                       year = cur[2];
+       }
+       if (user.datefmt<3) {
+               if (day<10) day = '0'+parseInt(day, 10);
+               if (month<10) month = '0'+parseInt(month, 10);
+       }
+       if (year<100) year = year<60 ? (2000+parseInt(year,10)) : (1900+parseInt(year,10));
+
+//     console.info(day,month,year)
+       if (user.datefmt == 0 || user.datefmt==3)
+               return month+user.datesep+day+user.datesep+year;
+       if (user.datefmt == 1 || user.datefmt==4)
+               return day+user.datesep+month+user.datesep+year;
+       return year+user.datesep+month+user.datesep+day;
+}
+
 /*
  Behaviour definitions
 */
 /*
  Behaviour definitions
 */
@@ -214,33 +275,33 @@ var inserts = {
        'input': function(e) {
                if(e.onfocus==undefined) {
                        e.onfocus = function() {
        'input': function(e) {
                if(e.onfocus==undefined) {
                        e.onfocus = function() {
-                           save_focus(this);
-                               if (this.className == 'combo' || this.className == 'combo3') 
+                               save_focus(this);
+                               if (string_contains(this.className, 'combo') || string_contains(this.className, 'combo3'))
                                        this.select();
                        };
                }
                                        this.select();
                        };
                }
-               if (e.className == 'combo' || e.className == 'combo2' || e.className == 'combo3') {
+               if (string_contains(e.className, 'combo') || string_contains(e.className, 'combo2') || string_contains(e.className, 'combo3')) {
                                _set_combo_input(e);
                                _set_combo_input(e);
-               } 
+               }
                else
                if(e.type == 'text' ) {
                else
                if(e.type == 'text' ) {
-                               e.onkeydown = function(ev) { 
+                               e.onkeydown = function(ev) {
                                        ev = ev||window.event;
                                        key = ev.keyCode||ev.which;
                                        if(key == 13) {
                                                if(e.className == 'searchbox') e.onblur();
                                                return false;
                                        ev = ev||window.event;
                                        key = ev.keyCode||ev.which;
                                        if(key == 13) {
                                                if(e.className == 'searchbox') e.onblur();
                                                return false;
-                                       } 
+                                       }
                                        return true;
                                }
                        }
        },
                                        return true;
                                }
                        }
        },
-       'input.combo2,input[aspect="fallback"]': 
+       'input.combo2,input[aspect="fallback"]':
        function(e) {
            // this hides search button for js enabled browsers
            e.style.display = 'none';
        },
        function(e) {
            // this hides search button for js enabled browsers
            e.style.display = 'none';
        },
-       'div.js_only': 
+       'div.js_only':
        function(e) {
            // this shows divs for js enabled browsers only
            e.style.display = 'block';
        function(e) {
            // this shows divs for js enabled browsers only
            e.style.display = 'block';
@@ -265,7 +326,7 @@ var inserts = {
 
        },
 //     '.ajaxsubmit,.editbutton,.navibutton': // much slower on IE7
 
        },
 //     '.ajaxsubmit,.editbutton,.navibutton': // much slower on IE7
-       'button.ajaxsubmit,input.ajaxsubmit,input.editbutton,button.editbutton,button.navibutton': 
+       'button.ajaxsubmit,input.ajaxsubmit,input.editbutton,button.editbutton,button.navibutton':
        function(e) {
                        e.onclick = function() {
                                if (validate(e)) {
        function(e) {
                        e.onclick = function() {
                                if (validate(e)) {
@@ -299,6 +360,20 @@ var inserts = {
                                }
                        }
        },
                                }
                        }
        },
+       '.date':
+               function(e) {
+                       e.setAttribute('_last_val', e.value);
+                       e.setAttribute('autocomplete', 'off');
+                       e.onblur = function() {
+                               var val = this.getAttribute('_last_val');
+                               if (val != this.value) {
+                                       this.value = fix_date(this.value, val);
+                                       this.setAttribute('_last_val', this.value);
+                                       if (e.className.match(/\bactive\b/))
+                                               JsHttpRequest.request('_'+this.name+'_changed', this.form);
+                               }
+                       }
+       },
        'button[aspect*selector], button[aspect*abort], input[aspect*selector]': function(e) {
                e.onclick = function() {
                        passBack(this.getAttribute('rel'));
        'button[aspect*selector], button[aspect*abort], input[aspect*selector]': function(e) {
                e.onclick = function() {
                        passBack(this.getAttribute('rel'));
@@ -314,7 +389,7 @@ var inserts = {
                                  "edit","Scrollbars=0,resizable=0,width=800,height=600, top="+top+",left="+left+",screenX="+left+",screenY="+top);
                          if (_w.opener == null)
                                  _w.opener = self;
                                  "edit","Scrollbars=0,resizable=0,width=800,height=600, top="+top+",left="+left+",screenX="+left+",screenY="+top);
                          if (_w.opener == null)
                                  _w.opener = self;
-                       //  editors._call = key; // store call point for passBack 
+                       //  editors._call = key; // store call point for passBack
 //                       _w.moveTo(50, 50);
                          _w.focus();
                        return false;
 //                       _w.moveTo(50, 50);
                          _w.focus();
                        return false;
@@ -327,7 +402,7 @@ var inserts = {
                        };
                }
                var c = e.className;
                        };
                }
                var c = e.className;
-               if (c == 'combo' || c == 'combo2' || c == 'combo3')
+               if (string_contains(c, 'combo') || string_contains(c, 'combo2') || string_contains(c, 'combo3'))
                        _set_combo_select(e);
                else {
                        e.onkeydown = function(ev) {    // block unintentional page escape with 'history back' key pressed on buttons
                        _set_combo_select(e);
                else {
                        e.onkeydown = function(ev) {    // block unintentional page escape with 'history back' key pressed on buttons
@@ -358,7 +433,7 @@ var inserts = {
                }
        },
        'a': function(e) { // traverse menu
                }
        },
        'a': function(e) { // traverse menu
-               e.onkeydown = function(ev) { 
+               e.onkeydown = function(ev) {
                        ev = ev||window.event;
                        key = ev.keyCode||ev.which;
                        if(key==37 || key==38 || key==39 || key==40) {
                        ev = ev||window.event;
                        key = ev.keyCode||ev.which;
                        if(key==37 || key==38 || key==39 || key==40) {
@@ -368,18 +443,20 @@ var inserts = {
                        }
                }
                // prevent unneeded transaction entry abortion
                        }
                }
                // prevent unneeded transaction entry abortion
-               if (e.className == 'shortcut' 
-                || e.className == 'menu_option' 
+               if (e.className == 'shortcut'
+                || e.className == 'menu_option'
                 || e.className == 'menu_tab'
                 || e.className == 'selected')
                        e.onclick = function(ev) {
                 || e.className == 'menu_tab'
                 || e.className == 'selected')
                        e.onclick = function(ev) {
-                               if (_validate._processing 
+                               if (_validate._processing
                                 && _validate._modified
                                 && !confirm(_validate._processing)) {
                                        ev.returnValue = false;
                                        return false;
                                }
                                 && _validate._modified
                                 && !confirm(_validate._processing)) {
                                        ev.returnValue = false;
                                        return false;
                                }
-                               window.location = e.href;
+                               if (_hotkeys.alt)       // ommit Chrome accesskeys
+                                       return false;
+                               window.location = e.href;
                        }
        },
        'ul.ajaxtabs':  function(ul) {
                        }
        },
        'ul.ajaxtabs':  function(ul) {
@@ -390,7 +467,8 @@ var inserts = {
 // ?  var modifiedurl=ulistlink.getAttribute("href").replace(/^http:\/\/[^\/]+\//i, "http://"+window.location.hostname+"/")
                    var url = tab.form.action
                    tab.onclick=function(){
 // ?  var modifiedurl=ulistlink.getAttribute("href").replace(/^http:\/\/[^\/]+\//i, "http://"+window.location.hostname+"/")
                    var url = tab.form.action
                    tab.onclick=function(){
-                       _expand(this);
+                   if (!_hotkeys.alt && !tab.disabled)
+                               _expand(this);
                        return false;
                    }
                }
                        return false;
                    }
                }
@@ -404,12 +482,12 @@ var inserts = {
                }
        }
 /*     'tr.editrow': function(e) {
                }
        }
 /*     'tr.editrow': function(e) {
-                       e.onkeydown = function(ev) { 
+                       e.onkeydown = function(ev) {
                        ev = ev||window.event;
                        key = ev.keyCode||ev.which;
                        if(key == 13) {
                          // Find & click additem/update button
                        ev = ev||window.event;
                        key = ev.keyCode||ev.which;
                        if(key == 13) {
                          // Find & click additem/update button
-                         
+
                        } else  if(key == 27) {
                          return false;
                        }
                        } else  if(key == 27) {
                          return false;
                        }
@@ -442,7 +520,7 @@ function stopEv(ev) {
                        return false;
 }
 /*
                        return false;
 }
 /*
-       Modified accesskey system. While Alt key is pressed letter keys moves 
+       Modified accesskey system. While Alt key is pressed letter keys moves
        focus to next marked link. Alt key release activates focused link.
 */
 function setHotKeys() {
        focus to next marked link. Alt key release activates focused link.
 */
 function setHotKeys() {
@@ -460,10 +538,10 @@ function setHotKeys() {
                        var l = document.getElementsBySelector('[accesskey='+key+']');
                        var cnt = l.length;
                        _hotkeys.list = l;
                        var l = document.getElementsBySelector('[accesskey='+key+']');
                        var cnt = l.length;
                        _hotkeys.list = l;
-                       for (var i=0; i<cnt; i++) { 
+                       for (var i=0; i<cnt; i++) {
                                n = (n+1)%cnt;
                                // check also if the link is visible
                                n = (n+1)%cnt;
                                // check also if the link is visible
-                               if (l[n].accessKey==key && l[n].scrollWidth) {
+                               if (l[n].accessKey==key && (l[n].offsetWidth || l[n].offsetHeight)) {
                                        _hotkeys.focus = n;
            // The timeout is needed to prevent unpredictable behaviour on IE.
                                        var tmp = function() {l[_hotkeys.focus].focus();};
                                        _hotkeys.focus = n;
            // The timeout is needed to prevent unpredictable behaviour on IE.
                                        var tmp = function() {l[_hotkeys.focus].focus();};
@@ -485,7 +563,7 @@ function setHotKeys() {
                                        var el = form.elements[i];
                                        var asp = el.getAttribute('aspect');
 
                                        var el = form.elements[i];
                                        var asp = el.getAttribute('aspect');
 
-                                       if (el.className!='editbutton' && (asp && asp.indexOf('selector') !== -1) && (key==13 || key==27)) {
+                                       if (!string_contains(el.className, 'editbutton') && (asp && asp.indexOf('selector') !== -1) && (key==13 || key==27)) {
                                                passBack(key==13 ? el.getAttribute('rel') : false);
                                                ev.returnValue = false;
                                                return false;
                                                passBack(key==13 ? el.getAttribute('rel') : false);
                                                ev.returnValue = false;
                                                return false;
@@ -508,10 +586,10 @@ function setHotKeys() {
                        ev.returnValue = false;
                        return false;
                }
                        ev.returnValue = false;
                        return false;
                }
-               if (editors && editors[key]) {
+               if (editors!=='undefined' && editors[key]) {
                        callEditor(key);
                        return stopEv(ev); // prevent default binding
                        callEditor(key);
                        return stopEv(ev); // prevent default binding
-               } 
+               }
                return true;
        };
        document.onkeyup = function(ev) {
                return true;
        };
        document.onkeyup = function(ev) {
@@ -523,7 +601,7 @@ function setHotKeys() {
                                _hotkeys.alt = false;
                                if (_hotkeys.focus >= 0) {
                                        var link = _hotkeys.list[_hotkeys.focus];
                                _hotkeys.alt = false;
                                if (_hotkeys.focus >= 0) {
                                        var link = _hotkeys.list[_hotkeys.focus];
-                                       if(link.onclick) 
+                                       if(link.onclick)
                                                link.onclick();
                                        else
                                                if (link.target=='_blank') {
                                                link.onclick();
                                        else
                                                if (link.target=='_blank') {
@@ -533,7 +611,7 @@ function setHotKeys() {
                                                        window.location = link.href;
                                }
                        return stopEv(ev);
                                                        window.location = link.href;
                                }
                        return stopEv(ev);
-                       } 
+                       }
                }
                return true;
        }
                }
                return true;
        }