Search code examples
laravellaravel-validation

Laravel mobile number validation with format and fixed digits


I have an input tel type field. That is for local mobile number with the format x-xxxx-xxx. With this, I am getting trouble invalidation. Even I enter eight digits it is giving digits validation error.

Validation Rule

I have tried multiple ways to validate as below but none of them works.

// without regex
'mobile'     => 'nullable|digits:8',

// regex one
'mobile'     => 'nullable|regex:/^([0-9\s\-\+\(\)]*)$/|digits:8',

// regex two

'mobile'     => 'nullable|regex:/^\d{1}-\d{4}-\d{3}$/|digits:8',

Input Markup

I am using inputmask js plugin, in case if it requires.

<div class="form-group"><label for="mobile">{{__('admin.user.profile.mobile')}}</label>
    <input type="tel" class="form-control" id="mobile" name="mobile"
           value="{{ isset($user) ? $user->profile->mobile : old('mobile') }}"
           placeholder="{{__('admin.user.profile.mobile')}}" data-inputmask="'mask': '9-9999-999'">
    @error('mobile')
    <span class="invalid-feedback d-block" role="alert"><strong>{{ $message }}</strong></span>
    @enderror
</div>

Validation Error Message

The mobile must be 8 digits.

DD

So here I can understand the reason, is probably it is sending number with the format. So now how can I manage to validate it?

array:14 [▼
  "_token" => "U5F3BkiAryYkaz75R1oraUfcx3ydz6bv6Ac7mw7K"
  "_method" => "PUT"
  "email" => "super@test.com"
  "password" => null
  "password_confirmation" => null
  "role" => "super"
  "first_name" => "Katheryn"
  "last_name" => "Jones"
  "mobile" => "4-6655-499"
  "city" => "Taylorbury"
  "facebook" => "http://fritsch.com/numquam-repudiandae-consectetur-sequi-suscipit-numquam"
  "twitter" => "http://jacobi.com/"
  "youtube" => "https://dubuque.org/explicabo-autem-corporis-distinctio.html"
  "instagram" => "https://www.franecki.com/eos-non-nostrum-quia-commodi-ex-totam"
]

Question:

How to validate mobile numbers with fixed digits and format?


Solution

  • I have tried with the following rules where I change the digit rule to string as laravel has no rule for digits plus dash.

    'mobile' => 'nullable|string|min:10|max:10|regex:/^\d{1}-\d{4}-\d{3}$/',

    May the above solution helps you.

    Update

    For the purpose of showing the appropriate error message to the user, you will need to create a custom rule

    Run the following command

    php artisan make:rule NumericDash

    Update the NumericDash.php file with the following content

    <?php
    
    namespace App\Rules;
    
    use Illuminate\Contracts\Validation\Rule;
    
    class NumericDash implements Rule
    {
        private $message = "The :attribute format is invalid.";
        /**
         * Create a new rule instance.
         *
         * @return void
         */
        public function __construct($digitsWithoutDash, $regex)
        {
            $this->digitsWithoutDash = $digitsWithoutDash;
            $this->regex = $regex;
        }
    
        /**
         * Determine if the validation rule passes.
         *
         * @param  string  $attribute
         * @param  mixed  $value
         * @return bool
         */
        public function passes($attribute, $value)
        {
            if (strlen(preg_replace('/[^0-9]/', '', $value)) !== $this->digitsWithoutDash) {
                $this->message = "The :attribute must include {$this->digitsWithoutDash} digits.";
                return false;
            }
            if (!preg_match($this->regex, $value)) {
                return false;
            }
            return true;
        }
    
        /**
         * Get the validation error message.
         *
         * @return string
         */
        public function message()
        {
            return $this->message;
        }
    }
    

    and use the rule as below

    'mobile' => ['nullable', 'string', new NumericDash(8, '/^\d{1}-\d{4}-\d{3}$/')],