【问题标题】:Rails 5 ajax form: submit form on clicking one of the 2 radio buttons in AjaxRails 5 ajax 表单:单击 Ajax 中的 2 个单选按钮之一提交表单
【发布时间】:2023-03-08 13:06:01
【问题描述】:

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

我在我的 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>

【问题讨论】:

    标签: javascript jquery ruby-on-rails ajax simple-form


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      请查看下面的代码并尝试根据您的情况对其进行调整。这是我在 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);
      

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-26
          • 2014-05-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多