1

I am trying to auto-format the postal code after entry by the user. The postal code rule is Please use the format A0A 0A0 or 12345. So if the user enters L9V0C7, it auto reformats to L9V 0C7 and when the postal code includes all digits like 12345, it stays as it is. The maxlength should be 6 when the postal code has numbers and alphabets and 5 when the postal code includes only numbers. Help me fix this handlePostalCode method.

The issue I am facing is when I enter L9V0, 0 disappears and I am not able to enter the postal code any further.

<v-text-field
    label='Postal Code'
    class="required"
    v-model='postal_code'
    required
    @input="handlePostalCode"
    validate-on-blur
    :rules='postalCodeRules'>
</v-text-field>

postalCodeRules: [
  value => /^[A-z]\d[A-z] \d[A-z]\d$|^\d\d\d\d\d$/.test(value) || 'Please use the format A0A 0A0 or 12345'
  ]


handlePostalCode() {
 if (this.postal_code.match(/^[0-9]+$/) != null) {
      var replacedInput = this.postal_code.replace(/\D/g, '').match(/(\d{0,3})(\d{0,2})/);
      this.postal_code = !replacedInput[2] ? replacedInput[1] : replacedInput[1] + '' + replacedInput[2];
 }
 else {
      var replacedInput = this.postal_code.match(/(\w{0,3})(\w{0,3})/);
      console.log(replacedInput)
      this.postal_code = !replacedInput[2] ? replacedInput[1] : replacedInput[1] + ' ' + replacedInput[2];
 }
}
3
  • [A-z] needs to be [A-Za-z] to avoid false positives. Your postalCodeRules test can be /^(?:[A-Za-z]\d[A-Za-z] \d[A-Za-z]\d|\d{5})$/ Commented Jan 10, 2023 at 19:03
  • The issue is not with the postalCodeRules it is with the handlePostalCode method Commented Jan 10, 2023 at 19:08
  • 1
    I am not familiar with vue, but for handlePostalCode possibly this: if (/^\d+$/.test(this.postal_code) { this.postal_code = postal_code.replace(/^(\d{5}).*$/, '$1'); } else { this.postal_code = this.postal_code.replace(/^(\w{0,3})(\w{0,3})$/, '$1 $2'); } Commented Jan 10, 2023 at 19:19

1 Answer 1

1

The problem is that when the space has been entered after the first three A0A characters, that the regular expression (\w{0,3})(\w{0,3}) cannot cross that space, and will match the empty string with the second capture group, losing out on anything else that follows.

I would suggest the following:

  • Make the distinction between the first and second postal code rule based on the first character only: if it is a digit, apply the first rule, if not, apply the second rule

  • The logic you have for the all-numbers case is overly complex: after having removed the non-digit characters, all that is left to do is to clip the string to at most 5 characters. You can use slice for that.

  • The logic for the second rule could first remove all non-alphanumeric characters (so also spaces would be removed)

  • Then it could remove any digit that follows immediately after a previous digit, and remove any letter that follows immediately after a previous letter

  • Finally it could clip the string to 6 characters, and inject the space if there are 4 or more characters.

Here is how your function would look:

function _handlePostalCode() {
    this.postal_code = /^\d/.test(this.postal_code)
        ? this.postal_code.replace(/[^\d]/g, "")
                          .slice(0, 5)
        : this.postal_code.replace(/\W/g, "")
                          .replace(/(\d)(?:\d+)|([A-Z])(?:[A-Z]+)/gi, "$1$2")
                          .slice(0, 6)
                          .replace(/^(...)(.)/, "$1 $2");
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.