Senden Sie das Formular in Schienen 3 auf Ajax-Weise (mit jQuery).

79

Ich bin ein Anfänger in Rails und jQuery. Ich habe zwei separate Formulare auf einer Seite und möchte sie separat auf Ajax-Weise (mit jQuery) einreichen. So weit bin ich gekommen. Kann jemand diesen Code hinzufügen oder korrigieren, damit er funktioniert? Ich verwende Rails 3.1 und jQuery 1.6. Danke im Voraus.

application.js

$(".savebutton").click(function() { 
    $('form').submit(function() {
         $(this).serialize();
    });
}); 

erste Form:

<%=form_for :users do |f| %>
  <fieldset>
    <legend>Basic details</legend>
    <%= f.label :school %>
    <%= f.text_field :school,:size=>"45",:class=>"round",:id=>"school" %><br/>      
  </fieldset>
  <p><%= button_to "save and continue",{:class=>"savebutton"} %></p>
<%end%>

zweite Form:

<%=form_for :courses do |c| %>
  <fieldset>
    <legend>Your current classes</legend>
    <label>class:</label><%= c.text_field :subject,:size=>"45",:class=>"round" %><br/>
  </fieldset>
  <p><%= button_to "save and continue",{:class=>"savebutton"} %></p>
<%end%>

SchoolController

class SchoolController < ApplicationController
  respond_to :json
  def create
    @school = current_user.posts.build(params[:school].merge(:user => current_user))
    if @school.save
      respond_with @school
    else
      respond_with @school.errors, :status => :unprocessable_entity
    end
  end
end

CourseController hat die gleiche Form wie SchoolController

Katie
quelle

Antworten:

108

Du möchtest:

  1. Stoppen Sie das normale Verhalten von Submit.
  2. Senden Sie es über Ajax an den Server.
  3. Erhalten Sie eine Antwort zurück und ändern Sie die Dinge entsprechend.

Der folgende Code sollte dies tun:

$('form').submit(function() {  
    var valuesToSubmit = $(this).serialize();
    $.ajax({
        type: "POST",
        url: $(this).attr('action'), //sumbits it to the given url of the form
        data: valuesToSubmit,
        dataType: "JSON" // you want a difference between normal and ajax-calls, and json is standard
    }).success(function(json){
        console.log("success", json);
    });
    return false; // prevents normal behaviour
});
Johan
quelle
14
Dies hat bei mir in der obigen Form nicht funktioniert. Ich glaube, das lag daran, dass ich versucht habe, auf einer Ressource zu posten, die dieselbe URL für den Index verwendet und Methoden in Rails erstellt. Dies erfordert, dass die Anforderung ein POST ist. Wenn Sie eine Formularanforderung für etwas senden möchten, in dem eine Ressource deklariert wurde routes.rb, müssen Sie sicherstellen, dass Sie einen POST und keinen GET verwenden. Fügen Sie mit jQuery einfach hinzutype: 'POST' dem $.ajaxAufruf hinzu.
Eli Hooten
Ich habe diesen Code implementiert, aber er scheint nicht wirklich einzureichen. Ich muss es in ein wickeln$(CODE).submit(); Aufruf einschließen, damit es ausgeführt wird, dann werden 2 Beiträge eingereicht. Irgendwelche Ideen?
Gedankenschlag
Wie mache ich das, wenn ich eine ziemlich große Form habe? .serialize () verursacht beim Senden einen zu langen Anforderungs-URI-Fehler.
Zykadelic
Siehe ersten Kommentar, Sie müssen dann eine POST-Anfrage machen. Also type: 'POST'zum Ajax-Call hinzufügen .
Johan
1
Diese Antwort ist wirklich nicht der Schienenweg.
Mild Fuzz
58

Wenn Sie :remote => trueauf Ihren Formularen verwenden, können Sie sie mit JavaScript mit senden

$('form#myForm').trigger('submit.rails');
Milder Flaum
quelle
4
Ich wurde heute von einem Fehler in meinem Code gebissen, also poste ich, um anderen zu helfen, die in einer Situation wie meiner enden. Ich hatte ein verstecktes Feld und hatte versehentlich (Kopier- und Einfügefehler) das Feld als "erforderlich" markiert. Dem Feld wurde kein Wert zugewiesen (sollte von mir statisch zugewiesen worden sein). Da es versteckt ist, gibt es kein UI-Artefakt, auf das Rails Sie hinweisen, um es zu reparieren. Wenn das Formular gesendet wird, lösen Rails stillschweigend ein Ereignis aus, bei dem Sie nicht wissen, was zum Teufel los ist und warum das Formular nie gesendet wurde, wenn Sie es nicht abonnieren.
saß
1
Das stille Senden eines Formulars über AJAX hat dieses Problem immer in der Entwicklung. Sie sollten in der Lage sein, die Transaktion in Ihren Entwicklertools zu sehen. Außerdem sollten Sie AJAX erst anwenden, wenn Ihr Formular korrekt gesendet wurde.
Mild Fuzz
Interessant, das wusste ich nicht
Alain Goldman
Dies ist die beste Antwort mit UJS. Angenommen, Sie haben ein Formular, das beim Senden eines Formulars asynchron ein Stripe-Token von einem Remotedienst abruft. In Ihrer Stripe-Rückruffunktion erhalten Sie die Stripe-Antwort. Jetzt müssen Sie Ihr Formular erneut an Rails create action senden. Wenn Sie dies mit tun, können .ajaxSie die Erfolgs- und Fehlerdaten in Ihrer Vorlage "create.js.erb" nicht wie gewünscht verarbeiten. Versuchen Sie es .submit()ein zweites Mal, und Ihr remote => trueund auth-Token gehen verloren. .triggerrockt, dein Formular schafft es, #create wie es sollte, und rendert 'create.js.erb'
user3670743
@ user3670743 - danke. Können Sie diesen Punkt näher erläutern?
BKSpurgeon
33

Die bevorzugte Methode in Rails 3 zum Senden von Ajax-Formularen ist die Verwendung von Rails-UJs.

Grundsätzlich erlauben Sie Rails-ujs, die Ajax-Übermittlung für Sie durchzuführen (und Sie müssen keinen js-Code schreiben). Dann schreiben Sie einfach js Code, um das Antwortereignis (oder andere Ereignisse) zu erfassen und Ihr Ding zu machen.

Hier sind einige Codes:

Verwenden Sie zunächst die Remote- Option in form_for, damit das Formular standardmäßig über Ajax gesendet wird:

form_for :users, remote:true do |f|

Wenn Sie dann eine Aktion basierend auf dem Ajax-Antwortstatus ausführen möchten (z. B. erfolgreiche Antwort), schreiben Sie die Javscript-Logik wie folgt:

$('#your_form').on('ajax:success', function(event, data, status, xhr) {
  // Do your thing, data will be the response
});

Es gibt verschiedene Ereignisse, an die Sie sich anschließen können.

lulalala
quelle
1
Gleiches gilt für Rails 4, wo es auf der Standardprojektvorlage installiert ist. Vergessen Sie nicht, das data: {type: 'text'}Attribut wie unter api.jquery.com/jquery.ajax dokumentiert festzulegen. Andernfalls schlägt die Anforderung möglicherweise aufgrund eines JSON- Analysefehlers fehl.
Ciro Santilli 法轮功 冠状 病 六四 事件 26
13

Um das Formular über AJAX einzureichen, können Sie es einfach :remote => truean den form_forHelfer weiterleiten. Standardmäßig verwendet Rails 3.0.x den Prototyp js lib. Sie können ihn jedoch mit dem Gem in jquery ändern jquery-rails(dies ist der Standard für Rails 3.1). bundle installes und dannrails g jquery:install die Prototyp-Dateien durch jquery zu ersetzen.

Danach müssen Sie nur noch den Rückruf bearbeiten. Schauen Sie sich diesen Screencast an

Bassneck
quelle
Ich habe bereits eine JQuery-Bibliothek in meinem Verzeichnis und habe Prototyp-Dateien entfernt. JQuery funktioniert, aber ich muss nur das Formular von dort
einreichen
Installer ist nicht mehr erforderlich: stackoverflow.com/questions/7103437/…
Alex Moore-Niemi
2

Es ist sehr wichtig, dass Sie bei Ihrer Anfrage mit Ajax die Verhaltensvorgabe stoppen. Senden Sie remote: true in Ihrem form_for

<%= form_for :session, url: sessions_path, remote: true, html: { class: "form-signin" } do |f| %>

<% end %>

in deinem Ajax

$(".form-signin").on("submit", function(e) {
    $.ajax({
        url: $(this).attr('action'),
        data: $(this).serialize(),
        type: "POST",
        dataType: "json",
        success: function(response) {
            console.log(response)
        },
        error: function(xhr, textStatus, errorThrown) {}
    });
    e.preventDefault(); //THIS IS VERY IMPORTANT
});
Ezequiel García
quelle
0

Hier funktionierte nichts für mich. Mein Problem war, dass die jQuery-Modalbibliothek meine Formulare nicht über Remote-Daten senden konnte, wenn ich ein Modalfenster aufrief, aber ich fand einen Fix.

Fügen Sie zuerst das jQuery Form Plugin zu Ihrem Assets-Javascript-Verzeichnis hinzu: http://malsup.github.io/jquery.form.js

Überschreiben Sie nun die Übermittlungsmethode für Ihr Formular. Zum Beispiel könnten Sie so etwas tun:

= form_for @object, html: {class: "ajax_form_submit"}, authorization_token: true do |f|
  = f.text_input

javascript:

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

    $(".ajax_form_submit").submit(function () {
      var form = $(this)
      form.ajaxSubmit({
        success: function (responseText, statusText, xhr) {
          console.log('success: ajax_form_submit')
        },
        error: function (jqXHR, statusText, errorThrown) {
          console.log('error: ajax_form_submit');
          console.log(jqXHR, statusText, errorThrown);
        }
      })
    })

  })
Mike Bethany
quelle