Force Text to UpperCase in RichInputText as the user is typing (make sure the cursor stays in one place)

2

The challenge is simple: users of an ADF Faces web application are only allowed to enter uppercase characters into a field. We want to help them by turning any lowercase character they type into its uppercase equivalent – as they are typing. And we of course need to make sure that this works, whether they are adding characters to the string in the input field or typing somewhere in the middle.

Our tools: clientListener for the keyUp event, JavaScript functions to determine the current caret position (position of cursor in text field) and to set the caret position in a specific field. And of course the toUpperCase() function on the JavaScript String object.

Edit: using Luc’s suggestion (see first comment) about the CSS Style property text-transform I have extended this blog post a little. This property can be used to define a style for an element that instructs the browser to show the value of that element in uppercase – even if the value is not uppercase. The user apparently is typing uppercase characters (whereas in fact she is typing whatever she is typing, for example lower case). When the user navigates out of the field, the value can be updated to be really uppercase; the user will not notice this as the field showed uppercase contents all along. The source below contains a second inputText element with this CSS style property set and a simple JavaScript function to perform the final capitalization of the contents.

image

Below the very simple ADF Faces page with those three JavaScript functions that will make it happen.

    <?xml version='1.0' encoding='UTF-8'?>
    <!DOCTYPE html>
    <f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
        <af:document title="Form.jsf" id="d1">
        <af:resource type="javascript">
        
        /* source: http://stackoverflow.com/questions/2897155/get-cursor-position-in-characters-within-a-text-input-field */
        function getCaretPosition (oField) {
    
      // Initialize
      var iCaretPos = 0;
    
      // IE Support
      if (document.selection) {
    
        // Set focus on the element
        oField.focus();
    
        // To get cursor position, get empty selection range
        var oSel = document.selection.createRange();
    
        // Move selection start to 0 position
        oSel.moveStart('character', -oField.value.length);
    
        // The caret position is selection length
        iCaretPos = oSel.text.length;
      }
    
      // Firefox support
      else if (oField.selectionStart || oField.selectionStart == '0')
        iCaretPos = oField.selectionStart;
    
      // Return results
      return iCaretPos;
    }
    
    
    /* source:  http://stackoverflow.com/questions/512528/set-cursor-position-in-html-textbox */
    
    function setCaretPosition(elem, caretPos) {
    
        if(elem != null) {
            if(elem.createTextRange) {
                var range = elem.createTextRange();
                range.move('character', caretPos);
                range.select();
            }
            else {
                if(elem.selectionStart) {
                    elem.focus();
                    elem.setSelectionRange(caretPos, caretPos);
                }
                else
                    elem.focus();
            }
        }
    }    
        
        
        function forceUppercase(evt) {
          //TODO filter on evt.getKeyCode() represents a lower case character and otherwise do nothing
          // extract the ADF Faces Rich Client Component - presumably a RichInputText
          var comp = evt.getSource();
          // get the rich client component id - because from it we can derive the identitier for the DOM input element
          var adfComponentClientId = comp.getClientId();
          // get hold of the DOM element into which the user is typing text
          var elem = document.getElementById(adfComponentClientId + '::content');
          // find the current position of the cursor in the input element
          var currentCaret = getCaretPosition (elem);
          // turn the value in the RichInputText to Uppercase; NOTE: this will place the cursor after the last character in the field 
          comp.setValue(comp.getSubmittedValue().toUpperCase());
          // return the cursor to the position it was at
          setCaretPosition(elem, currentCaret);
        }

       function toUppercase(evt) {
          var comp = evt.getSource();
          comp.setValue(comp.getSubmittedValue().toUpperCase());
        }

        </af:resource>
            <af:form id="f1">
                <!-- Content -->
                <af:inputText label="Name" id="it21" shortDesc="Enter a value in uppercase" >
                    <af:clientListener type="keyUp" method="forceUppercase"/>
                </af:inputText>
                <!-- and here the even simpler solution with the CSS Style property text-transform: uppercase -->
                <af:inputText label="Name" id="it2" shortDesc="Enter a value in uppercase"  contentStyle="text-transform: uppercase;">
                    <af:clientListener type="blur" method="toUppercase"/>
                </af:inputText>
             </af:form>
        </af:document>
    </f:view>

About Author

Lucas Jellema, active in IT (and with Oracle) since 1994. Oracle ACE Director and Oracle Developer Champion. Solution architect and developer on diverse areas including SQL, JavaScript, Kubernetes & Docker, Machine Learning, Java, SOA and microservices, events in various shapes and forms and many other things. Author of the Oracle Press book Oracle SOA Suite 12c Handbook. Frequent presenter on user groups and community events and conferences such as JavaOne, Oracle Code, CodeOne, NLJUG JFall and Oracle OpenWorld.

2 Comments

  1. Hi Lucas,
    Just checking if there is a reason why you picked the (rather complex) javascript solution instead of the easy css solution.
    If you put “text-transform: uppercase” on the contentStyle attribute it works like a charm.

    • Lucas Jellema on

      Hi Luc,

      I was under the impression that text-transform only works for rendering text values – and does not have an effect on the contents of an inputText while it is being edited. Was I wrong in that assumption? If so – this can indeed be done much easier. I will try it out and update the post according to my findings.

      thanks for the tip!

      Lucas

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.