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.
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>
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.
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