Recently, I was working on an Onsite Biometrics testing solution for a client using a customized front-end on a Salesforce back-end, all on iPads. Testers needed to be able to search for people, check them in, create new entries, and enter test results.
The problem was that whenever they entered a field on the data entry layout, an Alphabetic keypad would show up, which they then needed to switch to a numeric one. Not fun when you have up to 60 fields to enter!
I had to think of a way to get the number pad to show up, using native Salesforce elements.
When you specify an
<apex:inputText/>
element, it generates this:
<input type="text">
This is fine in most situations, but for a recent job, I had to attempt to make a number pad come up, not the standard keypad.
Easy! I thought – just define the inputText element like so:
<apex:inputText type="tel"/>
Well, that had the unfortunate side effect of flat out not working – the field made a number pad appear, but all the juju magic that you get with the data automatically syncing back to the controller fails to work.
One work around is to use a standard submit process and grab the parameters in the controller – but when you have about 60 parameters like I had for my form, I wasn’t too keen on that option.
So! The trick is simple – use JavaScript to rewrite the input type on document load (and refresh) and whenever the user looks like they might be about to hit a button that submits to the controller, write the input back to a “text” type.
First define your apex element like this:
<apex:inputText styleClass="keypad" onfocus="changeToTel()" value="{!yourControllerObject.aField}" />
Then in your onload javascript function, call this function:
function changeToTel(){
var currSelected = document.getElementsByClassName("keypad");
for (var i=0; i< currSelected.length;i++) {
currSelected[i].type = 'tel';
}
}
As you can see above, the inputText element also ensures that when the element receives focus, it calls the changeToTel() method.
Finally, so that data can be sent back to the controller, we need to call another function changeToText() which reverses our recent changes.
Here it is:
function changeToText(){
var currSelected = document.getElementsByClassName("keypad");
for (var i=0; i< currSelected.length;i++) {
currSelected[i].type = 'text';
}
}
The changeToText function is called whenever a mouseover event is triggered on the submit button:
<input id="quickSaveButton" type="button" value="Save" onclick="submit" onmouseover="changeToText()" />
The the last piece of the puzzle is an actionFunction element that is called by the input element. It has an oncomplete event, which then re-initialises all the inputs types back to ‘tel’ type again:
<apex:actionFunction name="submit" action="{!submitOrder}" rerender="inputAndErrors" oncomplete="changeToTel()"/>
There you have it! Numeric keypads on a Salesforce textInput object.