science-ation/js/listSelector.js
2010-06-22 17:14:23 +00:00

240 lines
6.4 KiB
JavaScript

// a generic tool for doing list selection, passing elements between two divs 'left' and 'right'
// the styling needs to be cleaned up a bit, making some options more configurable and others less
function listSelector(left, right, globalName){
var name;
var wrapper;
var leftDiv, rightDiv, leftTitle, rightTitle, leftColours, rightColours;
var items;
var styleTags, boxStyle, itemStyle, rowStyle;
var leftValidator = null;
var rightValidator = null;
this.name = globalName;
this.leftColours = [];
this.rightColours = [];
this.rowStyle = "height:1.2em; margin-top:1px; width:100%;";
this.styleTags = {
'height' : '100%',
};
this.boxStyle = {
'position' : 'absolute',
'width' : '100%',
'height' : '100%',
'line-height' : '1.2em',
'text-align' : 'left'
};
this.boxBackdropStyle = {
'position' : 'absolute',
'width' : '40%',
'height' : '90%',
'background' : '#FFF',
'border' : 'solid 1px',
'overflow' : 'hidden'
}
this.itemStyle = {
'margin-top' : '1px',
'height':'1.2em',
'width':'100%'
};
this.headerStyle = {
'width' : '50%',
'position' : 'absolute',
'text-align' : 'center',
'font-size' : '120%',
'font-weight' : 'bold'
};
this.highlightStyle = {
'background-color' : '#25BEFF'
};
this.unhighlightStyle = {
'background' : 'none'
};
this.drawLeftColumn = function(){
this.leftBackdrop = $('<div id="ls_leftBackdrop"></div>');
this.leftBackdrop.css(this.boxBackdropStyle);
this.leftBackdrop.css({
'top' : '5%',
'left' : '5%',
});
this.leftBackdrop.appendTo(this.wrapper);
this.leftHighlight = $('<div id="ls_leftHighlight"></div>');
this.leftHighlight.css(this.boxStyle);
this.leftHighlight.css({'overflow':'auto'});
this.leftHighlight.appendTo(this.leftBackdrop);
this.leftDiv = $('<div id="ls_leftItems"></div>');
this.leftDiv.css(this.boxStyle);
this.leftDiv.appendTo(this.leftHighlight);
if(this.leftTitle != undefined){
var pos = this.leftDiv.position();
var caption = $('<div>' + this.leftTitle + '</div>');
caption.appendTo(this.wrapper);
caption.css(this.headerStyle);
caption.css({
'left' : pos.left + 'px',
'top' : (pos.top - 15) + 'px'
});
}
// if any highlights were added, place them in the column now
var m = 0;
for(var n in this.leftColours){
while(m < n){
d = $('<div></div>');
d.css(this.itemStyle);
this.leftHighlight.append(d);
m++;
}
d = $('<div style="background-color:' + this.leftColours[n] + '"></div>');
d.css(this.itemStyle);
this.leftHighlight.append(d);
m = 1.0 * n + 1;
}
}
this.drawRightColumn = function(){
this.rightBackdrop = $('<div id="ls_rightBackdrop"></div>');
this.rightBackdrop.css(this.boxBackdropStyle);
this.rightBackdrop.css({
'top' : '5%',
'left' : '55%',
});
this.rightBackdrop.appendTo(this.wrapper);
this.rightHighlight = $('<div id="ls_rightHighlight"></div>');
this.rightHighlight.css(this.boxStyle);
this.rightHighlight.css({'overflow':'auto'});
this.rightHighlight.appendTo(this.rightBackdrop);
this.rightDiv = $('<div id="ls_rightItems"></div>');
this.rightDiv.css(this.boxStyle);
this.rightDiv.appendTo(this.rightHighlight);
if(this.rightTitle != undefined){
var pos = this.rightDiv.position();
var caption = $('<div>' + this.rightTitle + '</div>');
caption.appendTo(this.wrapper);
caption.css(this.headerStyle);
caption.css({
'left' : '50%',
'top' : (pos.top - 15) + 'px'
});
}
// if any highlights were added, place them in the column now
var m = 0, d;
for(var n in this.rightColours){
while(m < n){
d = $('<div></div>');
d.css(this.itemStyle);
this.rightHighlight.append(d);
m++;
}
d = $('<div style="background-color:' + this.rightColours[n] + '"></div>');
d.css(this.itemStyle);
this.rightHighlight.append(d);
m = 1.0 * n + 1;
}
}
this.draw = function(){
this.wrapper = $('<div id="ls_wrapper" style="position:relative"></div>');
this.wrapper.css(this.styleTags);
// create the columns
this.drawLeftColumn();
this.drawRightColumn();
// build our list of selectable items in each column
this.items = [];
for(id in left){
this.items[id] = $('<div id="ls_item_' + id + '">' + left[id] + '</div>');
eval(this.name + '.items[' + id + '].click(function(){' + this.name + '.switch(' + id + ');});');
eval(this.name + '.items[' + id + '].mouseenter(function(){' + this.name + '.highlight(' + id + ', true); document.body.style.cursor="pointer";});');
eval(this.name + '.items[' + id + '].mouseleave(function(){' + this.name + '.highlight(' + id + ', false); document.body.style.cursor="default";});');
this.items[id].css(this.itemStyle);
this.items[id].appendTo(this.leftDiv);
this.items[id].data('column', 'left');
}
for(id in right){
this.items[id] = $('<div id="ls_item_' + id + '">' + right[id] + '</div>');
eval(this.name + '.items[' + id + '].click(function(){' + this.name + '.switch(' + id + ');});');
eval(this.name + '.items[' + id + '].mouseenter(function(){' + this.name + '.highlight(' + id + ', true); document.body.style.cursor="pointer";});');
eval(this.name + '.items[' + id + '].mouseleave(function(){' + this.name + '.highlight(' + id + ', false); document.body.style.cursor="default";});');
this.items[id].css(this.itemStyle);
this.items[id].appendTo(this.rightDiv);
this.items[id].data('column', 'right');
}
return this.wrapper;
}
this.highlight = function(itemId, on){
if(on){
this.items[itemId].css(this.highlightStyle);
}else{
this.items[itemId].css(this.unhighlightStyle);
}
}
this.switch = function(itemId){
item = this.items[itemId];
if(item.data('column') == 'left'){
if(this.rightValidator == null || this.rightValidator(itemId)){
item.data('column', 'right');
this.items[itemId].appendTo(this.rightDiv);
}
}else{
if(this.leftValidator == null || this.leftValidator(itemId)){
item.data('column', 'left');
this.items[itemId].appendTo(this.leftDiv);
}
}
this.highlight(itemId, false);
}
this.setStyle = function(newTags){
for(var n in newTags){
this.styleTags[n] = newTags[n];
}
}
this.getLeftList = function(){
return this.getList('left');
}
this.getRightList = function(){
return this.getList('right');
}
this.getList = function(side){
var returnval = [];
var n = 0;
for(id in this.items){
if(this.items[id].data('column') == side){
returnval[n] = id;
n++;
}
}
return returnval;
}
}