Reputation: 83
I use 2 methods to check that the user is not entering too many characters in a textarea:
1) (passive) PHP:
$textarea = $_POST['textarea'];
if (strlen($textarea)>300){$verify="bad";}
2) (active-whyle typing) Javascript:
function ismaxlength(obj)
{
var mlength=obj.getAttribute? parseInt(obj.getAttribute("maxlength")) : ""
if (obj.getAttribute && obj.value.length>mlength)
obj.value=obj.value.substring(0,mlength)
}
And the textarea itself is as follows (html):
<textarea name="textarea" id="textarea" cols="40" rows="5" style="border: 1px solid #480091; width:460px;" wrap="soft" maxlength="300" onpaste="return ismaxlength(this)" onkeyup="return ismaxlength(this)"></textarea>
Both methods work, except the PHP strlen() function seems to count returns (line breaks) differently than my Javascript function.
Does anyone know how to resolve this, so that they both count the same # characters, regardless of line breaks & spaces, etc.
Thanks a lot!
Upvotes: 8
Views: 9112
Reputation: 10371
@RLJ: Here's another method which prevents the user from entering more text than the maximum length with JavaScript and if JavaScript is off, PHP will print the error message should there be too many characters. This is a sample script I made with the JavaScript function I use (save file as 4575150.php
on your localhost
and test):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>questions/4575150</title>
<script type="text/javascript">
function charsLeft(msgObj, cntObj, chrLen) {
var frmObj = document.getElementById(msgObj);
var cntField = document.getElementById(cntObj);
var maxlimit = chrLen;
var msg = 0;
while (cntField.firstChild) {
cntField.removeChild(cntField.firstChild);
}
if (frmObj.value.length > 0) { msg = frmObj.value.length + 0; }
// IE counts both CR and NL, so just count for NL
var IELength = 0;
if (frmObj.value.length > 0 && frmObj.value.match('\r')) {
splitL = frmObj.value.split('\n').length;
msgL = frmObj.value.length;
if (splitL >= 3) {
IELength = splitL - 1; // splitL >= 3
} else {
IELength = 1;
}
msg = msg - IELength;
}
if (msg > maxlimit) {
cntField.appendChild(document.createTextNode("0 characters left"));
var overflow = msg - maxlimit;
var backspace = frmObj.value.length - overflow;
if (frmObj.value.length > 0 && backspace < 0) {
backspace = backspace * -1;
if (frmObj.value.length < backspace) {
overflow = frmObj.value.length;
} else {
overflow = backspace;
}
} else if (frmObj.value.length == 0 && backspace < 0) {
overflow = 0;
}
frmObj.value = frmObj.value.substring(0, frmObj.value.length - overflow);
} else {
cntField.appendChild(document.createTextNode(maxlimit - msg + " characters left"));
}
}
</script>
<style type="text/css">
html, body, textarea {
font-family: arial, helvetica, sans-serif;
}
body {
font-size: 75%;
}
label {
display: block;
font-weight: bold;
}
form div {
margin: 0 0 10px 0;
}
</style>
</head>
<body>
<?php
define("chars", 15);
$request_method = strtoupper($_SERVER['REQUEST_METHOD']);
if ($request_method == "POST")
{
$text = $_POST['text'];
if (strlen($text) > chars)
{
echo "<p><b>Error:</b> Too many characters! There ";
echo "should be " . chars . ", you've entered ";
echo abs(chars - strlen($text)) . " too many</p>";
}
}
?>
<form action="4575150.php" method="post">
<div>
<label for="text">Text:</label>
<textarea name="text" id="text" style="width: 97%" class="resizable" cols="40" rows="3" onkeydown="charsLeft(this.id, this.id + '_left', <?php echo chars; ?>)" onkeyup="charsLeft(this.id, this.id + '_left', <?php echo chars; ?>)" onkeypress="charsLeft(this.id, this.id + '_left', <?php echo chars; ?>)" onchange="charsLeft(this.id, this.id + '_left', <?php echo chars; ?>)" onfocus="charsLeft(this.id, this.id + '_left', <?php echo chars; ?>)" onblur="charsLeft(this.id, this.id + '_left', <?php echo chars; ?>)"><?php echo $text; ?></textarea>
<div id="text_left"><span><?php echo chars - strlen($text); ?> characters left</span></div>
</div>
<div>
<input type="submit" value="Submit" />
</div>
</form>
</body>
</html>
Upvotes: 1
Reputation: 619
Javascript typically represents line breaks with just the new line character (e.g. /n) while in the browser itself rather than the /r/n pair. However, upon submitting it is represented by /r/n pair (a.k.a. "CR LF") per the HTML 4.01 specification.
Depending on which way you choose to count the line breaks, you may "standardize" the string either client side (e.g. make line breaks count as two characters; should you want the /r/n pairs handled for) or server side (e.g. make it count as one character if you don't care to handle for the /r/n pairs).
My personal pick would be to handle it so that the /r/n is preserved since line breaks are typically represented with these characters in most systems. However, I could see the logic in representing a line break as "one character" to the end user since it is a single keystroke.
Upvotes: 1
Reputation: 11364
You have to convert line breaks first. In JavaScript, a line break is a single newline character. When it is sent, there are two. You can normalize them:
$textarea = $_POST['textarea'];
$textarea = str_replace("\r\n", "\n", $textarea);
$textarea = str_replace("\r", "\n", $textarea);
And then you can count the length of the textarea.
Upvotes: 4
Reputation: 3503
Do you have magic quoting on in php? Try calling get_magic_quotes_gpc().
If you do, then every textual data send to server via GET or POST gets escaped with slashes. This makes characters like ", ', \, $, new line characters to be represented by combination of two characters: \ and the original character or in case of carriage return \r\n.
To use it on server you can filter data like this:
function unslash($string){
if(get_magic_quotes_gpc()){
return stripslashes($string);
}
return $string; // no need to unslash
}
$textarea = unslash($_POST['textarea']);
// the rest of your code
I hope this helps. Ivan
Upvotes: 0