s.b37, got to say, that is an odd function you have for the onload. Wouldn't you be better doing it with event handlers? It would also not work if someone had set the onload attribute of the <body> tag.
Either way, not being picky, just seemed a little odd to me.
ok, I thought I would give this a shot, however I had to think of a different way to do it compared to everyone else's, so it's probably not the most ideal way (and certainly isn't accessible) however it is different and we all know kids that that's what matters! :P
HTML Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><title>:: w00t ::</title><script type="text/javascript">
function monthGenerator(parentContainer, selectName, shortDateFormat) {
// parentContainer can be either a string or an object reference (required)
// selectName is the name attribute of the element (optional - default="month")
// shortDateFormat will output using 3 characters or the full name( optional - default=false;)
this.months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
this.date = new Date();
this.init = function(container, name, format) {
// allows the user to pass an object or an id string for the parent container
if (typeof(container)=="string")
container = document.getElementById(container);
// ok, if the string id was wrong or the element was null, we need to return a null value;
if (!container) return false;
// declare the variables required
var oSelect = document.createElement("select"), oOption, monthText;
// as this is a form element, it will need a name for submission, if none is given a default is set
oSelect.name = name?name:"month";
// loop through the months and append the month <option>'s
for (var monthIndex=0;monthIndex<this.months.length;monthIndex++) {
oOption = document.createElement("option");
monthText = this.months[(this.date.getMonth()+monthIndex)%this.months.length];
if (shortDateFormat) monthText = monthText.substr(0,3);
oOption.value = monthText;
// this should just be the .text property but thanks to IE, I need to do it differently
oOption.appendChild(document.createTextNode(monthText));
oSelect.appendChild(oOption);
if (!monthIndex) oOption.selected = true;
}
// finally add the select into it's container.
container.appendChild(oSelect);
// return a reference to our select
return oSelect;
}
// call the function to generate the select, returning either a null value or our select.
return this.init(parentContainer, selectName, shortDateFormat);
}
// I am declaring this as a global for this example, obviously it all depends on the scope of where you call it from.
// and in fact, if you are never going to reference the select again it's not needed at all.
var mySelect;
window.onload = function() {
mySelect = monthGenerator("container","mySelect",true);
}
</script></head><body><!-- the container for the select --><div id="container"></div><!-- a simple example showing that the referece was returned from the generation function --><input type="button" onclick="alert(mySelect.innerHTML)" value="click me!"/></body></html>
Flame away! It's longer than other's (hell, that's what all the girls say!) but if you removed the comments it would be cut down a fair bit.
One annoyance with IE is that you can't set the .text property when dynamically adding content into an <option>, so that's why I used the createTextNode method. I could as easily used .innerHTML too but the DOM method looked a little nicer..
Edit: Tested on WinXP using FF2/IE6/Op9 without problems.
Last edited by ricp; 04-15-2007 at 06:27 AM.
Essential Links: DOM | JS | CSS
--- #javascript on EfNet:Direct Link
--- I've known you since you were a twenty, and I was twenty, and thought that some years from now, a purple little, little, lady will be perfect, for this dirty old and useless clown... Gogol Bordello
s.b37, got to say, that is an odd function you have for the onload. Wouldn't you be better doing it with event handlers? It would also not work if someone had set the onload attribute of the <body> tag.
Either way, not being picky, just seemed a little odd to me.
ok, I thought I would give this a shot, however I had to think of a different way to do it compared to everyone else's, so it's probably not the most ideal way (and certainly isn't accessible) however it is different and we all know kids that that's what matters! :P
HTML Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><title>:: w00t ::</title><script type="text/javascript">
function monthGenerator(parentContainer, selectName, shortDateFormat) {
// parentContainer can be either a string or an object reference (required)
// selectName is the name attribute of the element (optional - default="month")
// shortDateFormat will output using 3 characters or the full name( optional - default=false;)
this.months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
this.date = new Date();
this.init = function(container, name, format) {
// allows the user to pass an object or an id string for the parent container
if (typeof(container)=="string")
container = document.getElementById(container);
// ok, if the string id was wrong or the element was null, we need to return a null value;
if (!container) return false;
// declare the variables required
var oSelect = document.createElement("select"), oOption, monthText;
// as this is a form element, it will need a name for submission, if none is given a default is set
oSelect.name = name?name:"month";
// loop through the months and append the month <option>'s
for (var monthIndex=0;monthIndex<this.months.length;monthIndex++) {
oOption = document.createElement("option");
monthText = this.months[(this.date.getMonth()+monthIndex)%this.months.length];
if (shortDateFormat) monthText = monthText.substr(0,3);
oOption.value = monthText;
// this should just be the .text property but thanks to IE, I need to do it differently
oOption.appendChild(document.createTextNode(monthText));
oSelect.appendChild(oOption);
if (!monthIndex) oOption.selected = true;
}
// finally add the select into it's container.
container.appendChild(oSelect);
// return a reference to our select
return oSelect;
}
// call the function to generate the select, returning either a null value or our select.
return this.init(parentContainer, selectName, shortDateFormat);
}
// I am declaring this as a global for this example, obviously it all depends on the scope of where you call it from.
// and in fact, if you are never going to reference the select again it's not needed at all.
var mySelect;
window.onload = function() {
mySelect = monthGenerator("container","mySelect",true);
}
</script></head><body><!-- the container for the select --><div id="container"></div><!-- a simple example showing that the referece was returned from the generation function --><input type="button" onclick="alert(mySelect.innerHTML)" value="click me!"/></body></html>
Flame away! It's longer than other's (hell, that's what all the girls say!) but if you removed the comments it would be cut down a fair bit.
One annoyance with IE is that you can't set the .text property when dynamically adding content into an <option>, so that's why I used the createTextNode method. I could as easily used .innerHTML too but the DOM method looked a little nicer..
Edit: Tested on WinXP using FF2/IE6/Op9 without problems.
It will work in those browsers without problems if the user has JS enabled, but if they don't then they dont have a select object to choose from. I would suggest having a default select object in the body already, and then use replaceChild() to replace that select with your dynamic one if JS is enabled.
Yup, I agree. Accessibility must be considered when doing JavaScript.
I only really done that as a bit of fun.
Essential Links: DOM | JS | CSS
--- #javascript on EfNet:Direct Link
--- I've known you since you were a twenty, and I was twenty, and thought that some years from now, a purple little, little, lady will be perfect, for this dirty old and useless clown... Gogol Bordello
i did use html code, and ricp's code colouring is wacky as well
oh and my function allows you to add many functions not at the same time to execute on window.onload
this makes the script more friendly to other scripts as well as allowing a script to declare an onload handler anywhere
s.b37, wouldn't that be better achieved with event handlers though? It not only allows you to set them without needing to concat any previous literal setting of the onload, plus it allows you to remove assignments.
I am not denying it wouldn't work, just I think I would have done it differently with the handlers.
Essential Links: DOM | JS | CSS
--- #javascript on EfNet:Direct Link
--- I've known you since you were a twenty, and I was twenty, and thought that some years from now, a purple little, little, lady will be perfect, for this dirty old and useless clown... Gogol Bordello
Yes, I use Simon's script because I have another script that also uses the onload function. That way, I can just add it to the submitted script and it will work just great.
O.k., is everybody ready for another one? This should be simple. I'm just trying to see if there is a more simple, clean, efficient way to do this:
From: Blinking Textbox Effect
Code:
function blinkExecute(target,color){
document.getElementById(target).style.backgroundColor = color;
}
function blinkBlink (target){
color1 = "#feff6f"; // blinking color
color2 = "#ffffff"; // background color
setTimeout('blinkExecute("'+target+'","'+color1+'")',0);
setTimeout('blinkExecute("'+target+'","'+color2+'")',500);
setTimeout('blinkExecute("'+target+'","'+color1+'")',1000);
setTimeout('blinkExecute("'+target+'","'+color2+'")',1500);
setTimeout('blinkExecute("'+target+'","'+color1+'")',2000);
setTimeout('blinkExecute("'+target+'","'+color2+'")',2500);
setTimeout('blinkExecute("'+target+'","'+color1+'")',3000);
setTimeout('blinkExecute("'+target+'","'+color2+'")',3500);
setTimeout('blinkExecute("'+target+'","'+color1+'")',4000);
setTimeout('blinkExecute("'+target+'","'+color2+'")',4500);
document.getElementById(target).focus();
}
// THIS PART BELOW DOESN'T NEED TO BE CHANGED UNLESS THE ONLOAD
// EVENT IS CHANGED
// Multiple onload function created by: Simon Willison
// http://simon.incutio.com/archive/2004/05/26/addLoadEvent
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
addLoadEvent(function() {
blinkBlink('name');
});
I'd hate to waste two functions on this.
You may as well allow (optionally) setting the color and the number of 'blinks'.
Pass the arguments in a single string, suitable for a timeout argument.
You can 'blink' the background of any element, but those that can receive focus will get it after the blinking is done.
test cases-
Blink('name')
Blink('name,red,16')
(The duration is the total on and off blinks)
The following is MrHoo's code minus useless count variable - obviously I'm not after credit for this.
HTML Code:
function Blink(args){
args= (/,/.test(args))? args.split(/,/): [args,'yellow',10];
var who=document.getElementById(args[0]);
if(args[2]==0){
if(who.focus) who.focus();
}
else{
who.style.backgroundColor=(--args[2]%2==0)? '': args[1];
args='\"'+args.join(',')+'\"';
setTimeout("Blink("+args+")",500);
}
}
The problem with this code is that the focus is set at the end instead of at the beginning, and I'm guessing an optimisation should not cause any behavioural changes.
cridley,
the focus is not called until the blink stops- lots of focus events have their own handlers, and you don't want them called repeatedly.
The reason for a separate count variable is that it explicitly converts a string to an integer.
Some browsers will return NaN for a string with the % operator,
and sometimes joining a number member at the end of an array of strings
throws a missing']' error.
I'll use yours with a slight change -- I added the onload handler and removed the portion from the onclick event. (Not sure why that was there in the first place.)
Code:
window.Blink = function(args){
args = (/,/.test(args))? args.split(/,/): [args,'yellow',10];
var who = document.getElementById(args[0]);
var count = parseInt(args[2]);
if (--count <=0) {
who.style.backgroundColor = '';
if(who.focus) who.focus();
} else {
args[2]=count+'';
who.style.backgroundColor=(count%2==0)? '': args[1];
args='\"'+args.join(',')+'\"';
setTimeout("Blink("+args+")",500);
}
}
// Multiple onload function created by: Simon Willison
// http://simon.incutio.com/archive/2004/05/26/addLoadEvent
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
addLoadEvent(function() {
Blink('name');
});
If you want to keep the inline event attributes (converting this to unobtrusive JS is a bit more work but not too hard):
Code:
This field will not accept special characters: (like !@#$%^&* etc)
<br>
<textarea rows=2 cols=20 onKeypress=
"var c = event.keyCode || event.charCode; return !((c > 32 && c < 48) || (c > 57 && c < 65) || (c > 90 && c < 97))">
</textarea>
<br><br>
This field will not accept double or single quotes:
<br>
<input onKeypress="var c = event.keyCode || event.charCode; return c != 34 && c != 39">
<br><br>
This field will only accept numbers:
<br>
<input onKeypress="var c = event.keyCode || event.charCode; return c >= 48 && c <= 57">
This removes NN4 support, if that's not desirable then simply replace all occurences of event.charCode with event.which.
Bookmarks