Textfield: Limit input to numbers only?

BlitzMax Forums/BlitzMax Beginners Area/Textfield: Limit input to numbers only?

Grisu(Posted 2006) [#1]
Hi!

Is there an easy way to let the user only enter numbers ranging from "0..9" into this 3 digits textfield with all other chars not being accepted at all?

SuperStrict 

Local window:TGadget
Local tf:TGadget

window: TGadget=CreateWindow("My Window",30,20,320,200)

tf:TGadget=CreateTextField(4,4,28,20,window)

While WaitEvent()
	Select EventID()
	Case EVENT_GADGETACTION
		Select EventSource()
			Case tf
				Print "textfield updated"
				If Len(TextFieldText(tf)) >3 Then SetGadgetText(tf,"") 
 		End Select
	Case EVENT_WINDOWCLOSE
		End
	End Select
Wend



Mark Tiffany(Posted 2006) [#2]
I'm at work, so this is from memory, but I'm sure there's a way to add a "FilterKey" function to any gadget. You could use this to mask out any non-numerics.


tonyg(Posted 2006) [#3]
Very quick...
If Not Int(TextFieldText(TF)) Print "Not integers"
<edit> Hmm works unless the first char is an int.


Grisu(Posted 2006) [#4]
Something bullet-proof would be nice.

Couldn't find something on setting a filter. But if this is possible, this SHOULD be in the docs.


tonyg(Posted 2006) [#5]
SuperStrict 

Local window:TGadget
Local tf:TGadget

window: TGadget=CreateWindow("My Window",30,20,320,200)

tf:TGadget=CreateTextField(4,4,28,20,window)

While WaitEvent()
	Select EventID()
	Case EVENT_GADGETACTION
		Select EventSource()
			Case tf
			 If Not Int(Right(TextFieldText(tf) , 1) ) 
					Print "Non integer entered"
					SetGadgetText(Tf,Left(TextFieldText(tf) , Len(TextFieldText(tf)) - 1))
				EndIf
				Print "textfield updated"
				If Len(TextFieldText(tf)) >3 Then SetGadgetText(tf,"") 
 		End Select
	Case EVENT_WINDOWCLOSE
		End
	End Select
Wend


My doc has an entry for SetGadgetFilter.
Here's a quick example...
SuperStrict 

Local window:TGadget
Local tf:TGadget

window: TGadget=CreateWindow("My Window",30,20,320,200)

tf:TGadget=CreateTextField(4,4,28,20,window)
SetGadgetFilter tf,filter




Function filter:Int(event:TEvent,context:Object)
	Select event.id
		Case EVENT_KEYDOWN
			Print "filtering non-integer:"+event.data+","+event.mods
			If event.data > 57 Or event.data < 48 Return 0
		Case EVENT_KEYCHAR
			Print "filtering charkey:"+event.data+","+event.mods
			If event.data > 57 Or event.data < 48 Return 0
		End Select
	Return 1
End Function

While WaitEvent()
	Select EventID()
		Case EVENT_WINDOWCLOSE
			End
		Case EVENT_GADGETACTION
		Select EventSource()
			Case tf
				If Len(TextFieldText(tf)) >3 Then SetGadgetText(tf,"") 
 		End Select

	End Select
Wend



Let me know when you want your tea stirring.


Grisu(Posted 2006) [#6]
Thanks for the try Tony. It's not as easy as it may look like.
Your code fails when entering "10" or "100".

SetGadgetfilter... *gets a headache when trying to understand the docs explanation

Would be nice to add this to "Createtextfield" (docs):
"Also see: SetGadgetText and TextFieldText and SetGadgetfilter"


Grisu(Posted 2006) [#7]
For the filter example:

Backspace should work and "013", "000" and such inputs should also be impossible...

Backspace=Ascii value? *thinking


tonyg(Posted 2006) [#8]
You're spending 5-10 mins before saying "It doesn't do x and y!"
Can't you take this as examples and see whether you can expand them to work the way you want?

SuperStrict 

Local window:TGadget
Local tf:TGadget

window: TGadget=CreateWindow("My Window",30,20,320,200)

tf:TGadget=CreateTextField(4,4,28,20,window)

While WaitEvent()
	Select EventID()
	Case EVENT_GADGETACTION
		Select EventSource()
			Case tf
			 If Not Int(Right(TextFieldText(tf) , 1) ) And Right(TextFieldText(tf) , 1)<>"0"
					Print "Non integer entered"
					SetGadgetText(Tf,Left(TextFieldText(tf) , Len(TextFieldText(tf)) - 1))
				EndIf
				Print "textfield updated"
				If Len(TextFieldText(tf)) >3 Then SetGadgetText(tf,"") 
 		End Select
	Case EVENT_WINDOWCLOSE
		End
	End Select
Wend

And SetGadgetFilter with backspace and <edit> leading zero not allowed...
SuperStrict 

Local window:TGadget
Local tf:TGadget

window: TGadget=CreateWindow("My Window",30,20,320,200)

tf:TGadget=CreateTextField(4,4,28,20,window)
SetGadgetFilter tf,filter




Function filter:Int(event:TEvent , context:Object)
	Local error:Int=1
	Select event.id
		Case EVENT_KEYDOWN
			Print "filtering non-integer:"+event.data+","+event.mods
			If event.data > 57 Or event.data < 48 error = 0
			If event.data = KEY_BACKSPACE error =1
		Case EVENT_KEYCHAR
			Print "filtering charkey:" + event.data + "," + event.mods
			If event.data > 57 Or event.data < 48 error = 0
			If event.data = KEY_BACKSPACE error =1
		
		End Select
	Return error
End Function

While WaitEvent()
	Select EventID()
		Case EVENT_WINDOWCLOSE
			End
		Case EVENT_GADGETACTION
		Select EventSource()
			Case tf
				 If Len(TextFieldText(tf))>1 And Left(TextFieldText(tf) , 1)="0"
					Print "Leading zero not allowed"
					SetGadgetText(Tf,Left(TextFieldText(tf) , Len(TextFieldText(tf)) - 2))
				EndIf

				If Len(TextFieldText(tf)) >3 Then SetGadgetText(tf,"") 
 		End Select

	End Select
Wend



Grisu(Posted 2006) [#9]
Much appreciated. Thank you Tony!


tonyg(Posted 2006) [#10]
Np, I've altered it to not accept a leading zero.
You can enter '0' on it's own but not '00' or '03' etc.


H&K(Posted 2006) [#11]
If it was going to be a built in command, it should allow all mathimatical Chars. That is, in a situatuton were we wanted more then the three didgits here, the user should, (Well the programmer should have the chosse really), be able to enter, (For example), 46*33/2

The reason I say this, is that I hate having to go to a calculator, just because, (For example), I cannot remember what 17.5% of 342 is

I Know this is not what you are talking about here, but it seemed a point worth raising.

@tonyg,

Ahhhh, When you tie their shoe laces, they still expect their socks washing ;)