-Immediate feedback about how many characters I have left
-Automatic trimming of my text entry once I hit the maximum number of characters
-Unobtrusive changes to the UI as I enter a length restricted field
-A flexible and simple way to implement the functionality multiple times on the same form.
First, the code that does the checking. I tried to make it fairly generic.
The textLimiter function accepts the name of the field to be checked, the name of the field that serves as the counter and the maximum number of characters as arguments. In the If statement, we compare the number of characters (inputField.value.length) to the maximum allowed. If the string in the given field is longer than the max, we use the substring function to trim it to the appropriate length. If not, then we know we haven't reached the max length yet and the user can still type characters into the field. As they do so, the Else statement updates the value of the counter field by subtracting the length of the string in the given field from the maximum allowed number of characters. Pretty simple, no?
That's all that is housed in the JS Header of the Notes form. Now let's take a look at one of the fields that implements this code. For purposes of this example, I added the functionality to two fields. For each, I used the onFocus event of the field to initiate the call to the textLimiter function and used onBlur to clear the setInterval method. You can see how this appears in the "UserTitle" field below:
(Editor's Note: I used some creative editing to show the two events in the same screenshot)
As you can see in the onFocus event, I just set some variables for the given field then use setInterval to call the textLimiter function every 10ms. inputName is the name of the field you are limiting the characters in, counterName is the name of the field that is counting down the number of characters remaining and charLimit is the maximum number of characters allowed in the input field. The onBlur event includes the call to clearInterval, which means the client will stop invoking textLimiter as soon as we exit the field. (We'll skip the other stuff for now and come back to it later).
With just those few pieces in place, the functionality works quite nicely. As you type in the given field, the text underneath updates you with a message as to how many characters you have remaining. It's not enough to stop here, though. In order to keep the screen as streamlined as possible, I don't want any user input messages to be displayed except for when I need them. This speaks to the third point in my list of requirements. What I want to happen is for the helper text to appear as soon as I enter the field and disappear as soon as I leave it. That's where the rest of the code comes in.
I chose to implement the dynamic nature of this functionality with simple hide-when formulas. I placed the helper text on a separate line, then set it's hide when formula to hidden except when the "CheckField" counter was equal to the name of the counter's corresponding input field.
f.CheckField.value = 'UserTitle';
The first line sets the value of "CheckField" to the name of the input field that corresponds to this counter and the second line "clicks" the hidden button, refreshing the doc and showing the counter line. When the user exits the field, we just do the reverse, setting "CheckField" to null and refreshing the document again to hide the counter.
When you put all this stuff together, you get a nice little bit of functionality. It accomplishes the goal of restricting user input and does so in a fairly elegant way. You also get a handy little example database where you can try this out yourself.
Addendum: Well, what do you know. Had I not already done the work and typed up half of this post, I would have just quit this as it turns out that Mr. Robichaux has done something very similar. Our approaches were quite alike, but I think this one has at least one advantage in that it keeps the field trimmed at the set number of characters. In any case, if you'd like to see how he tackled the problem, check it out here.