real-time validation in rails

1

Good morning, how could I validate a text_field in real time with js in rails? I have my validates in my model, and the validations and view of errors per field are made post submit, but how do I validate in the field itself without having to submit submit before. regards [updated] I tried the gem Judge, but it does not work, I leave the code:

#views/employees/new.html.erb

      <div class = "panel panel-primary">
        <div class = "panel-heading">
         <h3> Registro de Empleado</h3>
     </div>
<%= render 'form', employee: @employee %>
</div>
#views/employees/_form.html.erb

<%= form_for(employee, :builder => Judge::FormBuilder) do |f| %>
                <div class="row row-no-top">
               <div class="col-md-6">
                <div class="field">
                  <div class="form-group <%= @employee.errors[:legajo].any? ? " has-error has-feedback" : "" %>">
                       <h1><%= f.label :legajo, "Legajo" %></h1>  
                          <%= f.text_field :legajo, :validate => true, autofocus: true,requiered:true, :class=>"form-control input-sm " ,placeholder: "Legajo" %>  
                                <%if @employee.errors[:legajo].any? %>
                                        <span class="glyphicon  form-control-feedback"><i class="fa fa-exclamation" aria-hidden="true"></i>
                                        </span>
                                        <p class="bg-warning"><%= @employee.errors[:legajo].to_s[/\w([^"]*)/] %></p>
                                <% end %>
                  </div>
                </div>
                </div>

            </div>

<% end %>

#models/employee

class Employee < ApplicationRecord
    validates :legajo, :name, :last_name,:document_number,  presence:  { message: "Campo obligatorio" }
    validates :legajo, uniqueness: { message: " El legajo ya existe" }, on: :create
    validates :legajo,  numericality: {  message: " Se permite solo numeros enteros",only_integer: true }
    validates :legajo, length: { is: 5, :message => "Debe tener 5 digitos" }
    validates :legajo, uniqueness: { message: " El legajo ya existe" },  on: :update
end

#assets/javascript/application.js
        //= require underscore
        //= require json2
        //= require judge
        ...
#config/routes
Rails.application.routes.draw do
mount Judge::Engine => '/judge'
...
end

    
asked by sandovalgus 04.11.2016 в 14:11
source

3 answers

0

I recommend you take a look at the gems judge or client_side_validations

I've used the first one and it works pretty well.

For example for a typical user model

 # usuario.rb
 class Usuario
   validates :nombre, presence => true
   validates :apellidos, presence => true
 end

When building the creation forms in this way

form_for(@usuario, :builder => Judge::FormBuilder) do |f|
  f.text_field :nombre, :validate => true
  f.text_field :apellidos, :validate => true
end

generates a form similar to this

<form method="POST" action="/usuarios" id="new_usuario">
  <input type="text" data-klass="Usuario" data-validate="[{'kind':'presence','options':{},'messages':{'blank':'Nombre no puede estar vacío'}}]" id="usuario_nombre">
  <input type="text" data-klass="Usuario" data-validate="[{'kind':'presence','options':{},'messages':{'blank':'Apellidos no puede estar vacío'}}]" name="usuario[apellidos]" id="usuario_apellidos">
</form>

Many more details and features on the judge website

UPDATE If you want to validate the fields before doing the submit, you can add, for example, a class to all the fields you want to validate. I have called it "validation" and then I use the validate function provided by the gem judge

form_for(@usuario, :builder => Judge::FormBuilder) do |f|
  f.text_field :nombre, class: "validation", :validate => true
  f.text_field :apellidos, class: "validation", :validate => true
end

$(function() {
 $('.validation').on('input select', function() {
    judge.validate($(this)[0], {
        valid: function(element) {
                eliminaMensajeError(element);
        },
        invalid: function(element, messages) {
            muestraMensajeError (element, messages);
        }
    });
 });
});

The methods delete MessageError and sampleMessageError are their own and what they do is highlight the field in red in error and leave them green when they are ok

    
answered by 08.11.2016 / 17:06
source
1

I hope this helps you. Basically you are calling the function every time you "release" the key. That is, after each character entered.

This code can be put in app/assets/javascripts/application.js , but it would be better if you would make a file in that same folder, for example: app/assets/javascripts/validacion.js .

  

Note: Assuming you are using the Turbolinks gem (turbolinks comes in automatic included in each new rails project unless you have created it with the flag --api ) In Rails 4 we generally used 'page:load' , but from Rails 5 (Turbolinks v5) It is common to use 'turbolinks:load' when starting with your js. You can find more details about this in the official documentation of turbolinks .

$(document).on('turbolinks:load', function() {

  // en lugar de '.input' será la clase o id que identifique 
  // al campo que quieres validar
  $('.input').on('keyup', function() {
    setTimeout(function() {

      // ejemplo de un Regex para validar el formato de un email
      var emailRegex = /^(([^<>()\[\]\.,;:\s@"]+(\.[^<>()\[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

      if(emailRegex.test($('.input').val()) == true) {
        // lo que quieras que suceda si pasa la validación
      }
      else {
        // lo que quieras que suceda si NO pasa la validación
      }

    })
  })
})
    
answered by 04.11.2016 в 16:31
0

It depends on your needs, you have various options.
The easiest to implement is using the validation api of html5 , although it is not yet fully supported by some current explorers. There are also several js libraries that can help you validate your forms, such as ParsleyJS or validate.js

    
answered by 05.11.2016 в 14:22