Ask a Jedi: Counting words in a textarea

Pema asks:

Is there an easy way to count the number of words in a textarea using ColdFusion?

The quick and not very helpful answer to this is no. ColdFusion is a server side language. It can’t introspect anything in a form field until you actually submit the value. But can we do it both client side and server side? Sure! Here is a simple example. I began with a very simple form.

<form method="post"> <textarea name="body" id="body"></textarea> <input type="submit"><br/> <span id="count"></span> </form>

Notice I’ve added a span under my textarea. This span will be used to print out the number of words in the textarea. Now to hook up the JavaScript:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script>

$(document).ready(function() {

var status = $("#count")

$("#body").keyup(function() {
    var cVal = $(this).val()
cVal = $.trim(cVal)
if(cVal.length == 0) return
cVal = cVal.replace(/['\.\?"]/,"")
var words = cVal.split(/\W/)
status.text("You've written "+words.length+" word(s).")
}) })

</script> </code>

I begin by including the CDN version of jQuery. The main thing I want to do is monitor the textarea, but I know that I’ll be using that count span quite a bit so I create a variable for it immediately. This means jQuery doesn’t need to find the span every time I want to update it.

I’ve found to the keyup event for the textarea. Within it - I get the value of the text field and trim it. My code to handle the count is based on a blog entry I wrote two years ago: Counting Word Instances in a String. That entry detailed how you would get a count of unique words in a string. My needs are much simpler. I can break the string on word boundaries, using a regular expression, and then simply count it. The replace is there to handle some of the special cases mentioned in the comments.

Of course - by itself that isn’t enough. If you really wanted to limit the word count you would need to add code to bind to the form submit. I’d use caution though as this word count isn’t perfect. Web developers typically treat form validation in a very binary fashion - either the data is right or wrong. But this is probably a good example of where we would want to let a field pass even if it has too many words. You can always flag it in an email for further investigation.

Anyway - let’s wrap this up now by adding the ColdFusion side:

<cfif structKeyExists(form, "body")> <cfset wordstr = trim(form.body)> <cfset wordstr = replaceList(wordstr, "'.""?","")> <cfset words = reMatch("[[:word:]]+", wordstr)> <cfoutput> <p> You submitted #arraylen(words)# word(s). </p> </cfoutput> </cfif>

This is pretty much the exact same code as the JavaScript version. Obviously all of this could be done many different ways. Altogether now - my complete template:

<html>

<head> <script src=”http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js”></script> <script>

$(document).ready(function() {

var status = $("#count")

$("#body").keyup(function() {
    var cVal = $(this).val()
	cVal = $.trim(cVal)
	if(cVal.length == 0) return
	cVal = cVal.replace(/['\.\?"]/,"")
	var words = cVal.split(/\W/)
	status.text("You've written "+words.length+" word(s).")
}) })

</script> </head>

<body>

<form method=”post”> <textarea name=”body” id=”body”></textarea> <input type=”submit”><br/> <span id=”count”></span> </form>

<cfif structKeyExists(form, “body”)> <cfset wordstr = trim(form.body)> <cfset wordstr = replaceList(wordstr, “’.””?”,””)> <cfset words = reMatch(“[[:word:]]+”, wordstr)> <cfoutput> <p> You submitted #arraylen(words)# word(s). </p> </cfoutput> </cfif>

</body> </html> </code>

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate looking for his next gig. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support.

Lafayette, LA https://www.raymondcamden.com

Comments