M
markszlazak
In the following script, a control displays (black box) in each table
cell once you mouse over the cell. Mouse down on the control to change
the mode of the table. Drag the mouse over cells in the same column
then mouseup anywhere in a cell. The mouseup event sometimres fires
before the selection of table cells by dragging is complete. It's
important that I stop these "false" mouseup's from firing or
distinguish them from when I let go of the mouse button.
<html>
<head>
<title></title>
<style>
#calendar {
position:relative;
top:10;
left:10;
background-color:white;
width:700;
}
.calendarHeader {
background-color:lightgreen;
text-align:center;
font-family:sans-serif;
width:347;
}
.calendarRow {
height:30;
}
#book {
position:absolute;
width:400;
height:200;
color:grey;
background-color:lightyellow;
border:3px grey solid;
font-weight:bold;
font-family:sans-serif;
visibility:hidden;
}
#output {
position:relative;
top:30;
left:10
}
#clear {
position:relative;
top:40;
left:10;
width:80;
background-color:lightgrey;
border:2px black solid;
color:black;
text-align:center;
font-weight:bold;
font-family:sans-serif;
}
</style>
</head>
<body>
<table id='calendar' border='1' cellpadding='0' cellspacing='0'>
<tr>
<td class="calendarHeader">Mark</td>
<td class="calendarHeader">Jennie</td>
</tr>
<tr class='calendarRow'>
<td id='1|Mark'></td>
<td id='1|Jennie'></td>
</tr>
<tr class='calendarRow'>
<td id='2|Mark'></td>
<td id='2|Jennie'></td>
</tr>
<tr class='calendarRow'>
<td id='3|Mark'></td>
<td id='3|Jennie'></td>
</tr>
<tr class='calendarRow'>
<td id='4|Mark'></td>
<td id='4|Jennie'></td>
</tr>
<tr class='calendarRow'>
<td id='5|Mark'></td>
<td id='5|Jennie'></td>
</tr>
<tr class='calendarRow'>
<td id='6|Mark'></td>
<td id='6|Jennie'></td>
</tr>
<tr class='calendarRow'>
<td id='7|Mark'></td>
<td id='7|Jennie'></td>
</tr>
</table>
<div id="output"><textarea cols=50 rows=10></textarea></div>
<div id="clear"
onclick="document.getElementById('output').firstChild.value =
'';">CLEAR</div>
<div id="book" onclick="this.style.visibility = 'hidden';"> </
div>
<script>
var calendar = document.getElementById('calendar'),
slots = calendar.getElementsByTagName('td'),
rows = calendar.getElementsByTagName('tr'),
/*debug*/ output = document.getElementById('output').firstChild;
/*debug*/ output.value = '';
var apt = document.getElementById('book');
apt.appendChild(document.createTextNode(''));
function addWebControl(el) {
var wc = document.createElement('div');
wc.setAttribute('style',
'position:relative; ' +
'background-color:lightgrey;' +
'border-width:1px;' +
'border-color:black; ' +
'border-style:solid; ' +
'margin:0px; ' +
'padding:0px; ' +
'visibility:hidden; ' +
'top:0; ' +
'left:312; ' +
'height:10; ' +
'width:30;');
el.appendChild(wc);
}
var firstSlotSelected = null,
firstInitialState,
drag = false,
columnSelected,
firstRowSelected,
lastRowSelected;
function mousedownHandler(e) { // Handler only on web access control
button inside slot.
var target = getEventTarget(e);
drag = true;
firstInitialState = target.style.backgroundColor;
firstSlotSelected = target.parentNode;
columnSelected = firstSlotSelected.cellIndex;
firstRowSelected = firstSlotSelected.parentNode.rowIndex;
var wcs, bgC = (firstInitialState == 'lightgrey')?
'lightgrey':'white';
target.parentNode.style.backgroundColor = bgC;
(wcs = target.parentNode.firstChild.style).backgroundColor =
(firstInitialState == 'lightgrey')? 'white':'lightgrey';
wcs.visibility = 'hidden';
return false;
}
var highlightedSlot = null;
function mouseoverHandler(e) {
var target = getEventTarget(e);
if (target.nodeName != 'TD') return; // Mouse did not move into
table cell.
/** Find the element the mouse moved from **/
var relTarget = (!e)? nulle.relatedTarget)?
e.relatedTarget:e.fromElement; // Get the element the mouse comes
from.
if (!relTarget) return;
while (relTarget != target && relTarget.nodeName != 'BODY') { // Move
through ancestors until target or BODY found.
relTarget = relTarget.parentNode;
}
if (relTarget == target) return; // Mouse moves from a child
(related target) over the target element.
/** Mouse actually entered TD. Handle event. **/
if (!drag) {
if (highlightedSlot) { // Corrects for mouseout failing to
register with rapid cursor movement.
highlightedSlot.style.backgroundColor =
(highlightedSlot.firstChild.style.backgroundColor == 'lightgrey')?
'white':'lightgrey';
highlightedSlot.firstChild.style.visibility = "hidden";
}
highlightedSlot = target;
target.style.backgroundColor =
(target.firstChild.style.backgroundColor == 'lightgrey')?
'lightyellow':'lightgrey';
target.firstChild.style.visibility = "visible";
}
else {
if (target.cellIndex == columnSelected) {
lastRowSelected = target.parentNode.rowIndex;
var wcs, bgC = (firstInitialState == 'lightgrey')?
'lightgrey':'white';
target.style.backgroundColor = bgC;
(wcs = target.firstChild.style).backgroundColor =
(firstInitialState == 'lightgrey')? 'white':'lightgrey';
wcs.visibility = 'hidden';
}
else {
firstSlotSelected = null;
firstInitialState = null;
firstRowSelected = null;
lastRowSelected = null;
columnSelected = null;
}
}
}
function mouseoutHandler(e) {
var target = getEventTarget(e);
if (target.nodeName != 'TD') return; // Mouse did not move out of
table cell.
/** Find the element the mouse moved to. **/
var relTarget = (!e)? nulle.relatedTarget)?
e.relatedTarget:e.toElement; // Get the element the mouse goes to.
if (!relTarget) return;
while (relTarget != target && relTarget.nodeName != 'BODY') { // Move
through ancestors until target or BODY found.
relTarget = relTarget.parentNode;
}
if (relTarget == target) return; // Mouse moves to a child (related
target) out of the target element.
/** Mouse actually left TD. Handle event. **/
if (drag) {
target.style.backgroundColor =
(target.firstChild.style.backgroundColor == 'lightgrey')?
'white':'lightgrey';
}
else {
highlightedSlot = null;
target.style.backgroundColor =
(target.firstChild.style.backgroundColor == 'lightgrey')?
'white':'lightgrey';
target.firstChild.style.visibility = "hidden";
}
}
function mouseupHandler(e) {
var target = getEventTarget(e);
if (target.nodeName == 'DIV') target = target.parentNode;
/*debug*/ output.value += 'mouseUp\t';
if (drag) {
firstSlotSelected = null;
firstInitialState = null;
firstRowSelected = null;
lastRowSelected = null;
columnSelected = null;
drag = false;
}
else if (target.style.backgroundColor != 'lightgrey' &&
getEventCoordinateX(e) - getElementCoordinateX(target) < 310) {
apt.firstChild.replaceData(1,10,target.id);
apt.style.left = e.clientX + window.pageXOffset;
apt.style.top = e.clientY + window.pageYOffset;
apt.style.visibility = 'visible';
}
}
function getElementCoordinateX(el) {
var x = 0;
while (el) {
x += el.offsetLeft;
el = el.offsetParent;
}
return x;
}
function getEventCoordinateX(e) {
return (typeof e.offsetX != 'undefined')? e.offsetX:e.clientX +
window.pageXOffset;
}
function addEvent(el, evtType, listener, captures) {
if (el.addEventListener) {
el.addEventListener(evtType, listener, captures);
return true;
}
else if (el.attachEvent) {
return el.attachEvent('on' + evtType, listener);
}
else {
el['on' + evtType] = listener;
}
}
function getEventTarget(e) {
return (window.event)? window.event.srcElemente)? e.target:null;
}
for (var i=0; i < slots.length; i++) {
if (slots.id.length > 0) {
addWebControl(slots); // Add web control DIV element as second
child;
addEvent(slots, 'mouseout', mouseoutHandler, false);
addEvent(slots, 'mouseover', mouseoverHandler, false);
addEvent(slots, 'mouseup', mouseupHandler, false);
addEvent(slots.firstChild, 'mousedown', mousedownHandler, false);
}
}
</script>
</body>
</html>
cell once you mouse over the cell. Mouse down on the control to change
the mode of the table. Drag the mouse over cells in the same column
then mouseup anywhere in a cell. The mouseup event sometimres fires
before the selection of table cells by dragging is complete. It's
important that I stop these "false" mouseup's from firing or
distinguish them from when I let go of the mouse button.
<html>
<head>
<title></title>
<style>
#calendar {
position:relative;
top:10;
left:10;
background-color:white;
width:700;
}
.calendarHeader {
background-color:lightgreen;
text-align:center;
font-family:sans-serif;
width:347;
}
.calendarRow {
height:30;
}
#book {
position:absolute;
width:400;
height:200;
color:grey;
background-color:lightyellow;
border:3px grey solid;
font-weight:bold;
font-family:sans-serif;
visibility:hidden;
}
#output {
position:relative;
top:30;
left:10
}
#clear {
position:relative;
top:40;
left:10;
width:80;
background-color:lightgrey;
border:2px black solid;
color:black;
text-align:center;
font-weight:bold;
font-family:sans-serif;
}
</style>
</head>
<body>
<table id='calendar' border='1' cellpadding='0' cellspacing='0'>
<tr>
<td class="calendarHeader">Mark</td>
<td class="calendarHeader">Jennie</td>
</tr>
<tr class='calendarRow'>
<td id='1|Mark'></td>
<td id='1|Jennie'></td>
</tr>
<tr class='calendarRow'>
<td id='2|Mark'></td>
<td id='2|Jennie'></td>
</tr>
<tr class='calendarRow'>
<td id='3|Mark'></td>
<td id='3|Jennie'></td>
</tr>
<tr class='calendarRow'>
<td id='4|Mark'></td>
<td id='4|Jennie'></td>
</tr>
<tr class='calendarRow'>
<td id='5|Mark'></td>
<td id='5|Jennie'></td>
</tr>
<tr class='calendarRow'>
<td id='6|Mark'></td>
<td id='6|Jennie'></td>
</tr>
<tr class='calendarRow'>
<td id='7|Mark'></td>
<td id='7|Jennie'></td>
</tr>
</table>
<div id="output"><textarea cols=50 rows=10></textarea></div>
<div id="clear"
onclick="document.getElementById('output').firstChild.value =
'';">CLEAR</div>
<div id="book" onclick="this.style.visibility = 'hidden';"> </
div>
<script>
var calendar = document.getElementById('calendar'),
slots = calendar.getElementsByTagName('td'),
rows = calendar.getElementsByTagName('tr'),
/*debug*/ output = document.getElementById('output').firstChild;
/*debug*/ output.value = '';
var apt = document.getElementById('book');
apt.appendChild(document.createTextNode(''));
function addWebControl(el) {
var wc = document.createElement('div');
wc.setAttribute('style',
'position:relative; ' +
'background-color:lightgrey;' +
'border-width:1px;' +
'border-color:black; ' +
'border-style:solid; ' +
'margin:0px; ' +
'padding:0px; ' +
'visibility:hidden; ' +
'top:0; ' +
'left:312; ' +
'height:10; ' +
'width:30;');
el.appendChild(wc);
}
var firstSlotSelected = null,
firstInitialState,
drag = false,
columnSelected,
firstRowSelected,
lastRowSelected;
function mousedownHandler(e) { // Handler only on web access control
button inside slot.
var target = getEventTarget(e);
drag = true;
firstInitialState = target.style.backgroundColor;
firstSlotSelected = target.parentNode;
columnSelected = firstSlotSelected.cellIndex;
firstRowSelected = firstSlotSelected.parentNode.rowIndex;
var wcs, bgC = (firstInitialState == 'lightgrey')?
'lightgrey':'white';
target.parentNode.style.backgroundColor = bgC;
(wcs = target.parentNode.firstChild.style).backgroundColor =
(firstInitialState == 'lightgrey')? 'white':'lightgrey';
wcs.visibility = 'hidden';
return false;
}
var highlightedSlot = null;
function mouseoverHandler(e) {
var target = getEventTarget(e);
if (target.nodeName != 'TD') return; // Mouse did not move into
table cell.
/** Find the element the mouse moved from **/
var relTarget = (!e)? nulle.relatedTarget)?
e.relatedTarget:e.fromElement; // Get the element the mouse comes
from.
if (!relTarget) return;
while (relTarget != target && relTarget.nodeName != 'BODY') { // Move
through ancestors until target or BODY found.
relTarget = relTarget.parentNode;
}
if (relTarget == target) return; // Mouse moves from a child
(related target) over the target element.
/** Mouse actually entered TD. Handle event. **/
if (!drag) {
if (highlightedSlot) { // Corrects for mouseout failing to
register with rapid cursor movement.
highlightedSlot.style.backgroundColor =
(highlightedSlot.firstChild.style.backgroundColor == 'lightgrey')?
'white':'lightgrey';
highlightedSlot.firstChild.style.visibility = "hidden";
}
highlightedSlot = target;
target.style.backgroundColor =
(target.firstChild.style.backgroundColor == 'lightgrey')?
'lightyellow':'lightgrey';
target.firstChild.style.visibility = "visible";
}
else {
if (target.cellIndex == columnSelected) {
lastRowSelected = target.parentNode.rowIndex;
var wcs, bgC = (firstInitialState == 'lightgrey')?
'lightgrey':'white';
target.style.backgroundColor = bgC;
(wcs = target.firstChild.style).backgroundColor =
(firstInitialState == 'lightgrey')? 'white':'lightgrey';
wcs.visibility = 'hidden';
}
else {
firstSlotSelected = null;
firstInitialState = null;
firstRowSelected = null;
lastRowSelected = null;
columnSelected = null;
}
}
}
function mouseoutHandler(e) {
var target = getEventTarget(e);
if (target.nodeName != 'TD') return; // Mouse did not move out of
table cell.
/** Find the element the mouse moved to. **/
var relTarget = (!e)? nulle.relatedTarget)?
e.relatedTarget:e.toElement; // Get the element the mouse goes to.
if (!relTarget) return;
while (relTarget != target && relTarget.nodeName != 'BODY') { // Move
through ancestors until target or BODY found.
relTarget = relTarget.parentNode;
}
if (relTarget == target) return; // Mouse moves to a child (related
target) out of the target element.
/** Mouse actually left TD. Handle event. **/
if (drag) {
target.style.backgroundColor =
(target.firstChild.style.backgroundColor == 'lightgrey')?
'white':'lightgrey';
}
else {
highlightedSlot = null;
target.style.backgroundColor =
(target.firstChild.style.backgroundColor == 'lightgrey')?
'white':'lightgrey';
target.firstChild.style.visibility = "hidden";
}
}
function mouseupHandler(e) {
var target = getEventTarget(e);
if (target.nodeName == 'DIV') target = target.parentNode;
/*debug*/ output.value += 'mouseUp\t';
if (drag) {
firstSlotSelected = null;
firstInitialState = null;
firstRowSelected = null;
lastRowSelected = null;
columnSelected = null;
drag = false;
}
else if (target.style.backgroundColor != 'lightgrey' &&
getEventCoordinateX(e) - getElementCoordinateX(target) < 310) {
apt.firstChild.replaceData(1,10,target.id);
apt.style.left = e.clientX + window.pageXOffset;
apt.style.top = e.clientY + window.pageYOffset;
apt.style.visibility = 'visible';
}
}
function getElementCoordinateX(el) {
var x = 0;
while (el) {
x += el.offsetLeft;
el = el.offsetParent;
}
return x;
}
function getEventCoordinateX(e) {
return (typeof e.offsetX != 'undefined')? e.offsetX:e.clientX +
window.pageXOffset;
}
function addEvent(el, evtType, listener, captures) {
if (el.addEventListener) {
el.addEventListener(evtType, listener, captures);
return true;
}
else if (el.attachEvent) {
return el.attachEvent('on' + evtType, listener);
}
else {
el['on' + evtType] = listener;
}
}
function getEventTarget(e) {
return (window.event)? window.event.srcElemente)? e.target:null;
}
for (var i=0; i < slots.length; i++) {
if (slots.id.length > 0) {
addWebControl(slots); // Add web control DIV element as second
child;
addEvent(slots, 'mouseout', mouseoutHandler, false);
addEvent(slots, 'mouseover', mouseoverHandler, false);
addEvent(slots, 'mouseup', mouseupHandler, false);
addEvent(slots.firstChild, 'mousedown', mousedownHandler, false);
}
}
</script>
</body>
</html>