PDA

View Full Version : [DHTML] Form Field Limiter



Twey
04-07-2007, 05:23 PM
1) CODE TITLE: Form Field Limiter

2) AUTHOR NAME/NOTES: Twey, http://www.twey.co.uk/

3) DESCRIPTION: An object to control limited-length form fields, with a great deal more flexibility than that offered by the HTML maxlen attribute.

4) URL TO CODE: http://www.twey.co.uk/?q=limiter

mburt
04-07-2007, 05:25 PM
Nice script. This will be useful, considering alot of people ask how to do this.
Wouldn't the basic object.substring(0,maxlength); work though? :p

Twey
04-07-2007, 05:33 PM
Hey, it wasn't my idea, I just rewrote this (http://dynamicdrive.com/dynamicindex16/limitinput.htm) piece of crud :)

mburt
04-07-2007, 05:51 PM
Err... what's wrong with:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>max length</title>
<script type="text/javascript">
function loadMax(el,max) {
var end = document.createElement("div");
el.load = function() {
var charc = max-el.value.length,str=document.createTextNode("There are "+charc+" characters remaining.");
while (f=end.firstChild) end.removeChild(f);
end.appendChild(str);
}
el.load();
el.parentNode.appendChild(end);
el.onkeydown = function() {
el.value=el.value.substring(0,max);
el.load();
}
}
</script>
</head>
<body>
<form name="myForm">
<input type="text" name="foo">
</form>
<script type="text/javascript">
loadMax(document.forms['myForm'].foo,10);
</script>
</body>
</html>

//EDIT: created a work-around for the weird positioning:

<form name="myForm">
<div>
<input type="text" name="foo">
</div>
<div>
<textarea name="test"></textarea>
</div>
</form>

Twey
04-07-2007, 06:09 PM
Several big fat memory leaks in IE, for a start :) Also, doesn't offer any more flexibility than the original, it's still difficult to position the output correctly, doesn't give any options to style the output, doesn't indicate the length limit to non-JS browsers, &c. Most of those aren't problems, of course, per se, but just features found in mine and not that one... why'd you rewrite it again? Go and find your own antiquated script to do up :p

mburt
04-07-2007, 06:13 PM
Technically I didn't rewrite it... I started from scratch :p (not incredibly hard, by the way). I'll have a closer look at yours, but to be honest, it looked exactly the same as the old one.
I'm just saying mine is simpler, nothing less.

And what exactly is this "big fat" security leak in IE?

Twey
04-07-2007, 06:19 PM
The effect is the same (with a couple of optional extras), but it's achieved using better code: "rewritten."
And what exactly is this "big" security leak in IE?You've got a DOM element trapped in the onkeydown() and load() closures, and also referenced circularly by both: el references load references el.

mburt
04-07-2007, 06:23 PM
and also referenced circularly by both: el references load references el.
Actually, it doesn't.
el.load():

var charc = max-el.value.length,str=document.createTextNode("There are "+charc+" characters remaining.");
while (f=end.firstChild) end.removeChild(f);
end.appendChild(str);
All it does is set the charc variable, nothing else. It doesn't once use el as a reference, it's just an "updating" function later called in the onkeydown() handler. I don't know how this would end up in a loop. Could you clarify? (sorry if I'm being annoying, but I don't really understand)

Twey
04-07-2007, 07:00 PM
It doesn't matter, it's a closure, it has access to every variable in the scope in which it was created, which includes el.

mburt
04-07-2007, 07:24 PM
Okay... makes sense. Doesn't seem to have much of a negative effect though.

DimX
04-07-2007, 07:40 PM
One thing annoys me though: the onkeyup event is used, so when the maximum length gets exceeded, the last (disallowed) character still shows up for a moment.
And when I keep the key pressed, the character keeps being added to the field until the key is released, then the field gets trimed.

mburt
04-07-2007, 08:07 PM
That's why, in my example I used onkeydown().

Twey
04-07-2007, 08:33 PM
That's why, in my example I used onkeydown().But then if you hold the key down, it never gets trimmed. The only way to make sure it's always updated is to use setInterval() to check regularly, but this is terribly inefficient.

DimX
04-07-2007, 08:49 PM
But then if you hold the key down, it never gets trimmed.
Why so? The keydown/keypress events keep firing continuously while the key is pressed.

Edit:
A simplest example that works:

<input type="text" onkeypress="return this.value.length < 5" />

Edit:
Whoops, okay, this example isn't perfect (you can't delete text when field is full), but the onkeypress event still works as expected.

mburt
04-07-2007, 09:05 PM
Just call the function initially using window.onload or equivalent. Then it will have the desired effect.

Twey
04-07-2007, 09:38 PM
Why so? The keydown/keypress events keep firing continuously while the key is pressed.keypress does, keydown doesn't. Also, keypress still suffers from the validation problem: it's only called after the new data is entered. The inability to delete or navigate through text when the field is full is another problem with returning false. If we combine keypress and keyup, we can lessen the appearance of the extra characters (sample updated), but one still appears due to keypress validating before the effect.

DimX
04-07-2007, 09:54 PM
keypress does, keydown doesn't.
Hmm, in IE and Firefox keydown also does, in Opera not.

Also, keypress still suffers from the validation problem: it's only called after the new data is entered.
It's not, it's called before the new data is inserted.

Twey
04-07-2007, 10:17 PM
Er, yes, sorry. Thought one thing and typed another.
Hmm, in IE and Firefox keydown also does, in Opera not.In Konqueror it doesn't either.

djr33
04-07-2007, 10:47 PM
Works great, but pasting (with CTRL+V and similar methods, probably) gets around it.

Twey
04-07-2007, 10:54 PM
Not ctrl-V, but right-clicking and clicking "paste" would. That's not really an issue though, it's not meant to be a secure solution (we'd be in some trouble if it were :p The only thing it needs to do is provide some indication to the user when they've gone over the limit and it's pointless to type any more.

djr33
04-07-2007, 11:01 PM
CMND (apple key) + V works with Safari.

I'm not claiming it's a big issue, but if someone were to copy and paste something into the field (such as a prewritten description of something), then it would be cut without becoming obvious to them before submitting.

Why not just add an onChange attribute, so that it changes when typing and also checks after it is blurred and changed.

mburt
04-07-2007, 11:53 PM
Or a setTimeout() to update the values, and cut accordingly.

djr33
04-08-2007, 12:16 AM
Why? It would work, but that would just be more things running in the background.
We know that onChange will only run when it's changed. It would run each time it's changed, but not the entire time that the page is up.

Twey
04-08-2007, 12:19 AM
I think that with onkeyup, onkeypress, and onchange, we should be adequately covered, if in danger of suffocating the user's browser in event hooks :) Updated.

djr33
04-08-2007, 12:33 AM
Seems just fine to me. The only thing I'd say is that you might want to consider a reaction to CTRL+V specifically, so it's more immediate.

Anyway, it's certainly comprehensive enough at this point.