This repository has been archived on 2024-07-18. You can view files and clone it, but cannot push or open issues or pull requests.
lwb5/site/static/beta5/js/main.js

1400 lines
38 KiB
JavaScript
Raw Normal View History

2016-01-10 11:01:49 +01:00
function formatNumber(n)
{
var l = n.length, m = l % 3, c = (l - m) / 3, v = ((m > 0) ? n.substr(0, m) : ''), z;
for (z=0;z<c;z++)
{
if (v != "")
v += ',';
v += n.substr(m+(z*3), 3);
}
return v;
}
//--------------------------------------------------------------------------------------
// ARRAY EXTENSION
//--------------------------------------------------------------------------------------
Array_search = function (value) {
var found=null;
if (value != null)
for (var i in this) {
if (this[i]==value) {
found=i;
break;
}
}
return found;
}
//--------------------------------------------------------------------------------------
// HASHTABLE IMPLEMENTATION
//--------------------------------------------------------------------------------------
function Hashtable()
{
this.clear = Hashtable_clear;
this.containsKey = Hashtable_containsKey;
this.containsValue = Hashtable_containsValue;
this.get = Hashtable_get;
this.isEmpty = Hashtable_isEmpty;
this.keys = Hashtable_keys;
this.put = Hashtable_put;
this.remove = Hashtable_remove;
this.size = Hashtable_size;
this.toString = Hashtable_toString;
this.values = Hashtable_values;
this.hashtable = new Array();
}
function Hashtable_clear() { this.hashtable = new Array(); }
function Hashtable_get(key) { return this.hashtable[key]; }
function Hashtable_isEmpty() { return (parseInt(this.size())==0) ? true:false; }
function Hashtable_containsKey(key)
{
var exists=false;
for (var i in this.hashtable)
{
if (i==key&&this.hashtable[i]!=null)
{
exists=true;
break;
}
}
return exists;
}
function Hashtable_containsValue(value)
{
var contains=false;
if (value!=null)
for (var i in this.hashtable)
{
if (this.hashtable[i]==value)
{
contains=true;
break;
}
}
return contains;
}
function Hashtable_keys()
{
var keys=new Array();
for (var i in this.hashtable)
{
if(this.hashtable[i]!=null)
keys.push(i);
}
return keys;
}
function Hashtable_put(key,value)
{
if (key==null||value==null)
throw "NullPointerException {"+key+"},{"+value+"}";
else
this.hashtable[key]=value;
}
function Hashtable_remove(key)
{
var rtn=this.hashtable[key];
this.hashtable[key]=null;
return rtn;
}
function Hashtable_size()
{
var size=0;
for (var i in this.hashtable)
{
if (this.hashtable[i]!=null)
size++;
}
return size;
}
function Hashtable_toString()
{
var result="";
for (var i in this.hashtable)
{
if (this.hashtable[i]!=null)
result+="{"+i+"},{"+this.hashtable[i]+"}\n";
}
return result;
}
function Hashtable_values()
{
var values=new Array();
for (var i in this.hashtable)
{
if (this.hashtable[i]!=null)
values.push(this.hashtable[i]);
}
return values;
}
//----------------------------------------------------------------------------------------------
// COMPONENTS
//----------------------------------------------------------------------------------------------
Component = function(isBlock) {
if (typeof isBlock == "undefined")
return;
this.id = ++Component.lId;
Component.list[this.id] = this;
this.slots = new Hashtable();
this.events = new Hashtable();
this.children = new Hashtable();
this.visible = false;
this.isBlock = isBlock;
this.newSlot('show');
this.newSlot('hide');
this.newSlot('drawAll');
this.newSlot('draw');
this.newEvent('Show', true);
this.newEvent('Hide', true);
this.bindEvent('Show','drawAll');
}
Component.list = new Array();
Component.lId = -1;
Component.prototype.setVisible = function(v) {
this.visible=v;
var i,k=this.children.keys();
for (i=0;i<k.length;i++)
this.children.get(k[i]).setVisible(v);
}
Component.prototype.draw = function() { }
Component.prototype.drawAll = function() {
if (!this.visible)
return;
var i,k=this.children.keys();
this.draw();
for (i=0;i<k.length;i++)
this.children.get(k[i]).drawAll();
}
Component.prototype.show = function() {
this.setVisible(true);
this.onShow();
}
Component.prototype.hide = function() {
this.setVisible(false);
this.onHide();
}
Component.prototype.getDocID = function() { return "cmpid" + this.id; }
Component.prototype.getElement = function() { return document.getElementById(this.getDocID()); }
Component.prototype.jsCode = function() { return "Component.list[" + this.id + "]"; }
Component.prototype.html = function(cl) {
return (this.isBlock ? '<div' : '<span') + ' id="' + this.getDocID() + '"'
+ (typeof cl == "undefined" ? "" : (' class="' + cl + '"'))
+ '>&nbsp;</' + (this.isBlock ? 'div' : 'span') + '>';
}
Component.prototype.newSlot = function(name) {
if (this.slots.containsKey(name))
return;
var s = new Component.Slot(name,this);
this.slots.put(name, s);
}
Component.prototype.newEvent = function(name, propagate) {
if (this.events.containsKey(name))
return;
var e = new Component.Event(name, propagate);
this.events.put(name, e);
var f = function() { this.triggerEvent(name,arguments); };
eval("this.on"+name+'=f');
}
Component.prototype.bindEvent = function(eName,sName,cmp) {
var e = this.events.get(eName), c = (cmp ? cmp : this), s = c.slots.get(sName);
if (!(e && s))
return;
e.bind(s);
}
Component.prototype.detachEvent = function(eName,sName,cmp) {
var e = this.events.get(eName), c = (cmp ? cmp : this), s = c.slots.get(sName);
if (!(e && s))
return;
e.detach(s);
}
Component.prototype.triggerEvent = function(eName,args) {
var e = this.events.get(eName);
if (!e)
return;
var i, n = new Array();
for (i=0;i<args.length;i++)
n.push('args[' + i + ']');
eval('e.trigger(' + n.join(',') + ')');
if (!e.propagate)
return;
var k=this.children.keys();
for (i=0;i<k.length;i++)
this.children.get(k[i]).triggerEvent(eName, args);
}
Component.prototype.addChild = function(cmp) {
if (!cmp || cmp.id == this.id)
return;
cmp.setVisible(this.visible);
this.children.put(cmp.id, cmp);
this.drawAll();
}
Component.prototype.removeChild = function(cmp) {
if (!cmp || cmp.id == this.id || !this.children.containsKey(cmp.id))
return;
this.children.remove(cmp.id);
cmp.setVisible(false);
this.drawAll();
}
Component.prototype.hasChild = function(cmp) {
if (!cmp)
return false;
return this.children.containsKey(cmp.id);
}
Component.Slot = function (name, component) {
this.name = name;
this.component = component;
this.id = ++Component.Slot.lId;
}
Component.Slot.lId = -1;
Component.Slot.prototype.call = function() {
var i, n = new Array();
for (i=0;i<arguments.length;i++)
n.push('arguments[' + i + ']');
eval('this.component.'+this.name+'('+n.join(',')+')');
}
Component.Event = function (name, propagate) {
this.name = name;
this.propagate = propagate;
this.bindings = new Hashtable();
}
Component.Event.prototype.bind = function(slot) {
if (!this.bindings.containsKey(slot.id))
this.bindings.put(slot.id, slot);
}
Component.Event.prototype.detach = function(slot) {
if (this.bindings.containsKey(slot.id))
this.bindings.remove(slot.id);
}
Component.Event.prototype.trigger = function() {
var i, n = new Array();
for (i=0;i<arguments.length;i++)
n.push('arguments[' + i + ']');
var k = this.bindings.keys(), s = n.join(',');
for (i=0;i<k.length;i++)
eval('this.bindings.get('+k[i]+').call('+s+')');
}
//----------------------------------------------------------------------------------------------
// TIMER COMPONENT
//----------------------------------------------------------------------------------------------
Component.Timer = function(miliseconds,repeat) {
if (typeof miliseconds == 'undefined')
return;
Component.apply(this, [false]);
this.miliseconds = miliseconds;
this.repeat = repeat;
this.timer = null;
this.lastAt = 0;
this.pausedAt = 0;
this.locked = false;
this.running = false;
this.newEvent('Tick');
}
Component.Timer.prototype = new Component;
Component.Timer.prototype.start = function() {
while (this.locked) ;
this.locked = true;
if (!this.running)
{
this.running = true;
this.lastAt = new Date().getTime();
eval(this.getCode());
}
this.locked = false;
}
Component.Timer.prototype.stop = function() {
while (this.locked) ;
this.locked = true;
if (this.running)
{
clearTimeout(this.timer);
this.lastAt = this.pausedAt = 0;
this.running = false;
}
this.locked = false;
}
Component.Timer.prototype.restart = function() {
while (this.locked) ;
this.locked = true;
if (this.running)
{
clearTimeout(this.timer);
this.pausedAt = 0;
}
else
this.running = true;
this.lastAt = new Date().getTime();
eval(this.getCode());
this.locked = false;
}
Component.Timer.prototype.pause = function () {
while (this.locked) ;
this.locked = true;
if (this.running)
{
if (this.pausedAt == 0)
{
this.pausedAt = new Date().getTime();
if (this.timer)
clearTimeout(this.timer);
}
else
{
eval(this.getCode());
this.pausedAt = 0;
}
}
this.locked = false;
}
Component.Timer.prototype.tick = function() {
while (this.locked) ;
this.locked = true;
var re;
if (re=(this.running && !this.pausedAt))
{
if (this.repeat)
{
eval(this.getCode());
this.lastAt = new Date().getTime();
}
else
{
this.running = false;
this.timer = null;
this.lastAt = 0;
}
}
this.locked = false;
if (re)
this.onTick();
}
Component.Timer.prototype.getCode = function() {
return this.jsCode() + '.timer=setTimeout("' + this.jsCode() + '.tick()", '
+ (this.pausedAt ? (this.miliseconds - this.pausedAt + this.lastAt) : this.miliseconds)
+ ")";
}
//----------------------------------------------------------------------------------------------
// AJAX COMPONENT
//----------------------------------------------------------------------------------------------
Component.Ajax = function(callName) {
if (typeof callName == 'undefined')
return;
Component.apply(this, [false]);
this.callName = callName;
this.newEvent('Returned');
}
Component.Ajax.prototype = new Component;
Component.Ajax.prototype.call = function() {
eval('Array.prototype.push.apply(arguments,[function(d){'+this.jsCode()+'.onReturned(d)}])');
rpc_doCall(this.callName, arguments);
}
//----------------------------------------------------------------------------------------------
// FORM ELEMENT COMPONENT
//----------------------------------------------------------------------------------------------
Component.Form = {}
Component.Form.Element = function(type, hasContents) {
if (typeof type == "undefined")
return;
Component.apply(this, [false]);
this.type = type;
this.hasContents = hasContents;
this.attributes = new Hashtable();
this.htmlEvents = new Array();
this.value = null;
this.htmlElement = null;
this.setAttribute('name', this.getDocID() + 'f');
this.setAttribute('id', this.getDocID() + 'f');
this.newSlot('hideElement');
this.bindEvent('Hide', 'hideElement');
this.addHTMLEvent('MouseOver');
this.addHTMLEvent('MouseOut');
}
Component.Form.Element.prototype = new Component;
Component.Form.Element.prototype.addChild = function () { }
Component.Form.Element.prototype.hideElement = function () { this.htmlElement = null; }
Component.Form.Element.prototype.setAttribute = function (name,def) { this.attributes.put(name.toLowerCase(), def); this.drawAll(); }
Component.Form.Element.prototype.addHTMLEvent = function (name) { this.htmlEvents.push(name); this.newEvent(name); this.drawAll(); }
Component.Form.Element.prototype.getTag = function () {
var s = '<' + this.type;
var k = this.attributes.keys();
for (var a in k)
{
var av = this.attributes.get(k[a]);
if (av == '')
continue;
s += ' ' + k[a] + '="' + av + '"';
}
var jc = this.jsCode();
for (var ei in this.htmlEvents)
{
var ev = this.htmlEvents[ei];
s += ' on' + ev.toLowerCase() + '="' + jc + '.on' + ev + '(event)"';
}
return s + (this.hasContents ? '>' : '/>');
}
Component.Form.Element.prototype.draw = function () {
var e = this.getElement();
if (!e)
return;
var s = this.getTag();
if (this.hasContents)
s += '</' + this.type + '>';
e.innerHTML = s;
this.htmlElement = document.getElementById(this.attributes.get('id'));
this.updateValue();
}
Component.Form.Element.prototype.updateValue = function (nv) {
if (typeof nv != "undefined")
this.value = nv;
if (this.htmlElement)
this.htmlElement.value = this.value;
}
//----------------------------------------------------------------------------------------------
// LABEL COMPONENT
//----------------------------------------------------------------------------------------------
Component.Form.Label = function(target, text, key) {
if (typeof target == "undefined")
return;
Component.apply(this, [false]);
this.target = target;
this.text = text;
this.key = key;
}
Component.Form.Label.prototype = new Component;
Component.Form.Label.prototype.addChild = function () { }
Component.Form.Label.prototype.draw = function () {
var e = this.getElement();
if (!e)
return;
e.innerHTML = '<label for="' + this.target.getDocID() + 'f"'
+ (this.key ? (' key="' + this.key + '"') : '')
+ '>' + this.text + '</label>';
}
//----------------------------------------------------------------------------------------------
// TEXT INPUT COMPONENT
//----------------------------------------------------------------------------------------------
Component.Form.Text = function (defValue) {
if (typeof defValue == 'undefined')
return;
Component.Form.Element.apply(this, ['input type="text"', false]);
var ev = ['Click', 'KeyUp', 'KeyDown', 'KeyPress', 'Paste'];
this.newSlot('textEvent');
for (var i in ev)
{
this.addHTMLEvent(ev[i]);
this.bindEvent(ev[i], 'textEvent');
}
this.timer = new Component.Timer(500, false);
this.newSlot('timeout');
this.timer.bindEvent('Tick', 'timeout', this);
this.oldValue = this.value = defValue;
this.newEvent('TextChanged');
}
Component.Form.Text.prototype = new Component.Form.Element;
Component.Form.Text.prototype.textEvent = function() {
if (this.htmlElement)
this.value = this.htmlElement.value;
this.timer.restart();
}
Component.Form.Text.prototype.timeout = function() {
if (this.htmlElement)
this.value = this.htmlElement.value;
if (this.value != this.oldValue)
{
this.oldValue = this.value;
this.onTextChanged(this.value);
}
}
Component.Form.Text.prototype.setSize = function (sz) {
this.setAttribute('size', (typeof sz == 'undefined') ? '' : sz);
}
Component.Form.Text.prototype.setMaxLength = function (ml) {
if (typeof ml != "undefined" && this.value.length > ml)
{
this.timer.stop();
this.value = this.value.substr(0, ml);
}
this.setAttribute('maxlength', (typeof ml == 'undefined') ? '' : ml);
}
//----------------------------------------------------------------------------------------------
// CHECKBOX COMPONENT
//----------------------------------------------------------------------------------------------
Component.Form.Checkbox = function (value,name) {
if (typeof value == 'undefined')
return;
Component.Form.Element.apply(this, ['input type="checkbox"', false]);
this.newSlot('check');
this.addHTMLEvent('Click');
this.bindEvent('Click', 'check');
this.newEvent('Checked');
this.newEvent('Unchecked');
this.value = value;
this.checked = false;
this.setAttribute('name', this.group = name);
}
Component.Form.Checkbox.prototype = new Component.Form.Element;
Component.Form.Checkbox.prototype.check = function(evt) {
this.checked = !this.checked;
if (typeof evt == "undefined")
this.drawAll();
if (this.checked) {
this.attributes.put('checked', 'checked');
this.onChecked(this.value, this.group);
} else {
this.attributes.remove('checked');
this.onUnchecked(this.value, this.group);
}
}
//----------------------------------------------------------------------------------------------
// RADIO BUTTON COMPONENT
//----------------------------------------------------------------------------------------------
Component.Form.Radio = function (value,name) {
if (typeof value == 'undefined')
return;
Component.Form.Element.apply(this, ['input type="radio"', false]);
this.newSlot('check');
this.addHTMLEvent('Click');
this.bindEvent('Click', 'check');
this.newEvent('Checked');
this.newEvent('Unchecked');
this.value = value;
this.checked = false;
this.setAttribute('name', this.group = name);
with (Component.Form.Radio.groups)
{
if (!get(name))
put(name, new Array());
get(name).push(this);
}
}
Component.Form.Radio.prototype = new Component.Form.Element;
Component.Form.Radio.groups = new Hashtable();
Component.Form.Radio.prototype.check = function(evt) {
var k = Component.Form.Radio.groups.keys();
for (var i in k)
{
var c = Component.Form.Radio.groups.get(k[i]);
if (c.id != this.id && c.checked)
{
c.checked = false;
c.attributes.put('checked', '');
if (typeof evt == "undefined")
c.drawAll();
c.onUnchecked(c.group, c.value);
break;
}
}
this.checked = true;
this.attributes.put('checked', 'checked');
if (typeof evt == "undefined")
this.drawAll();
this.onChecked(this.value, this.group);
}
//----------------------------------------------------------------------------------------------
// DROP-DOWN COMPONENT
//----------------------------------------------------------------------------------------------
Component.Form.DropDown = function (emptyValue,emptyLabel) {
if (typeof emptyValue == 'undefined')
return;
Component.Form.Element.apply(this, ['select', true]);
this.newSlot('htmlSelect');
this.addHTMLEvent('Change');
this.bindEvent('Change', 'htmlSelect');
this.newEvent('Selected');
this.options = new Array();
this.byValue = new Hashtable();
if (typeof emptyValue != 'string')
emptyValue = emptyValue.toString();
this.emptyValue = emptyValue;
this.emptyLabel = emptyLabel;
this.selected = emptyValue;
}
Component.Form.DropDown.prototype = new Component.Form.Element;
Component.Form.DropDown.prototype.clearOptions = function(redraw) {
this.byValue.clear();
this.options = new Array();
this.selected = this.emptyValue;
}
Component.Form.DropDown.prototype.appendOption = function(value,text) {
if (typeof value != 'string')
value = value.toString();
if (this.byValue.containsKey(value))
return;
this.options.push([value, text]);
this.byValue.put(value, this.options.length - 1);
if (this.selected == this.emptyValue)
this.selected = value;
}
Component.Form.DropDown.prototype.finalize = function() {
this.drawAll();
this.onSelected(this.selected);
}
Component.Form.DropDown.prototype.htmlSelect = function() {
if (this.htmlElement)
{
var se = this.htmlElement.selectedIndex;
this.selected = this.htmlElement.options[se].value;
}
this.onSelected(this.selected);
}
Component.Form.DropDown.prototype.select = function(v) {
if (typeof v != 'string')
v = v.toString();
if (!this.options.length || ! this.byValue.containsKey(v) || this.selected == v)
return;
this.selected = v;
this.drawAll();
this.onSelected(this.selected);
}
Component.Form.DropDown.prototype.updateValue = function() { }
Component.Form.DropDown.prototype.draw = function() {
var e = this.getElement();
if (!e)
return;
var s = '';
if (this.options.length)
for (var i in this.options)
s += '<option value="' + this.options[i][0] + '"'
+ (this.selected == this.options[i][0] ? ' selected="selected"' : '')
+ '>' + this.options[i][1] + '</option>';
else
s = '<option value="' + this.emptyValue + '">' + this.emptyLabel + '</option>';
e.innerHTML = this.getTag() + s + '</select>';
this.htmlElement = document.getElementById(this.attributes.get('id'));
}
//----------------------------------------------------------------------------------------------
// LISTING COMPONENT
//----------------------------------------------------------------------------------------------
Component.Listing = function(rpcName, updateFreq, dataType, cl, rClass, hClass)
{
if (typeof rpcName == 'undefined')
return;
Component.apply(this, [false]);
this.pageCtrl = null;
this.searchCtrl = null;
this.pageSzCtrl = null;
this.dataCache = new Component.Listing.DataCache(this, rpcName, updateFreq, dataType);
this.addChild(this.dataCache);
this.fields = new Hashtable();
this.fLayout = { };
this.rows = 0;
this.cols = 0;
this.mClass = cl;
this.rClass = (rClass ? rClass : '');
this.hClass = (hClass ? hClass : '');
this.finalized = false;
this.sortField = -1;
this.sortDir = false;
this.notFoundText = Component.Listing.notFoundText;
this.loadingText = Component.Listing.loadingText;
this.errorText = Component.Listing.errorText;
}
Component.Listing.prototype = new Component;
Component.Listing.prototype.setPageController = function(c,itg) {
if (this.pageCtrl)
// FIXME, should detach the old controller
return;
this.pageCtrl = c;
this.pageCtrl.bindEvent('PageChanged', 'pageChanged', this.dataCache);
if (itg)
this.addChild(this.pageCtrl);
this.dataCache.pageChanged(this.pageCtrl.currentPage);
}
Component.Listing.prototype.setPageSizeController = function(c,itg) {
if (this.pageSzCtrl)
// FIXME, should detach the old controller
return;
this.pageSzCtrl = c;
this.pageSzCtrl.bindEvent('PageSizeChanged', 'pageSizeChanged', this.dataCache);
if (itg)
this.addChild(this.pageSzCtrl);
this.dataCache.pageSizeChanged(this.pageSzCtrl.currentSize);
}
Component.Listing.prototype.setSearchController = function(c,itg) {
if (this.searchCtrl)
// FIXME, should detach the old controller
return;
this.searchCtrl = c;
this.searchCtrl.bindEvent('SearchChanged', 'searchChanged', this.dataCache);
if (itg)
this.addChild(this.searchCtrl);
this.dataCache.searchChanged(this.searchCtrl.getParameter());
}
Component.Listing.prototype.addField = function(fld) {
var x,y,xe=fld.x+fld.width,ye=fld.y+fld.height;
for (y=fld.y;y<ye;y++)
for (x=fld.x;x<xe;x++)
if (this.fLayout[x+'_'+y])
return;
this.fields[fld.id] = fld;
fld.component = this;
if (fld.sortable) {
if (! this.dataCache.sortField)
this.dataCache.sortField = fld;
fld.bindEvent('Click', 'sortChanged', this.dataCache);
}
for (y=fld.y;y<ye;y++)
for (x=fld.x;x<xe;x++)
this.fLayout[x+'_'+y] = fld;
}
Component.Listing.prototype.finalizeLayout = function() {
var mx = 0, my = 0, x, y;
for (var c in this.fLayout)
{
var cs=c.split('_');
x=parseInt(cs[0],10); y=parseInt(cs[1],10);
if (x>mx)
mx = x;
if (y>my)
my = y;
}
this.rows = my+1; this.cols = mx+1;
for (y=0;y<this.rows;y++)
for (x=0;x<this.cols;x++)
if (!this.fLayout[x+'_'+y])
this.fLayout[x+'_'+y] = new Component.Listing.Spacer(x,y);
this.finalized = true;
}
Component.Listing.prototype.setMaxPage = function (v) {
if (this.pageCtrl)
this.pageCtrl.changeMaxPage(v);
}
Component.Listing.prototype.draw = function () {
var e = this.getElement();
if (!e)
return;
// Draw the listing's header including placeholders for the controllers if that is necessary
var s = '';
var hp = this.hasChild(this.pageCtrl), hs = this.hasChild(this.searchCtrl),
hps = this.hasChild(this.pageSzCtrl), hh = (hp||hs||hps);
if (hh)
{
s += '<table class="' + this.hClass + '">';
if (hp||hps)
{
s += '<tr><td style="width:50%;text-align:center"';
if (hp)
s += ' id="' + this.pageCtrl.getDocID() + '"';
s += '>&nbsp;</td><td style="width:50%;text-align:center"';
if (hps)
s += ' id="' + this.pageSzCtrl.getDocID() + '"';
s += '>&nbsp;</td></tr>';
}
if (hs)
s += '<tr><td style="text-align:center" id="' + this.searchCtrl.getDocID() + '"'
+ ((hp||hps)?' colspan="2"' : '') + '>&nbsp;</td></tr>';
s += '</td></tr></table>';
}
s += '<div id="' + this.id + 'data"></div>';
e.innerHTML = s;
}
Component.Listing.prototype.getHeaders = function () {
var s = '<table class="'+this.mClass+'">';
var lId = -1, x, y, rc = (this.rClass != '' ? (" class='" + this.rClass + "'") : "");
for (y=0;y<this.rows;y++)
{
if (y == 0)
s += '<tr><td><table'+rc+'>';
s += '<tr>';
for (x=0;x<this.cols;x++)
{
var f = this.fLayout[x+'_'+y];
if (f.id == lId || y != f.y)
continue;
lId = f.id;
s += f.getTitle();
}
s += '</tr>' + ((y == this.rows - 1) ? '</table></td></tr>' : '');
}
return s;
}
//----------------------------------------------------------------------------------------------
// LISTING COMPONENT - PAGE CONTROLLER
//----------------------------------------------------------------------------------------------
Component.Listing.PageController = function(text) {
if (typeof text == 'undefined')
return;
Component.apply(this, [false]);
this.text = text;
this.maxPage = 0;
this.addChild(this.select = new Component.Form.DropDown('', '-'));
this.newSlot('selected');
this.select.bindEvent('Selected','selected',this);
this.newSlot('changePage');
this.newSlot('changeMaxPage');
this.newEvent('PageChanged');
}
Component.Listing.PageController.prototype = new Component;
Component.Listing.PageController.prototype.selected = function(v) {
this.changePage(parseInt(v,10));
}
Component.Listing.PageController.prototype.changePage = function(np) {
var op = this.currentPage;
this.currentPage = (np > this.maxPage) ? this.maxPage : np;
if (op != this.currentPage) {
this.select.select(this.currentPage);
this.onPageChanged(this.currentPage);
}
this.drawAll();
}
Component.Listing.PageController.prototype.changeMaxPage = function(nmp) {
var omp = this.maxPage, ocp = this.currentPage;
this.maxPage = nmp;
if (omp != nmp)
{
var i;
this.select.clearOptions();
for (i=0;i<nmp+1;i++)
this.select.appendOption(i, i+1);
this.changePage(this.currentPage);
if (this.currentPage == ocp)
this.drawAll();
}
}
Component.Listing.PageController.prototype.draw = function() {
var e = this.getElement(), id = this.getDocID();
if (!e)
return;
var m, s2;
if (this.maxPage <= 0) {
m = 1;
s2 = '1';
} else {
m = (this.maxPage + 1);
s2 = this.select.html();
}
var s = this.text.replace(/__MP__/, m.toString());
e.innerHTML = s.replace(/__CP__/, s2);
}
//----------------------------------------------------------------------------------------------
// LISTING COMPONENT - PAGE SIZE CONTROLLER
//----------------------------------------------------------------------------------------------
Component.Listing.PageSizeController = function(text, minVal, maxVal, increment) {
if (typeof text == 'undefined')
return;
Component.apply(this, [false]);
this.text = text;
this.currentSize = minVal;
this.addChild(this.select = new Component.Form.DropDown('', '-'));
for (var i=minVal;i<=maxVal;i+=increment)
this.select.appendOption(i, i);
this.newSlot('selected');
this.select.bindEvent('Selected','selected',this);
this.newSlot('changePageSize');
this.newEvent('PageSizeChanged');
}
Component.Listing.PageSizeController.prototype = new Component;
Component.Listing.PageSizeController.prototype.selected = function(v) { this.changePageSize(parseInt(v,10)); }
Component.Listing.PageSizeController.prototype.changePageSize = function(nps) {
var os = this.currentSize;
this.currentSize = nps;
if (os != this.currentSize) {
this.select.select(this.currentSize);
this.onPageSizeChanged(this.currentSize);
}
this.drawAll();
}
Component.Listing.PageSizeController.prototype.draw = function() {
var e = this.getElement(), id = this.getDocID();
if (!e)
return;
e.innerHTML = this.text.replace(/__PS__/, this.select.html());
}
//----------------------------------------------------------------------------------------------
// LISTING COMPONENT - SEARCH CONTROLLER
//----------------------------------------------------------------------------------------------
Component.Listing.SearchController = function(text) {
if (typeof text == 'undefined')
return;
Component.apply(this, [false]);
this.newSlot('textChanged');
this.addChild(this.textField = new Component.Form.Text(''));
this.textField.bindEvent('TextChanged', 'textChanged', this);
this.text = text;
this.newSlot('modeChanged');
this.modes = new Array();
this.mode = -1;
this.newEvent('SearchChanged');
}
Component.Listing.SearchController.prototype = new Component;
Component.Listing.SearchController.prototype.addMode = function (value, text) {
if (typeof this.modes[value] != "undefined")
return;
var c = new Component.Form.Radio(value, this.getDocID() + 'mode');
c.bindEvent('Checked', 'modeChanged', this);
this.addChild(c);
var c2 = new Component.Form.Label(c, text);
this.addChild(c2);
this.modes[value] = [c,c2];
}
Component.Listing.SearchController.prototype.setText = function (text) {
if (text == this.textField.value)
return;
this.textField.updateValue(text);
this.onSearchChanged(this.mode + '!' + text);
}
Component.Listing.SearchController.prototype.setMode = function (mode) {
if (typeof this.modes[mode] == "undefined" || this.mode == mode)
return;
this.modes[mode][0].check();
}
Component.Listing.SearchController.prototype.draw = function () {
var e = this.getElement(), id = this.getDocID();
if (!e)
return;
var s, s2, cd;
s = this.text.replace(/__TF__/, this.textField.html());
if (this.modes.length > 1)
{
s2 = new Array();
for (var i in this.modes)
s2.push(this.modes[i][0].html() + this.modes[i][1].html() + ' ');
s = s.replace(/__MS__/, s2.join(' '));
}
e.innerHTML = s;
}
Component.Listing.SearchController.prototype.textChanged = function (text) { this.onSearchChanged(this.mode + '!' + text); }
Component.Listing.SearchController.prototype.modeChanged = function (mode) { this.onSearchChanged((this.mode=mode) + '!' + this.textField.value); }
Component.Listing.SearchController.prototype.getParameter = function () { return this.mode + '!' + this.textField.value; }
//----------------------------------------------------------------------------------------------
// LISTING COMPONENT - SPACERS
//----------------------------------------------------------------------------------------------
Component.Listing.Spacer = function (x,y,fClass) {
if (typeof x == 'undefined')
return;
Component.apply(this, [true]);
this.fClass = fClass ? fClass : '';
this.attrCode = null;
this.x = x; this.y = y;
this.width = this.height = 1;
this.sortable = false;
this.component = null;
this.newEvent('Click');
}
Component.Listing.Spacer.prototype = new Component;
Component.Listing.Spacer.prototype.getAttributes = function() {
if (typeof this.attrCode == 'string')
return this.attrCode;
var s = '';
if (this.fClass != '')
s += ' class="' + this.fClass + '"';
return (this.attrCode = s);
}
Component.Listing.Spacer.prototype.getData = function() {
return '<td' + this.getAttributes() + '>&nbsp;</td>';
}
Component.Listing.Spacer.prototype.getTitle = function() {
return '<th' + this.getAttributes() + '>&nbsp;</th>';
}
//----------------------------------------------------------------------------------------------
// LISTING COMPONENT - FIELDS
//----------------------------------------------------------------------------------------------
Component.Listing.Field = function (name,sortable,dataField,x,y,w,h,fClass) {
if (typeof name == 'undefined')
return;
Component.Listing.Spacer.apply(this, [x,y,fClass]);
this.name = name;
this.sortable = sortable;
this.dataField = dataField;
this.width = w; this.height = h;
}
Component.Listing.Field.prototype = new Component.Listing.Spacer;
Component.Listing.Field.prototype.getAttributes = function() {
if (typeof this.attrCode == 'string')
return this.attrCode;
var s = '';
if (this.fClass != '')
s += ' class="' + this.fClass + '"';
if (this.width != 1)
s += ' colspan="' + this.width + '"';
if (this.height != 1)
s += ' rowspan="' + this.height + '"';
return (this.attrCode = s);
}
Component.Listing.Field.prototype.getContents = function(d) {
var v;
eval('v=d.' + this.dataField);
if (typeof v != 'string')
v = v.toString();
return v;
}
Component.Listing.Field.prototype.getData = function(d) {
return '<td' + this.getAttributes() + '>' + this.getContents(d) + '</td>';
}
Component.Listing.Field.prototype.getTitle = function() {
var s = '<th' + this.getAttributes();
var srt = (this.sortable && this.component.dataCache.sortField
&& this.component.dataCache.sortField.id == this.id);
if (this.sortable)
s += ' onClick="' + this.jsCode() + '.onClick(Component.list[' + this.id + '])"';
s += '>';
if (srt)
s += '<b>';
s += this.name;
if (srt)
s += '</b><img src="' + staticurl + '/beta5/pics/'
+ (this.component.dataCache.sortDir ? "up" : "down")
+ '_' + color + '.gif" alt="'
+ (this.component.dataCache.sortDir ? "up" : "down") + '"/>';
return s + '</th>';
}
//----------------------------------------------------------------------------------------------
// LISTING COMPONENT - DATA CACHE
//----------------------------------------------------------------------------------------------
Component.Listing.DataCache = function (comp, rpcName, updateFreq, dataType)
{
Component.apply(this, [false]);
this.newSlot('pageChanged');
this.newSlot('pageSizeChanged');
this.newSlot('searchChanged');
this.newSlot('sortChanged');
this.newSlot('pageLoaded');
this.newSlot('checkUpdate');
this.newSlot('initDisplay');
this.newSlot('stopDisplay');
this.newEvent('SettingsChanged');
this.newEvent('Loaded');
this.rpcName = rpcName;
this.dataType = dataType;
this.component = comp;
this.sortField = null;
this.sortDir = false;
this.searchParam = '';
this.perPage = 10;
this.page = 0;
this.current = "";
this.cache = new Hashtable();
this.timer = new Component.Timer(updateFreq * 1000, true);
this.bindEvent('Hide', 'stop', this.timer);
this.bindEvent('Loaded', 'drawAll');
this.bindEvent('SettingsChanged', 'checkUpdate');
this.bindEvent('SettingsChanged', 'drawAll');
this.bindEvent('Show', 'initDisplay');
this.timer.bindEvent('Tick', 'checkUpdate', this);
}
Component.Listing.DataCache.prototype = new Component;
Component.Listing.DataCache.prototype.pageChanged = function (n) {
this.page = n;
this.onSettingsChanged();
}
Component.Listing.DataCache.prototype.pageSizeChanged = function (n) {
this.perPage = n;
this.onSettingsChanged();
}
Component.Listing.DataCache.prototype.searchChanged = function (p) {
this.searchParam = p;
this.onSettingsChanged();
}
Component.Listing.DataCache.prototype.sortChanged = function (col) {
if (this.sortField && col.id == this.sortField.id)
this.sortDir = ! this.sortDir;
else
this.sortField = col;
this.onSettingsChanged();
}
Component.Listing.DataCache.prototype.pageLoaded = function (id) {
if (this.current != id)
return;
this.drawAll();
this.onLoaded();
}
Component.Listing.DataCache.prototype.checkUpdate = function () {
if (!this.visible)
return;
var nid = this.page+'#'+this.perPage+'#'+(this.sortField?this.sortField.dataField:'')+'#'+(this.sortDir?1:0)+'#'+this.searchParam;
var ne;
if (this.cache.containsKey(nid))
ne = this.cache.get(nid);
else {
ne = new Component.Listing.DataCache.Page(this, nid);
ne.bindEvent('Loaded', 'pageLoaded', this);
this.cache.put(nid, ne);
}
this.current = nid;
ne.checkUpdate();
}
Component.Listing.DataCache.prototype.initDisplay = function () {
if (this.timer.running)
return;
this.timer.start();
this.onSettingsChanged();
}
Component.Listing.DataCache.prototype.draw = function () {
var e = document.getElementById(this.component.id + 'data');
if (!(e && this.cache.containsKey(this.current)))
return;
var s = this.component.getHeaders();
var p = this.cache.get(this.current);
if (p.loading)
s += '<tr><td style="text-align:center;padding:10px 0px 10px 0px;">'
+ this.component.loadingText + '</td></tr>';
else if (p.error)
s += '<tr><td style="text-align:center;padding:10px 0px 10px 0px;">'
+ this.component.errorText + '</td></tr>';
else if (p.data.length == 0)
s += '<tr><td style="text-align:center;padding:10px 0px 10px 0px;">'
+ this.component.notFoundText + '</td></tr>';
else {
var rc, i;
rc = (this.component.rClass != '' ? (" class='" + this.component.rClass + "'") : "");
for (i=0;i<p.data.length;i++) {
var lId = -1, x, y;
for (y=0;y<this.component.rows;y++) {
if (y == 0)
s += '<tr><td style="margin:0px;padding:0px"><table'+rc+'>';
s += '<tr' + p.data[i].getRowStyle() + '>';
for (x=0;x<this.component.cols;x++) {
var f = this.component.fLayout[x+'_'+y];
if (f.id == lId || y != f.y)
continue;
lId = f.id;
s += f.getData(p.data[i]);
}
s += '</tr>' + ((y == this.component.rows - 1) ? '</table></td></tr>' : '');
}
}
}
e.innerHTML = s + '</table>';
}
//----------------------------------------------------------------------------------------------
// LISTING COMPONENT - DATA CACHE PAGE
//----------------------------------------------------------------------------------------------
Component.Listing.DataCache.Page = function (cache, param)
{
Component.apply(this, [false]);
this.newSlot('dataReceived');
this.newEvent('Loaded');
this.cache = cache;
this.param = param;
this.loading = true;
this.md5 = "";
this.error = false;
this.data = new Array();
this.call = new Component.Ajax(this.cache.rpcName);
this.call.bindEvent('Returned', 'dataReceived', this);
}
Component.Listing.DataCache.Page.prototype = new Component;
Component.Listing.DataCache.Page.prototype.checkUpdate = function () {
this.loading = true;
this.call.call(this.param, this.md5);
}
Component.Listing.DataCache.Page.prototype.dataReceived = function (data) {
if (data == "") {
this.error = true;
this.data = new Array();
}
else if (data.indexOf("KEEP#") == 0)
this.cache.component.setMaxPage(parseInt(data.substr(5), 10) - 1);
else {
var dataArr = data.split('\n');
var a = dataArr.shift().split('#');
this.md5 = a.shift();
this.cache.component.setMaxPage(parseInt(a.shift(), 10) - 1);
this.data = new Array();
this.error = false;
while (dataArr.length > 0) {
var e = new this.cache.dataType (this.cache, this);
e.parse(dataArr);
this.data.push(e);
}
}
this.loading = false;
this.onLoaded(this.param);
}
//----------------------------------------------------------------------------------------------
// LISTING COMPONENT - GENERIC DATA
//----------------------------------------------------------------------------------------------
Component.Listing.Data = function (cache, page) {
if (typeof cache == "undefined")
return;
Component.apply(this, [false]);
this.cache = cache;
this.page = page;
}
Component.Listing.Data.prototype = new Component;
Component.Listing.Data.prototype.parse = function (data) {
alert("Listing using elemnts without a parse() method\n"
+ "Skipping line: " + data.shift());
}
Component.Listing.Data.prototype.getRowStyle = function () {
return '';
}