RahulOnRails
RahulOnRails

Reputation: 6542

Parsley + Rails 5 + Unable to validate Email address

Model :

class User < ApplicationRecord
  VALID_EMAIL_REGEX = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
  validates :email,
        presence: true,
        format: { with: VALID_EMAIL_REGEX }
end

HTML :

<%=
   f.email_field :email,
   placeholder: 'email',
   class: "form-control",
   id:"user_email",
   data: {
     parsley_required: "",
     parsley_pattern: User::VALID_EMAIL_REGEX,
     parsley_type: "email"
   }
%>

After Compile :

<input placeholder="email" class="form-control" id="user_email" data-parsley-required="" data-parsley-pattern="&quot;(?i-mx:\\A([^@\\s]+)@((?:[-a-z0-9]+\\.)+[a-z]{2,})\\z)&quot;" data-parsley-type="email" type="email" value="" name="user[email]">

Not working. Please suggest

Upvotes: 1

Views: 801

Answers (2)

Marc-Andr&#233; Lafortune
Marc-Andr&#233; Lafortune

Reputation: 79612

Additionally, you could simply use data-parsley-type="email" instead of pattern. This uses Parsley's builtin (and more accurate) regex for email.

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627380

Start of string anchor in Ruby is defined with \A operator and end of string anchor is expressed with \z. However, in JavaScript, ^ and $ anchors are used respectively. Moreover, when you send the Ruby Regexp object to the JS Parsley, the #to_s is run on it and you get the pattern mixed with modifiers that are added in their inline form, e.g. (?-im:).

What you can do is set the value of VALID_EMAIL_REGEX to a String like '[^@\s]+@(?:[-a-zA-Z0-9]+\.)+[a-z]{2,}' (note I removed unnecessary capturing groups as you are not going to access those submatches, and also not the backslash is single because the literal is a single quoted one), and then build the regex dynamically on the RoR part with format: { with: Regexp.new("\\A#{VALID_EMAIL_REGEX}\\z") } (so, the anchors are correct for Ruby - the backslashes are doubled since it is a double quoted string literal) and pass the ^/$ anchors to Parsley JS with parsley_pattern: "^"+User::VALID_EMAIL_REGEX + "$".

Resulting model:

class User < ApplicationRecord
  VALID_EMAIL_REGEX = '[^@\s]+@(?:[-a-zA-Z0-9]+\.)+[a-z]{2,}'
  validates :email,
    presence: true,
    format: { with: Regexp.new("\\A#{VALID_EMAIL_REGEX}\\z") }
end

And the resulting HTML:

<%=
    f.email_field :email,
    placeholder: 'email',
    id:"user_email",
    data: {
      parsley_required: "",
      parsley_pattern: "^"+User::VALID_EMAIL_REGEX + "$",
      parsley_type: "email"
    }
%>

Just in case, here is a Parsley JS fiddle.

Upvotes: 1

Related Questions