ColdFusion Function: character counting textarea with limit

Here is a cute CF Function that generates a textarea with a counter and limiter. The default look and function are pretty decent, with 255 characters perfect for varchar.

Here is the Function:

<cffunction name="textarea">

    <cfargument name="name" default="textarea">
    <cfargument name="id" default="#name#">
    <cfargument name="maxlength" default="255">
    <cfargument name="value" default="">
    <cfargument name="cols" default="">
    <cfargument name="rows" default="7">
    <cfargument name="css_width" default="">
    <cfargument name="css_height" default="">
    <cfargument name="css_float" default="">
    <cfargument name="css_margin" default="0px">
    <cfargument name="readonly" default="0">
    <cfargument name="css_clear" default="">
    <cfargument name="loadbase" default="1">

    <cfoutput>
    <cfif arguments.loadbase eq 1>
        <script type="text/javascript">
            function textCounter(field, countfield, maxlimit) {
                if (field.value.length > maxlimit) {
                    field.value = field.value.substring(0, maxlimit);
                    document.getElementById(countfield).innerHTML = field.value.length;
                    alert('You have exceded your character limit');
                } else {
                    document.getElementById(countfield).innerHTML = field.value.length;
                }
            }
        </script>
    </cfif>
    <textarea cols="#cols#" rows="#rows#"
        style="<cfif css_float is not ''>float:#css_float#;</cfif> margin:#css_margin#; <cfif css_width is not ''>width:#css_width#;</cfif> <cfif css_height is not ''>height:#css_height#;</cfif>"
        wrap="physical" name="#name#" id="#id#"
        onKeyDown="textCounter(this.form.#name#,'counter#name#',#maxlength#);"
        onKeyUp="textCounter(this.form.#name#,'counter#name#',#maxlength#);" <cfif readonly is 1>readonly</cfif>>#value#</textarea>
    <div style="width:#css_width#; text-align:right; clear:#css_clear#;"><span id="counter#name#">#len(value)#</span> / #maxlength# chars</div>
    </cfoutput>

</cffunction>

And to invoke it for display in your form:

#session.utils.textarea(name="metadesc", maxlength="500", value=read.metadesc, css_width="100%")#

This assumes you loaded the CFC into a session variable called ‘utils’. The value is preloaded from a CFQuery called ‘read’.

And if you want two textareas on the same page? No problem. Just tell the second one not to load the javascript, with the ‘loadbase=0’ attribute:

		#session.utils.textarea(name="metadesc", maxlength="500", value=read.metadesc, css_width="100%")#

		#session.utils.textarea(name="metakeyw", maxlength="500", value=read.metakeyw, css_width="100%", loadbase=0)#

I see now after posting this that there is room for improvement in the javascript. Especially if I consider scriptaculous. So look for a version 2 in the coming days (or weeks).

7 Replies to “ColdFusion Function: character counting textarea with limit”

  1. How do you load the CFC into a session variable called ‘utils’?
    What does this mean "The value is preloaded from a CFQuery called ‘read’."

  2. Hi Eva, sorry I didn’t see your question until today when I was notified of Lou’s comment.

    To load the cfc into a variable, you can set it up when you start a session. Like so:

    <cfset session.utils = createObject("component","path.to.utils")>

    And make sure the file name is ‘utils.cfc’ (or update your createObject accordingly).

    What I meant by “The value is preloaded from a CFQuery called โ€˜readโ€™” is that there would be a query that gets the textarea’s value from a database. In the examples above, the CFQuery’s name is ‘read’ and the fieldname is ‘metadesc’.

  3. Better to load something like this into the Application scope. Why have a CFC stored once in memory for each visitor when you could store it once in the Application scope and reference it (with new values) any time you needed it?

  4. Hm, I’ve never done this before. So would this work in application.cfm?

    
    
    <cfif not isdefined("application.utils") or isdefined("url.reinit")>
      <cflock scope="Application" type="Exclusive" timeout=30>
        <cfset application.utils = createObject("component","path.to.utils")>
      </cflock>
    </cfif>

    Is the cflock necessary?

Comments are closed.