RedMadRobot / input-mask-ios

User input masking library repo.
MIT License
574 stars 95 forks source link

First number of mask(#104) #111

Open margulan97 opened 1 year ago

margulan97 commented 1 year ago

Prerequisites

I have previous request #104 about first symbol

can you help me where I can fix that behavior, because I have multiple masks that comes from backend and I need to fill it correctly now I fix it only for phone number case.

open func put(text: String, into field: UITextField, autocomplete putAutocomplete: Bool? = nil, valueWithPrefix: Bool = false) -> InputMask.Result I add value with prefix parameter that duplicate first char, but I have case where I just put masks from backend I look at apply func in Mask, but I can't find solution

if valueWithPrefix && !updatedText.isEmpty { if let first = updatedText.first { let firstCharacter = String(first) updatedText = firstCharacter + updatedText } }

taflanidi commented 1 year ago

Hi @margulan97 I'd be glad to help you out.

From you, I need a complete user story, including all the edge cases, regarding the phone numbers ought to be formatted.

Right now, I haven't got enough information on what's actually happening in your app. From a cursory view, it feels like you've got to sanitise your data before it appears on the UI layer; thus, overriding the library behaviour would be a design violation.

margulan97 commented 1 year ago

for example I have many mask like "+7 [999]" and "55[999]" and etc, when value comes from backend and set value in mask like that and first char in text Is the same as +7 or 5 mask removes first character. example: mask "55 [999]", put(text: "555"), output 55 55, mask removed first char, in my code I add additional 5 in puted text.

taflanidi commented 1 year ago

Okay, does your app serve multiple countries?

margulan97 commented 1 year ago

this mask is not for the phone, but for payments. all masks come from the backend and can be pre-filled if the user made such a payment before.

margulan97 commented 1 year ago

if let firstMaskNumber = primaryMaskFormat.first(where: { $0.isNumber }), let firstTextNumber = updatedText.first, firstMaskNumber == firstTextNumber { updatedText.insert(firstTextNumber, at: updatedText.startIndex) } I have crutch solution like that but I think this logic must do apply func in mask class

taflanidi commented 1 year ago

I think this logic must do apply func in mask class

Why do you think so?

margulan97 commented 1 year ago

I think the mask class should return the correct result, because all the logic with the cursor and text in this class. Maybe I'm wrong idk

taflanidi commented 1 year ago

this mask is not for the phone, but for payments. all masks come from the backend and can be pre-filled if the user made such a payment before.

Got it. Here, you've got to apply an architectural design alteration.

See, previously, your user had conducted a payment associated with a concrete, formatted number.
This number is already proven to have no mistakes, which typically makes you want it to be immutable.

Thus, you've got two options.
First, during the initial payment, you may send not only the number, but also attach an applied mask.

{
  "number": "123…",
  "mask": "+7 [999]…"
}

Second option, during the initial payment attach an already formatted number and make sure to use it afterwards:

{
  "number": "123…",
  "formatted_number": "+7 123…"
}
taflanidi commented 1 year ago

I think the mask class should return the correct result

The Mask class is ought to be a "text formatting utility", regardless of the text attributes, properties nor the meta information it carries.

Your proposition is to make it aware that the text is actually a number and has some additional info behind it, which is an SRP violation and an abstraction hole.

taflanidi commented 1 year ago

AFAIU you receive masks from your backend, and it seems like you are omitting the first number of your value for some reason.

Meaning that you use +7 [000] instead of +{7} [999].

Thus, your system is missing a mandatory part of user information. This part is mandatory because you actually use it for subsequent payments.

roostique commented 1 year ago

In both cases +7 [000] & +{7} [999] a user must start editing with '+' or '7'. Otherwise a textfield will remain empty, it wont allow a user to type anything. How do we get around this? @margulan97 @taflanidi

Expected behavior: A user enters any number, and prefixes are inserted automatically. i.e. types 352, textfield shows +7 352

Solved: Need to set a desired mask to primaryMaskFormat

taflanidi commented 1 year ago

Hi @roostique

In both cases +7 [000] & +{7} [999] a user must start editing with '+' or '7'. Otherwise a textfield will remain empty, it wont allow a user to type anything

Are you sure? My apologies, but the library behaviour wasn't implemented like that.

For an empty text field with +7 [000] or +{7} [999] mask attached and autocompletion turned on, when you type 7, you achieve +7 (notice the trailing space). When you type anything else, say 1, you achieve +7 1.

roostique commented 1 year ago

Hi @roostique

In both cases +7 [000] & +{7} [999] a user must start editing with '+' or '7'. Otherwise a textfield will remain empty, it wont allow a user to type anything

Are you sure? My apologies, but the library behaviour wasn't implemented like that.

For an empty text field with +7 [000] or +{7} [999] mask attached and autocompletion turned on, when you type 7, you achieve +7 (notice the trailing space). When you type anything else, say 1, you achieve +7 1.

Thank you for response Might be issue with the custom textfield used in my project, we're using JVFloatLabeledTextField. I'll check it out and get back to you asap

taflanidi commented 1 year ago

@roostique thanks for a quick response!

You may check out our Sample project with simple text fields for a reference.

taflanidi commented 1 year ago

@roostique heya

Got any updates?

roostique commented 1 year ago

@taflanidi hi! i've updated my comment with the solution. The problem was i've set affine format, but not primaryMaskFormat. Its was "" by default, therefore didn't provide an expected behaviour.

taflanidi commented 1 year ago

Whoa.

Okay, thank you so much. Sounds like I've got to add some measures to manage this case as well.