CaioQuirinoMedeiros / react-native-mask-input

🎭:iphone: A simple and effective Text Input with mask for ReactNative on iOS and Android. Includes obfuscation characters feature.
https://www.npmjs.com/package/react-native-mask-input
MIT License
309 stars 31 forks source link

International Phone Number with a + Sign #36

Open Bilal-Abdeen opened 1 year ago

Bilal-Abdeen commented 1 year ago

Thank you very much for the excellent library. I am trying to develop a mask for phone numbers. I managed to cover all cases for local (in Australia) phone numbers. However, I am struggling to handle the situation when the user enters an international phone number (starting with a + sign). I think handling validation for different international numbers would be pretty complex.

So, I thought of using a simple, minimal validation (\+)[1-9][0-9 \-\(\)\.]{7,32}: If the 1st character is +, the user can enter any combination of (numbers, spaces, hyphens, dots, and/or parentheses). How can I code this into a mask function?

export const fMask = (text) => {
    // I NEED HELP WITH THE ALGORITHM FOR THIS CASE
    if (text?.startsWith("+")) {
        return [/(\+|00)[1-9][0-9 \-\(\)\.]{7,32}/]; // wrong
    }

    const onlyDigits = text?.replace(/\D+/g, "");

    // IMPORTANT: THE ORDER OF THE CONDITIONS BELOW IS IMPORTANT!

    // 0123
    // This condition is important to facilitate editing the number after typing it.
    // To fix: If the user starts typing a value that matches a mask, e.g. 02 123. Then, tries to delete what was entered. 
    if (onlyDigits?.length < 5) {
        return [/\d/, /\d/, /\d/, /\d/,];
    }
    // 0444 222 333
    else if (onlyDigits?.startsWith("04")) {
      return [/0/, /4/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, ];
    }
    // 13 12 34, 18 12 34
    else if (onlyDigits?.length <= 6 && (onlyDigits?.startsWith("13") || onlyDigits?.startsWith("18"))) {
        return [/1/, /3|8/, ' ',    /\d/, /\d/, ' ',    /\d/, /\d/, ];
    }
    // 1300 123 567, 1800 123 567
    else if (onlyDigits?.length > 6 && (onlyDigits?.startsWith("13") || onlyDigits?.startsWith("18"))) {
        return [/1/, /3|8/, /0/, /0/,    ' ',    /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, ];
    }
    // (02) 1234 5678
    else if (onlyDigits?.startsWith("0")) {
      return ['(', /0/, /\d/, ') ',     /\d/, /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/, ];
    }
       // (2) 1234 5678 
       else {
       return ['(', /\d/, ') ',   /\d/, /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/, ];
    }
};
Bilal-Abdeen commented 1 year ago

I found a solution.

    // I NEED HELP WITH THE ALGORITHM FOR THIS CASE
    if (text?.startsWith("+")) {
        // return [/(\+|00)[1-9][0-9 \-\(\)\.]{7,32}/]; // wrong

               // accepts a "+" sign followed by a maximum of 19 characters, each of which is a digit, a space, a dash, a dot or a parenthesis.
               return ['+', /[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,/[0-9 -().]/,];
    }