Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails remote forms validation

Just a simple question, I have followed the railscast

It's nice how for remote true works, but how can I validate the model ?

I have this one

<%= form_for [:admin,@course], remote: true  do |f| %>
  <div class="field">
    <%= f.label :title, "The title:" %><br />
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :description, "Descripcion:" %><br />
    <%= f.text_area :description %>
 </div>
 <div class="actions">
   <%= f.submit "Send"%>
 </div>
<% end %>

How I handle the error?

def create

  @course = Course.new(params[:course])

  respond_to do |format|
    if @course.save
      format.html { redirect_to admin_index_url, :notice=> 'Done !!' }
      format.js
    else
      format.html { flash.now[:alert] = "Not done" 
                    render "new"
                  }
      format.js
    end
  end        
end

Any ideas why this does not work?

like image 621
Nonyck Avatar asked Nov 05 '12 23:11

Nonyck


3 Answers

Since your format.js blocks are empty, and the create action is called via :remote=>true, rails will do the default, which is to look for create.js.erb to render back, which it probably isn't finding.

To illustrate, put this in the views directory in app/views/?/create.js.erb:

alert('HI');

Then put this in your controller to see an alternative:

respond_to do |format|
  if @course.save
    format.html { redirect_to admin_index_url, :notice=> 'Done !!' }
    format.js { render :js=>'alert("done");' }
  else
    format.html { flash.now[:alert] = "Not done" 
                render "new"
                }
    format.js { render :js=>'alert("not done");' }
  end
end        

So now, you just have to get the error messages into the HTML/Javascript sent back, probably the most railsy way is to just put it into the appropriate .js.erb file.

like image 143
RadBrad Avatar answered Nov 03 '22 07:11

RadBrad


you have to define the validators in your model.

 class Course 
    validates :title, :presence => true
 end

In your controller, you have try to save the instance with @course.save . If it does not save, you get back the errors by calling

    @course.errors.full_messages 

Once you get the hands in these errors , you pass to the view and display a message to the user. don't remember exacly how to do it with format js .

EDIT 2 ======== check this link: http://www.alfajango.com/blog/rails-3-remote-links-and-forms/ try this

    respond_to do |format|
       if @course.save
          format.html { redirect_to admin_index_url, :notice=> 'Done !!' }
          format.js { render :js=>'alert("done");' }
       else
         render :json => @comment.errors, :status => :unprocessable_entity
       end
    end  


 In your javascript, bind the error callback and get the errors you passed in your controller.


 $(document).ready(function(){

$('#form_name').bind("ajax:error", function(evt, xhr, status, error){
  var $form = $(this),
      errors,
      errorText;

  try {
    // Populate errorText with the comment errors
    errors = $.parseJSON(xhr.responseText);
  } catch(err) {
    // If the responseText is not valid JSON (like if a 500 exception was thrown), populate errors with a generic error message.
    errors = {message: "Please reload the page and try again"};
  }

  // Build an unordered list from the list of errors
  errorText = "There were errors with the submission: \n<ul>";

  for ( error in errors ) {
    errorText += "<li>" + error + ': ' + errors[error] + "</li> ";
  }

  errorText += "</ul>";

  // Insert error list into form
  $form.find('div.validation-error').html(errorText);
});

});
like image 44
Rodrigo Dias Avatar answered Nov 03 '22 09:11

Rodrigo Dias


I have developed jquery plugin for this purpose. It may worth to take a look at it.

https://github.com/bighostkim/remoteValidation

like image 2
allenhwkim Avatar answered Nov 03 '22 07:11

allenhwkim