首页 > 解决方案 > 为什么在我的 Rails 应用程序中再次呈现 HTML div(包含数据表)之前无法隐藏它?

问题描述

背景

这是对我正在尝试做的事情的清晰解释:

  1. 我有一个包含下拉列表的 Rails 表单(我称之为“预搜索”表单)
  2. 当下拉选择更改时,会向用户显示一个搜索表单(该表单允许用户选择一些搜索条件)此表单包含一个“运行搜索”按钮,用于提交表单选择
  3. 在上面的表单上单击“运行搜索”时,会在表单的正下方显示一个数据表

问题

这是我的问题:

  1. 当上面表格中的搜索条件改变并再次点击“运行搜索”时,我想:I.之前显示的数据表被删除和II。一个新的数据表显示在旧数据表的位置。

但这不会发生。我看到额外的数据表被添加到页面中,而不是删除旧的数据表并每次都替换它。因此,如果我运行搜索 4 次,我会在页面中看到 4 个数据表。我只想查看 1 个数据表我运行搜索的次数。

代码

这是我的带有下拉菜单的预搜索表单:

<%= form_for :anything, remote: true, html: { id: 'pre_search_form' } do |f| %>
  <div style="margin-left: 10px; margin-top: 10px">

      <div class="col-lg-2">
        <div class="form-group">
          <label style="font-weight: 600;font-size:95%"><b>Category : </b>&nbsp;<%= select_tag(:search_category, options_for_select([['-Select-', ''], ['Option1', 'o1'], ['Option 2', 'o2'], ['Option 3', 'o3'], ['Option 4', 'o4']], :selected => 0)) %></label>
        </div>
      </div>
    </div>
    <!-- end of row 1 -->

  </div>

  <div id="dummy_div"> </div>

  <div id="datatable_div"></div>

<% end %>

<script type='text/javascript'>

  $(function() {
   $(document).on("change", "#search_category", function(event){

     $.ajax('show_search_form', {
       type: 'GET',
       dataType: 'script',
       data: {
         search_category: $("#search_category").val()
       },
       error: function(jqXHR, textStatus, errorThrown) {
         return console.log("AJAX Error: " + textStatus);
       }
     });
   });
 });
</script>

这是在上述“预搜索”表单中更改下拉选择时调用的路由条目:

路线.rb

get "/show_search_form" => "search#show_search_form", :as => :show_search_form

这是由于上面的路由条目而执行的控制器功能:

search_controller.rb

class SearchController < ApplicationController

  def show_search_form
    render :partial => "search/show_search_form.js.erb"
  end

这是上面控制器函数渲染的部分:

搜索/show_search_form.js.erb

<%= form_for :anything, remote: true, html: { id: 'search_form' } do |f| %>
  <div class="row">
      <b><%= label_tag "Entity" %><br/></b>
      <%= select_tag(:search_entity, options_for_select([["Entity 1", 1], ["Entity 2", 2]]) %>
  </div>

  <%= button_tag 'Run Search', type: 'button', class: 'btn btn-primary btn-sm', id: "search_run_button" %> 
<%end%>


<!-- Javascript code to handle events for dropdowns in the above form-->

<script type='text/javascript'>
  /* Handle event when "Run Search" button is clicked */
   $(document).on("click", "#search_run_button", function(event){
    $.ajax('search_run', {
      type: 'GET',
      dataType: 'script',
      data: {
        search_entity: $("#search_entity").val()
      },
      error: function(jqXHR, textStatus, errorThrown) {
        return console.log("AJAX Error: " + textStatus);
      }
    });
  });
</script>

这是上表中单击按钮的路线条目:

get "/search_run" => "search#run_search", :as => :search_run

这是上面路由条目调用的控制器函数:

  def run_search
    logger.info "SearchController run_search"

    $search_entity = params[:search_entity]

    data_table = SearchDatatable.new(view_context)

    respond_to do |format|
      format.html
      format.json do
        render json: {
          "pageLength"      => data_table.page_length,
          "recordsTotal"    => data_table.records_total,
          "recordsFiltered" => data_table.records_filtered,
          "data"            => data_table.run_data
        }
      end
    end    
    render :partial => "search/run_search.js.erb"
  end

这是上面控制器函数调用的部分:

搜索/run_search.js.erb

$('#datatable_div').hide();
$('#datatable_div').hide().after('<%=escape_javascript(render(:partial => 'search/run_search')) %>');

如您所见,我datatable_div在渲染数据表之前隐藏了。但是,数据表仍然被附加到页面而不是被覆盖。

如何覆盖datatable_div每次,以便无论页面上完成的搜索次数如何,始终只显示一个数据表?

请帮忙!

这是数据表渲染代码,以防万一:

搜索/run_search.html.erb

<div id="datatable_div">
  <%= content_tag :table, 
                  role: :search_datatable, 
                  id: 'search_datatable', 
                  style: 'height:500px; width: 100vw; overflow-y: auto;',
                  class: 'table table-striped table-bordered table-hover', 
                  data: { url: search_datatable_path(format: :json)} do %>
    <thead>
      <tr>
        <th>Column1</th>
        <th>Column2</th>
      </tr>
    </thead>

    <tbody>
    </tbody>

  <% end %>
</div>

<script>
  $(document).ready(function(){
    $("table[role='search_datatable']").each(function(){
      var table = $(this).DataTable({
        columnDefs: [ 
        { "orderable": true, "targets": 1}, 
        ],
        aoColumns: [
              { mData: 'column1' },
              { mData: 'column2' }
          ],      
        autoWidth: true,
        pageLength: 50,
        processing: true,
        serverSide: true,
        sDom: 'ltipr',
        ajax: $(this).data('url')
      });
    });
  });  
</script>

我根据其他 stackoverflow 用户的评论尝试了这些:

方法 1(基于@MikeHeft 的建议)

方法 1. a)

$('#datatable_div').html('').html('<%=escape_javascript(render(:partial => 'search/dbr/run_search')) %>');

这种方法发生了什么?

即使是第一次,这也不会呈现数据表。它永远不会呈现任何数据表。

方法 1. b)

$('#datatable_div').html('').after('<%=escape_javascript(render(:partial => 'search/dbr/run_search')) %>');

这种方法之后发生了什么?

这将使数据表正常 - 但它仍然让我回到我原来的问题 - 它不会在我下次运行搜索时替换现有的数据表。它只是不断向我的搜索页面添加越来越多的数据表。

标签: javascripthtmlruby-on-railsdatatables

解决方案


推荐阅读