Надіслати форму в напрямках 3 в ajax-формі (з jQuery)


79

Я новачок у rails та jQuery. У мене є дві окремі форми на одній сторінці, і я хочу подати їх окремо ajax (за допомогою jQuery). Ось як далеко я дійшов. Хтось може додати або виправити цей код, щоб він працював. Я використовую Rails 3.1 та jQuery 1.6. Спасибі заздалегідь.

application.js

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

перша форма:

<%=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%>

друга форма:

<%=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 має таку ж форму, що і SchoolController

Відповіді:


108

Ти хочеш:

  1. Зупиніть нормальну поведінку поданого.
  2. Надішліть його через ajax на сервер.
  3. Отримайте відповідь і змініть речі відповідно.

Код нижче повинен робити це:

$('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
});

14
Це не спрацювало для мене у наведеній вище формі. Я вважаю, що це було тому, що я намагався розмістити повідомлення на ресурсі, який використовує ту саму URL-адресу для індексу та створює методи в Rails, це вимагає, щоб запит був POST. Якщо ви хочете подати запит форми на щось, що було оголошено ресурсом routes.rb, вам потрібно переконатися, що ви використовуєте POST, а не GET. За допомогою jQuery просто додайте type: 'POST'до $.ajaxдзвінка.
Елі Хутен,

Я реалізував цей код, але, схоже, він насправді не надсилається. Мені потрібно обернути це у $(CODE).submit();дзвінок, щоб змусити його виконати, тоді він подає 2 повідомлення. Будь-які ідеї?
thinkpunch

Як це зробити, якщо я маю досить велику форму? .serialize () спричинить занадто довгу помилку URI запиту під час надсилання.
zykadelic

Див. Перший коментар, тоді потрібно зробити POST-запит. Тож додайте type: 'POST'до ajax-дзвінка.
Йохан

1
Ця відповідь насправді не є напрямком.
Mild Fuzz

58

Якщо ви використовуєте :remote => trueу своїх формах, ви можете надіслати їх за допомогою JavaScript за допомогою

$('form#myForm').trigger('submit.rails');

4
Сьогодні мене покусила помилка в моєму коді, тому я розміщував повідомлення, щоб допомогти іншим, хто потрапив у ситуацію, подібну до моєї. У мене було приховане поле, і випадково (помилка копіювання та вставлення) поле було позначено як "обов'язкове". Поле не було присвоєне значення (повинно було статично призначатися мною). Оскільки його приховано, немає артефакту інтерфейсу, на який рейки вказуватимуть вам, щоб виправити. Швидше, коли форму буде подано, rails мовчки запускатимуть подію, за якою, якщо ви не підпишетесь, ви не будете знати, що, блін, відбувається і чому форму так і не надіслано.
сб

1
Подача форми мовчки через AJAX завжди має цю проблему в процесі розробки. Ви повинні були бачити транзакцію у своїх інструментах розробника. Крім того, ви повинні застосовувати AJAX лише після того, як ваша форма подається правильно.
Mild Fuzz

цікаво, я цього не знав
Ален Голдман

Це найкраща відповідь із UJS. Скажімо, у вас є форма, яка асинхронно отримує маркер Stripe із віддаленої служби при надсиланні форми. У вашій функції зворотного виклику Stripe ви отримуєте відповідь Stripe, і тепер вам потрібно знову надіслати форму в Rails create action. Якщо ви робите це за допомогою, .ajaxви не зможете обробляти дані про успіх та помилки у своєму шаблоні 'create.js.erb', як це слід було б. Спробуйте скористатися .submit()вдруге, і ваш remote => trueта маркер аутентифікації втрачені. .triggerскелі, ваша форма зробить це #create як слід, відтворюючи 'create.js.erb'
user3670743

@ user3670743 - дякую. Ви можете детальніше розказати про це?
BKSpurgeon

33

Найкращим способом Rails 3 для подання форми ajax є використання Rails-ujs.

В основному ви дозволяєте Rails-ujs робити подання ajax за вас (і вам не потрібно буде писати будь-який код js). Потім ви просто пишете js-код, щоб зафіксувати подію відповіді (або інші події) і зробити свою справу.

Ось декілька кодів:

По-перше, використовуйте віддалений параметр у form_for, щоб форма за замовчуванням подавалась через ajax:

form_for :users, remote:true do |f|

Потім, коли ви хочете виконати якусь дію на основі статусу відповіді ajax (наприклад, успішної відповіді), напишіть логіку javscript так:

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

Є кілька подій, на які ви можете підключитись.


1
Те саме на Rails 4, де він встановлюється на шаблоні проекту за замовчуванням. І не забудьте встановити data: {type: 'text'}атрибут так, як це задокументовано на api.jquery.com/jquery.ajax, інакше запит може не вдатися через помилку синтаксичного аналізу JSON.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

13

Щоб надіслати форму через AJAX, ви можете просто перейти :remote => trueдо form_forпомічника. За замовчуванням rails 3.0.x використовує прототип js lib, але ви можете змінити його на jquery за допомогою jquery-railsgem (що є типовим для рейок 3.1). bundle installа потім rails g jquery:installзамінити файли-прототипи на jquery.

Після цього вам просто потрібно буде обробити зворотний дзвінок. Погляньте на цей скринкаст


у мене вже є бібліотека jquery у моєму каталозі, і я видалив файли прототипів, jquery працює, але мені просто потрібно подати форму форми звідти
Кеті,

Встановлювач більше не потрібен: stackoverflow.com/questions/7103437/…
Alex Moore-Niemi

2

це дуже важливо у вашому запиті за допомогою ajax зупинити поведінку за замовчуванням, надіслати remote: true у вашому form_for

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

<% end %>

у вашому 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
});

0

У мене тут нічого не працювало, моя проблема полягала в тому, що модальна бібліотека jQuery могла б порушити подання моїх форм через віддалені дані, якщо я відкрив модальне вікно, але я знайшов виправлення.

Спочатку додайте плагін jQuery Form до каталогу JavaScript ваших активів: http://malsup.github.io/jquery.form.js

Тепер перевизначте спосіб подання для вашої форми. Наприклад, ви можете зробити щось подібне:

= 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);
        }
      })
    })

  })
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.