DavyJonesLocker / client_side_validations

Client Side Validations made easy for Ruby on Rails
MIT License
2.69k stars 403 forks source link

Changing position of error message and element of error #715

Closed reckerswartz closed 6 years ago

reckerswartz commented 7 years ago

Hey I am working on webapp with framework Materialize Which uses the different method to show the error message. Instead of, showing the message in label , It uses data-error attribute with in the label tag to show in error message.
Example

<div class="input-field col s12">
    <input id="email" type="email" class="validate invalid">
    <label for="email" data-error="Invaild Email" data-success="right" class="active">Email</label>
</div>

As per the document changes are need to be done in config/initializers/client_side_validations.rb

ActionView::Base.field_error_proc = proc do |html_tag, instance|

but I am unable to do that please guide me to how to changes according to my framework

ClientSideValidations && Rails!
class Student < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable,:lockable, :timeoutable ,
         :recoverable, :rememberable, :trackable, :validatable

  def timeout_in
   1.days
  end
end
The form code from your template
<div class="row">
  <%= form_for(resource, as: resource_name, url: session_path(resource_name), validate: true) do |f| %>
  <div class="row">
    <div class="input-field col s12">
      <i class="material-icons prefix">account_circle</i>
      <%= f.email_field :email, autofocus: true ,class: "validate", validate: true%>
      <%= f.label :email %>
    </div>
    <div class="input-field col s12">
      <i class="material-icons prefix">lock</i>
      <%= f.password_field :password, autocomplete: "off", class: "validate" %>
      <%= f.label :password %>
    </div>
    <div class=" col s12">
      <% if devise_mapping.rememberable? -%>
      <div class="field">
        <%= f.check_box :remember_me %>
        <%= f.label :remember_me %>
      </div>
      <% end -%>
    </div>
    <%= f.submit "Log in" ,class: " btn  col s12 " %>
  </div>
  <% end %>
</div>
The resulting HTML
<div class="row">
  <form class="new_student" id="new_student" novalidate="novalidate" data-client-side-validations="{&quot;html_settings..">
  <div class="row">
    <div class="input-field col s12">
      <i class="material-icons prefix">account_circle</i>
      <input autofocus="autofocus" class="validate valid" type="email" value="" name="student[email]" id="student_email" data-validate="true" style="background-image: url(&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGP6zwAAAgcBApocMXEAAAAASUVORK5CYII=&quot;); cursor: auto;" autocomplete="off">
      <label for="student_email" class="active">Email</label>
    </div>
    <div class="input-field col s12">
      <i class="material-icons prefix">lock</i>
      <input autocomplete="off" class="validate valid" type="password" name="student[password]" id="student_password" data-validate="true" style="background-image: url(&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGP6zwAAAgcBApocMXEAAAAASUVORK5CYII=&quot;); cursor: auto;">
      <label for="student_password" class="active">Password</label>
    </div>
    <div class=" col s12">
      <div class="field">
        <input name="student[remember_me]" type="hidden" value="0"><input type="checkbox" value="1" name="student[remember_me]" id="student_remember_me" data-validate="true">
        <label for="student_remember_me">Remember me</label>
      </div>
    </div>
    <input type="submit" name="commit" value="Log in" class=" btn  col s12 " data-disable-with="Log in">
  </div>
</form></div>
The resulting HTML After validation
<div class="input-field col s12">
      <i class="material-icons prefix active">account_circle</i>
      <div class="field_with_errors"><input class="validate invalid" type="email" value="" name="student[email]" id="student_email" data-validate="true" style="background-image: url(&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGP6zwAAAgcBApocMXEAAAAASUVORK5CYII=&quot;); cursor: auto;" autocomplete="off"><label for="student_email" data-error="" class="message active">is invalid</label></div>
      <div class="field_with_errors"><label for="student_email" class="active">Email</label></div>
    </div>
Need Result After validation
<div class="input-field col s12">
      <i class="material-icons prefix">account_circle</i>
      <input autofocus="autofocus" class="validate invalid" type="email" value="" name="student[email]" id="student_email" data-validate="true" style="background-image: url(&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGP6zwAAAgcBApocMXEAAAAASUVORK5CYII=&quot;); cursor: auto;" autocomplete="off">
      <label for="student_email" data-error="Is Invalid" class="active">Email</label>
    </div>
tagliala commented 7 years ago

Hi,

Thanks for all those details. Track down CSV issues is time consuming, debugging CSV issues with other frameworks is worse.

data-client-side-validations="{"html_settings..">

Did you voluntarily omit the data-client-side-validations attribute? it is very important.

For client side validations, you probably need a custom javascript file, something like this: https://github.com/DavyJonesLocker/client_side_validations-simple_form/blob/master/coffeescript/rails.validations.simple_form.coffee

If you are referring to server side validations message after an unsuccesful submit, I think CSV has very little to do with this. ActionView::Base.field_error_proc = proc do |html_tag, instance| is a Rails thing

reckerswartz commented 7 years ago

Hey, Thank you for the response. as per your guide I made my changes into javascript file as given below.

I am able to receive the message correctly but can't able to put proper validation for presence true. when I use validate presence: true I am able to get the error message of can't be blank but it was not removed when I enter the text until I resolve next validation related to the same field. For example when I keep email input blank and it shows the error "can't be blank" after that I enter the text, it still shows "can't be blank" until I enter the proper email address, where it should be showing invalid email message.

my application form page can found here

window.ClientSideValidations.formBuilders['ActionView::Helpers::FormBuilder'] = {
    add: function (element, settings, message) {
        // custom add code here
        var form = $(element[0].form);
        var for_id = element.attr('id');
        if (element.data('valid') !== false) {

            if (form.find("label.error[for='" + for_id + "']")[0] == null) {
                form.find("label[for='" + for_id + "']").addClass('custom-form-error').attr('data-error', message);
                element.removeClass("valid");
                element.removeClass("validate");
                element.addClass("invalid");
                element.addClass('custom-form-error');

            }

        }
        return form.find("label.error[for='" + for_id + "']").attr('data-error', message);

    },

    remove: function (element, settings) {
        var form = $(element[0].form);

        if (element.hasClass('custom-form-error')) {
            var for_id = element.attr('id');
            form.find("label[for='" + for_id + "']").removeClass('custom-form-error').removeAttr('data-error');
            element.addClass("valid");
            element.addClass("validate");
            element.removeClass("invalid");
            element.removeClass('custom-form-error');

        }
        return element;
    }

}
tagliala commented 7 years ago

Hi,

please double check that your remove function is checking that custom-form-error class is present on the proper element.

Please take another look here: https://github.com/DavyJonesLocker/client_side_validations-simple_form/blob/master/coffeescript/rails.validations.simple_form.coffee

tagliala commented 6 years ago

I'm going to close this one, since it looks like a third-party integration question about client side validation rather than an issue