/* Example Usage: var headerRow = [ ["Column 1","column1"], ["Column 2","column2"], ["Column 3","column3"], ["Column 4"], ["Column 5"] ]; // For the above header row example, the first 3 columns are sortable. // When clicked it will call the callback function with the 2nd array index as the parameter var myTable = new BeachheadUI.Table("my_table","table_holder",headerRow,"changeAccountSort"); myTable.useDefaultStyling(); // Or alternatively: myTable.setStyling("bh_table",0,0,"images/bh_arrowdown_white.gif","images/bh_arrowup_white.gif"); myTable.addRow(); myTable.addCell("Cell [0][0]"); myTable.addCell("Cell [0][1]"); myTable.addCell("Cell [0][2]"); myTable.addCell("Cell [0][3]"); myTable.addCell("Cell [0][4]"); myTable.addRow(); myTable.addCell("Cell [1][0]"); myTable.addCell("Cell [1][1]"); myTable.addCell("Cell [1][2]"); myTable.addCell("Cell [1][3]"); myTable.addCell("Cell [1][4]"); myTable.draw(); */ BeachheadUI.Table = function (pTableID, pContainerDiv) { if (arguments.length < 3) { this._noHeaders = true; pHeaderRowData = []; pHeaderRowCallback = ""; pNumCellsPerRow = pHeaderRowData = arguments[2]; } else { if (BHMemory.get("tableHeader")) pHeaderRowData = eval(BHMemory.get("tableHeader")); else pHeaderRowData = arguments[2]; pHeaderRowCallback = arguments[3]; pNumCellsPerRow = pHeaderRowData.length; this._noHeaders = false; } this._tableID = pTableID; if (pContainerDiv instanceof Object) this._containerDiv = pContainerDiv; else this._containerDiv = document.getElementById(pContainerDiv); this._cellsPerRow = pNumCellsPerRow; this._tableRows = []; this._headerRow = pHeaderRowData; this._headerRowCallback = pHeaderRowCallback; this._isDrawn = false; this.altCount = 0; } BeachheadUI.Table.prototype = new BeachheadUI; BeachheadUI.Table.prototype.clearDivOnDraw = true; BeachheadUI.Table.prototype._isDrawn = false; BeachheadUI.Table.prototype._isDrawing = false; BeachheadUI.Table.prototype._abortDrawing = false; BeachheadUI.Table.prototype._liveDrawTimer; BeachheadUI.Table.prototype._liveDrawStatusCallback; BeachheadUI.Table.prototype._liveDrawCompletionCallback; BeachheadUI.Table.prototype._tableRows = []; BeachheadUI.Table.prototype._tableRows = []; BeachheadUI.Table.prototype._noHeaders = this._noHeaders; BeachheadUI.Table.prototype._headerRow = []; BeachheadUI.Table.prototype._headerRowCallback = this._headerRowCallback BeachheadUI.Table.prototype._currentRow = []; BeachheadUI.Table.prototype._currentRowBlank = true; BeachheadUI.Table.prototype._defaultSortOrder = "asc"; BeachheadUI.Table.prototype._currentSortBy = ""; BeachheadUI.Table.prototype._currentSortOrder = this._defaultSortOrder; BeachheadUI.Table.prototype._containerDiv = this._containerDiv; BeachheadUI.Table.prototype._containerDivHTML = ""; BeachheadUI.Table.prototype._table = null; BeachheadUI.Table.prototype._tbody = null; /* Default table styling for useDefaultStyling(); */ BeachheadUI.Table.prototype._defTableClass = "bh_table"; BeachheadUI.Table.prototype._defCellPadding = 0; BeachheadUI.Table.prototype._defCellSpacing = 0; BeachheadUI.Table.prototype._defAscArrowSrc = "table_images/bh_arrowup_white.gif"; BeachheadUI.Table.prototype._defDescArrowSrc = "table_images/bh_arrowdown_white.gif"; BeachheadUI.Table.prototype._defCustomStyle = ""; BeachheadUI.Table.prototype.alternateColors = true; BeachheadUI.Table.prototype.mouseoverHighlight = true; BeachheadUI.Table.prototype.altCount = 0; BeachheadUI.Table.prototype._dynamicRowData = []; BeachheadUI.Table.prototype.setStyling = function(pTableClass,pCellPadding,pCellSpacing,pCustomStyle) { this._tableClass = pTableClass; this._cellPadding = pCellPadding; this._cellSpacing = pCellSpacing; this._customStyle = pCustomStyle; if(arguments.length > 4) { this._ascArrowSource = arguments[4]; this._descArrowSource = arguments[5]; } }; BeachheadUI.Table.prototype.useDefaultStyling = function() { this._tableClass = this._defTableClass; this._cellPadding = this._defCellPadding; this._cellSpacing = this._defCellSpacing; this._ascArrowSource = this._defAscArrowSrc; this._descArrowSource = this._defDescArrowSrc; this._customStyle = this._defCustomStyle; }; BeachheadUI.Table.prototype.noAlternatingColors = function() { this.alternateColors = false; }; BeachheadUI.Table.prototype.noMouseover = function() { this.mouseoverHighlight = false; }; BeachheadUI.Table.prototype.clearRows = function() { this._currentRow = []; this._currentRowBlank = true; this._tableRows = []; }; BeachheadUI.Table.prototype.numRows = function() { return this._getTable().rows.length; }; BeachheadUI.Table.prototype.addRow = function() { if (typeof (arguments[0]) != null) this._currentRow.id = arguments[0]; if(this._currentRowBlank == false) { var nextIndex = this._tableRows.length; this._tableRows[nextIndex] = this._currentRow; } this._currentRow = []; this._currentRowBlank = true; }; BeachheadUI.Table.prototype._getTable = function() { return document.getElementById(this._tableID); } BeachheadUI.Table.prototype.addCell = function () { var encode = true; if (arguments.length > 5) encode = arguments[5]; this._currentRowBlank = false; var nextIndex = this._currentRow.length; if (nextIndex > (this._cellsPerRow - 1)) { throw ("Row already full of cells, must start new one or check input data."); return false; } else { if (typeof(arguments[0]) != "string") pCellData = arguments[0]; else if (arguments.length > 1) { pCellData = new Array(); for (var i = 0; i < arguments.length; i++) { pCellData[i] = arguments[i]; } /*If no hover has been specified for the cell then set the hover equal to the data -Justin */ //NEED BETTER WAY TO ADD INPUTS IN OR NOT ALLOW (<, >) CHARACTERS...force them to use addHTMLCell var tempCellData = pCellData[0].toString(); if (arguments.length < 3) { for (; i < 2; i++) pCellData[i] = null; if (encode) { pCellData[i] = arguments[0]; } } pCellData[5] = encode; } else { pCellData = new Array(); pCellData[0] = arguments[0] == null ? "" : arguments[0]; pCellData[1] = null; //NEED BETTER WAY TO ADD INPUTS IN OR NOT ALLOW (<, >) CHARACTERS...must use addHTMLCell if (!encode) pCellData[2] = arguments[0]; else pCellData[5] = encode; //this should be the encode index...if we find input and type } this._currentRow[nextIndex] = pCellData; } }; // Added by Patrick on Nov 7, 2007 so HTML wouldn't interfere with html-encoding used on addCell(); BeachheadUI.Table.prototype.addHTMLCell = function(pHTMLContent) { this.addCell(pHTMLContent,null,null,null,null,false); }; BeachheadUI.Table.prototype.addHTMLCellWithHover = function (pHTMLContent, pHover) { this.addCell(pHTMLContent, null, pHover, null, null, false, true); }; BeachheadUI.Table.prototype.addBlankCell = function() { this._currentRowBlank = false; var nextIndex = this._currentRow.length; if(nextIndex > (this._cellsPerRow-1)) { throw("Row already full of cells, must start new one or check input data."); return false; } else { if(arguments.length > 0) this._currentRow[nextIndex] = new Array(" ",null,"",arguments[0], null, false); else this._currentRow[nextIndex] = new Array(" ", null, null, null, null, false); } }; BeachheadUI.Table.prototype.setCurrentSort = function(pSortBy,pSortOrder) { this._currentSortBy = pSortBy; this._currentSortOrder = pSortOrder; }; BeachheadUI.Table.prototype.findDefaultSortBy = function() { for(var i =0; i < this._headerRowData.length; i++) { if(this._headerRowData[i].length>3) { return this._headerRowData[i][2]; } } }; BeachheadUI.Table.prototype.draw = function () { if (this._currentRowBlank == false) { var nextIndex = this._tableRows.length; this._tableRows[nextIndex] = this._currentRow; this._currentRowBlank = true; } if (this.clearDivOnDraw) { while (this._containerDiv.childNodes.length > 0) this._containerDiv.removeChild(this._containerDiv.childNodes[0]); } if ((this._table == null) || (this._table.parentNode == null) || (this.clearDivOnDraw)) { this._table = this._containerDiv.appendChild(document.createElement("table")); this._table.name = this._table.id = this._tableID; this._table.className = this._tableClass; this._table.border = "0"; this._table.cellPadding = this._table.cellSpacing = "0"; try { this._table.style = this._customStyle; } catch (ex) { } this._tbody = this._table.appendChild(document.createElement("tBody")); } else { this._table.removeChild(this._tbody); this._tbody = this._table.appendChild(document.createElement("tBody")); } //this._containerDivHTML = '\n'; /*//not sure what this was for but had to move it up because of the change to the draw function...Justin if (arguments.length > 0) { if (arguments.length == 1) { this._containerDivHTML = arguments[0] + this._containerDivHTML; } else { this._containerDivHTML = arguments[0] + this._containerDivHTML + arguments[1]; } }*/ if (!this._noHeaders) this.drawHeader(); //this._containerDivHTML += "
\n"; //this._containerDiv.innerHTML = this._containerDivHTML; for (var i = 0; i < this._tableRows.length; i++) { this.drawRow(i); } this._isDrawn = true; try { if (typeof columnDisplayArray == "undefined") columnDisplayArray = eval(BHMemory.get("columnDisp")); BeachheadUI.Table.addDisplayNoColumnContextMenu("management_table", columnDisplayArray); } catch (e) { } if (typeof dragtable != "undefined") dragtable.makeDraggable(this._table); // for reordering table columns }; BeachheadUI.Table._liveDrawRows = function(pStartingRow, pNameSpace, pAmtToProcess) { clearTimeout(window[pNameSpace]._liveDrawTimer); if(window[pNameSpace]._abortDrawing) { window[pNameSpace]._isDrawing = false; window[pNameSpace]._abortDrawing = false; return; } if(!pAmtToProcess) pAmtToProcess = 10; var totalToDraw = pStartingRow + pAmtToProcess; for(var i = pStartingRow; ((i < totalToDraw)&&(i < window[pNameSpace]._tableRows.length)); i++) { try{window[pNameSpace].drawRow(i);}catch(ex){return;} } if(window[pNameSpace]._liveDrawStatusCallback) BeachheadUI.evaluateCallback(window[pNameSpace]._liveDrawStatusCallback, [i, window[pNameSpace]._tableRows.length]); if(i < window[pNameSpace]._tableRows.length) eval("window[\"" + pNameSpace + "\"]._liveDrawTimer = setTimeout(\"BeachheadUI.Table._liveDrawRows(" + i + ", '" + pNameSpace + "', " + pAmtToProcess + ");\", 0);"); else if(window[pNameSpace]._liveDrawCompletionCallback) { window[pNameSpace]._isDrawn = true; window[pNameSpace]._isDrawing = false; window[pNameSpace]._abortDrawing = false; BeachheadUI.evaluateCallback(window[pNameSpace]._liveDrawCompletionCallback); } }; BeachheadUI.Table.prototype.liveDraw = function (pFinishedCallback, pStatusCallback, pAmtToProcess) { if (this._isDrawing) { this._abortDrawing = true; return this.liveDraw(pFinishedCallback, pStatusCallback, pAmtToProcess); } if (this._currentRowBlank == false) { var nextIndex = this._tableRows.length; this._tableRows[nextIndex] = this._currentRow; this._currentRowBlank = true; } //this._containerDivHTML = '\n'; if (this.clearDivOnDraw) { while (this._containerDiv.childNodes.length > 0) this._containerDiv.removeChild(this._containerDiv.childNodes[0]); } if ((this._table == null) || (this._table.parentNode == null) || (this.clearDivOnDraw)) { this._table = this._containerDiv.appendChild(document.createElement("table")); this._table.name = this._table.id = this._tableID; this._table.className = this._tableClass; this._table.border = "0"; this._table.cellPadding = this._table.cellSpacing = "0"; try { this._table.style = this._customStyle; } catch (ex) { } this._tbody = this._table.appendChild(document.createElement("tBody")); } else { this._table.removeChild(this._tbody); this._tbody = this._table.appendChild(document.createElement("tBody")); } if (!this._noHeaders) this.drawHeader(); //this._containerDivHTML += "
\n"; //this._containerDiv.innerHTML = this._containerDivHTML; this._liveDrawStatusCallback = pStatusCallback; this._liveDrawCompletionCallback = pFinishedCallback; window[this._tableID] = this; BeachheadUI.Table._liveDrawRows(0, this._tableID, pAmtToProcess); if (typeof dragtable != "undefined") dragtable.makeDraggable(this._table); // for reordering table columns //if(arguments.length > 0) { // if(arguments.length == 1) { // this._containerDivHTML = arguments[0] + this._containerDivHTML; // } else { // this._containerDivHTML = arguments[0] + this._containerDivHTML + arguments[1]; // } //} }; BeachheadUI.Table.prototype.redraw = function() { /* This function was put here intentionally to: a) improve clarity b) allow for future optimizations of redraw method. */ this.draw(); }; BeachheadUI.Table.prototype.drawHeader = function () { if (BHMemory.get("tableHeader")) this._headerRow = eval(BHMemory.get("tableHeader")); //this._containerDivHTML += '\n'; var cellContent = ""; var cellLabel = ""; var tr = document.createElement("tr"); tr.className = "table_header"; var chooseDefaultSort = (this._currentSortBy == ""); for (var i = 0; i < this._headerRow.length; i++) { if ((this._headerRow[i].length > 1) && (this._headerRow[i][1] != null)) { if (chooseDefaultSort) { this._currentSortBy = this._headerRow[i][1]; } var isCurrentSort = (this._headerRow[i][1] == this._currentSortBy); var allAscDesc = isCurrentSort ? this._currentSortOrder : this._defaultSortOrder; var ascDescInverse = allAscDesc == "asc" ? "desc" : "asc"; var ascDescImage = allAscDesc == "asc" ? this._ascArrowSource : this._descArrowSource; var ascDescLink = isCurrentSort ? ascDescInverse : allAscDesc; if (isCurrentSort) { cellLabel = '' + this._headerRow[i][0] + ''; } else { cellLabel = this._headerRow[i][0]; } cellLabel += ' '; //added the href attribute to add a tab stop...justin cellContent = '' + cellLabel + '\n'; } else { cellContent = this._headerRow[i][0]; } var cell_width = (this._headerRow[i].length > 2) ? this._headerRow[i][2] : ''; var td = tr.appendChild(document.createElement("td")); try { td.width = cell_width; } catch (ex) { } td.innerHTML = cellContent; //this._containerDivHTML += "\t" + cellContent + "\n"; } this._tbody.appendChild(tr); //this._containerDivHTML += "\n"; }; BeachheadUI.Table.prototype.drawRow = function (pRowIndex) { var tempRow = this._tableRows[pRowIndex]; var tr = document.createElement("tr"); this.altCount++; if(((this.altCount % 2) == 0) || (!this.alternateColors)) { tr.className = "off"; if(this.mouseoverHighlight) { tr.onmouseover = function() { this.className = this.className + " highlight"; }; tr.onmouseout = function() { this.className = this.className.replace(/\shighlight/g,""); }; } } else { tr.className = "on"; if(this.mouseoverHighlight) { tr.onmouseover = function() { this.className = this.className + " highlight"; }; tr.onmouseout = function() { this.className = this.className.replace(/\shighlight/g,""); }; } } if (BHMemory.get("dataColIndexArr")) { dataColIndexArr = eval(BHMemory.get("dataColIndexArr")); for (var i = 0; i < dataColIndexArr.length; i++) tr.appendChild(this.createCell(tempRow[dataColIndexArr[i][0]])); } else { for (var i = 0; i < tempRow.length; i++) { tr.appendChild(this.createCell(tempRow[i])); } } var numBlankFills = (this._cellsPerRow - tempRow.length); for(var j = 0; j < numBlankFills; j++) { var blankTD = document.createElement("td"); blankTD.innerHTML = " "; tr.appendChild(blankTD); } this._tbody.appendChild(tr); }; BeachheadUI.Table.prototype.createCell = function (pCellData) { var title = ""; var link = ""; var label = ""; var cell_id = ""; var cell_width = ""; var encode = true; var td = document.createElement("td"); //Added the html encoding of the text //For future, may want to consider coming up with a better way to add additional html elements to //the table //Justin 11-5 if (isArray(pCellData)) { if (pCellData.length > 5) { encode = pCellData[5] == true ? true : false; } // bug 3677 // replace double quotes with \\\" //if ( (pCellData.length > 2) && (pCellData[2] != null) ) //{ // pCellData[2] = BeachheadUI.encodeHTML(pCellData[2]); //pCellData[2] = pCellData[2].replace(/\"/g, """); //} title = pCellData.length < 3 ? "" : (pCellData[2] != null ? pCellData[2] : pCellData[0]); cell_id = pCellData.length < 4 ? "" : (pCellData[3] != null ? ' id="' + pCellData[3] + '"' : ""); cell_width = pCellData.length < 5 ? "" : (pCellData[4] != null ? ' width="' + pCellData[4] + '"' : ""); link = pCellData[1]; //if(encode) // label = title ? BeachheadUI.encodeHTML(pCellData[0]) : pCellData[0]; //else label = pCellData[0]; } else if (((!pCellData) || (typeof (pCellData) == "undefined")) && pCellData != 0) label = ""; else if ((typeof (pCellData) == "object") && (typeof (pCellData) != "undefined")) { td.appendChild(pCellData); return td; } else { title = pCellData.toString(); link = null; label = pCellData.toString(); } td.id = cell_id; td.style.width = cell_width; td.title = title; if (link != null) { if (encode) { var a = document.createElement("a"); a.href = link; a.appendChild(document.createTextNode(label)); td.appendChild(a); } else { td.innerHTML = "" + label + ""; td.title = ""; } } else { if (encode) td.appendChild(document.createTextNode(label)); else { td.innerHTML = label; if (pCellData.length >= 7 && pCellData[6] == true) //leave hover title td.title = td.title; else td.title = ""; } } return td; }; /* START DYNAMIC CHANGES WHICH HAPPENS WITHOUT REDRAW */ BeachheadUI.Table.prototype.removeRow = function(pRowIndex) { /* can only be called AFTER it is drawn... */ if(!this._noHeaders) pRowIndex = pRowIndex + 1; this._tableRows[pRowIndex] = null; for(var i = pRowIndex; i < this._tableRows.length; i++) this._tableRows[i] = this._tableRows[i+1]; this._tableRows.pop(); this._getTable().deleteRow(pRowIndex); }; BeachheadUI.Table.prototype.startDynamicRow = function() { this._dynamicRowData = new Array(); }; BeachheadUI.Table.prototype.addDynamicCell = function(pContent) { var next_index = this._dynamicRowData.length; this._dynamicRowData[next_index] = pContent; }; BeachheadUI.Table.prototype.drawDynamicRow = function () { var newRow = this._getTable().insertRow(-1); var newCell = null; for (var i = 0; i < this._dynamicRowData.length; i++) { newCell = newRow.insertCell(i); if ((typeof (this._dynamicRowData[i]) == "object") && (this._dynamicRowData[i] instanceof Array)) { for(var x = 0; x < this._dynamicRowData[i].length; x++) if (typeof (this._dynamicRowData[i][x]) == "string") newCell.innerHTML += this._dynamicRowData[i][x]; else if (typeof (this._dynamicRowData[i][x]) == "object") newCell.appendChild(this._dynamicRowData[i][x]); } else { if (typeof (this._dynamicRowData[i]) == "string") newCell.innerHTML = this._dynamicRowData[i]; else if (typeof (this._dynamicRowData[i]) == "object") newCell.appendChild(this._dynamicRowData[i]); } } }; //Patrick you may want to change how this works but for now I made it a static function //for setting the widths of the table columns /* This function will set the widths of the cells of a table. NOTE: maybe this should be a function of the table pTableId-The id of the table to set the widths on pWidthArr-Each item in the array will be the width of the cell at that index. */ BeachheadUI.Table.setTableCellWidths = function (pTableId, pWidthArr, pAllRows) { var tabObj = document.getElementById(pTableId); if ((!tabObj) || (!pWidthArr) || (!(pWidthArr instanceof Array)) || (tabObj.rows.length <= 0)) return; else if ((tabObj.rows.length > 1) && (tabObj.rows[0].cells.length <= 0)) tabObj.tBodies[0].removeChild(tabObj.rows[0]); for (var y = 0; (y < tabObj.rows.length); y++) { var tabObjRows = tabObj.rows[y]; for (var x = 0; ((x < pWidthArr.length) && (x < tabObjRows.cells.length)); x++) { if (pWidthArr[x] == "auto") tabObjRows.cells[x].style.width = pWidthArr[x]; else { var tempWidth = parseInt(pWidthArr[x]); if (!BeachheadUI.IE) { if (window.opera) { if (x == 0) tempWidth = tempWidth + 10; //alert("opera" + tempWidth) } else if (navigator.vendor.indexOf("Apple") > -1) { tempWidth = tempWidth + 30; //alert("safari" + tempWidth); } else if (navigator.userAgent.indexOf("Chrome") > -1) { tempWidth = tempWidth + 10; //alert("chrome" + tempWidth); } else if (navigator.userAgent.indexOf("Android") > -1) { tempWidth = tempWidth + 30; //alert("android" + tempWidth); } else if (navigator.userAgent.indexOf("Firefox") > -1) { tempWidth = tempWidth + 10; //alert("firefox" + tempWidth); } else { //unknown browser tempWidth = tempWidth + 30; //alert("unknown" + tempWidth); } } else //add some extra width in ie10 tempWidth = tempWidth + 4; tabObjRows.cells[x].style.width = parseInt(tempWidth) + "px"; } } if (!pAllRows) break; } } /* This function will allow you to show/hide columns without the context menu appearing pTableId is the id of the table to add the context menu to pColumnArr is a double array. It contains an array of arrays and in the inner arrays it contains 3 values: index 0 is the column index index 1 is the column name index 2 is the current display state NOTE: The pColumnArr should be a global array variable that way state is maintained when sorting is done */ BeachheadUI.Table.addDisplayNoColumnContextMenu = function (pTableId, pColumnArr) { var tabObj = document.getElementById(pTableId); var counter = 0; for (var x = 0; x < tabObj.rows.length; x++) for (var y = 0; y < tabObj.rows[x].cells.length; y++) for (var z = 0; z < pColumnArr.length; z++) if ((pColumnArr[z][0] == y) && (!pColumnArr[z][2])) tabObj.rows[x].cells[y].style.display = "none"; else if (pColumnArr[z][0] == y) tabObj.rows[x].cells[y].style.display = ""; var div = document.getElementById(pTableId + "_cm"); if (!div) div = document.createElement("div"); else { while (div.childNodes.length > 0) try { delete (div.removeChild(div.childNodes[0])); } catch (ex) { } } div.style.display = "none"; div.id = pTableId + "_cm"; div.style.position = "absolute"; div.style.zIndex = 23; document.body.appendChild(div); var timer; var tab = document.createElement("table"); tab.style.width = "auto"; tab.style.cursor = "pointer"; tab.style.backgroundColor = "white"; tab.onmouseout = function () { div.style.display = "none"; }; div.appendChild(tab); tab.appendChild(document.createElement("tbody")); tab = tab.tBodies[0]; var tr; var td; for (var z = 0; z < pColumnArr.length; z++) { if (pColumnArr[z][1]) { tr = document.createElement("tr"); td = document.createElement("td"); td.innerHTML = pColumnArr[z][0]; td.style.display = "none"; tr.appendChild(td); td = td.cloneNode(true); td.innerHTML = z; tr.appendChild(td); td = document.createElement("td"); td.style.border = "black solid 1px"; td.innerHTML = pColumnArr[z][1]; tr.appendChild(td); tab.appendChild(tr); } } }; /* This function will add a context menu to a table that will allow you to show/hide columns. pTableId is the id of the table to add the context menu to pColumnArr is a double array. It contains an array of arrays and in the inner arrays it contains 3 values: index 0 is the column index index 1 is the column name index 2 is the current display state NOTE: The pColumnArr should be a global array variable that way state is maintained when sorting is done */ BeachheadUI.Table.addDisplayColumnContextMenu = function (pTableId, pColumnArr, pRenderColumnFunc) { var tabObj = document.getElementById(pTableId); var counter = 0; for (var x = 0; x < tabObj.rows.length; x++) for (var y = 0; y < tabObj.rows[x].cells.length; y++) for (var z = 0; z < pColumnArr.length; z++) if ((pColumnArr[z][0] == y) && (!pColumnArr[z][2])) tabObj.rows[x].cells[y].style.display = "none"; else if (pColumnArr[z][0] == y) tabObj.rows[x].cells[y].style.display = ""; var div = document.getElementById(pTableId + "_cm"); if (!div) div = document.createElement("div"); else { while (div.childNodes.length > 0) try { delete (div.removeChild(div.childNodes[0])); } catch (ex) { } } div.style.display = "none"; div.id = pTableId + "_cm"; div.style.position = "absolute"; div.style.zIndex = 23; document.body.appendChild(div); var timer; var tab = document.createElement("table"); tab.style.width = "auto"; tab.style.cursor = "pointer"; tab.style.backgroundColor = "white"; tab.onmouseout = function () { div.style.display = "none"; }; div.appendChild(tab); tab.appendChild(document.createElement("tbody")); tab = tab.tBodies[0]; var tr; var td; for (var z = 0; z < pColumnArr.length; z++) { if (pColumnArr[z][1]) { tr = document.createElement("tr"); td = document.createElement("td"); td.innerHTML = pColumnArr[z][0]; td.style.display = "none"; tr.appendChild(td); td = td.cloneNode(true); td.innerHTML = z; tr.appendChild(td); td = document.createElement("td"); td.style.border = "black solid 1px"; td.innerHTML = pColumnArr[z][1]; td.onmouseover = function (pEvent) { div.style.display = ""; var obj; if (pEvent) { obj = pEvent.target; pEvent.preventDefault(); pEvent.stopPropagation(); } else { pEvent = window.event; obj = pEvent.srcElement; pEvent.cancelBubble = true; pEvent.returnValue = false; } obj.style.backgroundColor = "blue"; obj.style.color = "white"; return false; }; td.onmouseout = function (pEvent) { var obj; if (pEvent) obj = pEvent.target; else obj = window.event.srcElement; obj.style.backgroundColor = "white"; obj.style.color = "black"; }; td.onclick = function (pEvent) { div.style.display = "none"; var obj; if (pEvent) obj = pEvent.target; else obj = window.event.srcElement; while (obj.tagName != "TR") obj = obj.parentNode; var index = obj.cells[0].innerHTML; var counter = 0; for (var x = 0; x < tabObj.rows.length; x++) if (tabObj.rows[x].cells.length > index) { if (tabObj.rows[x].cells[index].style.display == "none") { tabObj.rows[x].cells[index].style.display = ""; pColumnArr[obj.cells[1].innerHTML][2] = true; } else { tabObj.rows[x].cells[index].style.display = "none"; pColumnArr[obj.cells[1].innerHTML][2] = false; } } else { if (counter == 0) { for (var y = 0; y < tabObj.rows[0].cells.length; y++) if (tabObj.rows[0].cells[y].style.display != "none") counter++; } if ((tabObj.rows[x].cells.length > 0) && (tabObj.rows[x].cells[0].colSpan)) tabObj.rows[x].cells[0].colSpan = counter; } }; tr.appendChild(td); tab.appendChild(tr); } } tabObj.oncontextmenu = function (pEvent) { var obj; if (pEvent) { obj = pEvent.target; pEvent.preventDefault(); pEvent.stopPropagation(); } else { pEvent = window.event; obj = pEvent.srcElement; pEvent.cancelBubble = true; pEvent.returnValue = false; } var scrollObj = document.getElementsByTagName("html")[0]; if ((!scrollObj.scrollTop) && (!scrollObj.scrollTop)) scrollObj = document.body; div.style.top = (scrollObj.scrollTop + pEvent.clientY - 10) + "px"; div.style.left = (scrollObj.scrollLeft + pEvent.clientX - 10) + "px"; div.style.display = ""; return false; }; }; /* This function will add resizable columsn to a table. In order for this to work the table must be placed within two divs that are relatively positioned and the outer-most div must have the overflow set to auto pTableId is the id of the table to add the resizable columns to (adds the resize bar to the first row); pColumnArr is a double array. It contains an array of arrays and in the inner arrays it contains 3 values: index 0 is the column index index 1 is the column minimum size (if no minimum size is specified the start size is the minimum) pCurrentWidths is a global variable that holds the widths of the table and willl be updated when resized pResizeFunction is a function that will be called on a resize event */ BeachheadUI.Table.addResizeColumns = function(pTableId, pColumnArr, pCurrentWidths, pResizeFunction) { var minimumSize; var table = document.getElementById(pTableId); var parentDiv = table.parentNode; var newDiv; while(parentDiv.tagName != "DIV") parentDiv = parentDiv.parentNode; parentDiv.style.position = "relative"; table.style.position = "relative"; var resizeObj = document.getElementById(parentDiv.id + "_resizeBar"); if(!resizeObj) { resizeObj = document.createElement("div"); resizeObj.style.width = "2px"; resizeObj.style.position = "absolute"; resizeObj.style.backgroundColor = "green"; resizeObj.style.display = "none"; resizeObj.style.top = "0px"; parentDiv.appendChild(resizeObj); } if (BHMemory.get("columnWidths")) pCurrentWidths = eval(BHMemory.get("columnWidths")); for(var x = 0; x < table.rows[0].cells.length; x++) { if(!BeachheadUI.IE) { newDiv = document.createElement("div"); newDiv.style.position = "relative"; newDiv.style.overflow = "hidden"; for(var y = 0; y < table.rows[0].cells[x].childNodes.length; y++) newDiv.appendChild(table.rows[0].cells[x].childNodes[y]); table.rows[0].cells[x].appendChild(newDiv); } // minimumSize = table.rows[0].cells[x].clientWidth; for(var y = 0; y < pColumnArr.length; y++) if(x == pColumnArr[y][0]) { if(pColumnArr[y].length > 1) minimumSize = pColumnArr[y][1]; BeachheadUI.Table._addResizeColumns(table, x, minimumSize, resizeObj, parentDiv, newDiv, pCurrentWidths, table.rows[0].cells[x].innerText.trim(), pResizeFunction); } //add minimum size to all columns to resize if (x > 0 && x < table.rows[0].cells.length-1 && minimumSize == table.rows[0].cells[x].clientWidth) { minimumSize = 15; BeachheadUI.Table._addResizeColumns(table, x, minimumSize, resizeObj, parentDiv, newDiv, pCurrentWidths, table.rows[0].cells[x].innerText.trim(), pResizeFunction); } } }; /* The internal add resize columns function called by the public function pTable-the table object of the resizable headers pCellIndex-the index of the cell to add the resize to pMinimumSize-the minimum size of the column pResizeObj-the resize bar that is displayed pParentDiv-the table must be drawn in a div and this is the div object that the table is drawn in pNewDiv-for firefox, the position of the resize marker in the header is positioned absolute and needed it to be relative to that cell, so it needed to be in a relatively positioned div. In firefox, all elements of that header cell will be placed into this relatively positioned div. pCurrentWidths is a global variable that holds the widths of the table and willl be updated when resized pResizeFunction is a function that will be called on a resize event */ BeachheadUI.Table._addResizeColumns = function (pTable, pCellIndex, pMinimumSize, pResizeObj, pParentDiv, pNewDiv, pCurrentWidths, pCellTitle, pResizeFunction) { var div = document.createElement("div"); div.style.width = "3px"; div.style.backgroundColor = "#357FB6"; div.style.borderRight = "white solid 1px"; div.style.borderLeft = "white solid 1px"; var idiv = div.appendChild(document.createElement("div")); idiv.style.backgroundColor = "#fff"; idiv.style.opacity = "0.1"; idiv.style.width = idiv.style.height = "100%"; div.style.borderCollapse = "collapse"; div.style.position = "absolute"; div.style.cursor = "w-resize"; div.style.top = "0px"; div.style.top = "-5px"; div.style.bottom = "-5px"; div.style.right = "0px"; div.style.display = "inline"; /*if (BeachheadUI.IE) div.style.height = "100%"; else div.style.height = (pTable.rows[0].clientHeight - 1) + "px";*/ var startPos; var startBarPos; var mousemove; var mouseup; var width; mousemove = function (pEvent) { if (!pEvent) pEvent = window.event; var mmoved = pEvent.clientX - startPos; var cellIndex; if (BHMemory.get("dataColIndexArr")) { var dataColIndexArr = eval(BHMemory.get("dataColIndexArr")); for (var i = 1; i < dataColIndexArr.length; i++) { if (dataColIndexArr[i][1].trim().toLowerCase() == pCellTitle.toLowerCase()) { cellIndex = i; break; } else cellIndex = pCellIndex; } } else cellIndex = pCellIndex; //var newPos = (parseInt(pTable.rows[0].cells[pCellIndex].style.width) + mmoved); var newPos = (parseInt(pTable.rows[0].cells[cellIndex].style.width) + mmoved); if (newPos >= pMinimumSize) pResizeObj.style.left = (startBarPos + mmoved) + "px"; if (BeachheadUI.IE) { pEvent.cancelBubble = true; pEvent.returnValue = false; } else { pEvent.preventDefault(); pEvent.stopPropagation(); } return true; }; mouseup = function (pEvent) { var cellIndex; if (BHMemory.get("dataColIndexArr")) { var dataColIndexArr = eval(BHMemory.get("dataColIndexArr")); for (var i = 1; i < dataColIndexArr.length; i++) { if (dataColIndexArr[i][1].trim().toLowerCase() == pCellTitle.toLowerCase()) { cellIndex = i; break; } else cellIndex = pCellIndex; } } else cellIndex = pCellIndex; pTable.style.width = ""; pResizeObj.style.display = "none"; div.style.display = "none"; div.style.display = "inline"; var mmoved = parseInt(pResizeObj.style.left) - startBarPos; //var prePos = parseInt(pTable.rows[0].cells[pCellIndex].style.width); var prePos = parseInt(pTable.rows[0].cells[cellIndex].style.width); var newPos = prePos + mmoved; if (newPos < pMinimumSize) newPos = pMinimumSize; //if ((newPos == prePos)&&(pTable.rows[0].cells[pCellIndex].oncontextmenu)) if ((newPos == prePos) && (pTable.rows[0].cells[cellIndex].oncontextmenu)) { if (BeachheadUI.IE) { document.detachEvent("onmousemove", mousemove); document.detachEvent("onmouseup", mouseup); } else { window.removeEventListener("mousemove", mousemove, true); window.removeEventListener("mouseup", mouseup, true); } //return pTable.rows[0].cells[pCellIndex].oncontextmenu(pEvent); return pTable.rows[0].cells[cellIndex].oncontextmenu(pEvent); } //pTable.rows[0].cells[pCellIndex].style.width = newPos + "px"; pTable.rows[0].cells[cellIndex].style.width = newPos + "px"; if (pCurrentWidths) //pCurrentWidths[pCellIndex] = newPos; pCurrentWidths[cellIndex] = newPos; BHMemory.add("columnWidths", pCurrentWidths); BHMemory.save(); if (BeachheadUI.IE) { document.detachEvent("onmousemove", mousemove); document.detachEvent("onmouseup", mouseup); pEvent.cancelBubble = true; pEvent.returnValue = false; } else { window.removeEventListener("mousemove", mousemove, true); window.removeEventListener("mouseup", mouseup, true); pEvent.preventDefault(); pEvent.stopPropagation(); } if (typeof (pResizeFunction) == "string") { if (pResizeFunction.indexOf("(") == -1) eval(pResizeFunction + "()"); else eval(pResizeFunction); } else if ((typeof (pResizeFunction) == "function") || (typeof (pResizeFunction) == "object")) pResizeFunction(); }; div.onmousedown = (function(pCellIndex){ return function (pEvent) { if (BeachheadUI.IE) {//IE pEvent = window.event; document.attachEvent("onmousemove", mousemove); document.attachEvent("onmouseup", mouseup); pEvent.cancelBubble = true; pEvent.returnValue = false; } else {//FIREFOX window.addEventListener("mousemove", mousemove, true); window.addEventListener("mouseup", mouseup, true); pEvent.preventDefault(); pEvent.stopPropagation(); } var cellIndex; if (BHMemory.get("dataColIndexArr")) { var dataColIndexArr = eval(BHMemory.get("dataColIndexArr")); for (var i = 1; i < dataColIndexArr.length; i++) { if (dataColIndexArr[i][1].trim().toLowerCase() == pCellTitle.toLowerCase()) { cellIndex = i; break; } else cellIndex = pCellIndex; } } else cellIndex = pCellIndex; //width = pTable.rows[0].cells[pCellIndex].clientWidth; width = pTable.rows[0].cells[cellIndex].clientWidth; var offset = pParentDiv.offsetLeft - pParentDiv.scrollLeft; var offsetObj = pParentDiv.offsetParent; while (offsetObj.offsetParent) { offset += offsetObj.offsetLeft - offsetObj.scrollLeft; offsetObj = offsetObj.offsetParent; } offset += offsetObj.offsetLeft; if (BeachheadUI.IE) offset += 2; startPos = pEvent.clientX; startBarPos = (pEvent.clientX - offset); pResizeObj.style.height = pTable.clientHeight + "px"; pResizeObj.style.left = startBarPos + "px"; pResizeObj.style.display = "inline"; div.style.display = "none"; div.style.display = "inline"; return true; }})(pCellIndex); if (pNewDiv) { //pNewDiv.innerHTML += " "; pNewDiv.appendChild(div); } else { /**/ //pTable.rows[0].cells[pCellIndex].appendChild(div); pTable.rows[0].cells[cellIndex].appendChild(div); //if((div.offsetParent)&&(div.offsetParent.clientWidth > pCurrentWidths[pCellIndex] + 50)) if ((div.offsetParent) && (div.offsetParent.clientWidth > pCurrentWidths[cellIndex] + 50)) { //pTable.rows[0].cells[pCellIndex].style.position = "relative"; pTable.rows[0].cells[cellIndex].style.position = "relative"; } } var lenDiv; if (!lenDiv) { lenDiv = document.createElement("div"); lenDiv.appendChild(document.createTextNode("")); document.body.appendChild(lenDiv); lenDiv.style.fontFamily = "Verdana, Helvetica, San-Serif"; if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) { lenDiv.style.fontSize = "20px"; } else { lenDiv.style.fontSize = "10pt"; } lenDiv.style.position = "absolute"; lenDiv.style.padding = "4px"; // // lenDiv.style.top = lenDiv.style.left = "-100000px"; lenDiv.style.zIndex = "999"; lenDiv.style.width = "auto"; lenDiv.style.overflow = "visible"; lenDiv.style.textOverflow = "visible"; lenDiv.style.whiteSpace = "noWrap"; } pTable.rows[0].cells[pCellIndex].oncontextmenu = (function () { var prevLen = parseInt(pTable.rows[0].cells[pCellIndex].style.width); var curLen; var exp = false; return function (pEvent) { //var newPos = (parseInt(pTable.rows[0].cells[pCellIndex].style.width) + mmoved); var newLen = pMinimumSize; if (!exp) { exp = true; newLen = pTable.rows[0].cells[pCellIndex].scrollWidth + 20; var headerNodeChildren = pTable.rows[0].cells[pCellIndex].childNodes; var anchorNode; for (var i = 0; i < headerNodeChildren.length; i++) { anchorNode = BeachheadUI.Table.findAnchorTagNode(headerNodeChildren[i]); if (anchorNode) break; } if (anchorNode) { newLen = anchorNode.scrollWidth + 20; } for (var x = 1; x < pTable.rows.length; x++) { for (var y = 0; y < pTable.rows[x].cells[pCellIndex].childNodes.length; y++) { var childLen = pTable.rows[x].cells[pCellIndex].childNodes[y].scrollWidth; if (pTable.rows[x].cells[pCellIndex].childNodes[y].data) { lenDiv.childNodes[0].data = pTable.rows[x].cells[pCellIndex].childNodes[y].data; childLen = lenDiv.scrollWidth; } else if ((childLen == 0)&&(pTable.rows[x].cells[pCellIndex].childNodes[y].parentNode.scrollWidth)) { childLen = pTable.rows[x].cells[pCellIndex].childNodes[y].parentNode.scrollWidth; } if (childLen > newLen) { newLen = childLen; } if (pTable.rows[x].cells[pCellIndex].childNodes[y].tagName == "A") { for (var z = 0; z < pTable.rows[x].cells[pCellIndex].childNodes[y].childNodes.length; z++) { if (!pTable.rows[x].cells[pCellIndex].childNodes[y].childNodes[z].data) { continue; } lenDiv.childNodes[0].data = pTable.rows[x].cells[pCellIndex].childNodes[y].childNodes[z].data; childLen = lenDiv.scrollWidth; if (childLen > newLen) { newLen = childLen; } } } } } } else { exp = false; } if (newLen < pMinimumSize) newLen = pMinimumSize; pTable.rows[0].cells[pCellIndex].style.width = newLen + "px"; curLen = newLen; if (pCurrentWidths) pCurrentWidths[pCellIndex] = newLen; if (BeachheadUI.IE) { pEvent.cancelBubble = true; pEvent.returnValue = false; } else { pEvent.preventDefault(); pEvent.stopPropagation(); } if (typeof (pResizeFunction) == "string") { if (pResizeFunction.indexOf("(") == -1) eval(pResizeFunction + "()"); else eval(pResizeFunction); } else if ((typeof (pResizeFunction) == "function") || (typeof (pResizeFunction) == "object")) pResizeFunction(); return true; }; })(); } BeachheadUI.Table.findAnchorTagNode = function (pNode) { for (var i = 0; i < pNode.childNodes.length; i++) { if (pNode.childNodes[i].tagName && pNode.childNodes[i].tagName.toLowerCase() == "a") return pNode.childNodes[i]; else { var innerNode = BeachheadUI.Table.findAnchorTagNode(pNode.childNodes[i]); if (innerNode) return innerNode; } } return null; } BeachheadUI.Table.createDisplayArray = function (pHeaderArr) { var retArr = new Array(); for (var x = 0; x < pHeaderArr.length; x++) { if ((pHeaderArr[x][0].indexOf(" ") == 0)||(pHeaderArr[x][0].indexOf("