Rails 5 ajax 表单:单击 Ajax 中的 2 个单选按钮之一提交表单

Rails 5 ajax form: submit form on clicking one of the 2 radio buttons in Ajax

注意: 存在类似的问题,但 none 个与我的情况相似

我正在我的 rails 视图中制作一个带有是或否单选按钮的小 Ajax 表格,我使用 remote: true 制作了这个表格并且它正确地作为 Ajax 如果我使用单独的提交按钮(没有页面重新加载并且表单被传递给控制器​​)​​

如果我使用 Jquery 让单选按钮自己提交表单,那么它会提交但不会在 Ajax 中提交(但会重新加载页面)

那么如何解决这个问题:

单击 Ajax?

中的 2 个单选按钮之一提交表单

我试过的两件事:

1) 创建两个不同的提交按钮并尝试调整提交 btn 本身的表单值,如果我将它们设置为提交按钮,Ajax 工作正常但表单没有得到我需要的值

    <div class="radio-button-btn-wrapper mr-2">
      <%= f.submit t('yes'), recommended: true,  class: "radio-button-btn-label-white background-green"  %>
    </div>
    <div class="radio-button-btn-wrapper mr-2">
      <%= f.submit t('no'), recommended: false, class: "radio-button-btn-label-white background-red" %>
    </div>

2) 调整单选按钮以Ajax方式提交表单(尝试过但没有成功)

  <%= simple_form_for [...model names], remote: true do |f| %>
  <div class="flex">

    <div class="radio-button-btn-wrapper mr-2">
      <%= label :recommended, t('yes'), class: "radio-button-btn-label white" %>
      <%= f.radio_button :recommended, true, onclick: "$(this).closest('form').submit();", class: "radio-button-btn background-green" %>
    </div>
    <div class="radio-button-btn-wrapper">
      <%= label :recommended, t('no'), class: "radio-button-btn-label white" %>
      <%= f.radio_button :recommended, false, onclick: "$.ajax((this).closest('form').submit());", class: "radio-button-btn background-red" %>
    </div>
  </div>

对我有用的是添加 'normal' 提交按钮并将其设置为显示 none。然后添加一个监听单选按钮点击的事件监听器,如果发生这种情况,让它点击隐藏的提交按钮。

  <%= simple_form_for [...model names], remote: true do |f| %>
  <div class="flex">

    <div class="radio-button-btn-wrapper mr-2">
      <%= label :recommended, t('yes'), class: "radio-button-btn-label white" %>
      <%= f.radio_button :recommended, true, class: "radio-button-btn background-green" %>
    </div>
    <div class="radio-button-btn-wrapper">
      <%= label :recommended, t('no'), class: "radio-button-btn-label white" %>
      <%= f.radio_button :recommended, false, class: "radio-button-btn background-red" %>
    </div>
    <%= f.submit '', class: 'd-none', id: 'submitMyForm' %>
  </div>
document.addEventListener('click', function(event){
  if(event.target.classList.contains('radio-button-btn'){
    document.querySelector('#submitMyForm').click();
  }
});

请查看下面的代码并尝试根据您的情况进行调整。这是我在 Rails 应用程序中测试过的有效代码。

基本思想不是尝试将单选按钮制作为提交按钮,而是采用隐藏表单的方法,然后在单选按钮上绑定点击事件。在按钮单击处理程序中,我将所选单选按钮的值设置为隐藏表单中的隐藏字段值并提交隐藏表单。它作为 AJAX 请求提交,并在控制器端处理 JS 响应。

希望对您有所帮助。

routes.rb

  root "welcome#index"

  post "welcome_submit_form" => "welcome#submit_form", as: :welcome_submit_form

app/controllers/welcome_controller.rb

  class WelcomeController < ApplicationController

    def index

    end

    def submit_form
      @received_radio_value = params[:selected_radio_value]

      render file: "welcome/submit_form_response.js.haml"
    end
  end

app/views/welcome/index.html.haml

  .my-container<
    %div(style='display: none;')
      = form_tag(welcome_submit_form_path, class: 'my-hidden-form', remote: true) do |f|
        = hidden_field_tag "selected_radio_value", nil

    = radio_button_tag 'favorite_color', 'red', false, class: 'my-radio-btn'
    Red
    = radio_button_tag 'favorite_color', 'blue', false, class: 'my-radio-btn'
    Blue

  .my-selected-radio-value(style='display: none')

app/views/welcome/submit_form_response.html.haml

  %h2= "My Radio Value: #{@received_radio_value}"

app/views/welcome/submit_form_response.js.haml

  - response_markup = escape_javascript(render( partial: "welcome/submit_form_response.html.haml" ))

  :plain

    var responseMarkup = "#{response_markup}";

    var responseContainer = $('.my-selected-radio-value');

    responseContainer.html(responseMarkup);
    responseContainer.show();

app/assets/javascripts/welcome.js

(function ($) {

  bindClickEventOnMyRadioBtn = function() {
    $('.my-container .my-radio-btn').off('click').on('click', function(event) {
      var selectedRadioVal = $(this).val();

      var myHiddenForm = $('.my-container .my-hidden-form');
      var radioValueField = myHiddenForm.find('input[name=selected_radio_value]');
      radioValueField.val(selectedRadioVal);

      myHiddenForm.submit();
    })
  }

}) (jQuery);

var ready;

ready = function() {
  bindClickEventOnMyRadioBtn();
};

$(document).ready(ready);

在广泛搜索为什么会发生这种情况以及如何以最简单的方式修复它之后,我发现this issue in Rails 5.2 & thanks to this solution from Padi我们应该使用此代码使其按预期工作:

// Get hold of the form object
form = document.querySelector('form');
// Use the Rails fire helper 
Rails.fire(form, 'submit');