I have some span textual elements that, when clicked, turn to a form
element that can be modified and submited (specifically, you can
change the month/year of a calendar directly from the label itself,
and then go to that month/year in a snap).
Easier said than done.
the issue is functional. I got the DOM element to change, but when
clicking anywhere in the document I would like the span to convert
back to it's original textual state and (obviously) not submit the
form. I thought this would be a reasonable attempt:
<body onclick='javascript:edit("none");'><table>
Do a global replace to remove "javascript:" as it isn't needed.
<tr><td colspan=8 align=center><h2><form method=post>
Don't abuse headlines. These look like TH elements to me and those
appear bold by default in most browsers.
<span id='month' onclick='javascript:edit("month");'>October</
span>
<span id='year' onclick='javascript:edit("year");'>2006</span>
</form></h2></td>
</tr>
I can't imagine what this "edit" function looks like.
...
<!-- the table continue with each day label et cetera. -->
What happens when clicking the month text is that the edit("month")
gets called, then the edit("none") directly after, so the element
doesn't change at all. This is something I kind of expected going into
it, but thought i'd give it a shot and see if the parent object would
get called first. Is there any way to
As you have seen, it won't get called first. Events bubble up through
the DOM, not down.
modify this order of operations
here, or what have other people done to mitigate/resolve this issue.
Here is an example that illustrates how to handle event bubbling
(among other things.) It works without scripting and/or style
enabled. One caveat: very old browsers (eg IE4) will display both a
span and an input when scripting is enabled and style is not.
BTW, if you don't understand the example, you can just use CSS to
style the inputs like labels and use a submit button to update the
calendar.
<html>
<head>
<title>Label Edit</title>
<script type="text/javascript">
if (document.getElementsByTagName &&
document.getElementsByTagName('html') &&
document.getElementsByTagName('html')[0] &&
document.getElementsByTagName('html')[0].style &&
typeof(document.getElementsByTagName('html')[0].style.visibility) ==
'string') {
document.write('<style type="text/css">#myform {visibility:hidden}
#myform input {border:none}<\/style>');
var oldOnLoad = window.onload;
window.onload = function() {
var editing = {};
var frm = document.forms.myform;
var getComputedStyle = function() {
if (document.defaultView && document.defaultView.getComputedStyle)
{
return function(el, style) { var css =
document.defaultView.getComputedStyle(el, null); if (css) { return
(css[style])?css[style]:null; } else { return null; } };
}
else {
return function(el, style) { return (el.currentStyle)?
el.currentStyle[style]:null; };
}
}();
var setText = function() {
if (document.createTextNode) {
return function(el, text) { if (el.appendChild)
{ el.appendChild(document.createTextNode(text)); return true; } };
}
else {
return function(el, text) { if (typeof(el.innerHTML) == 'string')
{ el.innerHTML = text; return true; } };
}
}();
function cancelPropagation(e) {
e = e || window.event;
if (e.stopPropagation) { e.stopPropagation(); }
e.cancelBubble = true;
}
function cancelEdit() {
for (var id in editing) {
if (editing[id]) {
frm.elements[id].style.display = 'none';
editing[id].style.display = 'inline';
editing[id] = null;
}
}
}
function inputKeyPress(e) {
e = e || window.event;
var key = (typeof(e.which) == 'undefined')?e.keyCode:e.which;
if (key == 13) {
this.form.submit();
return false;
}
else {
if (key == 27) { cancelEdit(); }
}
}
function edit(e) {
if (this.id) {
this.style.display = 'none';
frm.elements[this.id].style.display = 'inline';
frm.elements[this.id].focus();
editing[this.id] = this;
}
cancelPropagation(e);
return false;
}
if (frm) {
var formStyle = getComputedStyle(frm, 'visibility');
var useCSSToSwap = (formStyle === null || formStyle ==
'hidden'); // assumes style enabled if can't tell
var anchors = frm.getElementsByTagName('a');
if (anchors && anchors.length && anchors[0].style &&
typeof(anchors[0].style.display) == 'string') {
var el;
var dontNeedSubmitButton;
for (var i = anchors.length - 1; i >= 0; i--) {
if (anchors
.id && (el = frm.elements[anchors.id])) {
if (useCSSToSwap && setText(anchors, el.value)) {
anchors.onclick = edit;
anchors.href = "#";
anchors.tabIndex = 0;
el.onclick = cancelPropagation;
el.style.display = 'none';
}
el.onkeypress = inputKeyPress;
dontNeedSubmitButton = true;
}
}
if (dontNeedSubmitButton) {
el = frm.elements.change;
if (el) { el.style.display = 'none'; }
}
frm.style.visibility = 'visible';
document.onclick = cancelEdit;
el = null;
anchors = null;
}
}
window.onunload = function() { // Check for circular reference
for (var id in editing) {
if (editing[id]) { editing[id].onclick = null; } // Prevent IE
memory leak
}
};
if (oldOnLoad) { oldOnLoad(); }
};
}
</script>
</head>
<body>
<form id="myform" name="myform" method="post">
<a id="month" title="Edit month"></a><input name="month"
value="October"> <a title="Edit year" id="year"></a><input
name="year" value="2006"> <input type="submit" name="change"
value="Change">
</form>
</body>
</html>