Rails - 在选项卡之间同步按钮点击

Posted

技术标签:

【中文标题】Rails - 在选项卡之间同步按钮点击【英文标题】:Rails - Synchronise button clicks among tabs 【发布时间】:2018-07-14 02:10:36 【问题描述】:

我对 bootstrap-tabs 有一个看法。选项卡是动态生成的。

<%= form_with(:id => 'my-form', model: [:admin, @island], local: true) do |form| %>
  <div class="tab-content bg-light" id="tabs-from-locales-content">

    <%= available_locales.each_with_index do |locale, i| %>
      <div
      class="tab-pane fade <%= 'show active' if i == 0 %>"
      id="<%= locale.downcase %>"
      role="tabpanel"
      aria-labelledby="<%= locale.downcase %>-tab">
        <%= render partial: 'island_form', locals: counter: i, locale: locale, f: form %>
      </div>
    <% end %>

  </div>

...
...

标签代表应用程序的每个可用本地化。 表单的模型包含两个嵌套属性。这些属性与模型有1 to many 关系。所以用户可以从表单中添加多个。它们的字段可以动态生成:

(为简单起见,我在问题中只包含一个。这是_island_form.html.erb partial 的一部分。)

<div class="form-group ports-div">
  <%= f.label :port %> </br>
  <%= f.fields_for :ports do |builder| %>

    <%= render 'port_fields', f: builder %>

  <% end %>
  <%= link_to_add_fields t('form.add_port'), f, :ports %>
</div>

<div class="form-group">
  <%= f.label :airport %> </br>
  <%= f.fields_for :airports do |builder| %>

    <%= render 'airport_fields', f: builder %>

  <% end %>
  <%= link_to_add_fields t('form.add_airport'), f, :airports %>
</div>

还有port_fields 部分:

<fieldset>
  <%= f.label :name %>
  <%= f.text_field :name, class: 'form-control' %>
  <%= f.hidden_field :_destroy %>
  <%= link_to t('form.remove'), '#', class: 'remove_fields' %>
</fieldset>

link_to_add_fields 辅助方法:

  def link_to_add_fields(name, f, association)
    # Builds an instance of the association record.
    new_object = f.object.send(association).klass.new
    # Grabbing ruby's object id.
    id = new_object.object_id
    fields = f.fields_for(association, new_object, child_index: id) do |builder|
      render(association.to_s.singularize + '_fields', f: builder)
    end
    link_to(name, '#', class: 'add_fields', data:  id: id, fields: fields.gsub('\n', '') )
  end

我想要实现的是在可用选项卡之间同步添加和删除这些字段。因此,当用户在第一个选项卡上单击 Add field 时,所有其他选项卡都将遵循此操作。字段移除也是如此。

Add 按钮的相关js 文件如下所示。我在triggertriggerHandlerstopPropagation 之间尝试了许多组合,尽管大多数时候我得到的是*** exception,并且这些字段仅添加到我单击add 按钮的选项卡中。

(由于我在selector 中传递了一个类(.add_fields),它不应该附加到所有具有.add_fields 类的元素吗?)

form.on('click', '.add_fields', function (event, param) 
    event.stopPropagation();
    event.preventDefault();

    var time = new Date().getTime();
    var regexp = new RegExp($(this).data('id'), 'g');
    $(this).before($(this).data('fields').replace(regexp, time));

    $('.tab-pane').each(function (index) 

        $('.add_fields').trigger("click", ["custom_click"]);
        console.log('Tab - ' + index);
    )
);

编辑

我正在使用该代码到达某个地方:

    $('.ports-div').each(function (index) 

        $(this).find('.add_fields').each(function () 
            this.click();
        )
    );

虽然,在所有选项卡中,添加了 6 个字段而不是 1 个字段。我将 ports-div 添加到包含所有相关元素的 div 中。

【问题讨论】:

【参考方案1】:

完全重写...

您所看到的问题是您的 click 事件处理程序正在触发对所有选项卡窗格的单击,包括您当前正在处理的选项卡窗格。您还不仅仅是单击循环中的单个项目,而是所有与“.add_fields”匹配的项目。这会导致再次递归处理点击。

为了防止这种情况,我建议调用一个函数来直接添加你的字段,而不是触发点击。如果在您的情况下触发点击是最简单的,请考虑以下示例,该示例大致执行您想要的操作,而不会出现递归错误。

https://jsfiddle.net/3ftf0j8e/1/

虚拟 HTML

<a class="add_fields" id='1'>link 1</a>    
<a class="add_fields" id='2'>link 2</a>    
<a class="add_fields" id='3'>link 3</a>    
<a class="add_fields" id='4'>link 4</a>

示例 Javascript

$(document).on('click', '.add_fields', function (event, param) 
    event.preventDefault();


    var clicked_id = $(this).attr('id');
    console.log('clicked id:' + clicked_id);

    $(this).addClass('done');
    $(this).addClass('clicked');
    // Just click items that have not been clicked
    var els = $('.add_fields').not('.clicked');
    console.log(els);    
    els.trigger("click");

    setTimeout(function()
      if($('.add_fields').length == $('.add_fields.done').length)
        $('.add_fields').removeClass('clicked');
    )

);

CSS

a.clicked 
  background-color: yellow;


a.done 
  color: red;

正如您现在所见,每个只触发一次。最后的 setTimeout 允许 DOM 在清除 clicked 类之前更新。

【讨论】:

不行,只是在当前标签中添加字段 我刚刚注意到一个错误。我会在一分钟内更新。对不起。 不是,console.log(clicked_id)undefined 另外,.add_fields 是一个链接标签,所以我想我应该使用.click 来触发它 使用您的代码,无论我在哪个选项卡中按下按钮,所有字段都会添加到第一个选项卡,我得到Stack Overflow 错误

以上是关于Rails - 在选项卡之间同步按钮点击的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 选项卡之间进行通信

小米13pro更新卡在已同步

有没有办法先在选项卡之间同步 redux 存储状态,然后让每个选项卡控制自己的状态?

在 DevTools 的性能选项卡中分析鼠标单击

如何在 Ionic 中的选项卡之间传递数据

SwiftUI 在选项卡之间导航的正确方式