// Copyright 2004-2009 Stephane Lavergne <www.imars.com>
// Free software under <http://www.gnu.org/licenses/gpl-3.0.txt>
// Modules below: imars.js imars.dom.js imars.dom.lv.js
if (!window['min']) {
window.min = function (a, b) {
return ((a<b) ? a : b);
};
};
if (!window['max']) {
window.max = function (a, b) {
return ((a>b) ? a : b);
};
};
var imars = {
base: document.getElementsByTagName ? (document.getElementsByTagName("base")[0] ? document.getElementsByTagName("base")[0].href : '') : null,
head: document.getElementsByTagName ? document.getElementsByTagName('head')[0] : null,
jsbase: '/lib/',
includes: [],
loaded: false,
require: function(s) { return false; },
use: function(base, that) {
if (typeof(base) == 'object') {
if (!that) {
that = window;
};
for (var i in base) {
that[i] = base[i];
};
};
},
onLoad: function (hook, args) {
var ready = document.readyState;
if (imars.loaded || (ready && (ready == 4 || ready == 'complete' || ready == 'loaded'))) {
hook.apply(null, args);
} else {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
if (args && hook.apply) {
window.onload = function() { hook.apply(null, args); };
} else {
window.onload = function() { hook(); };
};
} else {
if (args && hook.apply) {
window.onload = function() { oldonload(); hook.apply(null, args); };
} else {
window.onload = function() { oldonload(); hook(); };
};
};
};
}
};
imars.onLoad(function(){ imars.loaded = true; });
imars.dom = {
getElementsByClassName: function (doc, tName, cName) {
var r = [];
var e = (tName == "*" && doc.all) ? doc.all : (doc.getElementsByTagName ? doc.getElementsByTagName(tName) : []);
cName = cName.replace(/\-/g, "\\-");
var re = new RegExp("(^|\\s)" + cName + "(\\s|$)");
var oe;
for (var i = 0, max = e.length; i < max; i++) {
oe = e[i];
if (re.test(oe.className)) {
r.push(oe);
};
};
return r;
},
getElementsById: function (doc, tName, idre) {
var r = [];
var e = (tName == "*" && doc.all) ? doc.all : (doc.getElementsByTagName ? doc.getElementsByTagName(tName) : []);
idre = idre.replace(/\-/g, "\\-");
idre = idre.replace(/\*/g, ".*");
var re = new RegExp("(^|\\s)" + idre + "(\\s|$)");
var oe;
for (var i = 0, max = e.length; i < max; i++) {
oe = e[i];
if (re.test(oe.id)) {
r.push(oe);
};
};
return r;
},
addCSS: function (cssText) {
var node = document.createElement('style');
node.type = 'text/css';
node.rel = 'stylesheet';
if (node.styleSheet) {
node.styleSheet.cssText = cssText;
} else {
node.appendChild(document.createTextNode(cssText));
};
document.getElementsByTagName('head')[0].appendChild(node);
return false;
},
hide: function (el) {
var e = el;
if (!e.style && document.getElementById) e = document.getElementById(el);
if (e.style) e.style.display = 'none';
return false;
},
show: function (el) {
var e = el;
if (!e.style && document.getElementById) e = document.getElementById(el);
if (e.style) e.style.display = 'block';
return false;
},
toggle: function (el) {
var e = el;
if (!e.style && document.getElementByid) e = document.getElementById(el);
if (e.style) {
if (e.style.display == 'none') {
e.style.display = 'block';
} else {
e.style.display = 'none';
};
};
return false;
},
create: function (obj) {
if (!obj.tagName) return false;
var result = document.createElement(obj.tagName);
for (key in obj) {
if (key == 'childNodes') {
for (i=0, iMax=obj.childNodes.length; i < iMax; i++) {
result.appendChild(imars.dom.create(obj.childNodes[i]));
};
} else if (key == 'innerText') {
result.appendChild(document.createTextNode(obj.innerText));
} else if (key != 'tagName') {
result[key] = obj[key];
};
};
return result;
}
};
imars.require("imars.dom");
imars.dom.lv = {
currentTable: false,
load: function () {
var tables = imars.dom.getElementsByClassName(document, 'table', 'listview');
for (var i=0, iMax = tables.length; i < iMax; i++) {
var table = tables[i];
table.lvSortCol = 0;
table.lvSortFactor = 1;
table.lvCols = table.tHead.rows[0].cells;
for (var j=0, jMax=table.lvCols.length; j < jMax; j++) {
var col = table.lvCols[j];
col.lvClass = col.className;
if (col.className == 'select') col.lvUniques = [];
col.lvFilter = -1;
col.lvFilterArg = '';
col.onclick = imars.dom.lv.onClick;
col.lvClickMode = 'sort';
col.lvColIndex = j;
col.lvTable = table;
};
var rows = table.tBodies[0].rows;
for (var j=0, jMax=rows.length; j < jMax; j++) {
for (var k=0, kMax=rows[j].cells.length; k < kMax; k++) {
var col = rows[j].cells[k];
if (table.lvCols[k].lvClass == 'select') {
var found = 0;
var cleaned = col.innerHTML.replace(/(<[^>]+>)|(&[a-z0-9]{1,6};)/ig,'');
if (imars.dom.lv.iinArray(table.lvCols[k].lvUniques, cleaned) < 0) table.lvCols[k].lvUniques.push(cleaned);
};
col.className = table.lvCols[k].className;
};
};
for (var j=0, jMax=table.lvCols.length; j < jMax; j++) {
if (table.lvCols[j].lvUniques) table.lvCols[j].lvUniques.sort(imars.dom.lv.isort);
};
if (table.tFoot) {
if (table.tFoot.className.search('totals') >= 0) {
var totalsRow = document.createElement('tr');
for (var j=0, jMax = table.lvCols.length; j < jMax; j++) {
var newCol = document.createElement('td');
if (table.lvCols[j].lvClass == 'number') {
newCol.className = 'number';
var newText = document.createTextNode(' ');
newCol.appendChild(newText);
table.lvCols[j].lvTotal = newText;
};
totalsRow.appendChild(newCol);
};
table.tFoot.appendChild(totalsRow);
imars.dom.lv.refreshTotals(table);
};
if (table.tFoot.className.search('filters') >= 0) {
var filterRow = document.createElement('tr');
for (var j=0, jMax = table.lvCols.length; j < jMax; j++) {
var newCol = document.createElement('td');
if (table.lvCols[j].className == 'number' || table.lvCols[j].className == 'date') {
newCol.appendChild(imars.dom.create({
tagName: 'select',
lvClickMode: 'filter',
lvColIndex: j,
lvTable: table,
lvClass: table.lvCols[j].lvClass,
onkeyup: imars.dom.lv.onClick,
onchange: imars.dom.lv.onClick,
childNodes: [
{ tagName: 'option', value: '-1', innerText: 'All' },
{ tagName: 'option', value: 'lt', innerText: '<' },
{ tagName: 'option', value: 'lte', innerText: '<=' },
{ tagName: 'option', value: 'eq', innerText: '==' },
{ tagName: 'option', value: 'gte', innerText: '>=' },
{ tagName: 'option', value: 'gt', innerText: '>' }
]
}));
newCol.appendChild(document.createElement('br'));
newCol.appendChild(imars.dom.create({
tagName: 'input',
type: 'text',
lvClickMode: 'filterarg',
lvColIndex: j,
lvTable: table,
lvClass: table.lvCols[j].lvClass,
onkeyup: imars.dom.lv.onClick
}));
} else if (table.lvCols[j].className == 'select') {
newSelect = imars.dom.create({
tagName: 'select',
lvClickMode: 'filter',
lvColIndex: j,
lvTable: table,
lvClass: table.lvCols[j].lvClass,
onkeyup: imars.dom.lv.onClick,
onchange: imars.dom.lv.onClick,
childNodes: [
{ tagName: 'option', value: '-1', innerText: 'All' }
]
});
for (var k=0, kMax = table.lvCols[j].lvUniques.length; k < kMax; k++) {
newSelect.appendChild(imars.dom.create({ tagName: 'option', value: table.lvCols[j].lvUniques[k], innerText: table.lvCols[j].lvUniques[k] }));
};
newCol.appendChild(newSelect);
} else if (table.lvCols[j].className == 'bool') {
newCol.appendChild(imars.dom.create({
tagName: 'select',
lvClickMode: 'filter',
lvColIndex: j,
lvTable: table,
lvClass: table.lvCols[j].lvClass,
onkeyup: imars.dom.lv.onClick,
onchange: imars.dom.lv.onClick,
childNodes: [
{ tagName: 'option', value: '-1', innerText: 'All' },
{ tagName: 'option', value: '1', innerText: 'Yes' },
{ tagName: 'option', value: '2', innerText: 'No' }
]
}));
} else {
newCol.appendChild(imars.dom.create({
tagName: 'select',
lvClickMode: 'filter',
lvColIndex: j,
lvTable: table,
lvClass: table.lvCols[j].lvClass,
onkeyup: imars.dom.lv.onClick,
onchange: imars.dom.lv.onClick,
childNodes: [
{ tagName: 'option', value: '-1', innerText: 'All' },
{ tagName: 'option', value: 'starts', innerText: 'Starts with' },
{ tagName: 'option', value: 'contains', innerText: 'Contains' },
{ tagName: 'option', value: 'equals', innerText: 'Equals' }
]
}));
newCol.appendChild(document.createElement('br'));
newCol.appendChild(imars.dom.create({
tagName: 'input',
type: 'text',
lvClickMode: 'filterarg',
lvColIndex: j,
lvTable: table,
onkeyup: imars.dom.lv.onClick
}));
};
filterRow.appendChild(newCol);
};
table.tFoot.appendChild(filterRow);
};
if (table.tFoot.className.search('counter') >= 0) {
var counterRow = document.createElement('tr');
var counterCell = document.createElement('td');
counterCell.colSpan = table.lvCols.length;
var counterSpan = document.createElement('span');
var newText = document.createTextNode(rows.length);
counterSpan.appendChild(newText);
table.lvCounter = newText;
counterCell.appendChild(counterSpan);
counterCell.appendChild(document.createTextNode(' rows'));
counterRow.appendChild(counterCell);
table.tFoot.appendChild(counterRow);
};
};
};
},
onClick: function (e) {
var node;
if (e) {
if (e.target) node = e.target; else if (e.nodeName) node = e; else return;
} else {
if (window.event) node = window.event.srcElement; else return;
};
if (!node.lvClickMode) return;
switch (node.lvClickMode) {
case 'sort':
if (node.lvTable.lvSortCol == node.lvColIndex) {
if (node.lvTable.lvSortFactor == 1) node.lvTable.lvSortFactor = -1;
else node.lvTable.lvSortFactor = 1;
} else {
node.lvTable.lvSortCol = node.lvColIndex;
};
imars.dom.lv.reSort(node.lvTable);
imars.dom.lv.refreshHeader(node.lvTable);
break;
case 'filter':
node.lvTable.lvCols[node.lvColIndex].lvFilter = node.value;
imars.dom.lv.reFilter(node.lvTable);
imars.dom.lv.refreshTotals(node.lvTable);
break;
case 'filterarg':
if ((node.value != '') && (node.lvFilter == -1)) {
switch (node.lvTable.lvCols[node.lvColIndex].lvClass) {
case 'number': node.lvFilter = 'eq'; break;
case 'date': node.lvFilter = 'eq'; break;
case 'select': break;
case 'bool': break;
default: node.lvFilter = 'starts'; break;
};
};
node.lvTable.lvCols[node.lvColIndex].lvFilterArg = node.value;
imars.dom.lv.reFilter(node.lvTable);
imars.dom.lv.refreshTotals(node.lvTable);
break;
default:
alert('Unknown mode '+ mode);
};
},
refreshHeader: function (table) {
for (i=0, iMax=table.lvCols.length; i < iMax; i++) {
if (i == table.lvSortCol) {
if (table.lvSortFactor == 1) {
table.lvCols[i].className = 'sortup';
} else {
table.lvCols[i].className = 'sortdown';
};
} else {
table.lvCols[i].className = table.lvCols[i].lvClass;
};
};
},
reFilter: function (table) {
var displayed = 0;
var rows = table.tBodies[0].rows;
for (var i=0, iMax=rows.length; i < iMax; i++) {
var match = 1;
for (var j=0, jMax=table.lvCols.length; j < jMax && match == 1; j++) {
var filter = table.lvCols[j].lvFilter;
var filterarg = table.lvCols[j].lvFilterArg;
switch (table.lvCols[j].lvClass) {
case 'number':
if (filterarg) switch (filter) {
case 'lt': if (parseFloat(rows[i].cells[j].innerHTML) >= parseFloat(filterarg)) match = 0; break;
case 'lte': if (parseFloat(rows[i].cells[j].innerHTML) > parseFloat(filterarg)) match = 0; break;
case 'eq': if (parseFloat(rows[i].cells[j].innerHTML) != parseFloat(filterarg)) match = 0; break;
case 'gt': if (parseFloat(rows[i].cells[j].innerHTML) <= parseFloat(filterarg)) match = 0; break;
case 'gte': if (parseFloat(rows[i].cells[j].innerHTML) < parseFloat(filterarg)) match = 0; break;
};
break;
case 'date':
if (filterarg) switch (filter) {
case 'lt': if (imars.dom.lv.toDate(rows[i].cells[j].innerHTML) >= imars.dom.lv.toDate(filterarg)) match = 0; break;
case 'lte': if (imars.dom.lv.toDate(rows[i].cells[j].innerHTML) > imars.dom.lv.toDate(filterarg)) match = 0; break;
case 'eq': if (imars.dom.lv.toDate(rows[i].cells[j].innerHTML) != imars.dom.lv.toDate(filterarg)) match = 0; break;
case 'gt': if (imars.dom.lv.toDate(rows[i].cells[j].innerHTML) <= imars.dom.lv.toDate(filterarg)) match = 0; break;
case 'gte': if (imars.dom.lv.toDate(rows[i].cells[j].innerHTML) < imars.dom.lv.toDate(filterarg)) match = 0; break;
};
break;
case 'select':
if ((filter != -1) && (rows[i].cells[j].innerHTML.replace(/(<[^>]+>)|(&[a-z0-9]{1,6};)|(\s+)/ig,'').toUpperCase() != filter.replace(/(\s+)/ig,'').toUpperCase())) match = 0;
break;
case 'bool':
switch (parseInt(filter)) {
case 1: if (rows[i].cells[j].innerHTML.search(/^(\s|(&nbsp;))*$/i) >= 0) match = 0; break;
case 2: if (rows[i].cells[j].innerHTML.search(/^(\s|(&nbsp;))*$/i) < 0) match = 0; break;
};
break;
default:
if (filterarg) switch (filter) {
case 'starts': if (rows[i].cells[j].innerHTML.replace(/(<[^>]+>)|(&[a-z0-9]{1,6};)/ig,'').toUpperCase().indexOf(filterarg.toUpperCase()) != 0) match = 0; break;
case 'equals': if (rows[i].cells[j].innerHTML.replace(/(<[^>]+>)|(&[a-z0-9]{1,6};)/ig,'').toUpperCase() != filterarg.toUpperCase()) match = 0; break;
case 'contains': if (rows[i].cells[j].innerHTML.replace(/(<[^>]+>)|(&[a-z0-9]{1,6};)/ig,'').toUpperCase().search(filterarg.toUpperCase()) < 0) match = 0; break;
};
break;
};
};
if (match == 1) {
displayed++;
if (rows[i].style.display == 'none') rows[i].style.display = '';
} else {
if (rows[i].style.display != 'none') rows[i].style.display = 'none';
};
};
if (table.lvCounter) table.lvCounter.data = displayed;
},
reSort: function (table) {
imars.dom.lv.currentTable = table;
var cha = table.tBodies[0].rows;
var children = [];
for (i=0, iMax=cha.length; i < iMax; i++) {
children.push(cha[i]);
};
cha = null;
if (table.lvCols[table.lvSortCol].lvClass == 'number') {
children.sort(imars.dom.lv.sortNumbers);
} else {
children.sort(imars.dom.lv.sortStrings);
};
for (i=0, iMax=children.length; i < iMax; i++) {
table.tBodies[0].appendChild(children[i]);
};
},
sortStrings: function (a,b) {
var table = imars.dom.lv.currentTable;
var as = a.cells[table.lvSortCol].innerHTML.replace(/(<[^>]+>)|(&[a-z0-9]{1,6};)/ig,'').toUpperCase();
var bs = b.cells[table.lvSortCol].innerHTML.replace(/(<[^>]+>)|(&[a-z0-9]{1,6};)/ig,'').toUpperCase();
if (as.toString() > bs.toString()) return 1 * table.lvSortFactor;
else if (as < bs) return -1 * table.lvSortFactor;
else return 0;
},
sortNumbers: function (a,b) {
var table = imars.dom.lv.currentTable;
var an = parseFloat(a.cells[table.lvSortCol].innerHTML);
var bn = parseFloat(b.cells[table.lvSortCol].innerHTML);
if (table.lvSortFactor == 1) return(an - bn);
else return(bn - an);
},
refreshTotals: function (table) {
for (var k=0, kMax = table.lvCols.length; k < kMax; k++) {
table.lvCols[k].lvTotalNum = 0;
};
var rows = table.tBodies[0].rows;
for (var j=0, jMax = rows.length; j < jMax; j++) if (rows[j].style.display != 'none') {
var cols = rows[j].cells;
for (var k=0, kMax = cols.length; k < kMax; k++) if (table.lvCols[k].lvTotal) {
table.lvCols[k].lvTotalNum += parseFloat(cols[k].innerHTML);
};
};
for (var k=0, kMax = table.lvCols.length; k < kMax; k++) if (table.lvCols[k].lvTotal) {
table.lvCols[k].lvTotal.data = table.lvCols[k].lvTotalNum;
};
},
toDate: function (a) {
var almost = a.replace(/[\s\.\-\/]+/ig,'');
for (var i = almost.length; i < 8; i++) almost += "0";
return(parseInt(almost));
},
isort: function (a,b) {
var as = a.toString().toUpperCase();
var bs = b.toString().toUpperCase();
if (as > bs) return 1;
else if (as < bs) return -1;
else return 0;
},
iinArray: function(haystack, needle) {
var found = -1;
var ineedle = needle.toUpperCase();
for (var i=0, iMax=haystack.length; i < iMax; i++) {
if (haystack[i].toUpperCase() == ineedle) {
found = i;
break;
};
};
return found;
}
};
imars.onLoad(imars.dom.lv.load);
