judgegem / judge

Client-side form validation for Rails
MIT License
256 stars 41 forks source link

Customize Error messages? #64

Closed austinarchibald closed 9 years ago

austinarchibald commented 9 years ago

I'm using devise, and it looks like there is a way to customize those error messages, but this question is directed at customizing the Judge portion. e.g. I'm getting Judge validation for User#... in some of my error messages. Can I remove/change that somehow? Thank you.

joecorcoran commented 9 years ago

The error messages should be the same on both server and client. Can you be a bit more specific? Can you link to a repo, or paste some code here?

austinarchibald commented 9 years ago

Yeah, sorry. Thanks for taking a look! I followed this example.

<h2>Sign up</h2><br />

    <%= form_for(resource, as: resource_name, url: registration_path(resource_name), builder: Judge::FormBuilder) do |f| %>
      <div class="red"><%= devise_error_messages! %></div>

      <div class="form-group">
        <%= f.label :username %>
        <%= f.text_field :username, autofocus: true, class: 'form-control', validate: true %>
      </div>

      <div class="form-group">
        <%= f.label :email %>
        <%= f.email_field :email, class: 'form-control', placeholder: "Enter email", validate: true %>
      </div>

      <div class="form-group">
        <%= f.label :password %>
        <%= f.password_field :password, class: 'form-control', placeholder: "Enter password", validate: true %>
      </div>

      <div class="form-group">
        <%= f.label :password_confirmation %>
        <%= f.password_field :password_confirmation, class: 'form-control', placeholder: "Enter password confirmation", validate: true %>
      </div>

      <div class="form-group">
        <%= f.submit "Sign up", class: 'btn btn-success' %>
      </div>

      <hr>
      <div class="form-group ">
        <%= render "devise/shared/links" %>
      </div>

    <% end %>
</div>

<script language="JavaScript">
  judgeValidateForm($('#new_user'));

  function asyncValidateInput(elm) {
    var dfd = new $.Deferred();

    var q = judge.validate(elm,function(element, status, messages){
      if(status == 'valid'){
        element.style.border = '';
        $(element).parent().find('.field_with_errors').remove();
        dfd.resolve();
      }else if(status == 'invalid'){
        element.style.border = '1px solid red';
        $(element).parent().find('.field_with_errors').remove();
        $(element).after('<p class="field_with_errors">' + messages.join(',') + '</p>');
        dfd.reject();
      }
    });

    if(q.validations.length == 0){
      dfd.resolve();
    }

    return dfd;
  }

  function judgeValidateForm(frm) {
    $(frm).submit(function (e) {
      e.preventDefault();

      $(frm).find('.field_with_errors').remove();

      var defers = [];

      $(frm).find('.form-control').each(function (idx, elm) {
        defers.push(asyncValidateInput(elm));
      });

      $.when.apply($, defers).done(function() {
        $(frm).unbind('submit');
        $(frm).submit();
      });
    });
  }
</script>
joecorcoran commented 9 years ago

I see. I hadn't seen this tutorial before, thanks for the link.

What exactly is happening then? You added a custom error message to one of your user attributes but it doesn't show up on the client side? There's a long-standing problem with Rails autoloading that can be fixed by restarting your rails s in development.

FWIW, the example is very nice in that it's step-by-step and well-explained, but it kinda misses the point of Judge somewhat. If you only get validation feedback when submitting the form, why use client-side code at all? You can do the same using regular form submission. Judge was written with browser events like change, keyup, blur etc. in mind.

austinarchibald commented 9 years ago

Testing using an invalid username, which produces this just below the field: Judge validation for User#username not allowed,is too short (minimum is 3 characters)

It's doing what I expect, but I didn't expect it to begin with "Judge validation for User#". It's unnecessary and was curious how to remove that bit from the error message.

And great point about the tutorial... I will have to modify it to with some browser events. Thanks.

joecorcoran commented 9 years ago

Ah! I see what's happening. That's expected behaviour. You need to allow any attributes to be validated via the Engine in your config. See where the tutorial has this?

# config/initializers/judge.rb
Judge.configure do
  expose User, :name, :email
end

Your form has :username instead of :name.

austinarchibald commented 9 years ago

Yeah, I did that part and also did :username instead of :user. Wasn't that the correct thing to do? Also, if the email is already taken, it also does this error under it: Judge validation for User#email not allowed. Not a great message, so in addition to removing the "Judge validation for User#", I'll have to take a look into why it isn't saying email already taken. Thanks for taking a look!

joecorcoran commented 9 years ago

Yeah, sounds like you're doing the right thing – that error message is what shows you that validating email via XHR is not allowed, which means your config is either not correct, or not loaded. You possibly need to restart your development server to reload the initializer. Whenever you see that ugly error message, the config is not setup correctly.

austinarchibald commented 9 years ago

Oh my... it was just that. I feel stupid. Just restarted my server and it's working as expected. No weird messages. Thank you!

joecorcoran commented 9 years ago

Glad it's working for you! :tada: