RobinHerbots / inputmask.phone

Phone alias for Inputmask
MIT License
6 stars 9 forks source link

Country code doesn't work properly #7

Open BigDyuha opened 5 years ago

BigDyuha commented 5 years ago

Hi, Robin!

You've created an amazin plugin. But I can't to make it work. The problem is that the it's impossible to type an Armenian counry code 374 for example. Type 3 - 7 and the third "0" added automatically. When delete the digits - 0 is deleteng with 7 and only 3 stays.. Would be great if you could pay it some attention! Thanks in advance!

siberiadev commented 5 years ago

Same experience here. I use your plugin for nuxt.js project (element ui). I want to type this phone number +79085777888 I type 7 it shows me +7-5-_-__ Then I type 9 it shows me +79_--_-- I type 0 it shows +795(0_)-___ After that other digits is ok. But my number is russian number - but plugin shows me some other country code. Is here something I did wrong?

RobinHerbots commented 5 years ago

@BigDyuha , @siberiadev ,

After releasing Inputmask 5.0, I will restart working on this extension.

warzywar commented 5 years ago

Hello Everyone, I have the same issue and I notice when you sort the masks in descending order it works. Maybe not the best solution but for the time beeing it will allow you to use the phone masks.

Just change following code return maska.localeCompare(maskb) to return maska.localeCompare(maskb) * -1;

It looks like when there is a mask and next pre defined value is 0 it is geting this mask as default.

P.S. I use input mask (main plugin) in version 4.0.8

lmcsu commented 5 years ago

I spent all the evening on this. Well, I found that there's two issues.

1) There's a bug in Inputmask itself, it's not related to the phone extension. When you apply several different masks and type something, sometimes it autocompletes the input by determined mask. So there's a bug in that autocomplete. For example, as @BigDyuha wrote, when you type "37", it pust zero after it, because the first mask that it picks has "370" in it. It's OK. But.. There's a bug, that if you continue typing the last added number, (in this case "0"), and then trying to delete symbols, the mask breaks. (it often happens when you type fast and don't think about some kind of autocomplete) Seems like Inputmask doesn't handle symbols that it has inserted by itself. I haven't found how to fix it in Inputmask so I found another solution, to add additional masks in this extension the way that it will prevent the Inputmask from inserting symbols by itself.

2) There's a mistake in sorting function in the phone extension. @warzywar in the upper answer was close about that (but also zeroes doesn't matter). But we shouldn't just sort it in backward order because it gives some issues with appearing digits in the middle of the mask that Inputmask takes from the first picked mask. Now it's sorting by the alphabet order, that's also wrong. What we have to do is to sort all the masks by the length of their code numbers. (and by the way there's another issue in the sorting funtion, to sort the masks it's replacing "#" symbols with zeroes, what sorts masks with existing zeroes improperly, but we don't need it anymore, anyway sorting by the alphabet order is wrong)

So I have made the solution to make current versions of Inputmask and the Phone extension work properly.

Just put this code before initializing Inputmask (at least it seems to be working much better this way)

Inputmask.prototype.aliases.abstractphone.mask = function(opts) {
    opts.definitions = {
        "#": Inputmask.prototype.definitions["9"]
    };

    // getting clean phone codes and converting mask strings to objects
    var result = opts.phoneCodes.map(function (a) {
        if (typeof a === 'string') {
            a = { mask: a };
        }
        a._cleanCode = a.mask.replace(/[^0-9]/g, '');
        return a;
    });

    // sorting codes by alphabet order, because we need to generate missing masks in the next code block
    result = result.sort(function(a, b) {
        return a._cleanCode.localeCompare(b._cleanCode);
    });

    // generating missing masks
    var newCodes = {};
    result.forEach((a) => {
        for (var i = 1; i < a._cleanCode.length; i++) {
            var key = a._cleanCode.substr(0, i);

            // if we don't have such code then making it
            if (!newCodes[key]) {
                var newMask = a.mask;

                var rg = /[0-9]/g;
                var count = 0;
                var match;
                while ((match = rg.exec(a.mask))) {
                    count++;
                    if (count > key.length) {
                        newMask = newMask.substr(0, match.index) + '#' + newMask.substr(match.index + 1);
                    }
                }

                // adding new code
                newCodes[key] = {
                    mask: newMask,
                    cc: a.cc,
                    cd: a.cd,
                    desc_en: a.desc_en,
                    name_ru: a.name_ru,
                    desc_ru: a.desc_ru,
                    _cleanCode: key,
                };
            }
        }

        // marking current code as processed
        newCodes[a._cleanCode] = true;
    });

    // pushing generated codes to result
    for (var key in newCodes) {
        if (newCodes.hasOwnProperty(key)) {
            if (typeof newCodes[key] === 'object') { // if it's not just marked as processed
                result.push(newCodes[key]);
            }
        }
    }

    // sorting result by code length
    result = result.sort(function (a, b) {
        return a._cleanCode.length <= b._cleanCode.length ? 1 : -1;
    });

    return result;
};

P.S: @siberiadev seems like you have some another issue.