Man*_*nos 6 javascript ruby forms jquery ruby-on-rails
我有一个带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>
...
...
Run Code Online (Sandbox Code Playgroud)
选项卡表示应用程序的每个可用本地化.表单的模型包含两个嵌套属性.这些属性1 to many与模型有关系.因此,用户可以从表单中添加多个这些.他们的字段可以动态生成:
(为简单起见,我只在问题中包含一个.这是部分的_island_form.html.erb一部分.)
<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>
Run Code Online (Sandbox Code Playgroud)
而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>
Run Code Online (Sandbox Code Playgroud)
的link_to_add_fieldshelper方法:
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
Run Code Online (Sandbox Code Playgroud)
我想要实现的是在可用选项卡之间同步这些字段的添加和删除.因此,当用户单击Add field第一个选项卡时,所有其他选项卡将遵循此操作.字段删除相同.
我按钮的相关js文件Add如下所示.我曾尝试之间有许多组合trigger,triggerHandler而且stopPropagation,虽然大多数我得到时代StackOverflow exception和字段添加只对我点击标签add按钮.
(因为我传递的是一个类(.add_fields)selector不应该附加到所有带有类的元素.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);
})
});
Run Code Online (Sandbox Code Playgroud)
编辑
我正在使用该代码:
$('.ports-div').each(function (index) {
$(this).find('.add_fields').each(function () {
this.click();
})
});
Run Code Online (Sandbox Code Playgroud)
虽然,在所有选项卡中,但是添加了1个字段6字段.我添加了ports-div包含所有相关元素的div.
完全重写...
正如您所看到的,问题是您的单击事件处理程序正在触发所有选项卡窗格的单击,包括您当前正在处理的选项卡窗格。您也不只是单击循环中的单个项目,而是单击所有与“.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>
Run Code Online (Sandbox Code Playgroud)
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');
})
});
Run Code Online (Sandbox Code Playgroud)
CSS
a.clicked {
background-color: yellow;
}
a.done {
color: red;
}
Run Code Online (Sandbox Code Playgroud)
正如您现在所看到的,每个都只触发一次。最后的 setTimeout 允许在清除单击的类之前更新 DOM。
| 归档时间: |
|
| 查看次数: |
180 次 |
| 最近记录: |