1c1dd91e |
1 | // +--------------------------------------------------------------------+ |
2 | // | CiviCRM version 4.2 | |
3 | // +--------------------------------------------------------------------+ |
4 | // | Copyright CiviCRM LLC (c) 2004-2012 | |
5 | // +--------------------------------------------------------------------+ |
6 | // | This file is a part of CiviCRM. | |
7 | // | | |
8 | // | CiviCRM is free software; you can copy, modify, and distribute it | |
9 | // | under the terms of the GNU Affero General Public License | |
10 | // | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | |
11 | // | | |
12 | // | CiviCRM is distributed in the hope that it will be useful, but | |
13 | // | WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
15 | // | See the GNU Affero General Public License for more details. | |
16 | // | | |
17 | // | You should have received a copy of the GNU Affero General Public | |
18 | // | License and the CiviCRM Licensing Exception along | |
19 | // | with this program; if not, contact CiviCRM LLC | |
20 | // | at info[AT]civicrm[DOT]org. If you have questions about the | |
21 | // | GNU Affero General Public License or the licensing of CiviCRM, | |
22 | // | see the CiviCRM license FAQ at http://civicrm.org/licensing | |
23 | // +--------------------------------------------------------------------+ |
24 | (function($) { |
25 | |
26 | // Keep track of all header cells. |
27 | var cells = []; |
28 | |
29 | // Attach to all headers. |
30 | $(document).ready(function() { |
31 | $('table thead.sticky').each(function () { |
32 | // Make all absolute positioned elements relative to the table. |
33 | var height = $(this).parent('table').css('position', 'relative').height(); |
34 | |
35 | // Find all header cells. |
36 | $('th', this).each(function () { |
37 | |
38 | // Ensure each cell has an element in it. |
39 | var html = $(this).html(); |
40 | if (html == ' ') { |
41 | html = ' '; |
42 | } |
43 | if ($(this).children().size() == 0) { |
44 | html = '<span>'+ html +'</span>'; |
45 | } |
46 | |
47 | // Clone and wrap cell contents in sticky wrapper that overlaps the cell's padding. |
48 | $('<div class="sticky-header" style="position: fixed; display: none; top: 0px;">'+ html +'</div>').prependTo(this); |
49 | var div = $('div.sticky-header', this).css({ |
50 | 'marginLeft': '-'+ $(this).css('paddingLeft'), |
51 | 'marginRight': '-'+ $(this).css('paddingRight'), |
52 | 'paddingLeft': $(this).css('paddingLeft'), |
53 | 'paddingTop': $(this).css('paddingTop'), |
54 | 'paddingRight': $(this).css('paddingRight'), |
55 | 'paddingBottom': $(this).css('paddingBottom') |
56 | })[0]; |
57 | // Adjust width to fit cell and hide. |
58 | |
59 | //CRM-6467 |
60 | var length = $(this).width() - $(div).width(); |
61 | if ( length < 0 ) length = $(div).width() - $(this).width(); |
62 | $(div).css('paddingRight', parseInt($(div).css('paddingRight')) + length +'px'); |
63 | |
64 | cells.push(div); |
65 | |
66 | // Get position. |
67 | div.cell = this; |
68 | div.table = $(this).parent('table')[0]; |
69 | div.stickyMax = height; |
70 | div.stickyPosition = $(this).y(); |
71 | }); |
72 | }); |
73 | }); |
74 | |
75 | // Track scrolling. |
76 | var scroll = function() { |
77 | $(cells).each(function () { |
78 | // Fetch scrolling position. |
79 | var scroll = document.documentElement.scrollTop || document.body.scrollTop; |
80 | var offset = scroll - this.stickyPosition - 4; |
81 | if (offset > 0 && offset < this.stickyMax - 100) { |
82 | $(this).css({display:'block'}); |
83 | } |
84 | else { |
85 | $(this).css('display', 'none'); |
86 | } |
87 | }); |
88 | }; |
89 | $(window).scroll(scroll); |
90 | $(document.documentElement).scroll(scroll); |
91 | |
92 | // Track resizing. |
93 | var resize = function () { |
94 | $(cells).each(function () { |
95 | // Get position. |
96 | $(this).css({ 'position': 'relative', 'top': '0'}); |
97 | this.stickyPosition = $(this.cell).y(); |
98 | this.stickyMax = $(this.table).height(); |
99 | }); |
100 | }; |
101 | $(window).resize(resize); |
102 | |
103 | // Track the element positions |
104 | $.fn.x = function(n) { |
105 | var result = null; |
106 | this.each(function() { |
107 | var o = this; |
108 | if (n === undefined) { |
109 | var x = 0; |
110 | if (o.offsetParent) { |
111 | while (o.offsetParent) { |
112 | x += o.offsetLeft; |
113 | o = o.offsetParent; |
114 | } |
115 | } |
116 | if (result === null) { |
117 | result = x; |
118 | } else { |
119 | result = Math.min(result, x); |
120 | } |
121 | } else { |
122 | o.style.left = n + 'px'; |
123 | } |
124 | }); |
125 | return result; |
126 | }; |
127 | |
128 | $.fn.y = function(n) { |
129 | var result = null; |
130 | this.each(function() { |
131 | var o = this; |
132 | if (n === undefined) { |
133 | var y = 0; |
134 | if (o.offsetParent) { |
135 | while (o.offsetParent) { |
136 | y += o.offsetTop; |
137 | o = o.offsetParent; |
138 | } |
139 | } |
140 | if (result === null) { |
141 | result = y; |
142 | } else { |
143 | result = Math.min(result, y); |
144 | } |
145 | } else { |
146 | o.style.top = n + 'px'; |
147 | } |
148 | }); |
149 | return result; |
150 | }; |
151 | |
152 | })(jQuery); |