Restrict TextField to Numbers

I’m trying to force numbers only be entered into a text field, and allow for an optional decimal, as well as the use of backspace and delete keys.

Mask won’t work as it’s too restrictive (ex; the decimal, if any, could be anywhere).

I can see how to test against Keyboard.AsynckeyDown for all possible number keys, etc., but I don’t know how to prevent a key press from appearing in the text box if the Keyboard.AsynckeyDown test fails (in other words, if a user presses a letter instead of a number, how do I make sure “nothing happens”).

Also… That’s a heck of a lot of code to test for every applicable key. I also wondered if there was a simpler way. For example, in VB, it took 3 lines of code using KeyAscii.

You should use the TextField.KeyDown event handler. Return True for keys you do not want to accept.

and create a subclass of TextField if you have more than one you need this requirement for

TextField.KeyDown is what I’m using. I’ve come up with something that almost works, however there is an issue (seems like a bug in Xojo ?)…

Here’s the code I have…

[code] If Keyboard.AsynckeyDown(&h33) Then ’ Backspace
Return False
End If

If Keyboard.AsynckeyDown(&h75) Then ’ Delete
Return False
End If

Select Case val(Key)
Case 0 to 9
Return False
End Select

Select Case Key
Case “.”
Return False
End Select

Return True[/code]

Using “Case 0 to 9” causes any key (latters and all) to be allowed. If I change it to “Case 1 to 9” then it works correctly for just numbers (except zeros, of course).

I realize I can create a workaround using Keyboard.AsynckeyDown for both types of zeros, but is there something I’m missing or is this a Xojo bug?

Why are you using Keyboard.AsyncKeyDown instead of just using the Key parameter to check for backspace or delete?

Val(“A”) returns 0, which is why letters are allowed with your code.

This KeyDown event handler code doesn’t check for multiple decimal points and probably a few other edge cases, but it should give you the idea:

  Dim skipKey As Boolean = True // Skip all keys by default
  // Allow these keys
  If Key >= "0" And Key <= "9" Then skipKey = False
  If Key = "." Then skipKey = False
  If Key = Chr(8) Then skipKey = False ' BackSpace
  If Key = Chr(4) Then skipKey = False ' End
  If Key = Chr(1) Then skipKey = False ' Home
  If Key = Chr(127) Then skipKey = False ' Delete
  If Key = Chr(28) Then skipKey = False ' Left arrow
  If Key = Chr(29) Then skipKey = False ' Right arrow
  If Key = Chr(9) Then skipKey = False ' Tab
  Return skipKey

Doh! Didn’t think of using Chr(). Also didn’t occur to me that If Key >= "0" And Key <= "9" would work, given that Key is a string.

Thanks so much.

Good evening, I’m a new user. Will you please ask if you could do the same control in the web version.

Thanks so much

For a WebTextField, the Type property might be more appropriate:


Thank you very much.

Here’s another solution, also used in KeyDown event, that will only allow one decimal and numbers.

if IsNumeric( Key ) then
return false
elseif ( Key = “.” ) and ( InStr( me.Text, “.” ) = 0 ) then
return false
elseif ASC( Key ) < 32 or ASC( Key ) = 127 or ASC( Key ) = 8 then
return false
return true
end if