Portal Two update and bug fixes (#1860)
[openemr.git] / library / js / report_helper.js
blob5cacc2c1c5149cadad9f3b29512b8221ca8fd4c1
1 /**
2  * report_helper.js
3  *
4  * JavaScript functions to enhance reports.
5  *
6  * LICENSE: This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 3
9  * of the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see
16  * http://www.gnu.org/licenses/licenses.html#GPL .
17  *
18  * @package OpenEMR
19  * @license http://www.gnu.org/licenses/licenses.html#GPL GNU GPL V3+
20  * @author  Rod Roark <rod@sunsetsystems.com>
21  * @link    http://www.open-emr.org
22  */
24 var oeFixedHeaderSrc;     // the report's main table
25 var oeFixedHeaderNew;     // our clone of the table with just its thead
26 var oeFixedHeaderPad = 0; // fudge factor for cell padding
28 // Call this to manage a table that has a <thead> section, so that the header will
29 // appear to be fixed at the top of the window while the rest of the table scrolls.
31 function oeFixedHeaderSetup(tbl) {
32   if (!tbl) return;
33   // Here we make a clone of the original table that contains only a copy of its thead
34   // and all the contents of that thead.  It is initially invisible and always fixed in
35   // position at the top of the window.
36   oeFixedHeaderNew = tbl.cloneNode(false);
37   oeFixedHeaderNew.id = ''; // remove id because duplicates not allowed
38   oeFixedHeaderNew.style.tableLayout = 'fixed'; // this improves matching of column widths
39   oeFixedHeaderNew.style.position = 'fixed';
40   oeFixedHeaderNew.style.visibility = 'hidden';
41   oeFixedHeaderNew.appendChild(tbl.tHead.cloneNode(true));
42   // If there is more than one header row then create a dummy empty clone of the last at the top.
43   // This is a kludge because it does not work to set widths for any rows other than the first.
44   // We assume the last row is the most "detailed" and so setting its cell widths is enough.
45   var nrows = oeFixedHeaderNew.rows.length;
46   if (nrows > 1) {
47     var zrow = oeFixedHeaderNew.rows[nrows - 1].cloneNode(true);
48     for (var c = 0; c < zrow.cells.length; ++c) {
49       zrow.cells[c].innerHTML = '';
50       zrow.cells[c].style.height = '0px';
51       zrow.cells[c].style.padding = '0px';
52       zrow.cells[c].style.borderWidth = '0px';
53       zrow.cells[c].style.borderStyle = 'none';
54     }
55     zrow.style.height = '0px';
56     zrow.style.borderWidth = '0px';
57     zrow.style.borderStyle = 'none';
58     oeFixedHeaderNew.rows[0].parentNode.insertBefore(zrow, oeFixedHeaderNew.rows[0]);
59   }
60   // Position this new table after the original table in the DOM so it will appear on top.
61   tbl.parentNode.appendChild(oeFixedHeaderNew);
62   oeFixedHeaderNew.style.marginTop = '0px';
63   oeFixedHeaderNew.style.top = '0px';
64   oeFixedHeaderSrc = tbl;
65   window.onresize = oeFixedHeaderRepos;
66   window.onscroll = oeFixedHeaderRepos;
69 // This is invoked whenever the window or frame resizes or scrolls.  It sets the table
70 // and column widths and horizontal position of the clone table to match the original table,
71 // and makes it visible or not depending on scroll position.
73 function oeFixedHeaderRepos() {
74   var toppos = oeFixedHeaderSrc.offsetTop - $(window).scrollTop();
75   if (toppos < 0) {
76     oeFixedHeaderNew.style.left  = oeFixedHeaderSrc.offsetLeft - $(window).scrollLeft();
77     oeFixedHeaderNew.style.width = oeFixedHeaderSrc.offsetWidth + 'px';
78     // Set cell widths to match. In the case where there is more than one header row, we
79     // copy widths from the last one to the first one in the target row. See above comments.
80     var hrow = oeFixedHeaderSrc.rows[oeFixedHeaderNew.rows.length - 1];
81     for (var i = 0; i < hrow.cells.length; ++i) {
82       var width = hrow.cells[i].offsetWidth;
83       var newcell = oeFixedHeaderNew.rows[0].cells[i];
84       newcell.style.width = (width - oeFixedHeaderPad) + 'px';
85       // offsetWidth includes some padding that style.width does not include,
86       // so oeFixedHeaderPad is to compensate for the difference.
87       var tmp = newcell.offsetWidth - width;
88       if (tmp != 0) {
89         oeFixedHeaderPad += tmp;
90         newcell.style.width = (width - oeFixedHeaderPad) + 'px';
91       }
92       // oeFixedHeaderNew.rows[0].cells[i].innerHTML = oeFixedHeaderPad; // debugging
93     }
94     oeFixedHeaderNew.style.visibility = 'visible';
95   }
96   else {
97     oeFixedHeaderNew.style.visibility = 'hidden';
98   }