7 Jan 2014

Validating field length in JavaScript

Recently i have been working on an application that requires a field with a limited number of characters (200 in this case).
However from a users perspective it is difficult to know the number characters currently used so I decided to display the number of characters:


As the text area changes the count is updated, if the limit is reached further characters are prohibited. This is achieved by using the key up to trigger a client-side javascript function:
restrictCharacterCount(displayedCountId, sourceFieldId, maxValue, allowExceedMax)
The function accepts 4 arguments; only the first 3 are required.
  1. displayedCountId - this is the id of span (computed text) element that holds the count of the characters
  2. sourceFieldId - this is the id of the text area where the number of characters are being counted from
  3. maxValue - this is the maximum number of characters that are allowed in the field
  4. allowExceedMax - this is a flag which allows the maximum number of characters to be exceeded but turns the colour of the count to red instead- this is optional.
XPage
   1:  <xp:span id="spnAbstractLabel">
   2:      <xp:label id="lblAbstract" value="Abstract" for="edaAbstract" />
   3:      <xp:div rendered="#{javascript:docApplicationDetails.isEditable()}">
   4:          <xp:text id="cmpAbstractCharacterCount" value="0" />
   5:          <xp:text id="cmpAbstractCharacterAllowed"
   6:              value="${javascript:'/'+pageController.defaultDocumentEvents.ABSTRACT_MAX_LENGTH}" />
   7:      </xp:div>
   8:  </xp:span>
   9:  <xp:inputTextarea id="edaAbstract" styleClass="lotusText"
  10:      value="#{docApplicationDetails.Astract}" rows="3">
  11:      <xp:this.validators>
  12:          <!-- Unable to use EL here for some reason -->
  13:          <xp:validateLength
  14:              maximum="${javascript:pageController.defaultDocumentEvents.ABSTRACT_MAX_LENGTH}"
  15:              message="Abstract can only be 
  16:              ${javascript:pageController.defaultDocumentEvents.ABSTRACT_MAX_LENGTH} characters long.">
  17:          </xp:validateLength>
  18:      </xp:this.validators>
  19:      <xp:this.onkeyup>
  20:          <![CDATA[applicationUtils.restrictCharacterCount(
  21:              "#{id:cmpAbstractCharacterCount}",
  22:              this.id,
  23:              #{javascript:pageController.defaultDocumentEvents.ABSTRACT_MAX_LENGTH})]]>
  24:          </xp:this.onkeyup>
  25:      </xp:eventHandler>
  26:  </xp:inputTextarea>
Javascript
   1:  function restrictCharacterCount(displayedCountId, sourceFieldId, maxValue, allowExceedMax){
   2:      var sourceElement = XSP.getElementById(sourceFieldId);
   3:      var sourceText = sourceElement.value;
   4:      var count = sourceText.length;
   5:      var countElement = XSP.getElementById(displayedCountId);
   6:      
   7:      if(count < maxValue){
   8:          //remove any styling that may have been applied by any of the other conditions below
   9:          countElement.style = "";
  10:      }else if(count == maxValue){
  11:          //if the count of characters has reached max then bold the count text
  12:          countElement.style.fontWeight = "bold";
  13:      }else{
  14:          //count must be over the threshold
  15:          if(allowExceedMax){
  16:              //Change the colour of the count element to red
  17:              countElement.style.color = "red";
  18:          }else{
  19:              reset the text to the max allowed
  20:              sourceElement.value = sourceText.substring(0, maxValue);
  21:   
  22:              //reset count the new character count; in theory should be maxValue
  23:              count = sourceElement.value.length;
  24:          }
  25:          //highlight the count incase the condition maxValue condtion has not been triggered
  26:          countElement.style.fontWeight = "bold";
  27:      }
  28:      countElement.innerHTML = count;
  29:  }

BxSlider