Index: branches/5.1.x/core/admin_templates/js/grid_scroller.js =================================================================== --- branches/5.1.x/core/admin_templates/js/grid_scroller.js (revision 13573) +++ branches/5.1.x/core/admin_templates/js/grid_scroller.js (revision 13574) @@ -1,1220 +1,1223 @@ var sheetRules; // all rules in stylesheet Set by initStyleChange() var currentRule; // which rule are we editing? Set by assignRule() var defaultStyles = new Array(); function StyleManager() {} StyleManager.InitStyles = function() { if (!document.styleSheets) return; var sheets = document.styleSheets; this.Map = new Object(); // alert('total '+sheets.length+' sheets') for (var i=0;i<sheets.length;i++) { var currentSheet = sheets[i]; if (currentSheet.cssRules) sheetRules = currentSheet.cssRules else if (currentSheet.rules) sheetRules = currentSheet.rules; else { // alert('bad sheet '+currentSheet.href); continue; } // alert('sheet: '+currentSheet.href) for (var ii=0;ii<sheetRules.length;ii++) { var value = sheetRules[ii].selectorText; if (value.match(',')) { // Mozilla does not break comma-separated selectors into separate rules... var subselectors = value.split(','); for (var sub = 0; sub < subselectors.length; sub++) { var real_name = subselectors[sub].replace(/^[ \t]*(.*)[ \t]*/, '$1'); this.Map[real_name] = sheetRules[ii] } } else { this.Map[value.toLowerCase()] = sheetRules[ii]; } } } this.Inited = true; // preg_print_pre(this.Map, /last/); } StyleManager.ChangeStyle = function(selector, s, value) { if (!this.Inited) this.InitStyles() rule = this.Map[selector.toLowerCase()]; if (!rule) { if (this.AddStyle(selector, s, value)) { return true; } alert('rule '+selector+' not found') return; } alert('adjusting rule '+selector+' setting '+s+' to '+value+' from '+rule.style[s]) rule.style[s] = value; alert('now it is '+rule.style[s]) } StyleManager.AddStyle = function(selector, style, value) { var sheet = document.styleSheets[0]; var rule = false; if (sheet.insertRule) { sheet.insertRule(selector+'{'+style+':'+value+'}', sheet.cssRules.length); rule = sheet.cssRules[sheet.cssRules.length-1]; } else if(sheet.addRule) { sheet.addRule(selector, style+':'+value); rule = sheet.rules[sheet.rules.length-1]; } if (rule) { alert ('adding rule as '+selector); this.Map[selector.toLowerCase()] = sheet.cssRules[sheet.cssRules.length-1]; return true; } return false; } StyleManager.GetStyle = function(selector) { if (!this.Inited) this.InitStyles() rule = this.Map[selector.toLowerCase()]; if (!rule) return false; return rule; } StyleManager.GetStyleValue = function(selector, style) { rule = this.GetStyle(selector); if (!rule) return false; return rule.selector; } function preg_print_pre(obj, reg) { if (!reg) reg = /.*/; var p = '' for (var prop in obj) { if (prop.match(reg) ) { p += prop + ': '+obj[prop] + '\n' } } alert(p) } var startTime,endTime; var profile = 0; var profile_total = 0; var startTime = new Date().getTime(); function Profile(message,force) { if (profile || force) { endTime = new Date().getTime(); var tmp = (endTime-startTime); profile_total += tmp; alert(message+' took '+tmp+' ms of '+profile_total) startTime = new Date().getTime(); } } function ResetStart() { startTime = new Date().getTime(); profile_total = 0; } function GridScroller(grid_id, w, h) { this.GridId = grid_id this.Footer = false; this.LeftCells = 0; this.LeftWidth = 0; this.BottomOffset = 0; this.Width = w; this.Height = h; this.MaxHeight = h; // maximal grid height from constructor (also save here, because this.Height will be changed after Resize method call) this.AutoWidth = true; this.ScrollerW = 0; this.ScrollerH = 0; this.MinWidths = []; this.IDs = []; this.Rendered = false; this.PickerCRC = ''; this.MaxHeaderHeights = [50,30]; this.MaxRowHeight = 45; this.Html = ''; // html from last grid rendering } GridScroller.prototype._getMeasureHtml = function() { return '<div id="my_measure_'+this.GridId+'" style="width: auto; height: 0px; z-index: -105;"></div>'; } GridScroller.prototype._prepareHtml = function($container) { if (typeof($container) == 'undefined') { var dot = this._getMeasureHtml(); // console.log('dot without container'); document.write(dot); } else { // console.log('dot inside container'); var dot = document.createElement('div'); dot.id = 'my_measure_'+this.GridId; dot.style.width = 'auto'; dot.style.height = '0px'; dot.style.zIndex = '-105'; document.getElementById($container).appendChild(dot); } var dot = document.getElementById('my_measure_'+this.GridId); var measure = document.getElementById('my_measure_'+this.GridId); this.pos = findPos(dot); // alert('dot: '+this.pos[0]+','+this.pos[1]) var collapse_correction = this._getCollapseCorrection(); if (is.ie) this.pos[0] += 1; // this.MainOuter.style.width = 'auto' var w = measure.offsetWidth; var h = document.body.clientHeight; var dim = getDimensions(measure); h -= this.pos[1] + dim.padding[0] + dim.padding[2] + dim.borders[0] + dim.borders[2] + this.BottomOffset; var $html = this.AltHTML(this.pos[0],this.pos[1], w, h); return $html; } GridScroller.prototype._getCollapseCorrection = function() { return is.ie ? 0 : -1; } GridScroller.prototype.Render = function(id) { Application.removeDebuggerStatistics(); ResetStart(); // var widths = this.PrepareWidths(); // this.MinWidths = [40,null,null,250] this.MinWidths = this.PrepareWidths(); // [50,70,90,150,150,110,70,111]; document.body.style.height = '100%'; document.body.style.overflow = 'hidden'; document.body.scroll = 'no'; // this.Html = this.AltHTML(); // Profile('Getting HTML',1); // console.log('GridScroller.Render(', id, ')'); if (id && id != '') { // console.log('id given'); if (this.Html.length == 0) { // 1st render and inside container -> prepare html // console.log('1st render and no html'); this.Html = this._prepareHtml(id); var collapse_correction = this._getCollapseCorrection(); // direct innerHTML assignment results empty line (15px height) to be added before // container when grid data is set from ajax responce (like in catalog) in IE, so // use jQuery here // document.getElementById(id).innerHTML = this._getMeasureHtml() + '<div id="main_div_'+this.GridId+'" style="margin-left: '+collapse_correction+'px">'+this.Html+'</div>'; $( jq('#' + id) ).html( this._getMeasureHtml() + '<div id="main_div_'+this.GridId+'" style="margin-left: '+collapse_correction+'px">'+this.Html+'</div>' ); } else { // direct innerHTML assignment results empty line (15px height) to be added before // container when grid data is set from ajax responce (like in catalog) in IE, so // use jQuery here // document.getElementById(id).innerHTML = '<div id="main_div_'+this.GridId+'">'+this.Html+'</div>'; $( jq('#' + id) ).html( '<div id="main_div_'+this.GridId+'">'+this.Html+'</div>' ); } // execJS(document.getElementById(id)); } else { // console.log('id not given'); if (this.Rendered) { // console.log('rendering inside container'); this.Render('main_div_'+this.GridId); return; } // console.log('just rendering'); this.Html = this._prepareHtml(); var collapse_correction = this._getCollapseCorrection(); document.write('<div id="main_div_'+this.GridId+'" style="margin-left: '+collapse_correction+'px">'+this.Html+'</div>'); } this.Rendered = true; // Profile('Main render & refs',1) this.SetReferences(); // return; if (getFrame('head').ScrollerW) { this.ScrollerW = getFrame('head').ScrollerW; this.ScrollerH = getFrame('head').ScrollerH; } else { this.ScrollerW = 17; this.ScrollerH = 17; /*this.ScrollerW = this.MainInner.offsetWidth - this.MainInner.clientWidth this.ScrollerH = this.MainInner.offsetHeight - this.MainInner.clientHeight getFrame('head').ScrollerW = this.ScrollerW getFrame('head').ScrollerH = this.ScrollerH*/ } // Profile('Up to col widths',1); if (!this.UpdateColWidths()) return; if (this.Width == 'auto') { this.Resize( this.GetAutoSize(this.Height) ); } else { this.Resize(); } this.AdjustInputWidths(); this.TheGrid.style.visibility = 'visible' this.MainScroller.style.visibility = 'visible' // Profile('Finalizng', 1); var the_grid = this; if (document.all) { $status = window.attachEvent('onresize', function(ev) { the_grid.AutoResize() }); } else { $status = window.addEventListener('resize', function(ev) { the_grid.AutoResize() }, true); } if (document.all) { this.DataScroller.onmousewheel = function(ev) { var e = document.all ? window.event : ev; this.TheGrid.MainInner.scrollTop += -e.wheelDelta/2 this.TheGrid.SyncScroll(); } if (this.LeftCells > 0) { this.LeftDataInner.onmousewheel = function(ev) { var e = document.all ? window.event : ev; this.TheGrid.MainInner.scrollTop += -e.wheelDelta/2 this.TheGrid.SyncScroll(); } } } else { this.DataScroller.addEventListener("DOMMouseScroll", function(ev) { var e = document.all ? window.event : ev; this.TheGrid.MainInner.scrollTop += e.detail*10 this.TheGrid.SyncScroll(); }, false); if (this.LeftCells > 0) { this.LeftDataInner.addEventListener("DOMMouseScroll", function(ev) { var e = document.all ? window.event : ev; this.TheGrid.MainInner.scrollTop += e.detail*10 this.TheGrid.SyncScroll(); }, false); } } addLoadEvent( function() { the_grid.RefreshPos(); the_grid.AutoResize(); the_grid.SetResizeHandles(); } ); } GridScroller.prototype.SetReferences = function() { this.MainOuter = document.getElementById('outer_main_'+this.GridId ); this.MainInner = document.getElementById('inner_main_'+this.GridId) this.MainScroller = document.getElementById('main_scroller_'+this.GridId) this.TheGrid = document.getElementById(this.GridId ); this.HeadTable = document.getElementById('header_'+this.GridId); this.HeadScroller = document.getElementById('inner_header_'+this.GridId); this.HeadOuter = document.getElementById('outer_header_'+this.GridId); this.DataTable = document.getElementById('data_'+this.GridId); this.DataScroller = document.getElementById('inner_data_'+this.GridId); this.DataOuter = document.getElementById('outer_data_'+this.GridId); if (this.HasFooter) { this.FooterTable = document.getElementById('footer_'+this.GridId); this.FooterScroller = document.getElementById('inner_footer_'+this.GridId); this.FooterOuter = document.getElementById('outer_footer_'+this.GridId); } if (this.LeftCells != 0) { this.LeftHeaderTable = document.getElementById('left_header_'+this.GridId); this.LeftHeaderScroller = document.getElementById('inner_left_header_'+this.GridId); this.LeftHeaderOuter = document.getElementById('outer_left_header_'+this.GridId); this.LeftHeaderInner = document.getElementById('inner_left_header_'+this.GridId); this.LeftDataTable = document.getElementById('left_data_'+this.GridId); this.LeftDataOuter = document.getElementById('outer_left_data_'+this.GridId); this.LeftDataInner = document.getElementById('inner_left_data_'+this.GridId); if (this.HasFooter) { this.LeftFooterTable = document.getElementById('left_footer_'+this.GridId); this.LeftFooterInner = document.getElementById('inner_left_footer_'+this.GridId); this.LeftFooterOuter = document.getElementById('outer_left_footer_'+this.GridId); } } this.DataScroller.TheGrid = this; this.MainInner.TheGrid = this; if (this.LeftCells > 0) this.LeftDataInner.TheGrid = this; // this.Dot = document.getElementById('my_dot_'+this.GridId) this.MainOuter.className = 'grid-scrollable' if (!is.ie) { // this.MainOuter.style.marginLeft = '-1px'; } } GridScroller.prototype.SetLeftHeights = function() { if (this.LeftCells != 0) { this.SetHeights('left_header_'+this.GridId, 'header_'+this.GridId); this.SetHeights('left_data_'+this.GridId, 'data_'+this.GridId); if (this.HasFooter()) { this.SetHeights('left_footer_'+this.GridId, 'footer_'+this.GridId); } } } GridScroller.prototype.UpdateColWidths = function() { // pos = findPos(this.Dot) pos = this.pos; this.TheGrid.style.left = (pos[0])+ 'px' this.TheGrid.style.top = (pos[1]) + 'px' this.SetLeftHeights(); if (this.HasFooter()) { this.FooterHeight = this.FooterTable.offsetHeight; this.FooterOuter.style.height = this.FooterHeight + 'px' } else { this.FooterHeight = 0; } this.HeadHeight = this.HeadTable.offsetHeight; // console.log('measured Head Height: '+this.HeadHeight); this.DataHeight = this.DataTable.offsetHeight; this.HeadOuter.style.height = (this.HeadHeight) + 'px' if (this.LeftCells != 0) { this.LeftWidth = Math.max(this.LeftHeaderTable.offsetWidth, this.LeftDataTable.offsetWidth) this.LeftHeaderOuter.style.height = (this.HeadHeight) + 'px' if (this.HasFooter()) { this.LeftFooterOuter.style.height = (this.FooterHeight) + 'px' this.LeftWidth = Math.max(this.LeftWidth, this.LeftFooterTable.offsetWidth); } // console.log('measured Left Width: '+this.LeftWidth); } this.MainInner.onscroll = function() { this.TheGrid.SyncScroll() } this.MainOuter.style.width = 'auto' this.UpdateTotalDimensions(); return true; } GridScroller.prototype.UpdateTotalDimensions = function() { this.HeadHeight = this.HeadTable.offsetHeight; this.DataHeight = this.DataTable.offsetHeight; this.HeaderWidth = this.HeadTable.offsetWidth + this.LeftWidth - this.HeadTable.rows[0].cells[(this.HeadTable.rows[0].cells.length-1)].offsetWidth; this.DataTotalHeight = this.DataHeight + this.HeadHeight + this.FooterHeight; } GridScroller.prototype.ResetHeights = function(table1_id, table2_id) { var table1 = document.getElementById(table1_id); var table2 = document.getElementById(table2_id); var height1_div, height2_div; for (var row=0; row<table1.rows.length; row++) { // reseting heights table1.rows[row].cells[0].style.height = 'auto'; table2.rows[row].cells[0].style.height = 'auto'; table1.rows[row].style.height = 'auto'; table2.rows[row].style.height = 'auto'; var height1_div = document.getElementById(table1_id+'_left_height_'+row); if (height1_div) { height1_div.style.height = 'auto'; } var height2_div = document.getElementById(table2_id+'_left_height_'+row); if (height2_div) { height2_div.style.height = 'auto'; } } } GridScroller.prototype.SetHeights = function(table1_id, table2_id) { var table1 = document.getElementById(table1_id); var table2 = document.getElementById(table2_id); var height1_div, height2_div; this.ResetHeights(table1_id, table2_id); var heights1 = this.GetHeights(table1_id); var heights2 = this.GetHeights(table2_id); var table, the_height, num; - for (var row=0; row<table1.rows.length; row++) - { - if (heights1[row] > heights2[row]) - { + for (var row = 0; row < table1.rows.length; row++) { + if (heights1[row] > heights2[row]) { + // table1 row's height is larger -> adjust table2 row's height the_height = heights1[row]; table = table2; id = table2_id; } else { + // table2 row's height is larger -> adjust table1 row's height the_height = heights2[row]; table = table1; id = table1_id; } - var height_div = document.getElementById(id+'_left_height_'+row); + + var height_div = document.getElementById(id + '_left_height_' + row); + if (height_div) { // the div only exists for FF height_div.style.height = the_height+'px'; height_div.style.width = table.rows[row].cells[0].clientWidth+'px' } else { if (!is.ie) { // firefox needs div, but it can display it as table-cell var width = table.rows[row].cells[0].clientWidth; // table.rows[row].cells[0].innerHTML = '<div id="'+id+'_left_height_'+row+'" style="display: table-cell; background-color: inherit; width: '+width+'px; height: '+(the_height) +'px; overflow: hidden;">' + table.rows[row].cells[0].innerHTML + '</div>' } } // IE can't display div as table-cell, but it respects the tr height - table.rows[row].cells[0].style.height = the_height+'px'; - table.rows[row].style.height = the_height+'px'; + + if (document.all) { + $(table.rows[row].cells[0]).height(the_height); + } + + $(table.rows[row]).height(the_height); } } GridScroller.prototype.GetHeights = function(table_id) { - var table = document.getElementById(table_id); var heights = new Array(); - var height - for (var row=0; row<table.rows.length; row++) - { - var dim = getDimensions( table.rows[row].cells[0] ); - height = dim.innerHeight + (is.ie ? 0 : dim.padding[0] + dim.padding[2] + dim.borders[0] + dim.borders[2]); - heights.push( height ) -// alert('get ('+row+')'+table.rows[row].cells[0].innerHTML+' height (offset/client/computed (coorection)): '+table.rows[row].cells[0].offsetHeight + '/' + table.rows[row].cells[0].clientHeight + '/ ' +height + ' ('+correction+')') + var table = document.getElementById(table_id); + + for (var row = 0; row < table.rows.length; row++) { + var $cell = $( table.rows[row].cells[0] ); + heights.push( document.all ? $cell.height() : $cell.outerHeight() ); } + return heights; } - GridScroller.prototype.GetWidths = function(table_id) { var table = document.getElementById(table_id); var widths = new Array(); if (!table.rows[0]) return []; for (var col=0; col<table.rows[0].cells.length; col++) { var tmp = getDimensions(table.rows[0].cells[col]); widths.push( tmp.innerWidth ) // widths.push( table.rows[0].cells[col].offsetWidth ) if (table_id.match(/^header_/)) { // alert('get ('+col+')'+table.rows[0].cells[col].innerHTML+' width '+table.rows[0].cells[col].offsetWidth) } } return widths; } GridScroller.prototype.SetResizeHandles = function() { var points = new Array(); if (this.LeftCells > 0) { var table = this.LeftHeaderTable; var points = new Array(); if (!table.rows[0]) return []; for (var col=0; col<table.rows[0].cells.length; col++) { var tmp = findPos(table.rows[0].cells[col]); points.push(tmp); } } var table = this.HeadTable; if (!table.rows[0]) return []; for (var col=0; col<table.rows[0].cells.length; col++) { var tmp = findPos(table.rows[0].cells[col]); points.push(tmp); } var scroller = this; var resize_bar = document.getElementById(this.GridId + '[resize_bar]'); if (!resize_bar) { resize_bar = addElement(document.body, 'div'); resize_bar.id = this.GridId + '[resize_bar]'; } resize_bar.style.display = 'none'; resize_bar.style.width = '2px'; resize_bar.style.height = '200px'; resize_bar.style.backgroundColor = '#777'; resize_bar.style.zIndex = 40; resize_bar.style.position = 'absolute'; for (var i=1; i<points.length; i++) { var handle = document.getElementById(this.GridId + '[grid_resize_handle_' + i + ']'); if (!handle) { handle = addElement(document.body, 'div'); handle.id = this.GridId + '[grid_resize_handle_' + i + ']'; } handle.style.width='6px'; handle.style.height=this.HeadTable.offsetHeight+'px'; handle.style.position='absolute'; // handle.style.backgroundColor='red'; handle.style.left = (points[i][0] - 3)+'px'; handle.style.top = points[i][1]+'px'; handle.style.zIndex = 50; handle.style.cursor = 'col-resize'; handle.col_num = i-1; DragManager.MakeDragable(this.GridId + '[grid_resize_handle_' + i + ']', function(a_handle) { var resize_bar = document.getElementById(scroller.GridId + '[resize_bar]'); var pos = findPos(a_handle); resize_bar.style.left = (pos[0])+'px'; resize_bar.style.top = pos[1]+'px'; resize_bar.style.height = scroller.Height+'px'; resize_bar.style.display = 'block'; var col_num = a_handle.col_num; DragManager.DragObject.min_col_width = scroller.GetColWidth(col_num); }, function(drag_object, coords) { var offset = coords.x - DragManager.MouseOffset[0] - DragManager.InitialPos[0]; if (parseInt(DragManager.DragObject.min_col_width) + offset > 15) { var resize_bar = document.getElementById(scroller.GridId + '[resize_bar]'); resize_bar.style.left = (coords.x - DragManager.MouseOffset[0] + 2) + 'px'; } }, function(a_handle) { var resize_bar = document.getElementById(scroller.GridId + '[resize_bar]'); resize_bar.style.display = 'none'; coords = findPos(a_handle); var offset = (coords[0] - DragManager.InitialPos[0]); // alert('offset: '+offset+' ('+coords[0]+' - '+DragManager.MouseOffset[0]+' - '+DragManager.InitialPos[0]+')'); var col_num = a_handle.col_num; var cur_w = scroller.GetColWidth(col_num); if (cur_w + offset < 15) { offset = 15-cur_w; } scroller.SetColWidth(col_num, cur_w+offset); scroller.Resize( scroller.GetAutoSize() ); scroller.ScrollResizeHandles(); DragManager.InitialPos = [coords[0] - DragManager.MouseOffset[0], coords[1] - DragManager.MouseOffset[1]]; }, {VerticalDrag: false} ) } } GridScroller.prototype.GetColWidth = function(col) { return this.MinWidths[col]; } GridScroller.prototype.AdjustInputWidths = function() { var elems = new Array(); var inputs = this.HeadTable.getElementsByTagName('INPUT'); for (var i=0; i<inputs.length; i++) {elems[elems.length] = inputs[i];} var selects = this.HeadTable.getElementsByTagName('SELECT'); for (var i=0; i<selects.length; i++) {elems[elems.length] = selects[i];} if (this.LeftCells > 0) { var left_inputs = this.LeftHeaderTable.getElementsByTagName('INPUT'); for (var i=0; i<left_inputs.length; i++) {elems[elems.length] = left_inputs[i];} var left_selects = this.LeftHeaderTable.getElementsByTagName('SELECT'); for (var i=0; i<left_selects.length; i++) {elems[elems.length] = left_selects[i];} } var widths = new Array() for (var i=0; i<elems.length; i++) { elems[i].style.width = '1px'; } for (var i=0; i<elems.length; i++) { var input_dim = getDimensions(elems[i]); var parent_dim = getDimensions(elems[i].parentNode); widths[i] = (parent_dim.innerWidth - parent_dim.borders[1] - parent_dim.borders[3] - input_dim.borders[1] - input_dim.borders[3] - 2)+'px'; } for (var i=0; i<elems.length; i++) { try { elems[i].style.width = widths[i]; } catch (e) { // IE don't allow to set width for hidden element // alert('IE exception:' + e); } } } GridScroller.prototype.SetColWidth = function(col, width) { if (col >= this.LeftCells) { if (this.DataTable.rows.length) this.DataTable.rows[0].cells[col - this.LeftCells].style.width = width+'px'; for (var row=0; row < this.HeadTable.rows.length; row++) { this.HeadTable.rows[row].cells[col - this.LeftCells].style.width = width+'px'; var a = document.getElementById(this.GridId + '[cursor_work_around_A_'+col+'_'+row+']'); var b = document.getElementById(this.GridId + '[cursor_work_around_B_'+col+'_'+row+']'); if (a) a.style.width = width+'px'; if (b) b.style.width = width+'px'; } if (this.HasFooter()) { this.FooterTable.rows[0].cells[col - this.LeftCells].style.width = width+'px'; } } else { if (this.LeftDataTable.rows.length) this.LeftDataTable.rows[0].cells[col].style.width = width+'px'; for (var row=0; row < this.LeftHeaderTable.rows.length; row++) { this.LeftHeaderTable.rows[row].cells[col].style.width = width+'px'; var a = document.getElementById(this.GridId + '[cursor_work_around_A_'+col+'_'+row+']'); var b = document.getElementById(this.GridId + '[cursor_work_around_B_'+col+'_'+row+']'); if (a) a.style.width = width+'px'; if (b) b.style.width = width+'px'; } if (this.HasFooter()) { this.LeftFooterTable.rows[0].cells[col].style.width = width+'px'; } var cur_left_total_w = 0; var new_left_total_w = 0; for (var i=0; i < this.LeftCells; i++) { cur_left_total_w += this.MinWidths[i]; new_left_total_w += i==col? width : this.MinWidths[i]; }; var left_diff = this.LeftWidth - cur_left_total_w; this.SetLeftWidth(new_left_total_w+left_diff); } this.AdjustInputWidths(); this.MinWidths[col] = width; this.SetLeftHeights(); this.UpdateTotalDimensions(); this.SyncScroll(); this.ScheduleSaveWidths(); } GridScroller.prototype.ScrollResizeHandles = function() { for (var col=1; col<this.LeftHeaderTable.rows[0].cells.length; col++) { var handle = document.getElementById(this.GridId + '[grid_resize_handle_' + col + ']'); if (!handle) return; var pos = findPos(this.LeftHeaderTable.rows[0].cells[col]); handle.style.left = (pos[0]-3)+'px'; } if (this.HeadTable.rows[0].cells.length) { var left_most_pos = findPos(this.HeadTable.rows[0].cells[0]); var handle = document.getElementById(this.GridId + '[grid_resize_handle_' + (this.LeftCells) + ']'); if (handle) handle.style.left = (left_most_pos[0]-3)+'px'; } for (var col=1; col<this.HeadTable.rows[0].cells.length; col++) { var handle = document.getElementById(this.GridId + '[grid_resize_handle_'+(col+this.LeftCells)+']'); if (!handle) continue; var pos = findPos(this.HeadTable.rows[0].cells[col]); var n_left = pos[0]-this.MainInner.scrollLeft-3 if (n_left <= left_most_pos[0] || n_left > left_most_pos[0] + this.DataOuter.clientWidth) { handle.style.display = 'none'; //resize handle is outside of visible range } else { handle.style.display = 'block'; } handle.style.left = n_left+'px'; } } GridScroller.prototype.GetAutoSize = function(h) { this.MainOuter.style.width = 'auto' var w = this.MainInner.offsetWidth; if (!isset(h)) { h = this.MaxHeight; // 'auto'; } if (h == 'auto') { var h = document.body.clientHeight; var pos = findPos(this.MainOuter); var dim = getDimensions(this.MainOuter); h -= pos[1] + dim.padding[0] + dim.padding[2] + dim.borders[0] + dim.borders[2] + this.BottomOffset; } return [w, h]; } GridScroller.prototype.AutoResize = function() { var obj = this; if (this.ResizeHappening && this.ResizeTimer) { window.clearTimeout(this.ResizeTimer); this.ResizeTimer = false; } this.ResizeHappening = true; this.ResizeTimer = window.setTimeout(function() { // GridScroller sets references to it's elements after Render method is called (once). // When grid elements are replaced from ajax responce, then all stored // refrences are invalid (GridScroller.Render method is called after this timer is execuded). // To prevent "Unspecified error" in IE reset all references. obj.SetReferences(); obj.RefreshPos(); obj.Resize( obj.GetAutoSize() ); obj.ResizeHappening = false; }, 300) } GridScroller.prototype.RefreshPos = function() { var dot = document.getElementById('my_measure_'+this.GridId); this.pos = findPos(dot); if (is.ie) { // measure div is moved left for 1 pixel in IE during resize (nothing strange, it's IE) this.pos[0] += 1; } } GridScroller.prototype.Resize = function(w,h) { // alert('-1'); if (typeof(w) == 'object') { h = w[1]; w = w[0]; } if (w) this.Width = w; if (h) this.Height = h; var x,y; // pos = findPos(this.Dot) pos = this.pos; x = pos[0]; y = pos[1]; this.TheGrid.style.left = (x)+ 'px' this.TheGrid.style.top = (y) + 'px' // alert('moved'); // alert('0'); this.MainOuter.style.height = (this.Height)+'px' this.MainOuter.style.width = (this.Width)+'px' // alert('1'); var scroller_width; // this.HeadTable.rows[0].cells[(this.HeadTable.rows[0].cells.length-1)].offsetWidth scroller_height = this.HeaderWidth > this.Width ? this.ScrollerH : 0; scroller_width = this.DataTotalHeight > this.Height - scroller_height ? this.ScrollerW : 0; scroller_height = this.HeaderWidth > this.Width - scroller_width ? this.ScrollerH : 0; // alert('min: '+this.MinDataWidth+' pos: '+pos[0]+','+pos[1]+' scroller W x H: '+scroller_width+' x '+scroller_height+' will resize to '+this.Width+' x '+this.Height+' data: '+this.HeaderWidth+' x '+this.DataHeight) this.HeadOuter.style.width = (this.Width -scroller_width -this.LeftWidth)+ 'px'; this.DataOuter.style.width = (this.Width -scroller_width -this.LeftWidth)+ 'px'; // alert('1.2'); this.TheGrid.style.width = (this.Width - scroller_width) + 'px'; this.TheGrid.style.height = (this.Height - scroller_height) + 'px'; // alert('1.5'); this.SetLeftWidth(); // alert('2'); if (this.HasFooter()) { this.FooterOuter.style.width = (this.Width -scroller_width -this.LeftWidth)+ 'px'; } if (this.DataTotalHeight < this.Height - scroller_height) { var adjusted_data_height = this.DataTotalHeight - this.HeadHeight - this.FooterHeight } else { var adjusted_data_height = this.Height - this.HeadHeight - this.FooterHeight - scroller_height } this.DataOuter.style.height = adjusted_data_height + 'px' if (this.LeftCells != 0) { this.LeftDataOuter.style.height = adjusted_data_height + 'px' } // alert('3'); this.MainScroller.style.width = (this.HeadTable.offsetWidth + this.LeftWidth)+'px' this.MainScroller.style.height = ( this.DataHeight + this.HeadHeight + this.FooterHeight)+'px' // alert('4'); } GridScroller.prototype.SetLeftWidth = function(left_width) { if (left_width) this.LeftWidth = left_width; if (this.LeftCells != 0) { // there was -1 for Mozilla, but somehow it's not needed anymore... this.LeftHeaderOuter.parentNode.style.width = (this.LeftWidth + (is.ie ? 0 : 0) ) + 'px'; this.LeftHeaderOuter.style.width = (this.LeftWidth) + 'px'; this.LeftHeaderInner.style.width = (this.LeftWidth) + 'px'; this.LeftDataOuter.style.width = (this.LeftWidth) + 'px'; this.LeftDataInner.style.width = (this.LeftWidth) + 'px'; if (this.HasFooter()) { this.LeftFooterOuter.style.width = (this.LeftWidth) + 'px'; this.LeftFooterInner.style.width = (this.LeftWidth) + 'px' } // this is IE workaround, we have to set inner div width to given px (above) and then back to 100% // for IE to readjust the surrounding tables, otherwise it memorizes inner div pixel width and // cannot make surrounding table cells smaller then that this.LeftHeaderInner.style.width = '100%'; this.LeftDataInner.style.width = '100%'; if (this.HasFooter()) { this.LeftFooterInner.style.width = '100%'; } } } GridScroller.prototype.SyncScroll = function() { this.HeadScroller.scrollLeft = this.MainInner.scrollLeft; this.DataScroller.scrollLeft = this.MainInner.scrollLeft; if (this.HasFooter()) { this.FooterScroller.scrollLeft = this.MainInner.scrollLeft; } this.DataScroller.scrollTop = this.MainInner.scrollTop; if (this.LeftCells != 0) { this.LeftDataInner.scrollTop = this.MainInner.scrollTop; } this.ScrollResizeHandles(); } GridScroller.prototype.AltHTML = function(x,y,w,h) { var o = ''; o += this.CreateScroller( '<div id="main_scroller_'+this.GridId+'" style="background-color: inherit; position: relative; width: auto; z-index: 20; height: '+(h)+'px;"></div>', w, h, 'main_'+this.GridId, false, 1, 'grid-scrollable' ); // console.log(o) // return o+'</div>' o += '<div id="'+this.GridId+'" class="grid-container" style="background-color: inherit; position: absolute; left: '+(x)+'px; top: '+(y)+'px; visibility: visible; z-index: 10; width: auto; height: '+(h)+'px; overflow: hidden;">'; var header_rows = this.Header.length; var cols = this.Header[0].length; var data_rows = this.Data.length; var footer_rows = this.Footer.length; var header_h = 80; if (this.LimitedHeights) { for (var i=0; i<this.MaxHeaderHeights.length; i++) {header_h += this.MaxHeaderHeights[i]}; header_h += this.MaxHeaderHeightCorrection; } data_h = h - header_h; // console.log('header_h: %i, data_h: %i', header_h, data_h) var header = 'b'; var data = 'd'; var footer = 'f'; var left_header = '1'; var left_data = 'c'; var left_footer = 'e'; var header = this.GetTableWithScroller(this.Header, [this.LeftCells, 0, cols, header_rows], 'header', null, null, null, header_h) var data = this.GetTableWithScroller(this.Data, [this.LeftCells, 0, cols, data_rows], 'data', 'grid-data-row-even', '', null, data_h) var footer = this.HasFooter() ? this.GetTableWithScroller(this.Footer, [this.LeftCells, 0, cols, footer_rows], 'footer') : ''; var left_header = this.GetTableWithScroller(this.Header, [0,0,this.LeftCells, header_rows], ['header','left_header'], null, null, null, header_h) var left_data = this.GetTableWithScroller(this.Data, [0,0,this.LeftCells, data_rows], ['data','left_data'], 'grid-data-row-even', 'left_', null, data_h) var left_footer = this.GetTableWithScroller(this.Footer, [0,0,this.LeftCells, footer_rows], ['footer','left_footer']) /*var css = ''; for (var i=0;i<this.Header[0].length; i++) { css += '.width-adj-grid-col-'+i+' {} '; } o += '<style type="text/css">'+css+'</style>';*/ if (this.LeftCells != 0) { o += '<table style="width: 100%; table-layout: fixed; border-collapse: collapse;">\n' o += '<tr>\n<td style="vertical-align: top; margin: 0px; padding: 0px;">\n' + left_header + '\n</td>\n' o += '<td style="vertical-align: top; margin: 0px; padding: 0px;">\n' + header + '\n</td>\n</tr>\n' o += '<tr>\n<td style="vertical-align: top; margin: 0px; padding: 0px;">\n' + left_data + '\n</td>\n' o += '<td style="vertical-align: top; margin: 0px; padding: 0px;">\n' + data + '\n</td>\n</tr>\n' if (this.HasFooter()) { o += '<tr><td style="vertical-align: top; margin: 0px; padding: 0px">' + left_footer + '</td>' o += '<td style="vertical-align: top; margin: 0px; padding: 0px">' + footer + '</td></tr>' } o += '</table>\n' } else { o += header + data + footer; } o += '</div>'; return o; } GridScroller.prototype.PrepareWidths = function() { cache = getFrame('head').grid_widths_cache; if (!isset(cache)) { cache = new Object } if (this.MinWidths.length >= this.Header[0].length) { var has_all_widths = true; for (var i=0; i < this.MinWidths.length; i++) { if (isNaN(parseInt(this.MinWidths[i]))) { this.MinWidths[i] = 100; // has_all_widths = false; } } if (has_all_widths) { widths = this.MinWidths cache[this.GridId+'_'+this.PickerCRC] = widths; return widths; } } if (cache[this.GridId+'_'+this.PickerCRC]) { // return cache[this.GridId+'_'+this.PickerCRC] } // print_pre(this.MinWidths) var o = ''; data = this.Header.concat(this.Data).concat(this.Footer); o += this.GetTableCells(this.Header, [0,0,this.Header[0].length,this.Header.length], 'header', null, null, false, true)[0]; if (this.Data.length) { var data= this.GetTableCells(this.Data, [0,0,this.Data[0].length,this.Data.length], 'data', null, null, false, true)[0]; o += data; } var w = document.all ? window.document.body.offsetWidth : window.innerWidth var table_width = w < 500 ? '1024px' : 'auto'; // console.log('tmp table width: %s (window width: %s)', table_width, w) o = '<table style="visibility: visible; width: '+table_width+'; border-collapse: collapse" id="tmp_'+this.GridId+'">'+o+'</table>' document.write(o) widths = this.GetWidths('tmp_'+this.GridId); // print_pre(widths) tmp_el = document.getElementById('tmp_'+this.GridId); var p = tmp_el.parentNode; p.removeChild(tmp_el); cache[this.GridId+'_'+this.PickerCRC] = widths; return widths; } GridScroller.prototype.GetTableWithScroller = function(source, dim, class_mode, even_class, id_prefix, w, h) { // console.log(source, dim, class_mode, even_class, id_prefix, w, h) var tmp = this.GetIdAndClassName(class_mode); var id = tmp[1]; if (!h) h = 100; var cells = this.GetTableCells(source, dim, class_mode, even_class, id_prefix); // var cells = this.GetTableCells(source, dim, class_mode, even_class, id_prefix, false, true); // console.log('createing scroller %s w,h: %i,%i', id, cells[1],h) return this.CreateScroller('<table style="table-layout: fixed; width: 100%;" id="'+id+'_'+this.GridId+'">\n'+cells[0]+'\n</table>\n\n', cells[1], h, id+'_'+this.GridId, true, 5); } GridScroller.prototype.GetIdAndClassName = function(class_mode) { if (typeof(class_mode)=='object') { var class_name = class_mode[0]; var id = class_mode[1] } else { var class_name = class_mode; var id = class_mode; } return [class_name, id] } GridScroller.prototype.GetTableCells = function(source, dim, class_mode, even_class, id_prefix, needs_last, no_inner_div) { if (!source.length) return ['', 0]; var o = ''; var start_col = dim[0]; var start_row = dim[1]; var end_col = dim[2]; var end_row = dim[3]; var even = false; if (!even_class) even_class = ''; var tmp = this.GetIdAndClassName(class_mode); var class_name = tmp[0]; var id = tmp[1]; if (id_prefix==null) id_prefix = id; var needs_last = needs_last == null ? (end_col == (source[0].data ? source[0].data.length : source[0].length)) : needs_last; var total_width = 0; var width_printed = false; for (var row=start_row; row<end_row; row++) { row_data = source[row].data ? source[row].data : source[row]; var rh = ''; var row_id = this.IDs[row] ? 'id="'+id_prefix+this.IDs[row]+'"' : ''; var row_class = 'grid-'+class_name+'-row '+(even ? even_class : '')+' grid-'+class_name+'-row-'+row + (source[row].row_class ? ' '+source[row].row_class : ''); rh +='<tr '+row_id+' class="'+row_class+'" sequence="'+(row+1)+'">'+"\n" even = !even; total_width = 0; if (this.LimitedHeights) { var row_height = id.match(/^(left_)?header/) ? this.MaxHeaderHeights[row]+'px;' : this.MaxRowHeight+'px;' var height_style = id.match(/^(left_)?header/) ? 'height: '+this.MaxHeaderHeights[row]+'px;' : 'height: '+this.MaxRowHeight+'px;'; } else { var row_height = 'auto' var height_style = ''; } for (var col=start_col; col<end_col; col++) { total_width += this.MinWidths[col]+12; var cursor_workaround = ['','']; if (id.match(/^(left_)?header/) && is.gecko) { cursor_workaround = ['<div id="' + this.GridId + '[cursor_work_around_A_'+col+'_'+row+']" style="width: '+(this.MinWidths[col])+'px; overflow: auto;"><div id="' + this.GridId + '[cursor_work_around_B_'+col+'_'+row+']" style="width: '+(this.MinWidths[col])+'px; overflow: hidden;">', '</div></div>']; } else { if (this.LimitedHeights) { cursor_workaround = ['<div id="_clipper_'+col+'_'+row+'" style="'+(is.ie ? '' : 'display: table-cell; ')+'vertical-align: inherit; overflow: hidden; max-height: '+row_height+'"><div style="overflow: hidden; max-height: '+row_height+'">','</div></div>']; } } var width_style = width_printed ? '' : 'width: '+this.MinWidths[col]+'px;"' var td_style = 'style="overflow: hidden; max-height: '+row_height+'; '+width_style+'"'; var td_class = 'grid-'+class_name+'-col-'+col; if (this.FieldNames) { td_class += ' '+this.FieldNames[col]; } rh += "\t"+'<td '+td_style+' class="'+td_class+'">'+cursor_workaround[0]+row_data[col]+cursor_workaround[1]+'</td>'+"\n" } width_printed = true; // print widths in first row only if (needs_last) { rh += "\t"+'<td class="grid-'+class_name+'-last-cell"><img src="'+this.Spacer+'" width="1" height="1" alt=""/></td>'+"\n" } rh += '</tr>'+"\n" o += rh; } return [o, total_width]; } GridScroller.prototype.HasFooter = function() { return (this.Footer != false) } var colors = ['red', 'blue', 'green', 'pink', 'orange', 'brown', 'yellow', 'magenta', '#999', '#AAA', '#BBB', '#CCC', '#DDD', '#EEE', '#FFF']; var next_color = 0; GridScroller.prototype.CreateScroller = function(content, w, h, id, hidden, z, outer_class) { // console.log('creating scroller: ',w,h,id,hidden,z) if (hidden) { overflow = 'hidden' } else { overflow = 'auto' } if (!z) { z = 0; } if (id && id != '') { outer_id = 'id="outer_'+id+'"'; inner_id = 'id="inner_'+id+'"'; } else { outer_id = ''; inner_id = ''; } var o = ''; if (!outer_class) outer_class='scoller-outer'; o += '<div '+outer_id+' class="'+outer_class+'" style="z-index: '+z+'; width: '+w+'px; height: '+h+'px;">' o += '<div '+inner_id+' class="scroller-inner" style="z-index: '+z+'; width: 100%; height: 100%; overflow: '+overflow+'; position: relative;">' o += content o += '</div></div>' return o } GridScroller.prototype.SetData = function(a_data) { this.Data = a_data; } GridScroller.prototype.SetHeader = function(a_header) { this.Header = a_header; this.MaxHeaderHeightCorrection = (6*this.Header.length)+1; } GridScroller.prototype.SetFooter = function(a_footer) { this.Footer = a_footer; } GridScroller.prototype.SaveWidths = function() { if (!this.SaveURL) return; var w = this.MinWidths.join(':'); Request.makeRequest(this.SaveURL.replace('#WIDTHS#', w), this.BusyRequest, '', this.successCallback, this.errorCallback, '', this); } GridScroller.prototype.ScheduleSaveWidths = function() { var obj = this; if (this.SaveWidthsScheduled && this.SaveWidthsTimer) { window.clearTimeout(this.SaveWidthsTimer); this.SaveWidthsTimer = false; } this.SaveWidthsScheduled = true; this.SaveWidthsTimer = window.setTimeout(function() { obj.SaveWidths(); obj.SaveWidthsScheduled = false; }, 800) } \ No newline at end of file