Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Jquery plugin for adding and removing nested records (Rails accepts nested attributes for)

View example.erb.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
<!-- Sorry, this example is with formtastic but I think it would work the same with vanilla rails form helpers -->
 
 
 
<%= semantic_form_for @survey do |form| %>
<fieldset class="nested_models answers" data-association="answers">
<%- form.object.answers.build %>
<%= form.semantic_fields_for :answers do |answer| %>
<%- record = answer.object %>
<fieldset class="<%= record.new_record? ? :new : nil %>">
<ol>
<%= answer.input :text, required: false %>
<%= answer.input :_destroy, as: :boolean %>
</ol>
</fieldset>
<% end %>
<%= link_to t('.add_answer'), '#', :class => 'add_record', :style => 'display:none' %>
</fieldset>
<%= form.buttons do %>
<%= form.commit_button %>
<% end %>
<% end %>
 
 
<script>
$('fieldset[data-association]').nestedAssociations();
</script>
View example.erb.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
// macario ortega
// github.com/maca
// mit licence
 
(function($){
$.fn.nestedAssociationsChangeId = function(association, newId){
$(this).find('[id], [for], [name]').each(function(){
var tag = $(this);
$.each(['id', 'for', 'name'], function(index, attribute){
var value = tag.attr(attribute);
 
if (value && attribute == 'name') {
var matcher = new RegExp('\\[' + association + '_attributes\\]\\[\\d+\\]');
tag.attr(attribute, value.replace(matcher, '[' + association + '_attributes][' + newId + ']'));
} else if (value) {
var matcher = new RegExp(association + '_attributes_\\d+');
tag.attr(attribute, value.replace(matcher, association + '_attributes_' + newId));
};
});
});
};
 
$.fn.nestedAssociations = function(opts){
var self = $(this);
var associationFieldset = self;
var settings = {
add : $.noop,
remove : $.noop
}
if (opts) { $.extend(settings, opts); }
 
$(this).find('input[id$=_destroy]').closest('label').each(function(){
var destroyLink = $('<a href="#" class="remove-associated-record">').text($(this).text());
destroyLink.click(function(){
$(this).siblings('input').attr('value', '1');
settings.remove.apply($(this).closest('fieldset').slideUp());
return false;
});
 
$(this).hide().after(destroyLink);
});
 
return associationFieldset.each(function(){
var container = $(this);
var association = container.attr('data-association');
var template = container.children('fieldset.new').last().detach();
 
container.children('a.add_record').show().click(function(){
var cleanTemplate = template.clone(true);
$(this).before(cleanTemplate.hide());
 
$(this).parents('fieldset[data-association]').each(function(){
var association = $(this).attr('data-association');
$(this).children('fieldset.new').each(function(){
$(this).nestedAssociationsChangeId(association, new Date().getTime());
})
});
 
cleanTemplate.slideDown(function(){
settings.add.apply(this);
});
return false;
});
});
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.