B4A Library [B4X] [XUI] AS TextFieldAdvanced - Title, Information, Counter, Password, Button, Prefix, Suffix, Icons, Multiline

Alexander Stolte

Expert
Licensed User
Longtime User
Update
  • 1.19
    • Add FocusedShapeColor
      • Default: White with alpha 0 = Transparent
    • Add set TextColor
    • Add Designer Property TextFieldCornerRadius
      • Default: 5dip
    • B4J BugFix - The EnterPressed Event was not triggered
FocusedShapeColor
Default color is Transparent, so that it does not break anything existing

TextFieldCornerRadius
Your TextFields can now look like this:
 

Soheyl

Member
Licensed User
Longtime User
The usage of NativeTextField and NativeTextFieldMultiline is resulting in an error.

B4X:
Dim su          As StringUtils
Dim MaximumSize As Int = su.MeasureMultilineTextHeight(AS_TextFieldAdvanced_1.NativeTextFieldMultiline, "Text Size") * 8

log:
java.lang.RuntimeException: Object should first be initialized (B4XView).
 

Alexander Stolte

Expert
Licensed User
Longtime User
Update
  • 1.20
    • BugFixes
    • Add Designer Property StrengthIndicator - Password strength indicator
      • None|Line|Segmented
      • Default: None
Multiline Bug
-readonly mode
-text alignment
Works now
StrengthIndicator
Example:
 

Lucas Siqueira

Active Member
Licensed User
Longtime User



it would be great if it had mascara, here is a code to add to the class, I tested it on android, and it worked 100%

B4X:
#DesignerProperty: Key: Mask, DisplayName: Mask, FieldType: String, DefaultValue: None, List: None|Left|Right, Description: Where to start the mask.
#DesignerProperty: Key: MaskText, DisplayName: MaskText, FieldType: String, DefaultValue: XXX.XXX.XXX-XX, Description: Mask format use X or 0 to indicate the characters that will be replaced.

Sub Class_Globals
...
    Private m_Mask As String = ""
    Private m_MaskText As String = ""
End Sub

Private Sub IniProps(Props As Map)
...
    m_Mask = Props.GetDefault("Mask","")
    m_MaskText = Props.GetDefault("MaskText","")
End Sub



Private Sub TextChanged(Text As String)
    If m_Mask<>"None" And (m_MaskText.Contains("X") Or m_MaskText.Contains("0"))  Then
        Dim textMasked As String = applyMask(Text, m_MaskText, m_Mask)
        If Text <> textMasked Then 
            xtf_TextField.Text = textMasked
            xtf_TextField.SelectionStart = xtf_TextField.Text.Length
        End If        
    End If

    If g_Counter.Visible Then
        If Text.Length > g_Counter.CounterMax Then
            
            If xtf_TextField.IsInitialized Then 
                Dim SelectionStart As Int = xtf_TextField.SelectionStart
                xtf_TextField.Text = Text.SubString2(0,g_Counter.CounterMax)
                xtf_TextField.SelectionStart = Min(SelectionStart,xtf_TextField.Text.Length)
            End If
            If xtf_TextFieldPassword.IsInitialized Then 
                Dim SelectionStart As Int = xtf_TextFieldPassword.SelectionStart
                xtf_TextFieldPassword.Text = Text.SubString2(0,g_Counter.CounterMax)
                xtf_TextFieldPassword.SelectionStart = Min(SelectionStart,xtf_TextFieldPassword.Text.Length)
            End If
            If xtf_Multiline.IsInitialized Then    
                Dim SelectionStart As Int = xtf_Multiline.SelectionStart
                xtf_Multiline.Text = Text.SubString2(0,g_Counter.CounterMax)
                xtf_Multiline.SelectionStart = Min(SelectionStart,xtf_Multiline.Text.Length)
            End If
            Text = Text.SubString2(0,g_Counter.CounterMax)
        End If
    End If
    
    If Text.Length = 0 Then
        xlbl_ClearButton.Visible = False
        xlbl_RevealButton.Visible = False
        xlbl_Hint.Visible = g_Hint.Visible
    Else
        xlbl_ClearButton.Visible = m_ShowClearButton
        xlbl_RevealButton.Visible = m_PasswordField And m_ShowRevealButton
        xlbl_Hint.Visible = False
    End If
    
    xlbl_Counter.Text = Text.Length & "/" & g_Counter.CounterMax
    TextChanged_Event(Text)
End Sub


Private Sub lettersAndNumbers(Text As String) As String
    Dim enable As String = "abcdefghijklmnopqrstuvwxyzçáãàâäéèêëíìîïóòôõöúùûüçABCDEFGHIJKLMNOPQRSTUVWXYZÁÃÀÂÄÉÈÊËÍÌÎÏÓÒÔÕÖÚÙÛÜÜÇ0123456789"
    
    Dim textClear As StringBuilder
    textClear.Initialize
    For i = 0 To Text.Length-1
        Dim c As String = Text.CharAt(i)
        If enable.Contains(c) Then 
            textClear.Append(c)
        End If        
    Next
    Return textClear.ToString
End Sub

Private Sub applyMask(Text As String, Mask As String, Start As String) As String
    Dim textClear As String = lettersAndNumbers(Text)
    Dim textMasked As StringBuilder
    textMasked.Initialize
    Log(textClear)
    Try
        
        'check how many zeros are in the mask -> verifica quantos zeros tem na mascara
        Dim zeros As Int = 0
        For i = 0 To (Mask.Length-1)
            If Mask.CharAt(i)="0" Then
                zeros = zeros + 1
            End If
        Next
        
        If zeros > 0 Then
            If IsNumber(textClear) Then
                textClear = textClear.As(Long)
            End If
        End If
        
        'if there are more zeros in the mask than characters in the text, add zeros to the text, until you get the number of zeros in the mask -> caso tem mais zeros na mascara do que caracteres no texto, adiciona zeros ao texto, até dar a quantidade de zeros da mascara
        If zeros > textClear.Length Then
            textClear = "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & textClear
            textClear = textClear.SubString(textClear.Length-zeros)
        End If
        
        If Start="Left" Then
            For i = 1 To Mask.Length
                Dim c As Char = Mask.CharAt(i-1)
                If (c="X" And textClear.Length>0) Or (c="0" And textClear.Length>0) Then
                    Dim t As Char = textClear.CharAt(0)'get the last character -> pega o ultimo caracter
                    textClear = textClear.SubString(1)'remove the last character -> remove o ultimo caracter
                    textMasked.Append(t)
                Else
                    If c="X" Or textClear.Length=0 Then
                        Exit
                    End If
                    textMasked.Append(c)
                End If
            Next
            
        Else If Start="Right" Then
            For i = Mask.Length To 1 Step -1
                Dim c As Char = Mask.CharAt(i-1)
                If (c="X" And textClear.Length>0) Or (c="0" And textClear.Length>0) Then
                    Dim t As Char = textClear.CharAt(textClear.Length-1)'get the last character -> pega o ultimo caracter
                    textClear = textClear.SubString2(0,textClear.Length-1)'remove the last character -> remove o ultimo caracter
                    textMasked.Insert(0, t)
                Else
                    If c="X" Or textClear.Length=0 Then
                        Exit
                    End If
                    textMasked.Insert(0, c)
                End If
            Next
        End If
    Catch
        Log(LastException)
    End Try
    Log(textMasked.ToString)
    Return textMasked.ToString
End Sub
 

Alexander Stolte

Expert
Licensed User
Longtime User
Update
  • 1.21
    • Add Designer Property RequiredField - if True the field is a required field and is marked with a colored star
      • Default: False
    • Add Designer Property RequiredFieldColor
      • Default: Red
    • Add ShowDisplayMissingField - Call this function to inform the user that not all required fields are filled in
      • Call HideDisplayMissingField to remove it
    • Add HideDisplayMissingField - Removes the user notification from ShowDisplayMissingField
    • Add Designer Property Mask - You can use masks now
      • Default: None
    • Add Designer Property MaskText
      • Example: XXX.XXX.XXX-XX
Special thanks to @Lucas Siqueira for his code in #67 for the mask feature.

RequiredFields
Call the function "ShowDisplayMissingField" to show the user he has to fill something. Call the "HideDisplayMissingField" function to remove it

Mask
When the user types something, the text view automatically formats it into the correct format

 

PumaCyan

Member
Licensed User
Mask
When the user types something, the text view automatically formats it into the correct format

Can the mask property be enabled via code?
such as :

Sample Code:
Private Sub AS_TextFieldAdvanced_TextChanged(Text As String)
    If Text. Length = 4 Then
        AS_TextFieldAdvanced. mask = "X.XXX"
    Else If Text. Length = 7 then
        AS_TextFieldAdvanced.mask = "X.XXX.XXX"
    End If
End Sub
 

Lucas Siqueira

Active Member
Licensed User
Longtime User
Two other suggestions for improvements:

1) icon color (xlbl_ClearButton, xlbl_RevealButton) if the background is light and if the background is dark.
(using the code Alexandre Stolte: https://www.b4x.com/android/forum/threads/b4x-check-if-color-is-dark-or-light.110463/)

1.1) add code below isColorDark;
1.2) modify DesignerCreateView;
B4X:
...
xlbl_ClearButton.TextColor = IIf(isColorDark(m_BackgroundColor),xui.Color_ARGB(152,255,255,255),xui.Color_ARGB(152,0,0,0))
...
xlbl_RevealButton.TextColor = xlbl_ClearButton.TextColor
...

B4X:
Private Sub isColorDark(color As Int) As Boolean
    Dim res(4) As Int
    res(0) = Bit.UnsignedShiftRight(Bit.And(color, 0xff000000), 24)
    res(1) = Bit.UnsignedShiftRight(Bit.And(color, 0xff0000), 16)
    res(2) = Bit.UnsignedShiftRight(Bit.And(color, 0xff00), 8)
    res(3) = Bit.And(color, 0xff)
    
    Dim darkness As Int = 1 - (0.299 * res(1) + 0.587 * res(2) + 0.114 * res(3))/255
    
    If darkness <= 0.5 Then
        Return False 'It's a light color
    Else
        Return True 'It's a dark color
    End If
End Sub



2) add FocusedTitleTextColor and NonFocusedTitleTextColor as it is fixed to white color.
2.1) add properties in designer FocusedTitleTextColor and NonFocusedTitleTextColor;
2.2) modify the IniProps sub for g_Title to receive the FocusedTitleTextColor and NonFocusedTitleTextColor parameters;
2.3) modify the sub CreateASTextFieldAdvanced_Title to receive the new parameters FocusedTitleTextColor and NonFocusedTitleTextColor;
2.4) modify the Style sub to validate m_HasFocus = true, to define the title color using the new parameters FocusedTitleTextColor and NonFocusedTitleTextColor;


B4X:
...
#DesignerProperty: Key: FocusedTitleTextColor, DisplayName: Focused Title Text Color, FieldType: Color, DefaultValue: 0xFFFFFFFF, Description: You can use the built-in color picker to find the color values.
#DesignerProperty: Key: NonFocusedTitleTextColor, DisplayName: Non Focused Title Text Color, FieldType: Color, DefaultValue: 0x64FFFFFF, Description: You can use the built-in color picker to find the color values.
...

Private Sub IniProps(Props As Map)
...
g_Title = CreateASTextFieldAdvanced_Title(Props.Get("Title"),Props.Get("TitleText"),DipToCurrent(Props.Get("TitleHeight")),False,xui.CreateDefaultBoldFont(15),xui.PaintOrColorToColor(Props.Get("FocusedTitleTextColor")),xui.PaintOrColorToColor(Props.Get("NonFocusedTitleTextColor")),CreateASTextFieldAdvanced_ViewTitle(xlbl_Title))
...
End Sub
...


Private Sub Style
    '****************View Properties*******************************
    'Title Options
    If g_Title.IgnoreProperties = False Then
        xlbl_Title.Text = g_Title.Text
        If m_HasFocus Then
            xlbl_Title.TextColor = g_Title.FocusedTextColor
            Log(g_Title.FocusedTextColor)
        Else
            xlbl_Title.TextColor = g_Title.NonFocusedTextColor
            Log(g_Title.NonFocusedTextColor)
        End If
        xlbl_Title.Font = g_Title.xFont
        xlbl_Title.SetTextAlignment("CENTER","LEFT")
        
        xlbl_TitleReqiredField.Text = "*"
        xlbl_TitleReqiredField.Textcolor = m_RequiredFieldColor
        xlbl_TitleReqiredField.Font = g_Title.xFont
        xlbl_TitleReqiredField.SetTextAlignment("CENTER","LEFT")
        
    End If
...
End Sub


...
Public Sub CreateASTextFieldAdvanced_Title (Visible As Boolean, Text As String, Height As Float, IgnoreProperties As Boolean, xFont As B4XFont, FocusedTextColor As Int, NonFocusedTextColor As Int, View As ASTextFieldAdvanced_ViewTitle) As ASTextFieldAdvanced_Title e tambem modifique o type ASTextFieldAdvanced_Title
    Dim t1 As ASTextFieldAdvanced_Title
    t1.Initialize
    t1.Visible = Visible
    t1.Text = Text
    t1.Height = Height
    t1.IgnoreProperties = IgnoreProperties
    t1.xFont = xFont
    t1.FocusedTextColor = FocusedTextColor
    t1.NonFocusedTextColor = NonFocusedTextColor
    t1.View = View
    Return t1
End Sub

 

Attachments

  • AS_TextFieldAdvanced.bas
    66.1 KB · Views: 103

jahswant

Well-Known Member
Licensed User
Longtime User
How to set the hint programatically ! Setting it with AS_TextFieldAdvanced_4.Hint.View.xlbl_Hint.Text = is distorting the view.
Never Mind had to call :

AS_TextFieldAdvanced_4.Refresh
 
Last edited:

cobra666

Member
Licensed User
Longtime User
Got a request.

now u have to use designer to set keyboard type. can u make the option to use code to change it.

and found something strange.

When u use corner radius(base background) and u forget to change TextfieldCornerradius then i get this



maybe remove TextfieldCornerradius and background color(custom properties) and let Base Background handle the colors/radius
 

Alexander Stolte

Expert
Licensed User
Longtime User
hey @Alexander Stolte could you add option to cahange the reveal label color ? In the official lib ?
But then the change would be invalid to automatically adjust the text color when using a light design. in #71
When u use corner radius(base background) and u forget to change TextfieldCornerradius then i get this
Please use the provided function to change the corner radius.
B4X:
AS_TextFieldAdvanced_1.TextFieldCornerRadius = 10dip
maybe remove TextfieldCornerradius and background color(custom properties) and let Base Background handle the colors/radius
Why should I do that? There are properties provided for this purpose that you should use.
 

cobra666

Member
Licensed User
Longtime User

They both do the same thing. thats why i suggested it
 

fbritop

Active Member
Licensed User
Longtime User
Do you have an example of using CreateASTextFieldAdvanced_Hint?

Thanks
FBP
 

fbritop

Active Member
Licensed User
Longtime User
Thanks!
If it is an intern function, should it be kept as "Private" so it does not appears in the intellisense?
 

Daica

Active Member
Licensed User
I'm trying to make the textfield look something like this:


Not sure how I can do that? I've been messing with the designer settings and I just can't get it to look anything like that.

I set the border, which is good.
But when I set the background color to white, it just becomes invisible.
I dont think there is a "Non Focused Shape Color" or a border color
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…