Table in JavaScript
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN">
<html>
<head>
<!-- JsTable.js -->
<script language=JavaScript>
/****
JsTable v0.4.5 (20050725) written by AT Mulyana (atmulyana@yahoo.com)
This libary is to create DHTML widget of Table on web page which is
editable, cell navigatable and its content is submittable to web server.
The target browser for this widget are :
- Netscape 7.1+ / Mozilla 1.4+ or other Gecko browser whose the same
or the newer version of Gecko engine.
- Internet Explorer 6+
- Opera 7.5+
I hope you get the best version so that this script can run correctly
You should get the documentaion to see how to use this script
Copyright (C) 2005 AT Mulyana (atmulyana@yahoo.com)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License or (at your option) any later version.
This library 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. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Send the bug report to 'atmulyana@yahoo.com' (Tell the exact version of your
browser and under which Operating System you run the script)
Currently, this script is personal work of myself, not involving other people or
company including the company where I work.
*****/
/****** Checks the browser family ******/
function JsTableCheckBrowser()
{
var navFamily = navigator.userAgent.toLowerCase();
if (navFamily.indexOf('opera')!=-1) {
var ver = parseFloat( navFamily.substring(navFamily.indexOf('opera')+6,
navFamily.length) );
if (ver >= 7.5) navFamily = 'Opera7';
else navFamily = '';
} else if (navFamily.indexOf('msie')!=-1) {
var ver = parseFloat( navFamily.substring(navFamily.indexOf('msie')+5,
navFamily.length) );
if (ver >= 6.0) navFamily = 'IE6';
else navFamily = '';
} else if (navFamily.indexOf('gecko')!=-1) {
var ver = parseFloat( navFamily.substring(navFamily.indexOf('gecko')+6,
navFamily.length) );
if (ver >= 20030624) navFamily = 'Gecko'; //Good Gecko; Netscape 7.1+/Mozilla 1.4+
else navFamily = '';
} else {
navFamily = '';
}
return navFamily;
}
var JsTableNavFamily = JsTableCheckBrowser();
/********** Adds additional useful methods to the standart objects **********/
String.prototype.strip = function() { //Removes leading and trailing white space(s)
return this.toString().replace(/^\s+/,'').replace(/\s+$/,'');
};
String.prototype.isNumeric = function() { //Does the string evaluate to a numeric value?
var re = /-?\s*\d*\.?\d+/;
var val = this.toString();
val = val.strip();
var valid = true;
var found = re.exec(val);
if (!found) valid=false;
else valid = (found[0].length==val.length);
return valid;
};
//Can the string be used as variabel name?
String.prototype.isQualifiedVarName = function() {
var re = /[a-zA-Z_]\w*/;
var val = this.toString();
var valid = true;
var found = re.exec(val);
if (!found) valid=false;
else valid = (found[0].length==val.length);
return valid;
};
//Does the string evaluate to a date value? (format: 'dd-mm-yyyy' or 'mm-dd-yyyy')
//If true then returns a normalized date value
String.prototype.isDate = function(sFormat) {
var sFormat = (sFormat+'').toLowerCase();
//Only 'd-m-y' or 'm-d-y' is accepted (It implies the paramater may
//be omitted ==> 'd-m-y' will be used)
if (sFormat!='m-d-y') sFormat = 'd-m-y';
var idxDay = 0;
var idxMonth = 1;
if (sFormat=='m-d-y') {
idxDay = 1;
idxMonth = 0;
}
var sDate = this.toString().strip();
var bValid = true;
var arMonthlong = [0,31,28,31,30,31,30,31,31,30,31,30,31];
var regDate = /(\d{1,2}\s*-\s*\d{1,2}\s*-\s*\d{4,4})/;
var ar = regDate.exec(sDate);
if (ar) {
bValid = (sDate.length==ar[0].length);
if (!bValid) return false;
} else
return false;
sDate = sDate.replace(/\s+/g,''); //Removes all white spaces
var arDate = sDate.split('-');
var iYear = parseInt(arDate[2],10);
var iMonth = parseInt(arDate[idxMonth],10);
var iDay = parseInt(arDate[idxDay],10);
bValid = (iMonth > 0) && (iMonth <= 12);
if (bValid) {
bValid = (iDay > 0);
if (iMonth==2) {
if (iYear%4) bValid = bValid && (iDay <= 28);
else bValid = bValid && (iDay <= 29);
} else {
bValid = bValid && (iDay <= arMonthlong[iMonth]);
}
}
if (bValid) {
if (iDay < 10) iDay = '0' + iDay;
if (iMonth < 10) iMonth = '0' + iMonth;
iYear = '0000'.substring(0, 4 - (iYear+'').length) + iYear;
if (sFormat=='m-d-y') return (iMonth+'-'+iDay+'-'+iYear);
return (iDay+'-'+iMonth+'-'+iYear);
}
return bValid;
};
//Does the string evaluate to a date-time value? (format: 'dd-mm-yyyy hh:nn:ss'
//or 'mm-dd-yyyy hh:nn:ss')
//If true then returns a normalized date-time value
String.prototype.isDateTime = function(sFormat) {
var sDt = this.toString().strip();
var re = /((\d{1,2}\s*-\s*\d{1,2}\s*-\s*\d\d\d\d)\s+(\d{1,2}\s*:\s*\d{1,2}:\s*\d{1,2}))/;
var ar = sDt.match(re);
var bValid = true;
if (ar) {
bValid = (sDt.length==ar[0].length);
if (!bValid) return bValid;
} else
return false;
//Checks the date part
var sDate = ar[2].isDate(sFormat);
if (!sDate) return false;
//Checks the time part
ar[3] = ar[3].replace(/\s+/g,''); //Removes all white spaces
var arTime = ar[3].split(':');
var iHour = parseInt(arTime[0],10);
var iMinute = parseInt(arTime[1],10);
var iSecond = parseInt(arTime[2],10);
bValid = (iHour >= 0) && (iHour < 24);
if (bValid) bValid = (iMinute >= 0) && (iMinute < 60);
if (bValid) bValid = (iSecond >= 0) && (iSecond < 60);
if (bValid) {
if (iHour < 10) iHour = '0' + iHour;
if (iMinute < 10) iMinute = '0' + iMinute;
if (iSecond < 10) iSecond = '0' + iSecond;
return (sDate+' '+iHour+':'+iMinute+':'+iSecond);
}
return bValid;
};
//Gives denomination to the string if it evaluates to a numeric value
String.prototype.giveDenomination = function(denominator,fracDigits) {
var pointDec;
if (denominator!='.') { //Ignores denominator except ',' and '.'
denominator = ',';
var pointDec = '.';
} else pointDec = ',';
var sNumber = this.toString();
if (!sNumber.isNumeric()) return sNumber;
sNumber = sNumber.replace(/\s/g,'');
var sSign = '';
if (sNumber.charAt(0)=='-') {
sSign = '-';
sNumber = sNumber.substring(1,sNumber.length);
if (parseFloat(sNumber)==0.0) sSign = '';
}
var sDec = '';
var i = sNumber.indexOf('.');
if (i!=-1) {
sDec = sNumber.substring(i+1,sNumber.length); sDec = sDec.replace(/0+$/,'');
sNumber = sNumber.substring(0,i);
if (!sNumber) sNumber = '0';
}
if (fracDigits) {
fracDigits = parseInt(fracDigits);
fracDigits = (isNaN(fracDigits)? 0 : fracDigits);
if (!sDec) sDec = '0';
sDec = Math.round( parseFloat('0.'+sDec)* Math.pow(10,fracDigits) ) + '';
while (sDec.length < fracDigits) sDec = '0' + sDec;
if (sDec.length > fracDigits) {
i = parseInt(sDec.substring(0,1));
sDec = sDec.substring(1,sDec.length);
sNumber = (parseInt(sNumber)+i) + '';
}
}
var arNum = new Array();
while (sNumber.length > 3) {
arNum[arNum.length] = sNumber.substring(sNumber.length-3,sNumber.length);
sNumber = sNumber.substring(0,sNumber.length-3);
}
if (sNumber.length > 0) arNum[arNum.length] = sNumber;
arNum.reverse();
if (sDec) sDec = pointDec + sDec;
return (sSign+arNum.join(denominator)+sDec);
};
//Gives denomination to the string if it evaluates to a numeric value
String.prototype.removeDenomination = function(denominator,alterPointDecToPeriod,ignoreNumeric) {
var pointDec = ',';
if (denominator!='.') { //Ignores denominator except ',' and '.'
denominator = ',';
pointDec = '.';
}
var sNumber = this.toString();
sNumber = sNumber.replace(new RegExp('\\'+denominator,'g'),'');
var sNumber1 = sNumber.replace(new RegExp('\\'+pointDec,'g'),'.');
if (sNumber1.isNumeric() || ignoreNumeric) {
if (alterPointDecToPeriod) return sNumber1;
else return sNumber;
}
return this.toString();
};
//To search if the 'elm' is inside the array;
//The 'elm' is not an object
Array.prototype.isThere = function(elm) {
var s = this.join('|~&*&~|');
return (s.indexOf(elm+'')!=-1);
};
//Returns the date value with format 'dd-mm-yyyy'
Date.prototype.ddmmyyyy = function() {
day = this.getDate();
month = this.getMonth()+1;
year = this.getFullYear();
if (day<10) day='0'+day;
if (month<10) month='0'+month;
return (day+'-'+month+'-'+year);
};
//Returns the date value with format 'mm-dd-yyyy'
Date.prototype.mmddyyyy = function() {
day = this.getDate();
month = this.getMonth()+1;
year = this.getFullYear();
if (day<10) day='0'+day;
if (month<10) month='0'+month;
return (month+'-'+day+'-'+year);
};
//Returns the date value with format 'yyyy-mm-dd'
Date.prototype.sqldate = function() {
day = this.getDate();
month = this.getMonth()+1;
year = this.getFullYear();
if (day<10) day='0'+day;
if (month<10) month='0'+month;
if (year<10) year='0'+year;
return (year+'-'+month+'-'+day);
};
//Returns the time-stamp with format according to parameter 'format'
//Possible values (incasesensitive) for parameter format:
// 'd-m-y' ==> 'dd-mm-yyyy hh:nn:ss'
// 'm-d-y' ==> 'mm-dd-yyyy hh:nn:ss'
// 'sql' ==> 'yyyy-mm-dd hh:nn:ss'
Date.prototype.timeStamp = function(format) {
format = (format+'').toLowerCase();
//Only 'd-m-y' or 'm-d-y' or 'sql' is accepted (It implies the paramater may
//be omitted ==> 'd-m-y' will be used)
if (format!='m-d-y' && format!='sql') format = 'd-m-y';
hour = this.getHours();
minute = this.getMinutes();
second = this.getSeconds();
if (hour<10) hour='0'+hour;
if (minute<10) minute='0'+minute;
if (second<10) second='0'+second;
if (format=='m-d-y') return (this.mmddyyyy()+' '+hour+':'+minute+':'+second);
if (format=='sql') return (this.sqldate()+' '+hour+':'+minute+':'+second);
return (this.ddmmyyyy()+' '+hour+':'+minute+':'+second);
};
//Changes the date value according to parameter 'ddmmyyyy'
//'ddmmyyyy' is the date value with format 'dd-mm-yyyy'
Date.prototype.setFrom_ddmmyyyy = function(ddmmyyyy) {
ddmmyyyy = ddmmyyyy+'';
ddmmyyyy = ddmmyyyy.isDate();
if (!ddmmyyyy) return;
var dates = ddmmyyyy.split('-');
this.setFullYear( parseInt(dates[2],10), parseInt(dates[1],10)-1, parseInt(dates[0],10) );
}
//Changes the date value according to parameter 'mmddyyyy'
//'mmddyyyy' is the date value with format 'mm-dd-yyyy'
Date.prototype.setFrom_mmddyyyy = function(mmddyyyy) {
mmddyyyy = mmddyyyy+'';
mmddyyyy = mmddyyyy.isDate('m-d-y');
if (!mmddyyyy) return;
var dates = mmddyyyy.split('-');
this.setFullYear( parseInt(dates[2],10), parseInt(dates[0],10)-1, parseInt(dates[1],10) );
}
//Changes the date value according to parameter 'sqldate'
//'sqldate' is the date value with format 'yyyy-mm-dd'
Date.prototype.setFrom_sqldate = function(sqldate) {
sqldate = sqldate+'';
var dates = sqldate.split('-'); //No Checking
this.setFullYear( parseInt(dates[0],10), parseInt(dates[1],10)-1, parseInt(dates[2],10) );
}
if (JsTableNavFamily) { /************ The browser fulfils the requirement ***************/
function JsTableRemoveAllText(oParent)
{
var sText = '';
var oChild, sNodeName;
var idx = 0;
while (idx < oParent.childNodes.length) {
oChild = oParent.childNodes[idx];
sNodeName = oChild.nodeName;
if (sNodeName!='INPUT') oParent.removeChild(oChild);
if (sNodeName=='#text') {
sText += oChild.nodeValue;
} else if (sNodeName=='BR') {
sText += '\n';
} else {
idx++;
continue;
}
}
return sText;
}
/********** All about column models to set the colums behavior in the JsTable *******/
var JsTableCellEditorSelect = null;
function JsTableSetCellEditorSelect()
{
if (!JsTableCellEditorSelect) return;
JsTableCellEditorSelect.select();
JsTableCellEditorSelect.readOnly = false;
JsTableCellEditorSelect = null;
}
var JsTableColumnIndex = 0;
function JsTableColumnClass(columnName,inputName,width,align)
{
this.columnName = columnName || String.fromCharCode(160);
this.inputName = inputName || ('col'+JsTableColumnIndex);
JsTableColumnIndex++;
align = (align+'').toLowerCase();
this.align = ( ('left|center|right'.indexOf(align)!=-1)? align : 'left');
this.width = ( isNaN(parseInt(width))? 20 : parseInt(width) );
this.getInputElm = function(oCell) {
var arElms = oCell.getElementsByTagName('INPUT');
for (var i=0; i<arElms.length; i++) {
if (arElms[i].getAttribute('name') == this.inputName) return arElms[i];
}
};
this.getCellEditor = function(oCell,oJsTable) {
return null;
};
this.isValid = function(val,oJsTable) {
return true;
};
this.fixedValue = function(val,oJsTable) {
if (typeof val == 'undefined') return '';
return val.toString();
};
this.getValue = function(oCell,oJsTable) {
return this.getInputElm(oCell).value;
};
this._getShownValue = function(val,oJsTable) {
return val;
};
this.getShownValue = function(oCell,oJsTable) {
return this._getShownValue(this.getInputElm(oCell).value,oJsTable);
};
this.getShownValueOnEdit = function(oCell,oJsTable) {
return this.getShownValue(oCell,oJsTable);
};
this._setShownValue = function(val,oCell,oJsTable) {
JsTableRemoveAllText(oCell);
var arText = (val+'').split('\n');
var oText, oBR;
for (var i=0; i<arText.length; i++) {
oText = document.createTextNode(arText[i]);
oCell.appendChild(oText);
if (i<arText.length-1) {
oBR = document.createElement('BR');
oCell.appendChild(oBR);
}
}
};
this.setValue = function(val,oCell,oJsTable,oCellEditor) {
val = this.fixedValue(val,oJsTable);
this.getInputElm(oCell).value = val;
if (oCellEditor) oCellEditor.value = this.getShownValue(oCell,oJsTable);
else this._setShownValue( this._getShownValue(val,oJsTable), oCell, oJsTable);
};
this._setCellEditorSelect = function(oCellEditor) {
JsTableCellEditorSelect = oCellEditor;
setTimeout('JsTableSetCellEditorSelect()',0);
};
this.setEditorOnEdit = function(oCellEditor,oCell,oJsTable) {
var val = this.getShownValueOnEdit(oCell,oJsTable);
oCellEditor.value = val;
oCellEditor.readOnly = false;
this._setCellEditorSelect(oCellEditor);
};
this.setEditorOnCommit = function(oCellEditor,oCell,oJsTable) {
var val = oCellEditor.value;
oCellEditor.readOnly = true;
oCellEditor.select(); //IE6, to hide text cursor
if (JsTableNavFamily=='IE6') oJsTable._onclickIE6 = [oJsTable.row, oJsTable.col];
oCellEditor.value = ""; //clear highlight selected text if any
if (!this.isValid(val,oJsTable)) {
if (oJsTable.tableModel.oldValIfInvalid) val = this.getShownValue(oCell,oJsTable);
}
this.setValue(val,oCell,oJsTable,oCellEditor);
};
this.setEditorOnArrive = function(oCellEditor,oCell,oJsTable) {
var sText = JsTableRemoveAllText(oCell);
//var oSbl = (oCell.nextSibling ? oCell.nextSibling : oCell.previousSibling);
if (JsTableNavFamily=='Opera7') {
oCellEditor.style.height = (oCell.offsetHeight-2) + 'px';
} else if (document.compatMode=='CSS1Compat') {
oCellEditor.style.width = (oCell.offsetWidth-3) + 'px';
oCellEditor.style.height = (oCell.offsetHeight-4) + 'px';
} else {
oCellEditor.style.width = oCell.offsetWidth + 'px';
oCellEditor.style.height = (oCell.offsetHeight-2) + 'px';
}
oCell.style.padding = '0px';
oCellEditor.value = sText;
oCellEditor.style.textAlign = this.align;
oCellEditor = oCell.appendChild(oCellEditor);
};
this.setEditorOnRearrive = function(oCellEditor,oCell,oJsTable) {
//Invoked when the currently active cell is the same as before
};
this.setEditorOnLeave = function(oCellEditor,oCell,oJsTable) {
oCell.removeChild(oCellEditor);
oCell.style.padding = '';
if (oCell.style.removeProperty) {
oCell.style.removeProperty('padding');
//oCell.style.removeProperty('height');
} else {
oCell.style.padding = '';
//oCell.style.height = '';
}
this._setShownValue(this.getShownValue(oCell,oJsTable),oCell,oJsTable);
};
this.containsEditor = function(oCell,oCellEditor) {
//It returns integer because some consideration (See method oJsTable.setFocus
//and JsTableColumnBoolean.containsEditor)
if (oCell.contains(oCellEditor)) return -1;
return 0;
};
this.addCell = function(oRow,oJsTable,val,primaryKey) {
val = this.fixedValue(val);
var oCell = oRow.insertCell(oRow.cells.length);
oCell.style.textAlign = this.align;
var oInput = document.createElement("INPUT");
oInput.type = 'hidden';
oInput.setAttribute('name',this.inputName);
oInput.setAttribute('id',this.inputName); //IE6
oInput.value = val;
oCell.appendChild(oInput);
this._setShownValue( this._getShownValue(val,oJsTable), oCell,oJsTable);
return oCell;
};
}
function JsTableColumnString(columnName,inputName,width,align)
{
this.base = JsTableColumnClass;
this.base(columnName,inputName,width,align);
this._addCell_ = this.addCell;
this.addCell = function(oRow,oJsTable,val,primaryKey) {
var oCell = this._addCell_(oRow,oJsTable,val,primaryKey);
oCell.onkeypress = JsTableOnStringKeyPress;
return oCell;
}
}
function JsTableColumnNumber(columnName,inputName,width,align,denomination,fracDigits)
{
this.base = JsTableColumnClass;
align = align || 'right';
this.base(columnName,inputName,width,align);
this.denomination = (denomination?true:false);
this.fracDigits = parseInt(fracDigits); if (isNaN(fracDigits)) fracDigits = 0;
this.isValid = function (val,oJsTable) {
val = (val+'').removeDenomination(oJsTable.tableModel.numberDenominator,true);
return val.isNumeric();
};
this.fixedValue = function (val,oJsTable) {
var denominator = oJsTable.tableModel.numberDenominator;
if (typeof val != 'number') val = (val+'').removeDenomination(denominator,true,true);
val = parseFloat(val+'');
if (isNaN(val)) return 0;
val = (val+'').giveDenomination(denominator,this.fracDigits);
val = parseFloat(val.removeDenomination(denominator,true));
return val;
};
this.getValue = function(oCell,oJsTable) {
return parseFloat(this.getInputElm(oCell).value);
};
this._getShownValue = function(val,oJsTable) {
val = val+'';
var denominator = oJsTable.tableModel.numberDenominator;
val = val.giveDenomination(denominator,this.fracDigits);
if (this.denomination) return val;
return val.replace(new RegExp('\\'+denominator,'g'),'');
};
this.getShownValueOnEdit = function(oCell,oJsTable) {
var val = this.getInputElm(oCell).value;
var denominator = oJsTable.tableModel.numberDenominator;
var pointDec = ',';
if (denominator==',') pointDec = '.';
return val.replace(/\./,pointDec);
};
this.addCell = function(oRow,oJsTable,val,primaryKey) {
val = this.fixedValue(val,oJsTable);
var denominator = oJsTable.tableModel.numberDenominator;
var shownVal = (val+'').giveDenomination(denominator,this.fracDigits);
if (!this.denomination) shownVal = shownVal.removeDenomination(denominator,false,true);
var oCell = oRow.insertCell(oRow.cells.length);
oCell.style.textAlign = this.align;
var oInput = document.createElement("INPUT");
oInput.type = 'hidden';
oInput.setAttribute('name',this.inputName);
oInput.setAttribute('id',this.inputName); //IE6
oInput.value = val;
oCell.appendChild(oInput);
oCell.appendChild(document.createTextNode(shownVal));
oCell.style.whiteSpace = 'nowrap';
oCell.onkeypress = JsTableOnNumberKeyPress;
return oCell;
};
}
function JsTableColumnBoolean(columnName,inputName,width,align)
{
this.base = JsTableColumnClass;
align = align || 'center';
this.base(columnName,inputName,width,align);
this.setPrimaryKey = function(oCell,primaryKey) {
this.getInputElm(oCell).value = primaryKey+'';
};
this.getCellEditor = function(oCell,oJsTable) {
return this.getInputElm(oCell);
};
this.isValid = function (val) {
return true; //Always true as usual evaluation in JavaScript, all values of all types
//can be evaluated as boolean
};
this.fixedValue = function (val) {
if (val) return true;
return false;
};
this.getValue = function(oCell,oJsTable) {
return this.getInputElm(oCell).checked;
};
this.getShownValue = function(oCell,oJsTable) {
return this.getInputElm(oCell).checked;
};
this._setShownValue = function(val,oCell,oJsTable) {
};
this.setValue = function(val,oCell,oJsTable,oCellEditor) {
this.getInputElm(oCell).checked = this.fixedValue(val);
};
this.setEditorOnEdit = function(oCellEditor,oCell,oJsTable) {
oCellEditor.checked = !oCellEditor.checked;
oCell._checked = oCellEditor.checked;
oJsTable.onEdit = false;
};
this.setEditorOnCommit = function(oCellEditor,oCell,oJsTable) {
};
this.setEditorOnArrive = function(oCellEditor,oCell,oJsTable) {
oCell.className = 'cell-focus';
if (oCell._onclick) //oCellEditor.checked = !oCellEditor.checked;
oJsTable.setOnEdit(); //Also checks if the cell is editable, at once
};
this.setEditorOnRearrive = function(oCellEditor,oCell,oJsTable) {
this.setEditorOnArrive(oCellEditor,oCell,oJsTable);
};
this.setEditorOnLeave = function(oCellEditor,oCell,oJsTable) {
oCell.className = '';
};
this.containsEditor = function(oCell,oCellEditor) {
return 1;
};
this.addCell = function(oRow,oJsTable,bChecked,val) {
var oCell = oRow.insertCell(oRow.cells.length);
oCell.style.textAlign = this.align;
var oEditor = document.createElement("INPUT");
oEditor.type = 'checkbox';
oEditor.className = 'checkbox';
oEditor.setAttribute('name',this.inputName);
oEditor.setAttribute('id',this.inputName); //IE6
oEditor.value = val+'';
oEditor.checked = this.fixedValue(bChecked);
oEditor.defaultChecked = oEditor.checked;
oCell.appendChild(oEditor);
oEditor.onblur = JsTableOnBlur;
oEditor.onclick = JsTableOnCheckboxClick;
oEditor.onkeydown = JsTableOnCheckboxKeyDown;
oEditor.onkeypress = JsTableOnCheckboxKeyPress;
return oCell;
};
}
//This constructor is used to create object for option values in
//column whose type of JsTableColumnOptions
function JsTableOptionValues(arValuesSent,arValuesShown)
{
if (!arValuesSent) arValuesSent = [];
if (!arValuesShown) arValuesShown = [];
for (var i=0; i<arValuesSent.length; i++) {
if (typeof arValuesShown[i] == 'undefined') arValuesShown[i] = arValuesSent[i];
this[arValuesSent[i]] = arValuesShown[i];
}
}
function JsTableColumnOptions(columnName,inputName,width,align,options)
{
this.base = JsTableColumnClass;
this.base(columnName,inputName,width,align);
this.options = options || (new JsTableOptionValues());
var o = document.createElement('SELECT');
o.style.overflow = 'hidden';
o.style.margin = '0px';
o.style.padding = '0px';
o.style.borderStyle = 'none';
o.style.width = '100%';
for (var optVal in this.options) {
opt = document.createElement('OPTION');
opt.style.margin = '0px';
opt.appendChild(document.createTextNode(this.options[optVal]));
opt.setAttribute('value',optVal);
o.appendChild(opt);
//o.add(opt,null);
}
this.cellEditor = o;
this.cellEditor._selectedIndex = -1;
this.cellEditor.onblur = JsTableOnBlur;
//this.cellEditor.onkeydown = JsTableOnKeyDown;
//this.cellEditor.onkeypress = JsTableOnKeyPress;
this.cellEditor.onkeyup = function (e) {
if (this._selectedIndex >= 0) {
this.selectedIndex = this._selectedIndex;
this._selectedIndex1 = this._selectedIndex;
this._selectedIndex = -1;
}
}
/*if (JsTableNavFamily=='Opera7') { //For Linux
this.cellEditor.onkeypress = function (e) {
if (this._selectedIndex < 0 || (typeof this._selectedIndex=='undefined')) {
this._repeatedKeypress = true;;
}
}
this.cellEditor.onchange = function (e) {
if (this._repeatedKeypress) {
this.selectedIndex = this._selectedIndex1;
this._repeatedKeypress = false;
}
}
}*/
this.getCellEditor = function(oCell,oJsTable) {
if ( oJsTable.tableModel.isCellEditable(oCell.parentNode.rowIndex,oCell.cellIndex) )
return this.cellEditor;
return oJsTable.cellEditor;
};
this.isValid = function (val) {
return (typeof this.options[val] != 'undefined');
};
this.fixedValue = function (val) {
if (typeof val != 'undefined')
if (typeof this.options[val] != 'undefined') return val;
for (var optVal in this.options) return optVal;//the first option
};
this._getShownValue = function(val,oJsTable) {
return this.options[val];
};
this.setEditorOnEdit = function(oCellEditor,oCell,oJsTable) {
};
this.setEditorOnCommit = function(oCellEditor,oCell,oJsTable) {
};
this.setEditorOnArrive = function(oCellEditor,oCell,oJsTable) {
oCell.style.padding = '0px';
JsTableRemoveAllText(oCell);
var val = this.getValue(oCell,oJsTable);
if (oCellEditor.options) { //Combo box
for (var i=0; i<oCellEditor.length; i++)
if (oCellEditor.options[i].value==val) break;
oCellEditor = oCell.appendChild(oCellEditor);
oCellEditor.selectedIndex = i;
if (oCell._keydown) oCellEditor._selectedIndex = i;
} else { //Text box
if (JsTableNavFamily=='Opera7') {
oCellEditor.style.height = (oCell.offsetHeight-2) + 'px';
} else if (document.compatMode=='CSS1Compat') {
oCellEditor.style.width = (oCell.offsetWidth-3) + 'px';
oCellEditor.style.height = (oCell.offsetHeight-4) + 'px';
} else {
oCellEditor.style.width = oCell.offsetWidth + 'px';
oCellEditor.style.height = (oCell.offsetHeight-2) + 'px';
}
oCellEditor.value = this._getShownValue(val,oJsTable);
oCellEditor.style.textAlign = 'left';
oCell.appendChild(oCellEditor);
}
};
this.setEditorOnRearrive = function(oCellEditor,oCell,oJsTable) {
if (oCell._keydown) oCellEditor._selectedIndex = oCellEditor.selectedIndex;
};
this.setEditorOnLeave = function(oCellEditor,oCell,oJsTable) {
if (oCell.style.removeProperty) {
oCell.style.removeProperty('padding');
} else {
oCell.style.padding = '';
}
if (oCellEditor._selectedIndex >= 0) {
oCellEditor.selectedIndex = oCellEditor._selectedIndex;
oCellEditor._selectedIndex = -1;
}
var val = oCellEditor.value;
if (!oCellEditor.options) val = this.getInputElm(oCell).value; //Text box
oCell.removeChild(oCellEditor);
this.getInputElm(oCell).value = val;
this._setShownValue( this._getShownValue(val,oJsTable), oCell,oJsTable);
};
}
function JsTableColumnDate(columnName,inputName,width,align,saveAsSQLformat)
{
this.base = JsTableColumnClass;
align = align || 'center';
this.base(columnName,inputName,width,align);
this.saveAsSQLformat = (saveAsSQLformat?true:false);
this.isValid = function (val,oJsTable) {
val = val+'';
return val.isDate(oJsTable.tableModel.dateFormat);
};
this.fixedValue = function (val,oJsTable) {
var valid = this.isValid(val,oJsTable);
if (valid) return valid;
return '00-00-0000';
};
this.getValue = function(oCell,oJsTable) {
return this.getShownValue(oCell,oJsTable);
};
this._getShownDate = function(val,dateFormat) {
if (this.saveAsSQLformat) {
if (val=='0000-00-00') return '00-00-0000';
var dt = new Date();
dt.setFrom_sqldate(val);
if (dateFormat=='m-d-y') return dt.mmddyyyy();
return dt.ddmmyyyy();
}
return val;
};
this.getShownValue = function(oCell,oJsTable) {
var val = this.getInputElm(oCell).value;
return this._getShownDate(val,oJsTable.tableModel.dateFormat);
};
this._getSavedDate = function(val,dateFormat) {
if (this.saveAsSQLformat) {
dt = new Date();
if (val=='00-00-0000') return '0000-00-00';
else if (dateFormat=='m-d-y') dt.setFrom_mmddyyyy(val);
else dt.setFrom_ddmmyyyy(val);
return dt.sqldate();
}
return val;
};
this.setValue = function(val,oCell,oJsTable,oCellEditor) {
val = this.fixedValue(val,oJsTable);
this.getInputElm(oCell).value = this._getSavedDate(val, oJsTable.tableModel.dateFormat);
if (oCellEditor) oCellEditor.value = this.getShownValue(oCell,oJsTable);
else this._setShownValue(val,oCell,oJsTable);
};
this.addCell = function(oRow,oJsTable,val) {
val = this.fixedValue(val,oJsTable);
var savedval = this._getSavedDate(val,oJsTable.tableModel.dateFormat);;
var oCell = oRow.insertCell(oRow.cells.length);
oCell.style.textAlign = this.align;
var oInput = document.createElement("INPUT");
oInput.type = 'hidden';
oInput.setAttribute('name',this.inputName);
oInput.setAttribute('id',this.inputName); //IE6
oInput.value = savedval;
oCell.appendChild(oInput);
oCell.appendChild(document.createTextNode(val));
oCell.style.whiteSpace = 'nowrap';
oCell.onkeypress = JsTableOnNumberKeyPress;
oCell.dateCol = true;
return oCell;
};
}
function JsTableColumnDateTime(columnName,inputName,width,align,saveAsSQLformat)
{
this.base = JsTableColumnDate;
this.base(columnName,inputName,width,align,saveAsSQLformat);
this.isValid = function (val,oJsTable) {
val = val+'';
return val.isDateTime(oJsTable.tableModel.dateFormat);
}
this.fixedValue = function (val,oJsTable) {
var valid = this.isValid(val,oJsTable);
if (valid) return valid;
return '00-00-0000 00:00:00';
}
this.getShownValue = function(oCell,oJsTable) {
var val = this.getInputElm(oCell).value;
var dt = val.split(/\s+/);
var showndate = this._getShownDate(dt[0],oJsTable.tableModel.dateFormat);
return (showndate+' '+dt[1]);
};
this.setValue = function(val,oCell,oJsTable,oCellEditor) {
val = this.fixedValue(val,oJsTable);
var dt = val.split(/\s+/);
var saveddate = this._getSavedDate(dt[0],oJsTable.tableModel.dateFormat);
this.getInputElm(oCell).value = saveddate + ' ' + dt[1];
if (oCellEditor) oCellEditor.value = this.getShownValue(oCell,oJsTable);
else this._setShownValue(val,oCell,oJsTable);
};
this.addCell = function(oRow,oJsTable,val) {
val = this.fixedValue(val,oJsTable);
var dt = val.split(/\s+/);
var saveddate = this._getSavedDate(dt[0],oJsTable.tableModel.dateFormat);;
var oCell = oRow.insertCell(oRow.cells.length);
oCell.style.textAlign = this.align;
var oInput = document.createElement("INPUT");
oInput.type = 'hidden';
oInput.setAttribute('name',this.inputName);
oInput.setAttribute('id',this.inputName); //IE6
oInput.value = saveddate + ' ' + dt[1];
oCell.appendChild(oInput);
oCell.appendChild(document.createTextNode(val));
oCell.style.whiteSpace = 'nowrap';
oCell.onkeypress = JsTableOnNumberKeyPress;
oCell.datetimeCol = true;
return oCell;
};
}
function JsTableColumnLink(columnName,inputName,width,align,identifier,href)
{
this.base = JsTableColumnClass;
align = align || 'center';
this.base(columnName,inputName,width,align);
this.identifier = identifier;
this.href = href+'';
this.setPrimaryKey = function(oCell,primaryKey) {
var oLink = this.getInputElm(oCell);
var sHref = oLink.getAttribute("orgHref");
sHref = sHref.replace(/__ROW__/g, oCell.parentNode.rowIndex);
oLink.href = sHref.replace(/__PRIMARY_KEY__/g, primaryKey);
oLink.setAttribute('primaryKey',primaryKey);
};
this.setRowIndex = function(oCell) {
var oLink = this.getInputElm(oCell);
var sHref = oLink.getAttribute("orgHref");
sHref = sHref.replace(/__ROW__/g, oCell.parentNode.rowIndex);
oLink.href = sHref.replace(/__PRIMARY_KEY__/g, oLink.getAttribute('primaryKey'));
};
this.getInputElm = function(oCell) {
var arElms = oCell.getElementsByTagName('A');
for (var i=0; i<arElms.length; i++) {
if (arElms[i].getAttribute('name') == this.inputName) return arElms[i];
}
};
this.getCellEditor = function(oCell,oJsTable) {
return this.getInputElm(oCell);
};
this.getValue = function(oCell,oJsTable) {
return this.getInputElm(oCell).href;
};
this.getShownValue = function(oCell,oJsTable) {
return this.getInputElm(oCell).firstChild;
};
this.getShownValueOnEdit = function(oCell,oJsTable) {
};
this._setShownValue = function(val,oCell,oJsTable) {
if (typeof val != 'object') val = document.createTextNode(val+'');
var oLink = this.getInputElm(oCell);
if (oLink.firstChild) oLink.replaceChild(val,oLink.firstChild);
else oLink.appendChild(val);
};
this.setIdentifier = function(identifier,oCell,oJsTable) {
this._setShownValue(identifier,oCell,oJsTable);
this.identifier = identifier;
};
this.setValue = function(sHref,oCell,oJsTable,oCellEditor) {
var oLink = this.getInputElm(oCell);
oLink.href = sHref.replace(/__PRIMARY_KEY__/g,primaryKey);
oLink.setAttribute('orgHref',sHref);
};
this.setEditorOnEdit = function(oCellEditor,oCell,oJsTable) {
oJsTable.onEdit = false;
};
this.setEditorOnCommit = function(oCellEditor,oCell,oJsTable) {
};
this.setEditorOnArrive = function(oCellEditor,oCell,oJsTable) {
oCell.className = 'cell-focus';
};
this.setEditorOnRearrive = function(oCellEditor,oCell,oJsTable) {
this.setEditorOnArrive(oCellEditor,oCell,oJsTable);
};
this.setEditorOnLeave = function(oCellEditor,oCell,oJsTable) {
oCell.className = '';
};
this.containsEditor = function(oCell,oCellEditor) {
return 1;
};
this.addCell = function(oRow,oJsTable,sHref,primaryKey,iRow) {
var oCell = oRow.insertCell(oRow.cells.length);
oCell.style.textAlign = this.align;
var oLink = document.createElement("A");
oLink.setAttribute('name',this.inputName);
if (!sHref) sHref = this.href;
sHref = sHref + '';
oLink.setAttribute('orgHref',sHref);
oLink.setAttribute('primaryKey',primaryKey);
sHref = sHref.replace(/__PRIMARY_KEY__/g,primaryKey);
if (typeof oRow.rowIndex != 'undefined') iRow = oRow.rowIndex; //undefined for Opera7
oLink.href = sHref.replace(/__ROW__/g,iRow);
oCell.appendChild(oLink);
var identifier = this.identifier;
if (typeof this.identifier == 'object') {
if (this.identifier.cloneNode) identifier = this.identifier.cloneNode(true);
else identifier = this.identifier.toString();
}
this._setShownValue(identifier,oCell,oJsTable);
if (JsTableNavFamily=='Opera7') {
oLink.onclick = JsTableOnLinkClickOpera7;
oLink.onmouseup = JsTableOnLinkMouseUpOpera7;
//oLink.onkeypress = JsTableOnLinkKeyPress;
oLink.onkeydown = JsTableOnLinkKeyDownOpera7;
}
oLink.onblur = JsTableOnBlur;
return oCell;
};
}
/***** Sets needed CSS *********************************/
function JsTableSetCSS()
{
var noJsTableStyle = true;
var o, hasMethodInsert = true;
if (document.styleSheets) {
if (!document.styleSheets.length) {
o = document.getElementsByTagName('HEAD');
if (o) {
o = o[0];
o.appendChild(document.createElement('STYLE'));
}
}
var cssRules = 'cssRules';
if (JsTableNavFamily=='IE6') cssRules = 'rules';
var selectorText;
for (i=0; i<document.styleSheets.length; i++) {
o = document.styleSheets[i][cssRules];
for (j=0; j<o.length; j++) {
selectorText = o[j].selectorText.toLowerCase();
if (selectorText=='.jstable' || selectorText=='table.jstable') {
noJsTableStyle = false;
break;
}
}
if (!noJsTableStyle) break;
}
if (!document.styleSheets.length) hasMethodInsert = false; //We cannot insert new rules via DOM method
} else {//if (document.styleSheets)
hasMethodInsert = false;
}
var addRule = function(selector,sRule,o,iPhase) {
}
if (noJsTableStyle && hasMethodInsert) {
o = document.styleSheets[0];
if (JsTableNavFamily=='IE6') {
addRule = function(selector,sRule,oStyle,iPhase) {
oStyle.addRule(selector,sRule);
}
} else {
addRule = function(selector,sRule,oStyle,iPhase) {
oStyle.insertRule(selector + '{' + sRule + '}', o.cssRules.length);
}
}
} else if (noJsTableStyle && !hasMethodInsert) {
o = null;
addRule = function(selector,sRule,oStyle,iPhase) {
if (iPhase==1) document.write('<'+'style>\n');
document.write(selector + '{' + sRule + '}\n');
if (iPhase==2) document.write('<'+'/style>\n');
}
}
var sCellStyle = 'font-family:arial,sans-serif; font-size:12px; ';
var sCellEditorStyle = 'background-color:#cccccc; margin:0px; padding:0px; ' + sCellStyle;
sCellStyle = 'background-color:white; height:18px; ' + sCellStyle;
addRule('.JsTable', 'background-color:black', o, 1);
addRule('.JsTable TH', sCellStyle, o, 0);
addRule('.JsTable TD', sCellStyle, o, 0);
addRule('.JsTable TEXTAREA', sCellEditorStyle, o, 0);
addRule('.JsTable INPUT', sCellEditorStyle, o, 0);
addRule('.JsTable INPUT.checkbox', 'background-color:transparent', o, 0);
addRule('.JsTable .cell-focus', 'background-color:#cccccc', o, 0);
addRule('.JsTable SELECT', 'height:16px; ' + sCellEditorStyle, o, 2);
}
JsTableSetCSS();
var JsTableGetKeyCode = function(e) {};
if (JsTableNavFamily=='Gecko') {
//Makes the event object in Gecko like the one in IE
function JsTableGeckoEventButton() {
switch (this.which) {
case 1: return 1;
case 2: return 4;
case 3: return 2;
}
}
function JsTableGeckoEventSrcElement() {
return this.target;
}
function JsTableGeckoEventFromElement() {
return this.relatedTarget;
}
function JsTableGeckoEventToElement() {
return this.relatedTarget;
}
function JsTableGeckoEventReturnValue(bVal) {
if (!bVal) this.preventDefault();
}
function JsTableGeckoEventCancelBubble(bVal) {
if (bVal) this.stopPropagation();
}
function JsTableGeckoEventOffsetX() {
return this.layerX;
}
function JsTableGeckoEventOffsetY() {
return this.layerY;
}
//Other than Gecko, which doesn't support getter and setter statement, will not fail here
eval("Event.prototype.button getter= JsTableGeckoEventButton");
eval("Event.prototype.srcElement getter= JsTableGeckoEventSrcElement");
eval("Event.prototype.fromElement getter= JsTableGeckoEventFromElement");
eval("Event.prototype.toElement getter= JsTableGeckoEventToElement");
eval("Event.prototype.returnValue setter= JsTableGeckoEventReturnValue");
eval("Event.prototype.cancelBubble setter= JsTableGeckoEventCancelBubble");
eval("Event.prototype.offsetX getter= JsTableGeckoEventOffsetX");
eval("Event.prototype.offsetY getter= JsTableGeckoEventOffsetY");
//Emulates method contains in IE
Element.prototype.contains = function(oNode) {
while (oNode) {
if (this == oNode) return true;
oNode = oNode.parentNode;
}
return false;
}
JsTableGetKeyCode = function(e) {
if (e.type=='keypress') {
if (e.charCode) return e.charCode;
else switch (e.keyCode) {
case 8: //Backspace
case 9: //Tab
case 13: //Enter
return e.keyCode;
default:
return e.keyCode*1000; //Multiply by 1000 to avoid overlapping with printable keyCode
}
}
return e.keyCode;
};
} else if (JsTableNavFamily=='Opera7') {
//Opera7 has different value for middle button from IE has, but we forgive it
/*Event.prototype.button getter= function() {
switch (this.button) {
case 1: return 1;
case 2: return 2;
case 3: return 4;
}
}*/
JsTableKeyCodeOnKeyDown = 0;
JsTableGetKeyCode = function(e) {
//Opera 7.1 has different keyCode for extended keys (thousands value)
if (e.type=='keypress') {
switch (e.keyCode) {
case 113: if (JsTableKeyCodeOnKeyDown==81) return 81; // q
case 57346:
return 113000; //F2
case 37:
case 57387:
return 37000; //Left Arrow
case 38:
case 57385:
return 38000; //Up Arrow
case 39: //Right arrow or single quote ( ' ) on Opera 7.2+
case 57388:
if (JsTableKeyCodeOnKeyDown==222) return 39; //single quote ( ' )
return 39000; //Right Arrow
case 40:
case 57386: return 40000; //Down Arrow
case 57395: return 46000; //Delete
case 57381: return 36000; //Home
case 57382: return 35000; //End
default : return e.keyCode;
}
} else {
JsTableKeyCodeOnKeyDown = e.keyCode;
switch (e.keyCode) {
case 57346: return 113; //F2
case 57387: return 37; //Left Arrow
case 57385: return 38; //Up Arrow
case 57388: return 39; //Right Arrow
case 57386: return 40; //Down Arrow
case 57395: return 46; //Delete
case 57381: return 36; //Home
case 57382: return 35; //End
default : return e.keyCode;
}
}
};
} else { //IE 6
JsTableGetKeyCode = function(e) {
return e.keyCode;
};
}
/************** Event Handler ********************/
function JsTableGetObjectsOnEvent(sTagName,e)
{
if (!e) e = window.event;
var oTarget = e.srcElement;
var objs = {target: oTarget};
while (sTagName.indexOf('|'+oTarget.nodeName+'|')==-1) {
if (oTarget.nodeName=='TABLE') return null;
if (oTarget.nodeName=='HTML') return null;
oTarget = oTarget.parentNode;
if (!oTarget) return null;
}
if (oTarget.nodeName=='TD' || oTarget.nodeName=='TH') {
objs.cellEditor = null;
objs.cell = oTarget;
} else {
objs.cellEditor = oTarget;
objs.cell = oTarget.parentNode;
}
if (!objs.cell) return null;
objs.row = objs.cell.parentNode;
if (!objs.row) return null;
objs.tbl = (objs.row.parentNode ? objs.row.parentNode.parentNode : null);
if (!objs.tbl) return null;
objs.jsTable = window['_'+objs.tbl.id];
objs.event = e;
objs.keyCode = JsTableGetKeyCode(e);
return objs;
}
var JsTableColToResize = -1;
var JsTableOffsetXstartToResize = -1;
var JsTableObjectTblOnResize = null;
function JsTableHeaderOnMouseMove(e)
{
if (!e) e = window.event;
var oTarget = e.srcElement;
var oTbl = oTarget;
while (oTbl.nodeName!='TABLE') {
oTbl = oTbl.parentNode;
if (!oTbl) return;
}
var oRow = oTbl.rows[0];
var bOnEdge = false;
if (oTarget.tagName=='TH') {
if (e.offsetX==0 && oTarget.cellIndex!=0) {
JsTableColToResize = oTarget.cellIndex - 1; //Resize the left side column
bOnEdge = true;
}
if (e.offsetX==oTarget.offsetWidth-1) {
JsTableColToResize = oTarget.cellIndex; //Resize the left side column
bOnEdge = true;
}
}
if (bOnEdge) {
oTbl.style.cursor = 'w-resize';
} else {
oTbl.style.cursor = 'default';
JsTableColToResize = -1;
}
}
function JsTableHeaderOnMouseOver(e)
{
if (!e) e = window.event;
var oTbl = e.srcElement;
if (oTbl.tagName!='TABLE') return;
if (!e.fromElement) return;
if (e.fromElement.tagName!='TH') return;
var oRow = oTbl.rows[0];
var bOnEdge = (e.offsetY < oRow.offsetHeight && e.offsetX > 1); //On the edge precisely
if (bOnEdge) {
var iLeft = oRow.cells[0].offsetWidth + 1 + oRow.cells[1].offsetWidth;
var iCol = 1;
while (e.offsetX > iLeft) {
iCol++;
if (iCol==oRow.cells.length) break;
iLeft += oRow.cells[iCol].offsetWidth + 1;
}
JsTableColToResize = iCol - 1; //Resize the left side column
oTbl.style.cursor = 'w-resize';
} else {
oTbl.style.cursor = 'default';
JsTableColToResize = -1;
}
}
function JsTableHeaderOnMouseOut(e)
{
if (!e) e = window.event;
var oTarget = e.toElement;
var oTbl = oTarget;
while (oTbl) {
if (oTbl.nodeName=='TABLE') break;
oTbl = oTbl.parentNode;
}
if (!oTbl) {
JsTableColToResize = -1;
if (this.style) this.style.cursor = 'default';
}
}
function JsTableStopDragOnResize(oJsTable,bHasFocus)
{
oTbl = oJsTable.table;
oTbl.style.cursor = 'default';
oTbl.onmousemove = JsTableHeaderOnMouseMove;
oTbl.onmouseover = JsTableHeaderOnMouseOver;
oTbl.onmouseout = JsTableHeaderOnMouseOut;
oTbl.onmouseup = null;
if (document.releaseCapture) document.releaseCapture();
else {
document.removeEventListener('mouseup',JsTableOnResizeOnMouseUp,true);
document.removeEventListener('mouseout',JsTableOnResizeOnMouseOut,true);
}
JsTableColToResize = -1;
JsTableOffsetXstartToResize = -1;
JsTableObjectTblOnResize = null;
if (bHasFocus) oJsTable.setFocus(true);
}
function JsTableOnResizeOnMouseUp(e)
{
if (!JsTableObjectTblOnResize) return;
if (!e) e = window.event;
var dx = e.screenX - JsTableOffsetXstartToResize;
var oJsTable = window['_'+JsTableObjectTblOnResize.id];
var bHasFocus = oJsTable.hasFocus;
if (bHasFocus) oJsTable.setFocus(false);
var oCol = oJsTable.tableModel.columns[JsTableColToResize];
oCol.width += dx;
if (oCol.width < 20) oCol.width = 20;
var oTbl = oJsTable.table;
for (var i=0; i<oTbl.rows.length; i++) {
oTbl.rows[i].cells[JsTableColToResize].style.width = oCol.width + 'px';
oTbl.rows[i].cells[JsTableColToResize].width = oCol.width;
}
JsTableStopDragOnResize(oJsTable,bHasFocus);
}
function JsTableOnResizeOnMouseOut(e)
{
if (!JsTableObjectTblOnResize) return;
if (!e) e = window.event;
if (!e.toElement) {
var oJsTable = window['_'+JsTableObjectTblOnResize.id];
var bHasFocus = oJsTable.hasFocus;
JsTableStopDragOnResize(oJsTable,bHasFocus);
}
}
function JsTableOnMouseDown(e)
{
if (JsTableColToResize >= 0) {
if (!e) e = window.event;
JsTableOffsetXstartToResize = e.screenX;
JsTableObjectTblOnResize = this;
this.onmousemove = null;
this.onmouseover = null;
this.onmouseout = null;
if (JsTableNavFamily=='IE6') {
this.setCapture();
this.onmouseup = JsTableOnResizeOnMouseUp;
this.onmouseout = JsTableOnResizeOnMouseOut;
} else {
document.addEventListener('mouseup',JsTableOnResizeOnMouseUp,true);
document.addEventListener('mouseout',JsTableOnResizeOnMouseOut,true);
}
}
var o = JsTableGetObjectsOnEvent('|TD|TH|',e);
if (!o) return;
var iRow = o.row.rowIndex;
var iCol = o.cell.cellIndex;
if (iRow < 1) {
if (o.tbl.rows.length <= 1) return;
iRow = 1;
}
if ('|TEXTAREA|INPUT|SELECT|A|'.indexOf('|'+o.target.nodeName+'|')!=-1) o.cellEditor = o.target;
o.cell._onclick = true;
if (JsTableNavFamily=='IE6' && o.jsTable.hasFocus && o.jsTable.row==iRow && o.jsTable.col==iCol) {
if (o.target!=o.cellEditor) o.jsTable._onclickIE6 = [-1,-1];
else if (o.target.nodeName=='TEXTAREA' ||
(o.target.nodeName=='INPUT' && o.target.type=='text')) o.jsTable._onclickIE6 = [iRow,iCol];
}
o.jsTable.setActiveCell(iRow,iCol);
if (o.cellEditor!=o.target) {
o.event.returnValue = false;
return false;
}
}
function JsTableOnDblClick(e)
{
var o = JsTableGetObjectsOnEvent('|TEXTAREA|INPUT|',e);
if (!o) return;
o.jsTable.setOnEdit();
}
function JsTableOnBlur(e)
{
var o = JsTableGetObjectsOnEvent('|TEXTAREA|INPUT|SELECT|A|',e);
if (!o) return;
if (o.jsTable._onclickIE6)
o.jsTable._onclickIE6 = (o.jsTable._onclickIE6[0]!=o.row.rowIndex
|| o.jsTable._onclickIE6[1]!=o.cell.cellIndex);
if (o.jsTable._onmove) o.jsTable._onmove = false;
else if (o.jsTable._onclickIE6) //IE 6
//When JsTable has focus and then the active cell is clicked but not on the CellEditor,
//such as checkbox or link, the blur event will occur but we want the JsTable still has focus
o.cellEditor.focus();
else if (o.jsTable.row==o.row.rowIndex && o.jsTable.col==o.cell.cellIndex)//used especially for Opera 7
//must be the active cell which experiences the blur event. The event can happen on the previous
//active cell whose different cell editor from the one owned the current active cell.
//o.jsTable._onmove is useful when the cell editor remains the same
{ o.jsTable._onblur=true; o.jsTable.setFocus(false); }
o.jsTable._onclickIE6 = false;
}
function JsTableOnKeyPress(e)
{
var o = JsTableGetObjectsOnEvent('|TEXTAREA|INPUT|SELECT|',e);
if (!o) return;
var bRetVal = true;
switch (o.keyCode) {
case 37000: //Left Arrow
case 38000: //Up Arrow
case 39000: //Right Arrow
case 40000: //Down Arrow
if (o.jsTable.onEdit) break;
case 13: //Enter
if (o.cellEditor.nodeName=='A') break;
case 113000: //F2
case 27: //Esc
o.event.returnValue = false;
o.event.cancelBubble = true;
bRetVal = false;
default:
}
if (typeof o.jsTable.onkeypress == 'function') o.jsTable.onkeypress(o.event);
if (!bRetVal) return false;
}
function JsTableGetNewCoordOnArrow(iArrowKey,iRow,iCol,oTbl,oRow)
{
switch (iArrowKey) {
case 37: //Left
case 37000:
return {row: iRow, col: ( (iCol>0)?(iCol-1):iCol )};
case 38: //Up
case 38000:
return {row: ( (iRow>1)?(iRow-1):iRow ), col: iCol};
case 39: //Right
case 39000:
return {row: iRow, col: ( (iCol<oRow.cells.length-1)?(iCol+1):iCol )};
case 40: //Down
case 40000:
return {row: ( (iRow<oTbl.rows.length-1)?(iRow+1):iRow ), col: iCol};
}
}
function JsTableOnKeyDown(e)
{
var o = JsTableGetObjectsOnEvent('|TEXTAREA|INPUT|SELECT|A|',e);
if (!o) return;
var iRow = o.row.rowIndex;
var iCol = o.cell.cellIndex;
var bRetVal = true;
//Arrow keys
if (o.keyCode >= 37 && o.keyCode <= 40) {
if (!o.jsTable.onEdit) {
var oCoord = JsTableGetNewCoordOnArrow(o.keyCode,iRow,iCol,o.tbl,o.row);
o.cell._keydown = true;
o.jsTable.setActiveCell(oCoord.row, oCoord.col);
bRetVal = false;
}
} else {
switch (o.keyCode) {
case 13: //Enter
if (o.cellEditor.nodeName=='A') break;
if (!o.jsTable.onEdit) o.jsTable.setOnEdit();
else {
o.jsTable.setOnCommit();
var keyCode = 0;
if (o.jsTable.tableModel.enterAfterEdit == JsTable.ENTER_MOVE_DOWN) keyCode = 40;
if (o.jsTable.tableModel.enterAfterEdit == JsTable.ENTER_MOVE_RIGHT) keyCode = 39;
if (keyCode) {
var oCoord = JsTableGetNewCoordOnArrow(keyCode,iRow,iCol,o.tbl,o.row);
o.cell._keydown = true;
o.jsTable.setActiveCell(oCoord.row, oCoord.col);
}
}
bRetVal = false; break;
case 113: //F2
o.jsTable.setOnEdit();
bRetVal = false; break;
case 27: // Escape
o.jsTable.setOnCommit();
bRetVal = false; break;
}
}
if (typeof o.jsTable.onkeydown == 'function') o.jsTable.onkeydown(o.event);
if (!bRetVal) {
o.event.returnValue = false;
o.event.cancelBubble = true;
return false;
}
}
function JsTableOnCheckboxClick(e)
{
var o = JsTableGetObjectsOnEvent('|INPUT|',e);
if (!o) return;
o.event.returnValue = false;
o.cellEditor.checked = o.cell._checked;
}
function JsTableOnCheckboxKeyDown(e)
{
var o = JsTableGetObjectsOnEvent('|INPUT|',e);
if (!o) return;
switch (o.keyCode) {
case 32: //Space
o.jsTable.setOnEdit();
case 113: //F2
case 27: // Escape
o.event.returnValue = false;
o.event.cancelBubble = true;
return false;
case 13: //Enter
o.jsTable.setOnEdit();
o.jsTable.onEdit = true;
}
}
function JsTableOnCheckboxKeyPress(e)
{
var o = JsTableGetObjectsOnEvent('|INPUT|',e);
if (!o) return;
if (o.keyCode==32) { //space
o.event.returnValue = false;
o.event.cancelBubble = true;
return false;
}
}
function JsTableOnStringKeyPress(e) {
var o = JsTableGetObjectsOnEvent('|TEXTAREA|INPUT|',e);
if (!o) return;
if (!o.jsTable.onEdit && (o.keyCode >= 32 && o.keyCode <= 126)) { //typeable character
o.cellEditor.readOnly = false;
o.cellEditor.select(); //IE6
o.jsTable.onEdit = true;
o.cellEditor.value = '';//String.fromCharCode(o.keyCode);
}
}
function JsTableOnNumberKeyPress(e)
{
var o = JsTableGetObjectsOnEvent('|TEXTAREA|INPUT|',e);
if (!o) return;
var keyCode = o.keyCode;
var val = o.cellEditor.value;
var bTrueChar = ((keyCode >= 48 && keyCode <= 57) //numeric keys
|| keyCode == 45); //hyphen (-)
var bDecOk = true;
if (o.cell.dateCol || o.cell.datetimeCol) {
//if (keyCode==45) return;//hyphen
if (o.cell.datetimeCol)
bTrueChar = bTrueChar || keyCode==32 || keyCode==58; //space, : (colon)
} else {
var pointDec = ',';
if (o.jsTable.tableModel.numberDenominator==',') pointDec = '.';
if (pointDec==',' && keyCode==44) {
bTrueChar = true;
bDecOk = (val.indexOf(',')==-1);//ok if decimal point not yet exist
} else if (pointDec=='.' && keyCode==46) {
bTrueChar = true;
bDecOk = (val.indexOf('.')==-1);//ok if decimal point not yet exist
}
//if (keyCode==45 && val.indexOf('-')!=0) return; //hyphen
}
if (!o.jsTable.onEdit) {
if (bTrueChar) {
o.cellEditor.readOnly = false;
o.cellEditor.select(); //IE6
o.jsTable.onEdit = true;
o.cellEditor.value = '';//String.fromCharCode(keyCode);
return;
}
} else if ((bTrueChar && bDecOk)
// || keyCode == 13 || keyCode == 27 //Enter, Escape
|| keyCode == 46000 || keyCode == 8 || keyCode == 9 //Delete, Backspace, Tab
|| (keyCode >= 37000 && keyCode <= 40000) //Arrow
|| keyCode == 0 //Some extended keys on Opera
|| keyCode == 36000 || keyCode == 35000 //Home, end
) {
return;
}
o.event.returnValue = false;
o.event.cancelBubble = true;
return false;
}
function JsTableOnLinkClickOpera7(e)
{
if (this._nocancelclick) this._nocancelclick = false;
else return false;
}
var JsTableOnLinkMouseUpJsTableObject = null;
var JsTableOnLinkMouseUpLinkObject = null;
function JsTableOnLinkMouseUpOpera7(e) {
var o = JsTableGetObjectsOnEvent('|A|',e);
if (!o) return;
JsTableOnLinkMouseUpLinkObject = o.cellEditor;
JsTableOnLinkMouseUpJsTableObject = o.jsTable;
setTimeout(
'if (JsTableOnLinkMouseUpJsTableObject) { '
+ 'JsTableOnLinkMouseUpJsTableObject.setFocus(true); '
+ 'JsTableOnLinkMouseUpJsTableObject=null; } '
+ 'if (JsTableOnLinkMouseUpLinkObject) { '
+ 'JsTableOnLinkMouseUpLinkObject._nocancelclick=true; '
+ 'JsTableOnLinkMouseUpLinkObject.click(); '
+ 'JsTableOnLinkMouseUpLinkObject=null; }',0);
}
function JsTableOnLinkKeyDownOpera7(e)
{
if (!e) e = window.event;
if (e.keyCode==13) this._nocancelclick = true;
}
/************ End: Event Handler ****************************/
function JsTableModel(columns,phpStyle,numberDenominator,dateFormat,oldValIfInvalid,
withPrimaryKey)
{
//columns is a collection of instance of JsTableColumnClass
if (typeof columns != 'object') columns = [];
else if (!columns.length) columns = [];
this.columns = columns;
//Only ',' or '.' accepted
if (numberDenominator != ',') numberDenominator = '.';
this.numberDenominator = numberDenominator;
//Only 'd-m-y' or 'm-d-y' accepted
dateFormat = (dateFormat+'').toLowerCase();
if (dateFormat != 'm-d-y') dateFormat = 'd-m-y';
this.dateFormat = dateFormat;
if (oldValIfInvalid) this.oldValIfInvalid = true;
else this.oldValIfInvalid = false;
if (phpStyle) {
for (var i=0;i<columns.length;i++) columns[i].inputName += '[]';
}
this.withPrimaryKey = (withPrimaryKey ? true : false);
this.enterAfterEdit = JsTable.ENTER_STAY;
this.isCellEditable = function(iRow,iCol) {
return true;
};
}
function JsTable(sId,oTableModel,oParent,oNextSibling)
{
function errorId() {
alert('The table Id is invalid or has been existed');
return null;
}
if (typeof sId != 'string' || !sId) return errorId();
if (!sId.isQualifiedVarName()) return errorId();
if ( (typeof window[sId]!='undefined') || (typeof window['_'+sId]!='undefined')
|| document.getElementById(sId)) return errorId();
if (!oParent && !oParent.insertBefore) {
if (document.forms.length) {
oParent = document.forms[document.forms.length];
} else {
oParent = document.body.appendChild(document.createElement('FORM'));
}
}
var oTbl = document.createElement('TABLE');
//oTbl.onmousemove = JsTableHeaderOnMouseMove;
oTbl.id = sId;
oTbl.className = 'JsTable';
oTbl.cellSpacing = 1;
oTbl.cellPadding = 0;
/* Creates Column Headers */
var o = oTbl.createTHead();
o = o.insertRow(0);
var columns = oTableModel.columns;
var oText, oCell;
for (var i=0; i<columns.length; i++) {
oText = document.createTextNode(columns[i].columnName);
oCell = o.appendChild(document.createElement('TH'));
oCell.style.width = columns[i].width + "px";
oCell.appendChild(oText);
}
if (JsTableNavFamily == 'IE6') { //if (JsTableNavFamily != 'Gecko')
oTbl.onmousemove = JsTableHeaderOnMouseMove;
oTbl.onmouseover = JsTableHeaderOnMouseOver;
oTbl.onmouseout = JsTableHeaderOnMouseOut;
}
if (!oNextSibling) oNextSibling = null;
oTbl = oParent.insertBefore(oTbl,oNextSibling);
window[sId] = oTbl;
window['_'+sId] = this;
this.table = oTbl;
this.id = sId;
this.tableModel = oTableModel;
if (true) { //(JsTableNavFamily=='Opera7') {
o = document.createElement('INPUT');
o.type = 'text';
} else {
o = document.createElement('TEXTAREA');
if (JsTableNavFamily=='IE6') o.style.overflow = 'hidden';
else o.style.overflow = 'auto';
}
o.readOnly = true;
o.style.width = '100%';
o.style.height = '100%';
o.style.margin = '0px';
o.style.borderStyle = 'solid';
o.style.borderWidth = '1px';
//o.style.padding = '1px 1px 1px 0px';
o.style.paddingRight = '1px';
o.style.borderColor = '#cccccc';
this.cellEditor = o;
this.row = -1;
this.col = -1;
this.onEdit = false;
this.hasFocus = false;
oTbl.onmousedown = JsTableOnMouseDown;
oTbl.onkeydown = JsTableOnKeyDown;
oTbl.onkeypress = JsTableOnKeyPress;
//oTbl.onblur = JsTableOnBlur;
this.cellEditor.ondblclick = JsTableOnDblClick;
//this.cellEditor.onkeydown = JsTableOnKeyDown;
//this.cellEditor.onkeypress = JsTableOnKeyPress;
this.cellEditor.onblur = JsTableOnBlur;
this.onkeydown = function(e) {};
this.onkeypress = function(e) {};
this.oncellchange = function() {};
this.oncommit = function() {};
this._keys = [];
}
JsTable.prototype.getObjectsOnCell = function(iRow,iCol) {
var oColumn = this.tableModel.columns[iCol];
var oCell = this.table.rows[iRow];
if (oCell) oCell = oCell.cells[iCol];
var oCellEditor = oColumn.getCellEditor(oCell,this);
if (!oCellEditor) oCellEditor = this.cellEditor;
return {column: oColumn, cellEditor: oCellEditor, cell: oCell};
};
JsTable.prototype.getColumn = function(iCol) {
return this.tableModel.columns[iCol];
};
JsTable.prototype.setHeader = function(sHeader, iCol) {
var oCell = this.table.rows[0].cells[iCol];
if (!oCell) return;
JsTableRemoveAllText(oCell);
oCell.appendChild(document.createTextNode(sHeader+""));
};
JsTable.prototype.setValue = function(val, iRow, iCol) {
if (iRow < 1 || iCol < 0) return;
var o = this.getObjectsOnCell(iRow,iCol);
if (!o.cell) return;
var oCellEditor = null;
if (o.cellEditor) if (o.cell.contains(o.cellEditor)) oCellEditor = o.cellEditor;
o.column.setValue(val,o.cell,this,oCellEditor);
};
JsTable.prototype.getValue = function(iRow, iCol) {
var oTbl = this.table;
if (iRow < 1) return;
var oRow = oTbl.rows[iRow];
if (!oRow) return;
var oCell = oRow.cells[iCol];
if (!oCell) return;
var oColumn = this.tableModel.columns[iCol];
oColumn.getValue(oCell,this);
};
//arguments list the values for each cell
JsTable.prototype.insertRow = function(args,primaryKey,iRow) {
var oTbl = this.table;
var arColumn = this.tableModel.columns;
if (!iRow) iRow = oTbl.rows.length;
iRow = parseInt(iRow);
if (isNaN(iRow)) return;
if (iRow > oTbl.rows.length || iRow < 1) iRow = oTbl.rows.length;
if (!this.tableModel.withPrimaryKey) primaryKey = iRow;
var arColKey = [];
var i, j = 0;
var oRow = oTbl.insertRow(iRow);
for (i=0; i<arColumn.length; i++) {
arColumn[i].addCell(oRow, this, args[i], primaryKey, iRow);
oRow.cells[i].style.width = arColumn[i].width + 'px';
if (arColumn[i].setPrimaryKey) {
arColKey[j] = i;
j++;
}
}
if (!this.tableModel.withPrimaryKey) {
for (var i=iRow+1; i<oTbl.rows.length; i++) {
for (j=0; j<arColKey.length; j++) {
var oCell = oTbl.rows[i].cells[arColKey[j]];
arColumn[arColKey[j]].setPrimaryKey(oCell,i);
}
}
}
var oInput, oCell = oRow.cells[0];
//The new row must have all keys
for (i=0; i<this._keys.length; i++) {
oInput = document.createElement('INPUT');
oInput.type = 'hidden';
oInput.setAttribute('name',this._keys[i]);
oCell.appendChild(oInput);
}
};
JsTable.prototype.addMatrix = function(args2,primaryKeys) {
for (var i=0; i<args2.length; i++) {
this.insertRow(args2[i],primaryKeys[i]);
}
};
JsTable.prototype.deleteRow = function(iRow) {
var oTbl = this.table;
iRow = parseInt(iRow);
if (isNaN(iRow)) return;
if (iRow < 1 || iRow >= oTbl.rows.length) return;
var bHasFocus = this.hasFocus;
if (iRow == this.row && bHasFocus) this.setFocus(false);
oTbl.deleteRow(iRow);
var arColumn = this.tableModel.columns;
if (!this.tableModel.withPrimaryKey) {
for (var j=0; j<arColumn.length; j++) {
if (typeof arColumn[j].setPrimaryKey!='function') continue;
for (var i=iRow; i<oTbl.rows.length; i++) {
var oCell = oTbl.rows[i].cells[j];
arColumn[j].setPrimaryKey(oCell,i);
}
}
}
for (var j=0; j<arColumn.length; j++) {
if (typeof arColumn[j].setRowIndex!='function') continue;
for (var i=iRow; i<oTbl.rows.length; i++) {
var oCell = oTbl.rows[i].cells[j];
arColumn[j].setRowIndex(oCell);
}
}
if (iRow >= oTbl.rows.length) iRow = oTbl.rows.length-1;
if (iRow > 0) this.setActiveCell(iRow,this.col);
else this.row = -1;
};
JsTable.prototype.insertKey = function(sKeyName,val,iRow) {
var arColumn = this.tableModel.columns;
for (var i=0; i<arColumn.length; i++)
if (arColumn[i].inputName==sKeyName) {
alert('JsTable.insertKey : this key name has been owned by the input of a column');
return;
}
var oTbl = this.table;
if (!iRow) iRow = 1;
iRow = parseInt(iRow);
if (isNaN(iRow)) return;
if (iRow < 1 || iRow >= oTbl.rows.length) return;
var iLength = 0;
if ((typeof val != 'object') || (typeof val.length != 'number')) {
val = [val];
iLength = 1;
} else
iLength = val.length;
if (iRow+iLength > oTbl.rows.length) iLength = oTbl.rows.length - iRow;
var oCell = oTbl.rows[iRow].cells[0];
var bKeyExist = false;
var arInputs = oCell.getElementsByTagName('INPUT');
for (var i=0; i<arInputs.length; i++)
if (arInputs[i].getAttribute('name')==sKeyName) {
bKeyExist = true;
break;
}
if (bKeyExist) {
for (var i=0; i<iLength; i++) {
oCell = oTbl.rows[iRow+i].cells[0];
arInputs = oCell.getElementsByTagName('INPUT');
for (var j=0; j<arInputs.length; j++)
if (arInputs[j].getAttribute('name')==sKeyName) {
arInputs[j].value = val[i];
break;
}
}
} else {
var j = iRow + iLength;
//All rows must have this key
for (var i=0; i<oTbl.rows.length; i++) {
oCell = oTbl.rows[i].cells[0];
var oInput = document.createElement('INPUT');
oInput.type = 'hidden';
oInput.setAttribute('name',sKeyName);
if (i >= iRow && i < j) oInput.value = val[i-iRow];
oCell.appendChild(oInput);
}
}
};
JsTable.prototype.setActiveCell = function(iRow, iCol) {
if (iRow < 1 || iRow >= this.table.rows.length
|| iCol < 0 || iCol >= this.tableModel.columns.length) return;
if (!this.hasFocus) {
this._oncellchange = (iRow != this.row || iCol != this.col);
this.row = iRow;
this.col = iCol;
this.setFocus(true);
return;
}
var o = this.getObjectsOnCell(iRow,iCol);
if (this.row == iRow && this.col == iCol) {
o.column.setEditorOnRearrive(o.cellEditor,o.cell,this);
o.cell._onclick = false;
o.cell._keydown = false;
return;
} else {
if (this.row > 0 && this.col >= 0) {
var oldCell = this.getObjectsOnCell(this.row,this.col);
o.cell._keydown = oldCell.cell._keydown;
oldCell.cell._keydown = false;
//oldCell.cellEditor.blur();
this._onmove = true;
this.setFocus(false);
}
}
this._oncellchange = true;
this.row = iRow;
this.col = iCol;
this.setFocus(true);
};
JsTable.prototype.setOnEdit = function() {
if (!this.tableModel.isCellEditable(this.row,this.col)) return;
if (this.onEdit) return;
if (this.row < 1 || this.col < 0) return;
var o = this.getObjectsOnCell(this.row,this.col);
this.onEdit = true;
o.column.setEditorOnEdit(o.cellEditor,o.cell,this);
//Enter cannot be canceled on Opera
//if (o.cellEditor.value) o.cellEditor.value = o.cellEditor.value.replace(/\n/g,'').replace(/\r/g,'');
};
JsTable.prototype.setOnCommit = function() {
if (!this.onEdit) return;
if (this.row < 1 || this.col < 0) return;
var o = this.getObjectsOnCell(this.row,this.col);
this.onEdit = false;
//Enter cannot be canceled on Opera
//if (o.cellEditor.value) o.cellEditor.value = o.cellEditor.value.replace(/\n/g,'').replace(/\r/g,'');
o.column.setEditorOnCommit(o.cellEditor,o.cell,this);
this.oncommit();
};
JsTableActiveCellEditor = null;
JsTableSetCellEditorFocus = function() {
if (!JsTableActiveCellEditor) return;
JsTableActiveCellEditor.focus();
var oTbl = JsTableActiveCellEditor;
for (var i=0; i<4; i++) {
oTbl = oTbl.parentNode;
if (!oTbl) return;
}
//.parentNode.parentNode.parentNode.parentNode;
var oJsTable = window['_'+oTbl.id];
oJsTable._onmove = false;
JsTableActiveCellEditor = null;
};
JsTable.prototype._setCellEditorFocus = function(oCellEditor) {
JsTableActiveCellEditor = oCellEditor;
setTimeout('JsTableSetCellEditorFocus()',0);
};
JsTable.prototype.setFocus = function(bGetFocus) {
if (this.hasFocus == bGetFocus) return;
if (this.row < 1 || this.col < 0) return;
var o = this.getObjectsOnCell(this.row,this.col);
if (bGetFocus) {
this.hasFocus = true;
var iCont = o.column.containsEditor(o.cell,o.cellEditor);
if (iCont ^ -1) //o.column.constructor==JsTableColumnBoolean || !o.cell.contains(o.cellEditor)
o.column.setEditorOnArrive(o.cellEditor,o.cell,this);
o.cell._onclick = false;
o.cell._keydown = false;
if (this._oncellchange) this.oncellchange();
this._oncellchange = false;
this._setCellEditorFocus(o.cellEditor);
} else {
this.hasFocus = false;
if (o.column.containsEditor(o.cell,o.cellEditor)) {
if (this.onEdit) this.setOnCommit();
o.column.setEditorOnLeave(o.cellEditor,o.cell,this);
if (o.column.containsEditor(o.cell,o.cellEditor)) //such as checkbox, Link
if (!this._onblur) {
if (o.cellEditor.blur) o.cellEditor.blur;
} else {
this._onblur = false;
}
}
}
};
JsTable.ENTER_STAY = 0;
JsTable.ENTER_MOVE_DOWN = 1;
JsTable.ENTER_MOVE_RIGHT = 2;
} /**************** if (JsTableNavFamily) *****************************/
</script>
<style><!--
/*
.JsTable .cell-focus {
background-color: red;
}
*/
--></style>
<script language=JavaScript>
<!--
var g_oJsTable;
function setValues(iRow, str, num, denNum, bool, opt, date, datetime )
{
//alert(iRow + ' : ' + str + ',' + num + ',' + denNum + ',' + bool + ',' + opt + ',' + date);
g_oJsTable.setValue(str, iRow, 0);
g_oJsTable.setValue(num, iRow, 1);
g_oJsTable.setValue(denNum, iRow, 2);
g_oJsTable.setValue(bool, iRow, 3);
g_oJsTable.setValue(opt, iRow, 4);
g_oJsTable.setValue(date, iRow, 5);
g_oJsTable.setValue(datetime, iRow, 6);
}
function addRow()
{
g_oJsTable.insertRow([]);
if (g_oJsTable.row > 0) g_oJsTable.setFocus(true);
else g_oJsTable.setActiveCell(1,g_oJsTable.col);
}
window.editedRowIndex = 0;
function editRow(iRow)
{
var win = window.open('./JsTable-selectValue.htm', 'JsTableSelectValues',
'left=40,top=40,height=400,width=720,resizable=1,scrollbars=1');
if (!win.opener) win.opener = window;
window.editedRowIndex = iRow;
}
function deleteRow(iRow)
{
g_oJsTable.deleteRow(iRow);
}
function showTable()
{
if (!JsTableNavFamily) { //If the browser doesn't support JsTable
document.open('text/html','replace');
document.write("<h3>Your browser does not support</h3>");
document.write("Use the following browsers:<ul>");
document.write("<li>Gecko browsers which is equivalent with or newer than Mozilla 1.4/Netscape 7.1</li>");
document.write("<li>Opera 7.5 or newer</li>");
document.write("<li>Internet Explorer 6</li></ul>");
document.write("Some versions is still buggy. Have the best browser.");
document.close();
return;
}
var oSbm = document.getElementById('submit');
var align;
var columns = [
new JsTableColumnString('String','string',120),
new JsTableColumnNumber('Number','number',75),
new JsTableColumnNumber('Denominated Number','denNumber',75,'right',true,2),
new JsTableColumnBoolean('Boolean','boolean',50),
new JsTableColumnOptions( 'Options','options',100,align,
new JsTableOptionValues(['Satu','Dua','Tiga'],['_Satu','_Dua','_Tiga']) ),
new JsTableColumnDate('Date','date',70,'center'),
new JsTableColumnDateTime('Date Time','datetime',140,'center',true),
new JsTableColumnLink('','link',50,'center','Edit',
'javascript:editRow(__ROW__)'),
new JsTableColumnLink('','link',50,'center',document.createTextNode('Delete'),
'javascript:deleteRow(__ROW__)')
];
// JsTableColumnLink(columnName,inputName,width,align,identifier,href)
var oTableModel = new JsTableModel(columns,true,'.','d-m-y',true);
oTableModel.enterAfterEdit = JsTable.ENTER_MOVE_RIGHT;
oTableModel.isCellEditable = function(iRow,iCol) {
//if (iRow==1) return false;
return true;
};
g_oJsTable = new JsTable('trans',oTableModel,
document.getElementById('showTable'),oSbm);
g_oJsTable.insertRow(['aaa',1234.8,22456,true,'Tiga','9-4-2005','31-7-1978 21:0:0']);
g_oJsTable.insertRow(['yaa',-.98,'234x6',false,'Dua','','27-1-1981 9:0:0']);
for (var i=1; i<5; i++) {
g_oJsTable.insertRow([]);
}
}
//-->
</script>
</head>
<body onload='showTable()' style="width:90%">
<p>Hello this is editable, navigatable and submitable table. Click on the table to give it the focus.
<br>The decimal point of numbers in the table is represented by comma ( , ) not period ( . ).
The date time format is 'dd-mm-yyyy hh:nn:ss'</p>
<noscript><h2>Turn on your JavaScript!!</h2></noscript>
<form method=post action='JsTable.php' target='submittedValues'>
<div id=showTable align=center style="width:100%">
<div id=submit>
<input type=submit value=Submit>
<input type=button value='Add Row' onclick="addRow()">
</div>
<div>Button 'Submit' is to submit the content of table to web server.
Button 'Add Row' is to add row in the table</div>
</div>
</form>
<div> </div>
<div align=center>
<h4 style="width:791px; margin:0px"><div align=left>How To Edit and Navigate :</div></h4>
<div align=left style="font-family:sans-serif;font-size:13px; border-style:solid; border-width:1px;
border-color:black; background-color:#c0c0c0; color:#404000; height:150px; width:775px;
overflow:scroll; padding:8px; text-align:justify">
To give focus to table, click on the table. The cell on which we click,
automatically become the active cell. The active cell is the cell in which
we can edit its content. If usually its cell
editor is hidden for that cell, when the cell is active, it reveals its
cell editor, so we can edit it.<br>
<br>
Navigation:<br>
We can move the active cell by pressing the arrow
keys on keyboard by intuitive direction. We can also click on a cell,
if we want that cell become active.<br>
<br>
Editing:<br>
To edit the cell's content needs some steps which is
different for different cell editor. I will explain for each cell
editor.<br>
<ul>
<li><u>Textbox</u> (element <span
style="font-family: monospace; font-size: 12px;"><TEXTAREA></span>
or <span style="font-family: monospace; font-size: 12px;"><INPUT
type=text></span>)<br>
To edit, press Enter. Then we will go into the state, we call it <span
style="font-style: italic;">editing state</span>. In editing state,
the text cursor will appear and thus we can edit the cell's content.
When editing state, the arrow keys cannot be used to navigate but used
to move text cursor instead. To end the editing state, press Enter
again. Another way to go into editing state is by pressing F2 (on
Opera, F2 has the meaning for the browser itself). To end the editing
state, press Esc. Pressing any valid character will also set the JsTable
into editing state automatically (as of version 0.4.5).
We can also double click on a cell (may be triple
click) if we want to edit the cell. But to end the editing state, still
use the keyboard. Clicking on another cell, when the active cell is
edited, will end the editing state of current active cell and move the
active cell to the cell has just been clicked. When on the number column,
you may only press the valid character for a number. So do the date column
and datetime column.</li>
<li><u>Checkbox</u> (element <span
style="font-family: monospace; font-size: 12px;"><INPUT
type=checkbox></span>)<br>
To change the state of the checkbox, press Enter or Space. Clicking on
the cell will also change the checkbox' state.</li>
<li><u>Combobox</u> (element <span
style="font-family: monospace; font-size: 12px;"><SELECT></span>)<br>
To edit, press Enter and then going into editing state. Use up arrow
and down arrow, to change the option. Press enter again, to end the
editing state. Key F2 can also be used but key Esc may not be useful in
all browsers. Esc may reset the option. Another way to change the
option, when in editing state, press Alt+down_arrow, the the combobox
will reveal its option, choose option by pressing down arrow or up
arrow and then press Enter to end the editing state. This way doesn't
run perfectly in all browsers.<br>
If you want to use mouse, do with usual steps: click on the combobox
and choose the option.</li>
<li><u>Link</u><br>
The Link cannot be edited but only execute its link's target. To
execute its target, press Enter or click the Link.<br>
</li>
</ul>
This software is licensed under GNU Lesser General Public License as published by the
Free Software Foundation; either version 2.1 of the License or (at your option) any later version.<br>
See the JsTable's <a href='./JsTable.js' target='_blank'>source</a> and the
<a href='./JsTable_Documentation.html' target='_blank'>documentation</a>.<br>
Send the bugs report to <a href="mailto:almulyana@yahoo.com">almulyana@yahoo.com</a>.
</div>
<small>Copyright © 2005 AT Mulyana</small>
</div>
</body>
</html>
JsTable20050725.zip( 34 k)Related examples in the same category