javascript - AJAX 呈现的表单不发送 RAILS 中的参数

标签 javascript jquery ruby-on-rails ajax

我有一个 HTML 表,其中包含名为 Transaction 的模型实例的列表。然而,第一行包含用于创建新事务的表单。这是表格的 _tranasctions_table.html.erb 部分:

<table id="transactions-table-id" class="table table-striped table-bordered table-hover">
<thead>
    <tr><th>Date</th><th>Description</th><th>Category</th><th class="transaction-value-cell">Value</th><th class="icon-cell"></th></tr>
</thead>
<tbody id="transactions-table-body">
    <tr id="new-transaction-row">
        <%= form_for @new_transaction, url: {action: "create"}, remote: true do |f| %>
          <td><%= f.text_field :date, id:"datepicker", readonly: true %></td>
          <td><%= f.text_field :description %></td>
          <td><%= f.text_field :category_id %></td>
          <td class="transaction-value-cell"><%= f.number_field :value %></td>
          <td class="icon-cell"><a href="#" class="fa fa-plus fa-lg text-muted text-center" ></a></td>
          <input type="submit" style="display:none;">
        <% end %>
    </tr>

    <% transactions.each do |trans| %>
    <tr class=<%= (trans.value < 0) ? "red-row" : "green-row" %> >
        <td><%= trans.date %></td>
        <td><%= trans.description %></td>
        <td class="transaction-category-name" style="color:gray;"><%= trans.category.name %></td>
        <td style="border-right:none;"><%= trans.value %></td>
        <td class="icon-cell"><a href="#" class="fa fa-trash fa-lg text-muted text-center"/></td>
        <td class="transaction-id" style="display:none;"><%= trans.id %></td>
    </tr>
    <% end %>
</tbody>
</table>
<%= paginate transactions %>

我可以通过按“Enter”键或单击最后一个表格单元格中的“加号”图标来提交表单,这是使用 jQuery 命令完成的

$('#new_transaction').submit();

当页面首次加载时,这可以正常工作。但是,还有第二个表列出了类别。当用户单击其中一行时,交易表将被刷新,仅显示属于所选类别的交易。这是通过 AJAX 完成的,因此页面上仅刷新交易表。这是我的尝试:

function filter_by_category(category) {
  var category_name = category.html();
  $.ajax({
    method: "GET",
    url: "expenses/filter_category",
    data: { category: category_name }
  })
  .done(function( msg ) {
    $('tr').removeClass("selected-category");
    category.closest('tr').addClass("selected-category");
    $('#transactions_table_span').html(msg);
    add_listeners();
  });
}

add_listener() 函数将 jQuery 提交命令绑定(bind)到新表单等。这是处理请求的 Controller 的相关部分:

def filter_category
  @new_transaction = Transaction.new
  # other variables are set, such as @transactions, depending on the selected category
  render partial: 'transactions_table', locals: {transactions: @transactions}
end

结果是一个正确呈现的表格,其形式看似正确。但是,当我尝试从这个新呈现的表单提交时,没有发送任何参数。

我做错了什么?

更新:

按照要求,我包含了包含两个表的 View index.html.erb:

<%= javascript_tag do %>
    $(document).ready(function() {
      add_listeners();
      select_current_category();
      highlight_expenses_menu_tab();
    });
<% end %>

<div class="container-fluid">

    <div class="row">
        <div class="col-lg-8">
            <div class="panel panel-primary">
                <div class="panel-heading">Transactions</div>

                <div class="panel-body">

                        <%= form_tag({action: :upload}, multipart: true, class: "form-inline") do %>
                            <div class="form-group">
                                <label class="sr-only" for="transactions">File upload</label>
                                <%= file_field_tag 'transactions' %>
                            </div>

                            <%= submit_tag("Upload", class: "btn btn-default") %>
                        <% end %>
                </div>

                <span id="transactions_table_span">
                    <%= render partial:"transactions_table", locals: {transactions: @transactions} %>
                </span>
            </div>
        </div>

        <div class="col-lg-offset-1 col-lg-3">
            <div class="panel panel-primary">
              <div id="category-panel-heading" class="panel-heading">Categories</div>
                    <%= render partial:"categories_table", locals: {categories: @categories, category_name: @category_name, new_category: @new_category} %>
            </div>
        </div>
    </div>
</div>

这就是调用 filter_by_category() 的方式:

  • 通过 add_select_category_listener() 将点击事件监听器附加到类别行
  • 监听器调用另一个函数 select_category(),该函数的行为取决于当前是否有选定的事务。如果有,单击类别会将这些交易更改为所选类别。

这是两个函数:

function add_select_category_listener() {
  $('tr.category-row > td').not('td.icon-cell').off('click');
  $('tr.category-row > td').not('td.icon-cell').click( function() {
    select_category($(this));
  });
}

function select_category(category) {
  var category_name = category.html();
  var number_selected_rows = $('.selected-transaction').length

  if (number_selected_rows == 0) {
    filter_by_category(category);
  } else {
    var selected_transactions = [];
    var html_selected_transactions = $('.selected-transaction > td.transaction-id');

    for (i = 0; i < html_selected_transactions.length; i++) {
      selected_transactions.push(html_selected_transactions[i].innerHTML);
    }
    change_to_category(category_name, selected_transactions);
  }
}

我检查了一下,确实正在调用 filter_by_category() 。另外,我正在使用 Rails 4.1.7。

最佳答案

我的代码中的问题与 this one 相同:您不能将 form 作为 tabletbodytr 的子项。它可以包含表格或放在表格单元格内。如果你按照我的做法,渲染的 HTML 将有一个表单,其中没有任何内容,所有输入都在外面。

根据W3C spec ,表单之外的输入对于提交无效(HTML5 中具有 form attribute 的输入除外),并且不应在请求中发送,因此不发送任何数据实际上是正确的行为。然而,浏览器用户代理有时会接受这些输入作为表单的一部分并发送它们,即使它不应该这样做。

关于javascript - AJAX 呈现的表单不发送 RAILS 中的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30030835/

相关文章:

ruby-on-rails - 如何从 Puma 获取隔离线程信息

ruby-on-rails - 带有 Rails 4 的 compass 不起作用

javascript - 无法从 redom 库导入

javascript - highcharts,垂直对齐顶部的条形图图例不起作用

javascript - 如何从具有特定类名的特定标签获取文本值?

ruby-on-rails - 关于在 Ryan bates Active_Merchant 集成视频中创建信用卡对象的问题

Javascript 作为函数式语言

javascript - 使用javascript在鼠标悬停时查看内容顶部的放大图像

javascript - 触发 onload、内联 javascript 事件

jquery - 具有指定jsonpCallback的jQuery 1.4.2 $ .ajax使IE6/7崩溃