我使用Cocoon gem构建一个嵌套表单,其中field_for包含另一个field_for。层次结构如下所示:
使用link_to_add_association链接添加每个卡条目。我使用after-insert回调允许用户点击创建的卡片以显示包含按钮字段的弹出窗口(用于UX目的)。
我的插入后回调示例:
$('#carousel-stage-ul')
.on('cocoon:after-insert', function(e, insertedItem) {
insertedItem.find('#add-card-button, .new_button_card').click(function() {
$('#black-background')[0].style.display = "block";
insertedItem.find('.add-button-card-modal').css('display', 'block');
});
insertedItem.find('#delete_new_card_button').click(function() {
$('#black-background')[0].style.display = "none";
insertedItem.find('.add-button-card-modal').css("display", "none");
$firstIn = insertedItem.find('.add-button-card-modal input[type=text]').eq(0);
$secondIn = insertedItem.find('.add-button-card-modal input[type=text]').eq(1);
$firstIn.val("");
$secondIn.val("");
$buttonForm = $.parseHTML('<div id="add-card-button" class="add-button">+ Add Button</div>')
insertedItem.find('#new_card_button').replaceWith($buttonForm[0]);
insertedItem.find('#add-card-button, .new_button_card').click(function() {
$('#black-background')[0].style.display = "block";
insertedItem.find('.add-button-card-modal').css('display', 'block');
});
});
})
.on('cocoon:after-remove', function(e, insertedItem) {
...
_card_fields.html.erb部分呈现按钮:
<% f.object.buttons.build %>
<%= f.fields_for :buttons do |button_card_fields| %>
<%= render 'button_fields', f: button_card_fields %>
<% end %>
_button_fields.html.erb partial:
<div class="add-button-card-modal">
<h4>Add New Button</h4>
<label>Button Text</label>
<%= f.text_field :button_text, :maxlength => 20, placeholder: "Enter the text to display on the button..." %>
<br><br>
<label>Button URL</label>
<%= f.text_field :button_url, placeholder: "Paste URL..." %>
<div class="nav-popups-buttons">
<button type="button" id="validate_new_card_button" class="small-cta2">Add Button</button>
<p class="remove-link" id="delete_new_card_button">Remove Button</p>
</div>
</div>
这是为卡片轮播中的一张卡片呈现的HTML,以便更好地理解我的插入后回调:
<div class="connected-carousels" style="display: block;">
<div class="stage">
<div class="carousel carousel-stage" data-jcarousel="true">
<ul id="carousel-stage-ul" style="left: 0px; top: 0px;">
<li class="carousel-slide">
<div id="card-messenger">
<div class="DIV_1b">
<div class="DIV_2b">
<div class="DIV_3">
<a class="A_4"></a>
<div class="DIV_5" style="">
</div>
</div>
<div class="DIV_6">
<div class="DIV_7">
<div class="DIV_8">
<div class="DIV_9">
<div class="DIV_10">
</div>
<div class="DIV_11">
<input maxlength="80" size="0" placeholder="Enter title..." type="text" name="letter[cards_attributes][1509602161650][title]" id="letter_cards_attributes_1509602161650_title">
</div>
</div>
<div class="DIV_12">
<div class="DIV_14">
<input maxlength="80" size="0" placeholder="Enter subtitle..." type="text" name="letter[cards_attributes][1509602161650][subtitle]" id="letter_cards_attributes_1509602161650_subtitle">
</div>
</div>
</div>
</div>
</div>
</div>
<div id="add-card-button" class="add-button" style="width: 308.203px;">+ Add Button</div>
<div id="DIV_19" class="card-share-button" style="display:none;">
<a id="A_20">Share</a>
</div>
<div id="DIV_19" class="input-card-share-button">
<div id="add-share-card-button" class="add-button" style="padding: 0!important;">+ Add Share</div>
</div>
<input value="false" id="hidden-share-field" type="hidden" name="letter[cards_attributes][1509602161650][button_share]">
</div>
</div>
<div class="add-button-card-modal">
<h4>Add New Button</h4>
<label>Button Text</label>
<input maxlength="20" placeholder="Enter the text to display on the button..." size="20" type="text" name="letter[cards_attributes][1509602161650][buttons_attributes][0][button_text]" id="letter_cards_attributes_1509602161650_buttons_attributes_0_button_text">
<br><br>
<label>Button URL</label>
<input placeholder="Paste URL..." type="text" name="letter[cards_attributes][1509602161650][buttons_attributes][0][button_url]" id="letter_cards_attributes_1509602161650_buttons_attributes_0_button_url">
<div class="nav-popups-buttons">
<button type="button" id="validate_new_card_button" class="small-cta2">Add Button</button>
<p class="remove-link" id="delete_new_card_button">Remove Button</p>
</div>
</div>
<div class="modal-image">
<div id="display_image_upload">
<label>Upload Image</label>
<input id="image-input" class="inputBox_upload_image" type="file" name="letter[cards_attributes][1509602161650][image_url]"><div class="progress"><div class="bar"></div></div>
</div>
<label id="or">OR</label>
<div id="display_image_url">
<label>Paste Image Url</label>
<input id="image-input" class="inputBox_image" type="text" name="letter[cards_attributes][1509602161650][remote_image_url]">
</div>
<div class="nav-popups-buttons">
<button type="button" id="validate_image" class="small-cta2">Add Image</button>
<p class="remove-link" id="delete_new_card_image">Remove Image</p>
</div>
</div>
<div>
<input type="hidden" name="letter[cards_attributes][1509602161650][_destroy]" id="letter_cards_attributes_1509602161650__destroy" value="false"><a class="remove-link remove_fields dynamic" data-wrapper-class="carousel-slide" href="#">Remove Card</a>
</div>
</li></ul>
</div>
<a href="#" class="prev prev-stage inactive" data-jcarouselcontrol="true"><span>‹</span></a>
<a href="#" class="next next-stage inactive" data-jcarouselcontrol="true"><span>›</span></a>
</div>
<div class="navigation">
<a href="#" class="prev prev-navigation inactive" data-jcarouselcontrol="true">‹</a>
<a href="#" class="next next-navigation inactive" data-jcarouselcontrol="true">›</a>
<div class="carousel carousel-navigation" data-jcarousel="true">
<ul id="carousel-navigation-ul" style="left: 0px; top: 0px;"><li data-jcarouselcontrol="true" class="active"><img alt="botletter" class="carousel-ico" src="/assets/icon-cards-0178dc5a1fb2811909dcd1d1fcef121baa165e46d49973dff5fdea12090631fa.png"></li></ul>
</div>
</div>
<div>
<a id="add-card-button-bis" data-association-insertion-node="#carousel-stage-ul" data-association-insertion-method="append" class="add_fields" data-association="card" data-associations="cards" data-association-insertion-template="<li class="carousel-slide">
<div id="card-messenger">
<div class="DIV_1b">
<div class="DIV_2b">
<div class="DIV_3">
<a class="A_4"></a>
<div class="DIV_5" style="">
</div>
</div>
<div class="DIV_6">
<div class="DIV_7">
<div class="DIV_8">
<div class="DIV_9">
<div class="DIV_10">
</div>
<div class="DIV_11">
<input maxlength="80" size="0" placeholder="Enter title..." type="text" name="letter[cards_attributes][new_cards][title]" id="letter_cards_attributes_new_cards_title" />
</div>
</div>
<div class="DIV_12">
<div class="DIV_14">
<input maxlength="80" size="0" placeholder="Enter subtitle..." type="text" name="letter[cards_attributes][new_cards][subtitle]" id="letter_cards_attributes_new_cards_subtitle" />
</div>
</div>
</div>
</div>
</div>
</div>
<div id="add-card-button" class="add-button" style="width: 308.203px;">+ Add Button</div>
<div id="DIV_19" class="card-share-button" style="display:none;">
<a id="A_20">Share</a>
</div>
<div id="DIV_19" class="input-card-share-button">
<div id="add-share-card-button" class="add-button" style="padding: 0!important;">+ Add Share</div>
</div>
<input value="false" id="hidden-share-field" type="hidden" name="letter[cards_attributes][new_cards][button_share]" />
</div>
</div>
<div class="add-button-card-modal">
<h4>Add New Button</h4>
<label>Button Text</label>
<input maxlength="20" placeholder="Enter the text to display on the button..." size="20" type="text" name="letter[cards_attributes][new_cards][buttons_attributes][0][button_text]" id="letter_cards_attributes_new_cards_buttons_attributes_0_button_text" />
<br><br>
<label>Button URL</label>
<input placeholder="Paste URL..." type="text" name="letter[cards_attributes][new_cards][buttons_attributes][0][button_url]" id="letter_cards_attributes_new_cards_buttons_attributes_0_button_url" />
<div class="nav-popups-buttons">
<button type="button" id="validate_new_card_button" class="small-cta2">Add Button</button>
<p class="remove-link" id="delete_new_card_button">Remove Button</p>
</div>
</div>
<div class="modal-image">
<div id="display_image_upload">
<label>Upload Image</label>
<input id="image-input" class="inputBox_upload_image" type="file" name="letter[cards_attributes][new_cards][image_url]" />
</div>
<label id="or">OR</label>
<div id="display_image_url">
<label>Paste Image Url</label>
<input id="image-input" class="inputBox_image" type="text" name="letter[cards_attributes][new_cards][remote_image_url]" />
</div>
<div class="nav-popups-buttons">
<button type="button" id="validate_image" class="small-cta2">Add Image</button>
<p class="remove-link" id="delete_new_card_image">Remove Image</p>
</div>
</div>
<div>
<input type="hidden" name="letter[cards_attributes][new_cards][_destroy]" id="letter_cards_attributes_new_cards__destroy" value="false" /><a class="remove-link remove_fields dynamic" data-wrapper-class="carousel-slide" href="#">Remove Card</a>
</div>
</li>
" href="#" style="display: block;">+ Add Card</a>
</div>
</div>
除非创建操作引发错误或加载编辑视图,否则一切正常。在这两种情况下,已经创建了已创建的卡,但未调用后插入回调。因此,我无法显示我的按钮弹出窗口......
有没有办法在编辑视图/错误视图中调用渲染后关联的插入后回调?
答案 0 :(得分:2)
如果我理解正确,您希望after-insert
回调中的内容也是服务器呈现的html。这在某种意义上是奇怪的,因为imho实际上是我先做的事情:)
因此,不是附加点击事件,而是始终处理它们(动态)。请注意id
- 元素只允许一次页面(正确的html,否则会导致很多错误),所以我用类似的替换所有那些,因为它们似乎在重复。
所以做一些像
这样的事情$(document).on('click', '.add-card-button, .new-button-card'), function() {
$('#black-background')[0].style.display = "block";
$(this).nearest('.add-button-card-modal').css('display', 'block');
})
有人可能想知道为什么你不使用普通的模态库,就像普通人一样:P
第二个单击处理程序虽然稍微复杂一点,实际上会以同样的方式解决,因此不再需要after-insert
处理程序。
类似
$(document).on('click', '.delete-card-button', function() {
...
})
答案 1 :(得分:1)
你真的不应该使用jquery来修复这样的编辑代码......这是一个症状,而不是问题...如果关系&amp; .build
设置正确,编辑将正常工作&amp;自动加载所有内容 - 因为rails会生成表单的hmtl。
在您真正尝试使用jquery hacks修复代码之前 - 我建议您构建一个没有弹出窗口的页面......这一切都只是在一个大混乱中吐出来。如果嵌套模型适用于您当前的关系,那么请继续实现复杂的弹出系列。如果它不起作用 - 问题是您在模型中的关系或控制器使用.build
的方式
据说你要找的答案可以在jquery中采用两种形式:
$( document ).ready()
检测何时设置为触发包含对cocoon.js
的{{1}}回调调用的函数。具体 - 由于您可能知道包含按钮after-insert
的名称或css元素,因此您首先要创建一个选择器,以便在field_for
...之后的css后面进行查找可能是field_for
。你这样做,所以jquery不会在你的dom&amp;事故中改变其他部分。然后使用jquery .on()
指定按钮所属类型的所有dom元素,以及触发的触发器。