我有一个 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
作为 table
、tbody
或 tr
的子项。它可以包含表格或放在表格单元格内。如果你按照我的做法,渲染的 HTML 将有一个表单,其中没有任何内容,所有输入都在外面。
根据W3C spec ,表单之外的输入对于提交无效(HTML5 中具有 form attribute 的输入除外),并且不应在请求中发送,因此不发送任何数据实际上是正确的行为。然而,浏览器用户代理有时会接受这些输入作为表单的一部分并发送它们,即使它不应该这样做。
关于javascript - AJAX 呈现的表单不发送 RAILS 中的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30030835/