TextBox Input Filter?

Discussion in 'Questions (Windows Mobile)' started by dlfallen, May 9, 2007.

  1. dlfallen

    dlfallen Active Member Licensed User

    Has anyone figured out a way to filter textbox input? For example, I wish to have the textbox ignore any key press that is not numeric. I tried the IsNumber function in the KeyPress event but that doesn't work.

    The first approach I tried was:

    Sub TextBox1_KeyPress (key)
    if IsNumeric(key) = False then key = ""
    End Sub

    But changing the variable "key" within that subroutine does not do anything to what is displayed in the textbox. To illustrate this, replace the "if" statement above with "key = R". The textbox will still display what you type, not the value "R".

    My second approach was to chop the right-hand character off of TextBox1.Text but alas, TextBox1.Text is not updated until AFTER the TextBox1.KeyPress(key) subroutine has been completed.

    The only other events for a textbox are GotFocus and LostFocus, neither of which helps for this problem. The KeyPress event allows me to detect which key was pressed, but does not let me do anything about it.

    Any ideas?

    -dlfallen
     
  2. Erel

    Erel Administrator Staff Member Licensed User

    You should use IgnoreKey method:
    If IsNumeric(key) = false then TextBox1.IgnoreKey
     
  3. dlfallen

    dlfallen Active Member Licensed User

    Thanks Erel. Your response was quick and to the point, as usual!

    -dlfallen
     
  4. Rioven

    Rioven Active Member Licensed User

    Code help anyone...

    B4PPC community, Hi!

    I'm coding a dynamic textbox input and need help (the last item).
    Any simple or correct solution for these filters?

    Code:
    Sub HHStart_KeyPress (key) 

      
    'input only number
    If IsNumber(key) = false AND Asc(key) <> 8  Then HHstart.IgnoreKey

      
    'mouse selected character and replace
    If StrLength(HHStart.Text) <=2 AND HHstart.SelectionLength<>0 Then
    s = HHStart.SelectionStart
    HHstart.Text=StrRemove(HHstart.Text,s,HHstart.SelectionLength)
    HHStart.SelectionStart=s
    End If

      
    'limiting input length
    If StrLength(HHstart.text)>=2 AND Asc(key) > 31 Then HHstart.IgnoreKey

      
    'limiting input number range
    ????????? from 0 to 24 only

    End Sub
    Thanks in advance:D
     
  5. agraham

    agraham Expert Licensed User

    Could be a bit more elegant, especially if you removed the need to replace a selected character, but it works.
    Code:
    Sub HHStart_KeyPress (key)

       
    'process only numbers, Asc("0")=48, AsSc("1")= 50 etc. and backspace = 8
       If (IsNumber(key) = false AND Asc(key) <> 8Then
          HHstart.IgnoreKey
          
    Return
       
    End If

       
    If HHstart.SelectionLength <> 0 Then
          s = HHStart.SelectionStart
          
    If s = 0 AND Asc(key) > 50 AND  StrLength(HHStart.Text) >=2 Then 
             
    ' only allow first digit to be in range
             HHstart.IgnoreKey
             
    Return
          
    End If
          HHstart.Text=StrRemove(HHstart.Text,s,HHstart.SelectionLength)
          HHStart.SelectionStart=s
       
    End If

                 
    'limit input number range 
         If StrLength(HHStart.Text) > 0 AND IsNumber(key) Then
          first = 
    Asc(StrAt(HHStart.Text,0))
           
    If first > 50 Then
             HHstart.IgnoreKey 
    ' first digit more than "2"
          Else If   first = 50 AND Asc(Key) > 52 Then
             HHstart.IgnoreKey 
    ' final number would be > 24
          Else If StrLength(HHStart.Text) >= 2
             HHstart.IgnoreKey 
    ' final number would be more then two digits
          End If      
       
    End If
    End Sub
     
  6. Rioven

    Rioven Active Member Licensed User

    Hi agraham, thanks for your help, I could apply you techniques but still need to fix something...

    when mouse is placed in between the 2 digits and use backspace, I could enter number that results more than 24, sometimes cannot enter any valid number.

    or

    When there is an existing 1 digit, and input number before this digit, I could enter number that results more than 24, sometimes cannot enter any valid number.

    My problem looks simple, but seems no shortcut solution?:confused:

    but if you can easily solve the above...will be much appreciated.

    thanks again.
     
  7. Erel

    Erel Administrator Staff Member Licensed User

    Maybe you can use a NumUpDown control instead of a TextBox?
     
  8. agraham

    agraham Expert Licensed User

    Or maybe a TrackBar?

    The logic is more complicated than it seems. So brute force then?

    Code:
    Sub HHStart_KeyPress (key)
       
    'process only numbers and backspace
       If (IsNumber(key) = false AND Asc(key) <> 8Then
          HHstart.IgnoreKey
          
    Return
       
    End If
    End Sub

    Sub HHStart_LostFocus (key)
       
    'process only numbers and backspace
       If HHStart.Text <0 OR HHStart.Text > 24 Then
          
    Msgbox("Must be between 0 and 24")
       HHStart.Focus
       
    End If
    End Sub
     
  9. Rioven

    Rioven Active Member Licensed User

    Yes Erel, I have thought about that and more often applied on hours, but if I have solution for these kind of filters on textbox, I could think of some other positive applications.


    :sign0148:difficult for years of not writing code like me, only started again when found Basic4PPC and still refreshing and learning. I could try to do some logic flowcharting then...as it seems I could not do it on the spot anymore.:D


    thank you!
     
  10. agraham

    agraham Expert Licensed User

    I just love a challenge! Try to break this one


    Code:
    Sub HHStart_KeyPress (key)
       
    ' I know this takes time but this is slow user input processing and avoids global clutter
       MAXNUM = 3456
       HHshadow = HHstart.text
       
       
    If (IsNumber(key) = false AND Asc(key) <> 8Then
          
    'process only numbers, Asc("0")=48, AsSc("1")= 50 etc. and backspace = 8      
          HHstart.IgnoreKey
          
    Return
       
    Else If    HHstart.SelectionLength <> 0 Then
          
    ' part of string selected
          ss = HHStart.SelectionStart
          sl = HHStart.SelectionLength
          hl = StrLength(HHstart.text)
          first = SubString(HHshadow,
    0,ss)
          last = SubString(HHshadow,ss+sl,hl-sl)
          HHshadow = first & key & last      
       
    Else
          
    ' no selection so process normally and check limit
          HHshadow = HHshadow & key
       
    End If
       
       
    If IsNumber(key) AND  HHshadow > MAXNUM   Then
          HHstart.IgnoreKey
          
    Return   
       
    End If
    End Sub
     
  11. dzt

    dzt Active Member Licensed User

    Easy!
    ;)

    1. Type 0000 and at the beginning type any number
    2. Paste anything Shift-Insert (desktop only, OK doesn't counts)
    3. Type 555 and at the beginning try to type any number

    :)
     
  12. Rioven

    Rioven Active Member Licensed User

    Not yet foolproof...
    Add more logic operators...:eek:

    @agraham, the challenge for this subroutine isn't over yet.:D
    thanks for helping me...
    EDIT:thanks for doing this... :sign0188:
     
  13. Rioven

    Rioven Active Member Licensed User

    This one seems working and applied as subroutine function....yet needs more improvements.:)

    Code:
    Sub HHStart_KeyPress (key)
                 
    'maxNum, ControlName,key
    textboxFilter01("12345","HHStart",key)
    End Sub
    Code:
    Sub textboxFilter01(MaxNum,tb,key)
    HHshadow=
    Control(tb).Text

    'process only numbers and backspace
    If (IsNumber(key) = false AND Asc(key) <> 8Then
       
    Control(tb).ignorekey
       
    Return
    End If

      
    'mouse selected character and replace
    If Control(tb).SelectionLength<>0 AND Asc(key) <> 8 Then
    s = 
    Control(tb).SelectionStart
    Control(tb).Text=StrRemove(Control(tb).Text,s,Control(tb).SelectionLength)
    Control(tb).SelectionStart=s
    n=StrInsert(
    Control(tb).Text,Control(tb).selectionstart,key)
          
    If (Asc(key) <> 8 AND n>maxNum ) Then 
          
    Control(tb).Text=HHshadow
          
    Control(tb).SelectionStart=s
          
    Control(tb).SelectionLength=1
          
    End If
    End If

      
    'insert input
    If StrLength(Control(tb).text)<StrLength(maxnum) Then
    n=StrInsert(
    Control(tb).Text,Control(tb).selectionstart,key)
          
    If (Asc(key) <> 8 AND n>maxNum ) Then 
          
    Control(tb).ignoreKey
          
    End If
    End If

      
    'limiting input length
    If (StrLength(Control(tb).text)>=StrLength(maxnum) AND Asc(key) <> 8Then
    Control(tb).IgnoreKey
    Return
    End If
    End Sub
    feedbacks are welcome;)
     
  14. agraham

    agraham Expert Licensed User

    Yeah. I realised that last night. There is a fundamental problem in that you don't know and can't find where the insertion point is. So you can deal with selections and normal input appended at the end but cannot predict the result of insertions. The only way round this I can think of is to reset the insertion point to disallow insertion and also disallow leading zeros

    Code:
    Sub HHStart_KeyPress (key)
       
    ' I know this takes time but this is slow user input processing and avoids global clutter
       MAXNUM = 3456
       HHshadow = HHstart.text
       
       
    If  StrLength(HHstart.text) = 0 AND Asc(Key) = 48 Then
          
    'don't allow leading zeros
          HHstart.IgnoreKey
          
    Return
       
    End If
       
       
    If (IsNumber(key) = false AND Asc(key) <> 8Then
          
    'process only numbers, Asc("0")=48, AsSc("1")= 50 etc. and backspace = 8      
          HHstart.IgnoreKey
          
    Return
       
    Else If    HHstart.SelectionLength <> 0 Then
          
    ' part of string selected
          ss = HHStart.SelectionStart
          sl = HHStart.SelectionLength
          hl = StrLength(HHstart.text)
          first = SubString(HHshadow,
    0,ss)
          last = SubString(HHshadow,ss+sl,hl-sl)
          HHshadow = first & key & last   
       
    Else
          
    ' no selection so process normally and check limit
          HHStart.SelectionStart = StrLength(HHshadow)
          HHshadow = HHshadow & key
       
    End If
       
       
    If IsNumber(key) AND  HHshadow > MAXNUM  Then
          HHstart.IgnoreKey
          
    Return   
       
    End If
    End Sub
     
  15. dzt

    dzt Active Member Licensed User

    Hello agraham,

    I know it is very difficult and you do not have enough weapons to fight.

    But if you use your ControlEvents and catch TextChanged event you need only to check for the value of the Textbox and if it is out of the limits, restore it to it's previous state or show a warning messagebox.

    Didn't test it.

    Am I wrong?
     
  16. agraham

    agraham Expert Licensed User

    Hi dzt

    You are right but I was trying to do it only with what is supplied with B4PPC.

    I was also trying to avoid the warning message because if you do that you may as well keep it very simple, catch LostFocus in B4PPC and show a message box.
     
  17. dzt

    dzt Active Member Licensed User

    Hi again,

    There are significant advantages for TextChanged against LostFocus and KeyPress events.

    It is by far the most elegant solution.
     
  18. agraham

    agraham Expert Licensed User

    Hi dzt

    I think you misunderstood. I'm not disagreeing at all - it is the most elegant. I just wanted to see how far I could go "as standard" which is what most people would be comfortable with.
     
  19. agraham

    agraham Expert Licensed User

    As dzt suggested here it is using my ControlEvents libary - a bit too easy really!
    Code:
    Sub Globals
       
    'Declare the global variables here.
       MAXNUM = 3456
       
    Dim AGeventsTextSave

    End Sub

    Sub App_Start
                 Form1.Show
                 
    ' AGeventsX is a ControlEvents object
                 AGeventsX.New1("AGevents")
    End Sub

    Sub AGeventsX_TextCHanged()
       
    If AGevents.Text > MAXNUM Then
           AGevents.Text = AGeventsTextSave
          AGevents.SelectionStart = StrLength(AGevents.text)
       
    Else
          AGeventsTextSave = AGevents.Text
       
    End If
    End Sub
     
Loading...