I'm not a big fan of sticking an mask representation in front of the user. I prefer they just type and I'll work on interpreting what they are giving me. I adapted the phone number edit mask function from Martin Francom and built one the way I wanted things to work. It probably could use some more fiddling around with. There is a small adaptation that tries to detect the DELETE key in the area code area. I haven't done anything like that with the body of the number and the delimiter "-".
The functions:
Function EditMaskPhoneAreaCode (ByVal hWndControl As Long) As String
' Formats phone number as (222) 333-4444
Static fProcessing As Long
Static fTest As Long
Local sInput As String
Local nStartPos As Long
Local nEndPos As Long
Local sEditedInput As String
Local nPos As Long
' Prevent re-entry until after process finishes
If fProcessing = %TRUE Then Exit Function
SendMessage hWndControl, %EM_GETSEL, VarPtr(nStartPos), VarPtr(nEndPos)
If fTest <> 0 Then Exit Function
fTest = 1
sInput = FF_TextBox_GetText (hWndControl)
sEditedInput = sInput
AreaCodePhoneNumbers (sEditedInput)
If sEditedInput <> sInput Then
nPos = Len(sEditedInput)
FF_TextBox_SetText (hWndControl, sEditedInput)
FF_TextBox_SetSel (hWndControl, nPos, nPos )
End If
fTest = 0
Function = sEditedInput
fProcessing = %False
End Function
Sub AreaCodePhoneNumbers (ByRef sInput As String)
' Phone numbers in the format (999) 999-9999 where the area code is optional
Local sRaw As String
Local sOutput As String
' If input is empty exit
If Len(sInput) < 1 Then
Exit Sub
End If
sOutput = ""
' Remove non-valid characters and truncate to maximum raw phone number length
sRaw = Retain$ (sInput, Any "0123456789")
If Len(sRaw) > 10 Then
sRaw = Left$(sRaw,10)
End If
' If we have no numbers check if first character of input is a "(" and exit
If Len(sRaw) < 1 Then
If Left$(sInput,1) = "(" Then
sInput = "("
Else
sInput = ""
End If
Exit Sub
End If
' If first character of input is a "(" and the closing ")" is also found with fewer than 3 characters between the two
' then assume the DELETE key was used and do nothing.
If Left$(sInput,1) = "(" And Instr(sInput,")") < 5 Then
Exit Sub
End If
' If first character of input is a "(" then format for the optional area code
If Left$(sInput,1) = "(" Or Len(sRaw) > 7 Then
' Check if we have enough numbers to insert the ")"
If Len(sRaw) > 2 Then
sInput = "(" + Left$(sRaw,3) + ") "
' Check for enough numbers to insert the "-"
If Len(sRaw) = 3 Then
Exit Sub
End If
If Len(sRaw) < 6 Then
sInput = sInput + Mid$(sRaw,4,Len(sRaw) - 3)
Exit Sub
End If
' Insert the "-"
sInput = sInput + Mid$(sRaw,4,3) + "-"
If Len(sRaw) > 6 Then
sInput = sInput + Mid$(sRaw,7,Len(sRaw) - 6)
End If
Exit Sub
Else
sInput = "(" + sRaw
Exit Sub
End If
End If
' Phone number without the optional area code
If Len(sRaw) > 2 Then
sInput = Left$(sRaw,3) + "-" + IIF$(Len(sRaw) > 3,Right$(sRaw,Len(sRaw) - 3),"")
Else
sInput = sRaw
End If
End Sub
Then in the edit control just put this in the EN_CHANGE function
EditMaskPhoneAreaCode (hWndControl)
To validate the results before updating a database, just check for 7 or 10 digits using:
sRawPhoneNumber = RETAIN$ (sYourEnteredPhoneNumber, ANY "0123456789")
If LEN(sRawPhoneNumber) = 7 or LEN(sRawPhoneNumber) = 10 Then
' Phone number is ok
Else
' Phone number is incomplete
End If
Rick Kelly
Rick,
I have had a running debate with myself as to which is the best way to implement structure to a text field. Using a edit mask that formats the field as the user types or to format what has been typed after they leave the field. There are advantages and problems with both. With an edit mask I have had problems with keeping tack of the carrot when the user moves around in the field using the mouse. But I like that the edit mask shows the user what is expected in the field.
I would love to see Paul add a Field in the Properties box of a Text Box where the mask could be described and FF would add the appropriate code at compile time. That way any type of mask could be described and appropriate code added. These are some of the masks that I use frequently:
Phone: (###) ###-####
SSN: ###-##-####
DEA: AA#######
Metric Decimal Quantity: #######.###
Money: #######.##
ProperCase: Ucccccc