diff --git a/app/assets/javascripts/cocoon.js b/app/assets/javascripts/cocoon.js index 2cedf00..b45c389 100644 --- a/app/assets/javascripts/cocoon.js +++ b/app/assets/javascripts/cocoon.js @@ -7,6 +7,9 @@ content.replace(reg_exp, with_str); } + $.fn.parentSiblings = function(selector) { + return $(this).parent().siblings(selector); + } $('.add_fields').live('click', function(e) { e.preventDefault(); diff --git a/app/assets/javascripts/cocoon/ordered.js b/app/assets/javascripts/cocoon/ordered.js index 37ed84a..99a9ffc 100644 --- a/app/assets/javascripts/cocoon/ordered.js +++ b/app/assets/javascripts/cocoon/ordered.js @@ -1,29 +1,88 @@ //= require jquery-ui // (function($) { - $(function() { - $('li[data-ordered_by]').each(function(index, element) { - var field = $(element).data('ordered_by'); - var fieldSearch = "[name*='[" + field + "]']" - - $(element).sortable({ - items: '.nested-fields', + $.cocoon = { + ordered: { + options: { + items: '> .nested-fields', stop: function(e, ui) { - $(element).find(fieldSearch).each(function(index, element) { - $(element).val(index); - }); + if (window.CKEDITOR) { + var editors = $(ui.item).data('cocoon_ckeditors'); + var i, j; + + for (i = 0, j = editors.length; i < j; ++i) { + var id = editors[i]; + var editor = CKEDITOR.instances[id]; + + if (editor) { + editor.destroy(true); + CKEDITOR.remove(id); + } + + CKEDITOR.replace(id); + } + + $(ui.item).data('cocoon_ckeditors', []); + } + + $.cocoon.ordered._updateFields(this) + }, + start: function(e, ui) { + if (window.CKEDITOR) { + var editors = []; + + $(ui.item).find('textarea').each(function(index, element) { + var id = $(element).attr('id'); + var editor = CKEDITOR.instances[id]; + if (editor) { + editors.push(id); + + editor.destroy(); + CKEDITOR.remove(id); + } + }); + + $(ui.item).data('cocoon_ckeditors', editors); + } } - }); + }, + _updateFields: function(element) { + console.log(element) + console.log($(element).data('fieldSearch')) + console.log($(element).find($(element).data('fieldSearch'))) - $(element).bind('cocoon:after-insert', function(e, node) { - var nextOrder = 0; + $(element).find($(element).data('fieldSearch')).each(function(index, element) { + $(element).val(index); + }); + }, + setup: function() { + $('li[data-ordered_by]').each(function(index, element) { + var field = $(element).data('ordered_by'); + var fieldSelector = "[name*='[" + field + "]']" + var fieldGroupSelector = "> .forms > .nested-fields" + var orderFieldSelector = "> .nested-fields " + fieldSelector; + var fieldSearch = "> .forms " + orderFieldSelector; - $(element).find(fieldSearch).each(function() { - nextOrder = Math.max(nextOrder, Number($(this).val()) + 1); + $(element).find('.forms').data('fieldSearch', orderFieldSelector).sortable($.cocoon.ordered.options); + + $(element).unbind('cocoon:after-insert').bind('cocoon:after-insert', function(e, node) { + var nextOrder = 0; + + if ($(element).find(fieldGroupSelector).is(node)) { + $(element).find(fieldSearch).each(function() { + nextOrder = Math.max(nextOrder, Number($(this).val())); + }); + + $(node).find(fieldSelector).val(nextOrder + 1) + } + }); }); - $(node).find(fieldSearch).val(nextOrder) - }); - }); - }); + $(document).on('cocoon:after-insert', function() { $.cocoon.ordered.setup(); }); + } + }, + }; + + $(function() { $.cocoon.ordered.setup(); }); })(jQuery); + diff --git a/app/assets/stylesheets/cocoon/active_admin.css.scss b/app/assets/stylesheets/cocoon/active_admin.css.scss index 3678246..e685d2a 100644 --- a/app/assets/stylesheets/cocoon/active_admin.css.scss +++ b/app/assets/stylesheets/cocoon/active_admin.css.scss @@ -19,7 +19,7 @@ li.cocoon { @extend .button; } - &.ui-sortable { + .forms.ui-sortable { fieldset { border-top: solid #777 12px; cursor: move; diff --git a/lib/cocoon/formtastic/cocoon_input.rb b/lib/cocoon/formtastic/cocoon_input.rb index 8e2cbdb..ae2a67a 100644 --- a/lib/cocoon/formtastic/cocoon_input.rb +++ b/lib/cocoon/formtastic/cocoon_input.rb @@ -4,7 +4,7 @@ class CocoonInput include ::Formtastic::Inputs::Base def to_html - output = label_html << semantic_fields_for << links + output = label_html << wrapped_semantic_fields << links template.content_tag(:li, output.html_safe, wrapper_html_options) end @@ -26,10 +26,22 @@ class CocoonInput end end + def wrapped_semantic_fields + template.content_tag(:div, semantic_fields_for, :class => 'forms') + end + def links template.content_tag(:div, :class => 'links') do template.link_to_add_association template.t('.add'), builder, method, input_html_options end end + + def input_html_options + super.merge( + 'data-association-insertion-node' => '.forms', + 'data-association-insertion-traversal' => 'parentSiblings', + 'data-association-insertion-method' => 'append' + ) + end end