Home All Groups Group Topic Archive Search About

insert char in txtbox on key up?

Author
14 Oct 2005 1:48 PM
Impakt
Hi,

I am trying to make a 'credit card' number input form. I want to use a
single text box and have it insert a space after every 4 characters.
eg: xxxx xxxx xxxx xxxx

I can get it to 'sort of work' using the keypress method, but I want
it to insert the space after the 4th character is pressed.

So far I have the following code (not working):

Private Sub txtCardNo_KeyUp(KeyCode As Integer, Shift As Integer)
'when the card number text box detects a keypress, assign the string
of the card number text box to a variable and then find the length of
the string.

strCardNo = txtCardNo.Text
intChrCnt = Len(strCardNo)

'if the string lenght is 4, 9 or 14 add a space character to the
string and reflect the change in the card number text box.

Select Case intChrCnt

Case 4
txtCardNo.Text = strCardNo & " "

Case 9
txtCardNo.Text = strCardNo & " "

Case 14
txtCardNo.Text = strCardNo & " "

End Select

If Len(strCardNo) = 18 Then
txtCardNo.Enabled = False
cmdPrintExit.SetFocus
End If
End Sub


Any help greatly appreciated. It's 'easy' but tricky at the same time
Show quoteHide quote
:-P

Author
14 Oct 2005 2:04 PM
Dave
Just a thought, this might be easier using four textboxes, once one is full
shift the focus to the next one. If you make them borderless and position
them in a locked textbox it would look like a single box.

This might make handling of backspace and delete a bit easier too.

Regards
Dave O.

Show quoteHide quote
"Impakt" <fcoll***@mail.iinet.net.au> wrote in message
news:434fb551.219049937@news.iinet.net.au...
> Hi,
>
> I am trying to make a 'credit card' number input form. I want to use a
> single text box and have it insert a space after every 4 characters.
> eg: xxxx xxxx xxxx xxxx
>
> I can get it to 'sort of work' using the keypress method, but I want
> it to insert the space after the 4th character is pressed.
>
> So far I have the following code (not working):
>
> Private Sub txtCardNo_KeyUp(KeyCode As Integer, Shift As Integer)
> 'when the card number text box detects a keypress, assign the string
> of the card number text box to a variable and then find the length of
> the string.
>
> strCardNo = txtCardNo.Text
> intChrCnt = Len(strCardNo)
>
> 'if the string lenght is 4, 9 or 14 add a space character to the
> string and reflect the change in the card number text box.
>
> Select Case intChrCnt
>
> Case 4
> txtCardNo.Text = strCardNo & " "
>
> Case 9
> txtCardNo.Text = strCardNo & " "
>
> Case 14
> txtCardNo.Text = strCardNo & " "
>
> End Select
>
> If Len(strCardNo) = 18 Then
> txtCardNo.Enabled = False
> cmdPrintExit.SetFocus
> End If
> End Sub
>
>
> Any help greatly appreciated. It's 'easy' but tricky at the same time
> :-P
Author
14 Oct 2005 2:42 PM
Impakt
On Fri, 14 Oct 2005 15:04:43 +0100, "Dave" <nob***@nowhere.com> wrote:

>Just a thought, this might be easier using four textboxes, once one is full
>shift the focus to the next one. If you make them borderless and position
>them in a locked textbox it would look like a single box.

Our lecturer expects that we will use 4 text box's, but I thought I'd
be smart and do it with one. So while your solution is neat, it
defeats the purpose of the exercise ;-)

If I use the keydown event, it almost works, but it detects the 5th
character and converts it to a space, so if you enter:
1111222233334444

you get

1111 2223 3344 4

so close yet so far! :-(

Thanks for the reply.
Author
14 Oct 2005 2:44 PM
Dave
You would be best to go with Ricks suggestion of using the Masked text
control

Dave O.

Show quoteHide quote
"Impakt" <fcoll***@mail.iinet.net.au> wrote in message
news:434fc281.222426046@news.iinet.net.au...
> On Fri, 14 Oct 2005 15:04:43 +0100, "Dave" <nob***@nowhere.com> wrote:
>
>>Just a thought, this might be easier using four textboxes, once one is
>>full
>>shift the focus to the next one. If you make them borderless and position
>>them in a locked textbox it would look like a single box.
>
> Our lecturer expects that we will use 4 text box's, but I thought I'd
> be smart and do it with one. So while your solution is neat, it
> defeats the purpose of the exercise ;-)
>
> If I use the keydown event, it almost works, but it detects the 5th
> character and converts it to a space, so if you enter:
> 1111222233334444
>
> you get
>
> 1111 2223 3344 4
>
> so close yet so far! :-(
>
> Thanks for the reply.
Author
14 Oct 2005 2:48 PM
Bob Butler
"Dave" <nob***@nowhere.com> wrote in message
news:OQ6UA3M0FHA.2076@TK2MSFTNGP14.phx.gbl
> You would be best to go with Ricks suggestion of using the Masked text
> control

Has that control gotten better?  I remember trying it when it first came out
and there were lots of bugs in it.  I know I gave up on it shortly
thereafter and haven't tried it in years.

--
Reply to the group so all can participate
VB.Net: "Fool me once..."
Author
14 Oct 2005 2:56 PM
Dave
Don't know, I just had a quick look and it seemed to do what the OP wanted,
maybe Jeff will know how robust it is (or isn't).

Dave O.

Show quoteHide quote
"Bob Butler" <tiredofit@nospam.com> wrote in message
news:uvScO5M0FHA.1256@TK2MSFTNGP09.phx.gbl...
> "Dave" <nob***@nowhere.com> wrote in message
> news:OQ6UA3M0FHA.2076@TK2MSFTNGP14.phx.gbl
>> You would be best to go with Ricks suggestion of using the Masked text
>> control
>
> Has that control gotten better?  I remember trying it when it first came
> out
> and there were lots of bugs in it.  I know I gave up on it shortly
> thereafter and haven't tried it in years.
>
> --
> Reply to the group so all can participate
> VB.Net: "Fool me once..."
>
Author
14 Oct 2005 6:33 PM
Jeff Johnson [MVP: VB]
"Dave" <nob***@nowhere.com> wrote in message
news:%23LzoG%23M0FHA.3300@TK2MSFTNGP15.phx.gbl...

> Don't know, I just had a quick look and it seemed to do what the OP
> wanted, maybe Jeff will know how robust it is (or isn't).

Me? Or did you mean Rick and I'm just so dear to your heart that you typed
my name instead? Because I HATE the Masked Text Box. Haven't used it in
years except for a program I inherited from another developer.
Author
14 Oct 2005 3:13 PM
Rick Rothstein [MVP - Visual Basic]
> > You would be best to go with Ricks suggestion of using the
Masked text
> > control
>
> Has that control gotten better?  I remember trying it when it
first came out
> and there were lots of bugs in it.  I know I gave up on it
shortly
> thereafter and haven't tried it in years.

Yes, the MaskEditBox has problems, but a simply entry mask like
this should be alright provided the OP puts in some error checking
to make sure the pattern is fully filled in. Something like this I
would assume...

If Len(MaskEdBox1.FormattedText) = 16 Then
  ' The entry is properly formatted
End If

Rick
Author
14 Oct 2005 3:42 PM
Impakt
On Fri, 14 Oct 2005 15:44:10 +0100, "Dave" <nob***@nowhere.com> wrote:

>You would be best to go with Ricks suggestion of using the Masked text
>control
>
I was just looking at that now, but as soon as I entered the 'custom
mask' dialog, VB crashed. And that's it for me tonight!

Cheers
Author
14 Oct 2005 2:27 PM
Jeff Johnson [MVP: VB]
"Impakt" <fcoll***@mail.iinet.net.au> wrote in message
news:434fb551.219049937@news.iinet.net.au...

> I am trying to make a 'credit card' number input form. I want to use a
> single text box and have it insert a space after every 4 characters.
> eg: xxxx xxxx xxxx xxxx
>
> I can get it to 'sort of work' using the keypress method, but I want
> it to insert the space after the 4th character is pressed.

I recommend using the Change event. Then you examine the contents of the box
and determine what to do. You should also keep track of how many characters
WERE in the box on the last Change event. That way, if there were 3 and I
type a 4th, you decide it's time to insert a space. However, if there were 5
and now there are 4, I must be using backspace and it would be really
annoying to delete that space and then have it re-inserted. "But now there
are 4 characters and you can type a 5th one right next to number 4" you say?
Yes, so you should examine the string and if you see "xxxxx" then
immediately change it to "xxxx x".
Author
14 Oct 2005 2:30 PM
Bob Butler
"Impakt" <fcoll***@mail.iinet.net.au> wrote in message
news:434fb551.219049937@news.iinet.net.au
> Hi,
>
> I am trying to make a 'credit card' number input form. I want to use a
> single text box and have it insert a space after every 4 characters.
> eg: xxxx xxxx xxxx xxxx

A couple of things to keep in mind:
if the user types 4 characters and you add a space you need to move the
SelStart value so that the next keypress is after the space

if the user types fewer than 4 characters, then moves left and inserts
additional characters you may want to add the space but not change the
SelStart value

if the user types fewer than 4 characters and then types a space you may not
want to add a space since they obviously need to fix the incorrect entry

if the user pastes a value into the textbox you have to determine if spaces
are there already or not

using 4 boxes and adjusting focus is one option; the downside is that they
can't paste the full value easily

here's a quick & dirty thing that seems to come close (can't say I tested it
extensively):

Private Sub txtCard_Change()
Dim p As Long
Dim sCard As String
Dim x As Long
p = txtCard.SelStart ' remember where the user is
sCard = Trim$(txtCard.Text)
For x = Len(sCard) To 1 Step -1
  If Not (Mid$(sCard, x, 1) Like "[0-9]") Then
    sCard = Left$(sCard, x - 1) & Mid$(sCard, x + 1)
  End If
Next
If Len(sCard) > 16 Then sCard = Left$(sCard, 16)
If Len(sCard) > 4 Then
  sCard = Left$(sCard, 4) & " " & Mid$(sCard, 5)
  If p > 3 Then p = p + 1
End If
If Len(sCard) > 9 Then
  sCard = Left$(sCard, 9) & " " & Mid$(sCard, 10)
  If p > 8 Then p = p + 1
End If
If Len(sCard) > 14 Then
  sCard = Left$(sCard, 14) & " " & Mid$(sCard, 15)
  If p > 13 Then p = p + 1
End If
txtCard.Text = sCard
txtCard.SelStart = p
End Sub

--
Reply to the group so all can participate
VB.Net: "Fool me once..."
Author
14 Oct 2005 2:46 PM
Bob Butler
"Bob Butler" <tiredofit@nospam.com> wrote in message
news:eK2sSvM0FHA.460@TK2MSFTNGP15.phx.gbl

forgot one thing to make it a bit more efficient:

Private Sub txtCard_Change()
Dim p As Long
Dim sCard As String
Dim x As Long
Static FromCode As Boolean
If Not FromCode Then
  FromCode = True
  p = txtCard.SelStart ' remember where the user is
  sCard = Trim$(txtCard.Text)
  For x = Len(sCard) To 1 Step -1
    If Not (Mid$(sCard, x, 1) Like "[0-9]") Then
      sCard = Left$(sCard, x - 1) & Mid$(sCard, x + 1)
    End If
  Next
  If Len(sCard) > 16 Then sCard = Left$(sCard, 16)
  If Len(sCard) > 4 Then
    sCard = Left$(sCard, 4) & " " & Mid$(sCard, 5)
    If p > 3 Then p = p + 1
  End If
  If Len(sCard) > 9 Then
    sCard = Left$(sCard, 9) & " " & Mid$(sCard, 10)
    If p > 8 Then p = p + 1
  End If
  If Len(sCard) > 14 Then
    sCard = Left$(sCard, 14) & " " & Mid$(sCard, 15)
    If p > 13 Then p = p + 1
  End If
  txtCard.Text = sCard
  txtCard.SelStart = p
  FromCode = False
End If
End Sub

Of course, I didn't recognize this as a homework assignment from the OP so
don't turn it in unless you make sure it works and you understand what it is
doing! <g>

--
Reply to the group so all can participate
VB.Net: "Fool me once..."
Author
14 Oct 2005 3:47 PM
Bob Butler
"Bob Butler" <tiredofit@nospam.com> wrote in message
news:O%23iId4M0FHA.2076@TK2MSFTNGP14.phx.gbl
> Of course, I didn't recognize this as a homework assignment from the
> OP so don't turn it in unless you make sure it works and you
> understand what it is doing! <g>

Realized I had a bug if the insertion point (.SelStart) was after any of the
spaces that were inserted.  It would cause it to jump 1-3 characters to the
right as you typed.  I think this fixes that:

Private Sub txtCard_Change()
Dim p As Long
Dim sCard As String
Dim x As Long
Static FromCode As Boolean
If Not FromCode Then ' ignore Change event triggered by this routine
  FromCode = True
  p = txtCard.SelStart ' remember where the user is
  sCard = Trim$(txtCard.Text)
  For x = Len(sCard) To 1 Step -1 ' strip out all non-numeric characters
    If Not (Mid$(sCard, x, 1) Like "[0-9]") Then
      sCard = Left$(sCard, x - 1) & Mid$(sCard, x + 1)
      If p > x Then p = p - 1 ' back off the user position to keep in step
    End If
  Next
  If Len(sCard) > 16 Then sCard = Left$(sCard, 16) ' remove anything extra
  If Len(sCard) > 4 Then ' if we have 5+ then we need a space XXXX X
    sCard = Left$(sCard, 4) & " " & Mid$(sCard, 5)
    If p > 4 Then p = p + 1 ' and we need to keep the relative position
  End If
  If Len(sCard) > 9 Then ' same for 9 XXXX XXXX X
    sCard = Left$(sCard, 9) & " " & Mid$(sCard, 10)
    If p > 9 Then p = p + 1
  End If
  If Len(sCard) > 14 Then ' and 14 XXXX XXXX XXXX X
    sCard = Left$(sCard, 14) & " " & Mid$(sCard, 15)
    If p > 14 Then p = p + 1
  End If
  txtCard.Text = sCard ' update text (triggers Change event)
  txtCard.SelStart = p ' restore relative position
  FromCode = False
End If
End Sub


--
Reply to the group so all can participate
VB.Net: "Fool me once..."
Author
14 Oct 2005 3:51 PM
Bob Butler
"Bob Butler" <tiredofit@nospam.com> wrote in message
news:eDRLmaN0FHA.316@TK2MSFTNGP10.phx.gbl
> "Bob Butler" <tiredofit@nospam.com> wrote in message
> news:O%23iId4M0FHA.2076@TK2MSFTNGP14.phx.gbl
>> Of course, I didn't recognize this as a homework assignment from the
>> OP so don't turn it in unless you make sure it works and you
>> understand what it is doing! <g>
>
> Realized I had a bug if the insertion point (.SelStart) was after any
> of the spaces that were inserted.  It would cause it to jump 1-3
> characters to the right as you typed.  I think this fixes that:

The final thing I see that is "odd" about it is that if you position early
in the text and type non-numeric characters it moves 1 character to the
right for each keypress but doesn't replace the contents.  That can probably
be dealt with also but I kind of like it the way it is.

--
Reply to the group so all can participate
VB.Net: "Fool me once..."
Author
14 Oct 2005 3:00 PM
Impakt
On Fri, 14 Oct 2005 07:30:25 -0700, "Bob Butler"
<tiredofit@nospam.com> wrote:


>A couple of things to keep in mind:
>if the user types 4 characters and you add a space you need to move the
>SelStart value so that the next keypress is after the space

And I think that will fix the problem because I've had it sort of
working but it kept going to the start of the box after it checked the
string length.

>if the user types fewer than 4 characters, then moves left and inserts
>additional characters you may want to add the space but not change the
>SelStart value
Because this is not a -real- app, I've just made it so that before you
print the page, it asks you to confirm the card number (yes/no msg
box) - it's it's wrong, it clears the text box - it's not very tidy,
but the lecturer will not be looking that deep into it.

>if the user pastes a value into the textbox you have to determine if spaces
>are there already or not
No mouse allowed (this is a school project for a 'hotel quote/booking'
app and we are not allowed to use a mouse).

>using 4 boxes and adjusting focus is one option; the downside is that they
>can't paste the full value easily
Most (all) people in my class will use 4 boxes but I figured I could
do it with one (I figured wrong!).

>here's a quick & dirty thing that seems to come close (can't say I tested it
>extensively):
I'll give it a try.

Cheers.
Author
14 Oct 2005 3:08 PM
Bob Butler
"Impakt" <fcoll***@mail.iinet.net.au> wrote in message
news:434fc5bc.223252812@news.iinet.net.au
> Because this is not a -real- app, I've just made it so that before you
> print the page, it asks you to confirm the card number (yes/no msg
> box) - it's it's wrong, it clears the text box - it's not very tidy,
> but the lecturer will not be looking that deep into it.

That's no reason not do do it right!

>> if the user pastes a value into the textbox you have to determine if
>> spaces are there already or not
> No mouse allowed (this is a school project for a 'hotel quote/booking'
> app and we are not allowed to use a mouse).

Sounds like a foolish restriction. In the "real world" users, even ones
doing hotel booking, will use the mouse and if you only know how to code for
the keyboard then your apps will appear to be bug-ridden to mouse users.
Coding for a limited scenario has it's uses, especially when learning, but
denying the existence of the mouse doesn't make much sense to me.

>> using 4 boxes and adjusting focus is one option; the downside is
>> that they can't paste the full value easily
> Most (all) people in my class will use 4 boxes but I figured I could
> do it with one (I figured wrong!).

You had the right general idea and found out that most things are more
complicated than they appear when you get into them.  That's a valuable
lesson in itself!

--
Reply to the group so all can participate
VB.Net: "Fool me once..."
Author
14 Oct 2005 3:35 PM
Impakt
On Fri, 14 Oct 2005 08:08:40 -0700, "Bob Butler"
<tiredofit@nospam.com> wrote:

>"Impakt" <fcoll***@mail.iinet.net.au> wrote in message
>news:434fc5bc.223252812@news.iinet.net.au
>> Because this is not a -real- app, I've just made it so that before you
>> print the page, it asks you to confirm the card number (yes/no msg
>> box) - it's it's wrong, it clears the text box - it's not very tidy,
>> but the lecturer will not be looking that deep into it.
>
>That's no reason not do do it right!

Yes it is ;-) I consistantly go way over the top with my programming
tasks - all I do is create a lot of extra work for myself and I don't
score any extra points for it. Also, we have 5 weeks to complete this
program (along with the projects from our other classes!) and three of
those weeks we can not 'interview the client' because they are 'on
holiday'.


>Sounds like a foolish restriction. In the "real world" users, even ones
>doing hotel booking, will use the mouse and if you only know how to code for
>the keyboard then your apps will appear to be bug-ridden to mouse users.
True, but this app is a 'self serve kiosk' type thing and we have to
make is as robust as possible (no crashing, no way to exit the app
(except via a specific log in name).

>Coding for a limited scenario has it's uses, especially when learning, but
>denying the existence of the mouse doesn't make much sense to me.
Well this is a learning app. A few weeks ago we were messing around
with keycode and keyascii, so we are being forced to use what we
learnt.

>You had the right general idea and found out that most things are more
>complicated than they appear when you get into them.  That's a valuable
>lesson in itself!
Looking at your solution gave me a few extra grey hairs! Now I need to
try an figure out what you did (I can sort of see it, but I've been
coding for 16 hours and I need a break).

Thanks again.
Author
14 Oct 2005 3:09 PM
Impakt
On Fri, 14 Oct 2005 07:30:25 -0700, "Bob Butler"
<tiredofit@nospam.com> wrote:


>here's a quick & dirty thing that seems to come close (can't say I tested it
>extensively):

That bit of code worked great Bob. Thanks heaps.
I've credited the code to you via code comments.


Cheers

Paul - West Aust.
Author
14 Oct 2005 2:32 PM
Rick Rothstein [MVP - Visual Basic]
> I am trying to make a 'credit card' number input form. I want to
use a
> single text box and have it insert a space after every 4
characters.
> eg: xxxx xxxx xxxx xxxx

You might want to consider using a MaskEditBox control instead.
Just set the Mask to

     #### #### #### ####

and you are set to go. You can read in the digits only (without
the separating spaces) using the control's ClipText property. The
FormattedText property will give you the numbers along with the
separating blanks if that is what you want. There is one more
"text" property to know about and that is the Text property which
gives you the text as it appears in the control (the character set
into the PromptChar property is retained).

Rick
Author
14 Oct 2005 3:10 PM
Impakt
On Fri, 14 Oct 2005 13:48:05 GMT, fcoll***@mail.iinet.net.au (Impakt)
wrote:

>Hi,
>
>I am trying to make a 'credit card' number input form. I want to use a
>single text box and have it insert a space after every 4 characters.
>eg: xxxx xxxx xxxx xxxx

Thanks to all who took the trouble to reply. Bob's solution worked
great!


Have fun!


Paul - West. Aust.