B4A Library [Lib] Masked EditText

Informatix

Expert
Licensed User
This EditText fixes a few issues with the standard EditText and adds new features:
- Filter: you can transform any input before the text is changed;
- Mask: you can define an input mask;
- Read-only: you can protect your EditText against changes;
- Floating hint: the hint moves above the EditText when the user starts typing;
- Error popup: you can display a message in a popup to warn the user:

met.png

v1.1:
- It is now a custom view supported by the designer
- I fixed a bug when Format was set after WithSuggestions

v1.2:
- I moved the CompactText function from the example to the library;
- I fixed a bug with SelectionStart;
- I fixed a bug when InputType is set to NONE.

v1.3:
- WithSuggestions works now as expected on Samsung devices.
- Suggestions are automatically disabled in password mode.

v1.4:
- I added the EnableFloatingHint function;
- I added the custom view properties for the designer.

v1.41:
- I improved the animation of the floating hint;
- I fixed an issue with the hint color.

v1.42:
- I fixed a bug with the floating hint when the EditText is moved.

v1.5:
- I rewrote the code of floating hints to make it more robust and fix a few issues;
- I added the SetFromHTML function.

v1.51:
- A few properties set in the designer were not taken into account.

v1.52:
- There was an issue with the background drawable as it was set by default by the designer to a white colored drawable. The support of this property in the designer was removed to keep the original default background.

This library does not work with Android versions < 2.
 

Attachments

Last edited:

Harris

Expert
Licensed User
Man, it never stops with you, does it?

I can't fathom where you come up with these ideas? Just DON'T stop! We love it.

All your contributions are Great! I use many... and shall (soon) contribute (donate).

Personally, I prefer classes over libs since I can learn and modify them to suit my needs.

Check out my latest work in progress - you shall see your handy work at play..


The BC RV Forum &bull; View topic - New Android App
 

Informatix

Expert
Licensed User
All your contributions are Great!
Thank you. :)

Personally, I prefer classes over libs since I can learn and modify them to suit my needs.
I prefer too, but most of my recent works cannot be written directly in B4A.

Check out my latest work in progress - you shall see your handy work at play..
It's always nice to see my code in other projects than mine.
 

swissmade

Well-Known Member
Licensed User
Thank you. :)



I prefer too, but most of my recent works cannot be written directly in B4A.



It's always nice to see my code in other projects than mine.
Very nice Work thanks;):)
 

lhbrito

Member
Licensed User
Great!

I was creating a class to implement the mask in the EditText, but your solution is better.

I would only suggest the following:

In property "Format":
- Add something like "@l" for all characters in lowercase.
- Add something like "@u" for all characters in uppercase.
- Add a property (or method) to return the text without the mask:
example:
If the format is "##.###.###-##" and typed "12.345.678-90", return is "1234567890".
(this is useful for recording in the database without the mask)

Thanks and congratulations!

Edit :
A function that removes the mask of a string (I used in the class that I was developing):

B4X:
Sub WithoutMask(cString As String, cMask As String) As String
  Dim I As Int
    Dim MaskElements As String
    Dim Result As String
   
    Result      = ""
    MaskElements = "#LAH?"
    For I = 0 To cMask.Length-1
      If (MaskElements.Contains(cMask.CharAt(I))) AND (I<=cString.Length-1) Then
          Result = Result & cString.CharAt(I)
        End If
    Next
    Return Result
End Sub
This EditText fixes a few issues with the standard EditText and adds new features:
- Filter: you can transform any input before the text is changed;
- Mask: you can define an input mask;
- Read-only: you can protect your EditText against changes;
- Error popup: you can display a message in a popup to warn the user:

v1.1:
- It is now a custom view supported by the designer
- I fixed a bug when Format was set after WithSuggestions

v1.2:
- I moved the CompactText function from the example to the library;
- I fixed a bug with SelectionStart;
- I fixed a bug when InputType is set to NONE.

This library does not work with Android versions < 2.
 
Last edited:

Informatix

Expert
Licensed User
In property "Format":
- Add something like "@l" for all characters in lowercase.
- Add something like "@u" for all characters in uppercase.
That was my first intent but I realized during the development that it was better to use the filter event. A mask for a name, for example, is too complex to do with mask characters only. If you set something like U???????????????? (with U = upper case), you allow any character, but a name cannot accept numbers. If you set something like ULLLLLLLLLLLLL (with L = lower case), you don't allow space or hyphen and you don't handle properly names with two capitals like "Leneuf-Magaud" or "Di Gregorio".


Edit :
A function that removes the mask of a string (I used in the class that I was developing):
In the example provided with the library, you should look at the RawText function. It returns the text without the mask characters and it's more efficient than your own example (when you create strings by appending characters, it is a lot faster to use a StringBuilder).
 

lhbrito

Member
Licensed User
That was my first intent but I realized during the development that it was better to use the filter event. A mask for a name, for example, is too complex to do with mask characters only. If you set something like U???????????????? (with U = upper case), you allow any character, but a name cannot accept numbers. If you set something like ULLLLLLLLLLLLL (with L = lower case), you don't allow space or hyphen and you don't handle properly names with two capitals like "Leneuf-Magaud" or "Di Gregorio".
yes ... validating the name only through the mask is complex. The idea was not to validate, it was only to force all characters are uppercase or all lowercase.
For fields of e-mail, for example.
But of course the solution at the time of recording in the database is simple. It was just to avoid typing was possible to type in uppercase when I know that the field will only accept lowercase.

In the example provided with the library, you should look at the RawText function. It returns the text without the mask characters and it's more efficient than your own example (when you create strings by appending characters, it is a lot faster to use a StringBuilder).
sorry.. I have not seen in the example...my main source of reference was the "Methods and properties.html" file that accompanies the library.


Thanks for the tip of the StringBuilder and explanations.
 

gdeppi

Member
Licensed User
Very interesting library.

I have a request: when I insert data with format mask "##/##/####", if the Text it's still filled
for example 31/03/2014 and I try to change the first character for example from 3 to 2, the entire text
starting from postition 2 is shifted by one to the right.
Result I must to re enter the entire text because the date become wrong.
It would be nice if only the character typed was changed, keeping unchanged the rest of the text .
Eg:
before 31/03/2014
I type 2 on first position
after result is 23/10/3201
instead of 21/03/2014
 

Informatix

Expert
Licensed User
Very interesting library.

I have a request: when I insert data with format mask "##/##/####", if the Text it's still filled
for example 31/03/2014 and I try to change the first character for example from 3 to 2, the entire text
starting from postition 2 is shifted by one to the right.
Result I must to re enter the entire text because the date become wrong.
It would be nice if only the character typed was changed, keeping unchanged the rest of the text .
Eg:
before 31/03/2014
I type 2 on first position
after result is 23/10/3201
instead of 21/03/2014
All text fields under Android are in Insert mode by default; they switch in Replace mode only when you select some text, and switch back to the Insert mode when the text has been replaced. Thus, to replace the first char, you have to position the cursor behind, hit the delete key, then enter the new char, or you can select the first char and type the new char. If, in my code, I try to force a replacement while I'm in Insert mode, I'll have to handle many particular cases to avoid a big mess in the most common situations, so I prefer to stick to the Android guidelines.
 

cds-soft

Member
Licensed User
First of all, thanks for this great library.

I have only one question, should be posible to change the definition of mask characters? I'm spanish, and if i put 'Horas: ##:##' for a time input, H is recognize as Hexadecimal. Can i change something in the xml or in the jar to make my 'custom' definition? Thanks.
 

Informatix

Expert
Licensed User
First of all, thanks for this great library.

I have only one question, should be posible to change the definition of mask characters? I'm spanish, and if i put 'Horas: ##:##' for a time input, H is recognize as Hexadecimal. Can i change something in the xml or in the jar to make my 'custom' definition? Thanks.
By laziness, I put a descriptive text directly in the EditText field in my example, but this text should be displayed in a label before the EditText. Same thing for you. Horas should not be in the EditText, but in a separate Label.
 

Roberto Cardenas

Member
Licensed User
Hello, I hope you are doing fine.
I'm trying to use this library to capture a currency field but I have some troubles when assigning the value directly from code (I read the value from a table, but is the same when I assign it directly); for example I have the value "220.50" the expected result when I assign it to the maskedit is: "000,220.50" but I'm getting "000,022.05", I attached a sample of the current result, the code I'm using is the following.

B4X:
          txtAmount.Format = "###,###.##"
          txtAmount.SingleLine = True
          txtAmount.InputType = txtAmount.INPUT_TYPE_DECIMAL_NUMBERS
          txtAmount.Text = sf.Pad(tblExpense.GetValue(6, Row),"0",9,False)

Thanks for your help.

Best Regards,
Robert
 

Attachments

Top