1

after checking a lot of answers and tutorials to work with ajax in rails, i came up to a dead end.

The ajax:beforeSend, and ajax:error are not working, but the ajax:success works just fine when i load the page for the first time.

I can't find a way to make this work, though i did a lot of changes since i started to try. I found a lot of similar question in stackoverflow, but all of them have different approaches than this one.

Once the form is submitted, and the success response appeared, the other ajax functions work. I mean, i loose the client side validation from rails, and the form can be submitted without any content in the field, have the beforeSend and error working.

Anyway, if you guys could give me some light on what's wrong with it, i'd appreciate.

controller.rb

def create
  @message = Home.new(message_params)

  respond_to do |format|
    if @message.valid?
      ContactMailer.new_message(@message).deliver_now
      format.html { redirect_to root_path, notice: "Mensagem enviada com sucesso" }
      format.js
    else
      format.html { redirect_to root_path, alert: "Houve um erro ao processar sua mensagem. Por favor, tente novamente." }
      format.js { render json: @message.errors.full_messages, status: :unprocessable_entity }
    end
  end        
end

create.js.erb

$('#new_home')
  .on("ajax:beforeSend", function(evt, xhr, settings){
  alert("beforeSend worked");
})
  .on("ajax:success", function(evt, data, status, xhr){
    $( "#form_int" ).append("<p>Mensagem enviada com sucesso.<br>Obrigado pelo contato.</p>");
    $(this)[0].reset();
})
  .on("ajax:error", function(evt, xhr, status, error){
    alert("error worked");
});

form.html.erb

<%= form_for @message, remote: true, validate: true, url: root_path do |f| %>
  <fieldset>
    <div class="fields">
      <%= f.text_field :name, placeholder: "Nome Completo", class: "name" %>
    </div>
    <div class="fields">
      <%= f.email_field :email, placeholder: "E-mail", class: "email" %>
    </div>
    <div class="fields">
      <%= f.text_field :phone, placeholder: "Telefone com DDD", class: "phone" %>
    </div>
    <div class="fields">
      <%= f.text_field :city, placeholder: "Cidade", class: "city" %>
    </div>
    <div class="fields">
      <%= f.text_field :state, placeholder: "Estado", maxlength: 2, class: "state" %>
    </div>
    <div class="fields message_content">
      <%= f.text_area :content, placeholder: "Mensagem", class: "content" %>
    </div>
  </fieldset>
  <fieldset id="form_int">
      <%= f.submit "Enviar", class:"send_form" %>
  </fieldset>
<% end %>
user67
  • 11
  • 3

1 Answers1

0

You should do this:

  1. Make sure that you have <%= csrf_meta_tag %> in your layout

  2. Add beforeSend to all the ajax request to set the header like below:


$.ajax({ url: 'YOUR URL HERE',
  type: 'POST',
  beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))},
  data: 'someData=' + someData,
  success: function(response) {
    $('#someDiv').html(response);
  }
});

To send token in all requests you can use:

$.ajaxSetup({
  headers: {
    'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
  }
});

source: https://stackoverflow.com/a/8175979/657509

Community
  • 1
  • 1
  • Did you ever find out why it was not working ? I have the same code as you and beforeSend and errors are not working either. – Snake Feb 28 '16 at 17:12