Commit a941d776791c41ab9ebf7b04f32326e60dbcb4d5

Authored by Jared Pace
1 parent 2ab6a694
Exists in master and in 1 other branch production

Add JS to allow adding/destroying nested attributes

app/models/project.rb
... ... @@ -15,7 +15,7 @@ class Project
15 15 validates_presence_of :name, :api_key
16 16 validates_uniqueness_of :name, :api_key, :allow_blank => true
17 17  
18   - accepts_nested_attributes_for :watchers,
  18 + accepts_nested_attributes_for :watchers, :allow_destroy => true,
19 19 :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
20 20  
21 21 def self.find_by_api_key!(key)
... ...
app/views/projects/_fields.html.haml
... ... @@ -2,9 +2,9 @@
2 2 = f.label :name
3 3 = f.text_field :name
4 4  
5   -%fieldset
  5 +%fieldset.nested-wrapper
6 6 %legend Watchers
7 7 - f.fields_for :watchers do |w|
8   - %div
  8 + %div.nested
9 9 = w.label :email
10 10 = w.text_field :email
11 11 \ No newline at end of file
... ...
public/javascripts/application.js
... ... @@ -0,0 +1,54 @@
  1 +$(function(){
  2 + activateNestedForms();
  3 +});
  4 +
  5 +function activateNestedForms() {
  6 + $('.nested-wrapper').each(function(){
  7 + var wrapper = $(this);
  8 +
  9 + makeNestedItemsDestroyable(wrapper);
  10 +
  11 + var addLink = $('<a/>').text('add another').addClass('add-nested');
  12 + addLink.click(appendNestedItem);
  13 + wrapper.append(addLink);
  14 + });
  15 + $('.nested a.remove-nested').live('click',removeNestedItem);
  16 +}
  17 +
  18 +function makeNestedItemsDestroyable(wrapper) {
  19 + wrapper.find('.nested').each(function(){
  20 + var nestedItem = $(this);
  21 + var destroyLink = $('<a/>').text('remove').addClass('remove-nested');
  22 + destroyLink.css('float','right');
  23 + nestedItem.find('label').first().prepend(destroyLink);
  24 + })
  25 +}
  26 +
  27 +function appendNestedItem() {
  28 + var addLink = $(this);
  29 + var nestedItem = addLink.parent().find('.nested').first().clone();
  30 + nestedItem.find('input, select').each(function(){
  31 + var input = $(this);
  32 + var timestamp = new Date();
  33 + timestamp = timestamp.valueOf();
  34 + input.attr('id', input.attr('id').replace(/([_\[])\d+([\]_])/,'$1'+timestamp+'$2'));
  35 + input.attr('name', input.attr('name').replace(/([_\[])\d+([\]_])/,'$1'+timestamp+'$2'));
  36 + input.val('');
  37 + });
  38 + addLink.before(nestedItem);
  39 +}
  40 +
  41 +function removeNestedItem() {
  42 + var destroyLink = $(this);
  43 + var nestedItem = destroyLink.closest('.nested');
  44 + var inputNameExample = nestedItem.find('input').first().attr('name');
  45 + var idFieldName = inputNameExample.replace(/\[[^\]]*\]$/,'[id]');
  46 + if($("input[name='"+idFieldName+"']").length) {
  47 + var destroyFlagName = inputNameExample.replace(/\[[^\]]*\]$/,'[_destroy]')
  48 + var destroyFlag = $('<input/>').attr('name',destroyFlagName).attr('type','hidden').val('true');
  49 + $("input[name='"+idFieldName+"']").after(destroyFlag);
  50 + nestedItem.hide();
  51 + } else {
  52 + nestedItem.remove();
  53 + }
  54 +}
0 55 \ No newline at end of file
... ...