Greetings!
I'm trying to make this tool for some fellow librarians who answer questions via text messaging. As you see beneath that page's text box, the catch is that the PC-to-SMS client treats the forward slash as two characters.

I'd like if possible for the JavaScript character counter to recognize slashes and automatically add 'two' to the character count, instead of just one, for each forward slash.

(BTW the reason for 155 instead of 160 is that the client adds a shortcode to our outgoing texts.)

Thanks very much for any help--

Recommended Answers

All 13 Replies

This is the section of JS code which returns the count:

// fieldname, warningname, remainingname, maxchars
function CheckFieldLength(fn,wn,rn,mc) {
  var len = fn.value.length;
  if (len > mc) {
    fn.value = fn.value;
    len = len;
  }
  document.getElementById(wn).innerHTML = len;
  document.getElementById(rn).innerHTML = mc - len;
}

Here is some code which should add 1 to the length of text for every "/" character found, that is each / character will then be counted twice.

// fieldname, warningname, remainingname, maxchars
function CheckFieldLength(fn,wn,rn,mc) {
  var len = fn.value.length;
////////// Add this line ////////////
  len = len + fn.value.match(/\//g).length;
/////////////////////////////////////
 if (len > mc) {
    fn.value = fn.value;
    len = len;
  }
  document.getElementById(wn).innerHTML = len;
  document.getElementById(rn).innerHTML = mc - len;
}

The code is in the file http://faculty.kutztown.edu/rjensen/js/charCount.js.

...there is something in it that breaks the script, instead of escaping the '/'

When I put your line in with a letter, instead of the fwd slash and the escape backslash, it works perfectly: if z is in there it counts double when a z is typed in the text box. Thank you for showing me that; now I'm stuck on trying to make that troublesome slash work.

Now I see more clearly, Simon: your line of code does work, even with the escaped slash: however, the catch is that the script counts nothing until it sees the character that's in your code. In other words, if the string in the textbox lacks a forward slash, the counter does nothing.

You've not just mis-read it have you?

If F is a forward slash, and B is a backward slash, then the line is: len = len + fn.value.match(FBFFg).length; I tested this out by hacking a W3Schools example, which you can find at http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_match_regexp

Just go there, change the lines

var patt1=/ain/gi;
document.write(str.match(patt1));

to

var patt1=/\//g;
document.write(str.match(patt1).length);

..then the example should count the number of slashes in the text line above.

If the example works, and your changed code doesn't, then I'm stuck too. Maybe it's something to do with some other part of the software changing the slash, perhaps also escaping it with a backslash before your subroutine sees it. Maybe, that would explain why a slash counts as two characters?

Guessing wildly here, perhaps if you tried counting occurences of \/ , or using the F B notation as above, for easier reading, try: len = len + fn.value.match(FBBBFFg).length that is F for the regexp opening delimiter, BB for an escaped backslash, BF for an escaped forward slash, F for the regexp closing delimiter, g for global search of the whole string.

Don't you just hate regular expressions?

Now I see more clearly, Simon: your line of code does work, even with the escaped slash: however, the catch is that the script counts nothing until it sees the character that's in your code. In other words, if the string in the textbox lacks a forward slash, the counter does nothing.

I think there was a cross-posting there!

I don't quite understand your problem any more - if the string in the textbox lacks a forward slash, then surely nothing is what it *should* do? Or rather, it should add zero to the count, which is what you want anyway.

Just seen the latest version of your script -

// fieldname, warningname, remainingname, maxchars
function CheckFieldLength(fn,wn,rn,mc) {
 var len = fn.value.length;
 var len = len + fn.value.match(/\//g).length;


  if (len > mc) {
    fn.value = fn.value;
    len = len;
  }
  document.getElementById(wn).innerHTML = len;
  document.getElementById(rn).innerHTML = mc - len;

I don' quite know what the if clause in the middle is doing (nothing?), and I don't know whether re-declaring "var len" twice might be causing a problem, but maybe the script should be simplified to

// fieldname, warningname, remainingname, maxchars
function CheckFieldLength(fn,wn,rn,mc) {

 var len = fn.value.length + fn.value.match(/\//g).length;

  document.getElementById(wn).innerHTML = len;
  document.getElementById(rn).innerHTML = mc - len;
}

You're quite right, Simon: your single line

var len = fn.value.length + fn.value.match(/\//g).length;

does precisely what my awkward two lines did.

While this counts perfectly once a '/' enters the textbox, it unfortunately does no counting till it sees one.

Since the original line

var len = fn.value.length;

by itself counts perfectly when the box has no '/' (i.e. it doesn't know to double for the forward slash), it makes me wonder if an if - else statement might work? Something (that I am clueless how to properly write) sort of like this:

var str= value  // This needs to be whatever's in the text box
var pos=str.IndexOf("\/")
if (pos>=0)
{
var len = fn.value.length + fn.value.match(/\//g).length;
} 
else 
{
var len = fn.value.length
}

Could something like this possibly work? If so, my problem is to get it to read whatever is entered in the box into str. Users will often enter text that has no URL or, most often, a URL at the very end, so they'll want the counter to be keeping a tally from the start even if it doesn't see a slash.

You're quite right, Simon: your single line

var len = fn.value.length + fn.value.match(/\//g).length;

does precisely what my awkward two lines did.

While this counts perfectly once a '/' enters the textbox, it unfortunately does no counting till it sees one.

Since the original line

var len = fn.value.length;

by itself counts perfectly when the box has no '/' (i.e. it doesn't know to double for the forward slash), it makes me wonder if an if - else statement might work? Something (that I am clueless how to properly write) sort of like this:

var str= value  // This needs to be whatever's in the text box
var pos=str.IndexOf("\/")
if (pos>=0)
{
var len = fn.value.length + fn.value.match(/\//g).length;
} 
else 
{
var len = fn.value.length
}

Could something like this possibly work? If so, my problem is to get it to read whatever is entered in the box into str. Users will often enter text that has no URL or, most often, a URL at the very end, so they'll want the counter to be keeping a tally from the start even if it doesn't see a slash.

Ok, this looks like it might be that the match(...) actually returns a null value if no match is found, and the length of a null is probably a null, and adding a null to the original length might give a null or zero, which could explain the problem.

So, your latest approach looks promising, however the slash in the IndexOf shouldn't need escaping, and don't forget to terminate statements with a semicolon. Try this:

// fieldname, warningname, remainingname, maxchars
function CheckFieldLength(fn,wn,rn,mc) {
    var str = fn.value;  // This needs to be whatever's in the text box
    var pos = str.IndexOf("/");
    var len = fn.length;

    if (pos >= 0) {  // Is there a / in the box? If so, add one for every slash found
        len = len + str.match(/\//g).length;
    }
 
    if (len > mc) { // what to do if the length exceeds the max
        // fn.value = fn.value; // this does nothing, what do you want to do here?
        // len = len; // ditto
    }

    document.getElementById(wn).innerHTML = len;
    //(display number of characters used)
    document.getElementById(rn).innerHTML = mc - len;
    //(display number of characters remaining)
}

Hi,
you could also try this:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!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" xml:lang="en-US">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<meta http-equiv="Conent-Style-Type" content="text/css" />
		<meta http-equiv="Content-Script-Type" content="text/javascript" />
		<title>www.daniweb.com [ JS character counter to 'double' certain characters? ]</title>
		<script type="text/javascript">
		// <![CDATA[
		var getObj = ( function( ids ) {
			return document.getElementById( ids ) || document.all[ ids ];


		} );
		
		var selectAll = ( function( oId ) {
			ids = getObj( oId );
				ids.selected = 1;
				ids.select();
		} );

		onload = ( function() {
		var numTxt = getObj( 'charcount' );
		var remTxt = getObj( 'remaining' );
		var txtArea = getObj( 'taMessage' );
			
			txtArea.onkeyup = ( function() {
				
				var slash = this.value.split(/[\/]/).length;	
				var nLen = Number( this.value.length <= 1 ? 0 : this.value.length ) + ( slash <= 1 ? 0 : 

slash - 1 );
				var rLen = 155;
			numTxt.innerHTML =  nLen;
			remTxt.innerHTML = rLen - nLen;
			
			
			} );
		} );

		// ]]>
		</script>
		<style type="text/css">
		/* <![CDATA[ */
		span[id] { font: bold normal normal 100%/1.2 Tahoma, Verdana, Arial, sans-serif; color: #E00; }



		/* ]]> */
		</style>
	</head>
	<body>
		<form id="testform" action="#" method="post" onsubmit="return false;">
			<div>
				<button id="tbtn" name="tbtn" onclick="selectAll('taMessage');">Select All, then copy and 

paste over the mail message</button><br />
				<textarea name="taMessage" id="taMessage" cols="55" rows="7"></textarea>
				<p>
				<span id="charcount">0</span>  characters used | <span id="remaining">155</span> characters 

left
You can use 153 characters &amp; spaces in a single Info Quest
message if you include a URL: each forward slash / counts
as two characters when sent. If no URL is in your message,
155 characters will normally fit—but you should give a source!</p>


			</div>
		</form>

	</body>
</html>

Thank you both for your efforts. Aaargh!

I can't understand why not, but neither solution works to double-count the slash, I'm afraid.

Essential, yours has an additional quirk in that it doesn't begin counting till the 2nd character--not a big deal, by itself. Anyway I've posted your work here. I will study it some more.

Simon, you are absolutely right of course about the redundant lines. So it all boils down to the below--which at least does the basic count properly, though for some reason it doesn't count the slashes twice. :-/

function CheckFieldLength(fn,wn,rn,mc) {
    var str = fn.value;  // This needs to be whatever's in the text box
    var pos = str.IndexOf("/");
    var len = fn.length;

    if (pos >= 0) {  
        len = len + str.match(/\//g).length;
    }

    document.getElementById(wn).innerHTML = len;
    document.getElementById(rn).innerHTML = mc - len;
    }

Essential, when I got home this evening I could see your form in other browsers: even though it doesn't count the "/" double in IE, it does do so perfectly in Firefox and Safari.

Thank you both for your efforts. Aaargh!

I can't understand why not, but neither solution works to double-count the slash, I'm afraid.

Essential, yours has an additional quirk in that it doesn't begin counting till the 2nd character--not a big deal, by itself. Anyway I've posted your work here. I will study it some more.

Simon, you are absolutely right of course about the redundant lines. So it all boils down to the below--which at least does the basic count properly, though for some reason it doesn't count the slashes twice. :-/

function CheckFieldLength(fn,wn,rn,mc) {
    var str = fn.value;  // This needs to be whatever's in the text box
    var pos = str.IndexOf("/");
    var len = fn.length;

    if (pos >= 0) {  
        len = len + str.match(/\//g).length;
    }

    document.getElementById(wn).innerHTML = len;
    document.getElementById(rn).innerHTML = mc - len;
    }

Fourth line needs to be var len = fn.value.length . Now we have two almost working solutions: combining the two, in my function change the middle bit (the if clause) to:

if (pos >= 0) {  
        len = len + str.split(/[\/]/).length;
    }

- this puts Essential's count method (which counts the slashes as double) into your original function (which counts from the first keypress) - then, if you can test it on Firefox (or something not IE!) - if that works, then try on IE.

Sadly and mysteriously (to me, anyway) that script somehow disables the counting entirely.

Essential's solution works in Firefox, Chrome, and Safari; the issues it has in Internet Exploder are a puzzlement but I've placed an onload alert on that test page to warn IE users.

Even though it doesn't work perfectly in IE, this tool is going to be a real aid for our service. I'm marking this "Solved" and after I add proper credit to Simon and Essential I will publish and share the tool with the other participating librarians across the US and Canada. Thanks to you both.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.