UPDATE:
I'm an idiot. the proper thing to set is "maxLength", "maxlength" just won't do. The obvious way works now, and thanks to the
Dark Shell I will be able to catch these things without all the frustration. Here's the original post, if anyone wishes to revel in my chasing red herrings to the ends of the earth.
On the heels of Nathan's posts about the Inappropriate Expletive
browser, here's a rant of mine from a few days back.
The task at hand was relatively simple. There are 4 textboxes for taking a single credit card number, with a dropdown
for what type of credit card. When the dropdown says "American Express", the boxes should limit input to 4 letters in the first box, 3 in second,
3 in the third, and then 5 in the last. When the dropdown is anything else, it should limit input to 4 letters in each.
I figure I can just hook the onchange event of the dropdown, and then if we're American Express, change the maxlength
attribute of the boxes. The javascript looked something like this:
function setLength(id, length){
document.getElementById(id).setAttribute('maxlength', length);
}
function creditCardChanged(cardType){
if(cardType == 'American Express'){
setLength('cc1', 4);
setLength('cc2', 3);
setLength('cc3', 3);
setLength('cc4', 5);
}
else{
setLength('cc1', 4);
setLength('cc2', 4);
setLength('cc3', 4);
setLength('cc4', 4);
}
}
What I wrote before was more dense, but I don't have that code anymore, and this is easier to read. Now, this worked fine in Firefox, and everything
was good.
Then I tried it in IE, and found that the maxlength attribute is only processed by the rendering engine when the page first loads. Any
attempts to change it after the page has loaded are completely ignored. I tried several different methods of setting the attribute, and none of them
worked. The code doesn't throw an exception, it just doesn't work. I guess someone decided
that maxlength is immutable. Good job guys, and now I have to figure out a non-obvious, unneccesarily complicated solution.
Some googling revealing a post from 2002 by "nitwit" on how to
Dynamicly set maxlength of input text. Spelling errors aside, it did indeed work. Here's the IE-compatible solution:
- Hook the
onkeypress event on each textbox
- In that event handler, check the length of the current value of the text box.
- If we have room for one more character before reaching our limit, return
true so the keypress will succeed.
I made some modifications to his code to pull the character limit from a custom attribute on the textbox, "my_maxlength".
function ChangedCreditCard(ddl){
function setLength(id, len, clear){
var box = document.getElementById(id);
box.setAttribute('my_maxlength', len);
box.setAttribute('size', len);
if (clear) box.value = '';
}
var cardType = ddl.options[ddl.selectedIndex].value;
if(cardType == "2"){
setLength('cc1', 4, 1)
setLength('cc2', 3, 1)
setLength('cc3', 3, 1)
setLength('cc4', 5, 1)
}
else{
setLength('cc1', 4)
setLength('cc2', 4)
setLength('cc3', 4)
setLength('cc4', 4)
}
}
function limitMe(evt, txt){
if (evt.which && evt.which == 8) return true; // allow Netscape backspace
else return txt.value.length < txt.getAttribute('my_maxlength') ;
}
So, the proper way to change
maxlength with IE is to reimplement
maxlength.
Congratulations IE, you stole yet another hour of my life.