Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] How do I initially fill in the mask having only symbols for blanks? #114

Open
krypt-lx opened this issue Apr 1, 2024 · 10 comments
Assignees
Labels

Comments

@krypt-lx
Copy link

krypt-lx commented Apr 1, 2024

It is not a bugreport, but I question I can't find the answer for:

  • I have a mask, lets use +1 ([000]) [000] [00] [00] for example
  • I have a value 1234567890, which represents blank characters of the mask (the same value returned in extractedValue by Mask.apply)

If I feed the value into the mask, it will return formatted value "+1 (234) 567 89 0", with complete flag set to false (the first digit was eaten by non-blanked symbol)

How do I properly fill in the mask? What about more complex cases (fixed character in the middle of the mask, for example)?

@taflanidi
Copy link
Collaborator

taflanidi commented Apr 3, 2024

Hi @krypt-lx
Thanks for your question.

Since I don't have the whole context, I'll assume you've got one of the following scenarios:

  1. Your app is available for a single country

In this case, your phone number values will always contain no country codes, thus the +1 prefix within the field serves only aesthetic/UX purposes.

Hence, for rendering, you must adapt those values and insert the +1 prefix programmatically.

Imagine you have a User object with name and surname fields. You've got to display the full name on the account screen. There's got to be a space between name and surname, so that John Doe becomes John Doe instead of JohnDoe. The values are not prepared for rendering, it is up to you to put that space there.

  1. Your app is available in multiple countries

Therefore, the +1 prefix is information you don't want to lose. You must include it in the value itself.

@krypt-lx
Copy link
Author

krypt-lx commented Apr 4, 2024

It isn't answer the question, though. I boiled down the issue I have to simple example.

Basically I have the mask (one which I convert to compatible format in app) and the value from third party via api. It can be any kind of mask for any purpose.
The mask contains some blanks and the value contains only characters for those blanks

So, that it, I need to fill in blanks with given characters and preset it to the user to edit. Nothing more, nothing less.

It isn't hard to manually evaluate the characters in the mask and fill blanks in, but I before I do so I want to know if there maybe a proper solution?

@taflanidi
Copy link
Collaborator

Ah, the third-party masking patterns :D
My favourites.

A go-to here is a two-step process.
For clarity, let's imagine an example, where you receive a phone number:

{
  "mask": "+1 (###) ### ## ##",
  "value": "1234567890"
}

The 1234567890 value is not for the input-mask library but for the +1 (###) ### ## ## pattern!
So you've got to "zip" it accordingly:

var output = "+1 (###) ### ## ##"
let value = "1234567890"

value.forEach { char in
    output.replace("#", with: String(char), maxReplacements: 1)
}

As you've said earlier,

I need to fill in blanks with given characters
Nothing more, nothing less

—so go ahead and do it.

Next, you apply the input-mask library to the output.

@krypt-lx
Copy link
Author

krypt-lx commented Apr 4, 2024

I will add, though, It would be nice if this lib would be able to process its own output (extractedValue). Consider it to be a feature request

@taflanidi
Copy link
Collaborator

@krypt-lx but you already can.

Inherit, override. Everything's open.

@krypt-lx
Copy link
Author

krypt-lx commented Apr 5, 2024

You missing the point: it is not about what I can and what I can't do, the lib can produce output (containing sufficient amount of data) which it can't handle as input. It looks like the lib is incomplete.

@taflanidi
Copy link
Collaborator

Hey, let's keep this conversation constructive, please.

First of all, describe an expected library behaviour and business features you're trying to achieve. The end goal and the algorithms you'd like to have under the hood.

Second, keep in mind that this library occupies the same shelf as the regular expressions. This is a low-level String-operating utility that has no knowledge about the domain semantics whatsoever—and it must not.

@krypt-lx
Copy link
Author

krypt-lx commented Apr 5, 2024

describe an expected library behaviour and business features you're trying to achieve

The task:

The mask contains some blanks and the value contains only characters for those blanks
So, that it, I need to fill in blanks with given characters and preset it to the user to edit. Nothing more, nothing less.

For example, I have mask "123 [000]" and value "345" and I need to construct value "123 345" and present it to the user. The Mask.apply will return "123 45" as the output, so, I can't use it is as.
I expected the lib to have some way to implement required behavior "from the box", specifically because the lib is able to extract values in this format (Mask(format: "123 [000]").apply("123 345").extractedValue will return "345")

I'm aware there are reasons to do it in a different way, but like I already said this is the data format I have. I wrote a simple state machine processing mask format, but I rather avoid having unnecessary complex code in the project.

@taflanidi
Copy link
Collaborator

taflanidi commented Apr 10, 2024

@krypt-lx my apologies for the delay.

I'll be able to roll out an update during this week, I guess.

In my head, the use case should be like

let format = "123 [000]"
let input = "234"

let result = Mask(
  format: format, 
  turnOnTheFeatureTemporaryName: true
).apply(toText: input).formattedText

 "123 234"

Please let me know if it works for you.

P.S. If you happen to come up with a catchy name instead of turnOnTheFeatureTemporaryName — let me know as well

@krypt-lx
Copy link
Author

krypt-lx commented Apr 15, 2024

fillInBlanksOnly? wildcardsOnly? matchOnlyWildcards?
I guess some combination of "blank" or "wildcard" or how you call those wildcards ([0],{A}, etc) internally and of the fact it limits matching to it?
Also, {123} wildcard, I guess it should match 123 only and return a failure otherwise? Like, "precise" match on all wildcards?
Also, maybe a parameter on .apply? (unless some internal architecture reasons) Because mask probably should work as a way to format the value for text for user to edit and a way to format the user input? But I guess I'm there in a weird spot, it is the inherited code in my case and it do not use MaskedTextInputListener and implements its own UITextFieldDelegate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants