I’m using the nested form gem in my Rails 3 app: https://github.com/ryanb/nested_form. I’m able to add/remove the “audience fields” in my form. The audience model belongs to the upload model.
What I’d like to be able to do is to count the number of times the audience fields are added in the form. So, for example, the form will initially display “Audience 1” above the audience fields. If I add another audience field, then “Audience 2” will be displayed, and so on.
application.js
var n = $("div.audiencefields").length;
$("span").text("Audience " + n);
What am I doing wrong?
edit:
application.js
$("#removelink").hide().filter(":first-child").show();
$("div.audiencefields span").each(function(index, element) {
$(this).text("Audience " + (index + 1));});
nested_form.js
jQuery(function($) {
window.NestedFormEvents = function() {
this.addFields = $.proxy(this.addFields, this);
this.removeFields = $.proxy(this.removeFields, this);
};
NestedFormEvents.prototype = {
addFields: function(e) {
// Setup
var link = e.currentTarget;
var assoc = $(link).attr('data-association'); // Name of child
var content = $('#' + assoc + '_fields_blueprint').html(); // Fields template
// Make the context correct by replacing new_<parents> with the generated ID
// of each of the parent objects
var context = ($(link).closest('.fields').closestChild('input:first').attr('name') || '').replace(new RegExp('\[[a-z]+\]$'), '');
// context will be something like this for a brand new form:
// project[tasks_attributes][new_1255929127459][assignments_attributes][new_1255929128105]
// or for an edit form:
// project[tasks_attributes][0][assignments_attributes][1]
if (context) {
var parentNames = context.match(/[a-z_]+_attributes/g) || [];
var parentIds = context.match(/(new_)?[0-9]+/g) || [];
for(var i = 0; i < parentNames.length; i++) {
if(parentIds[i]) {
content = content.replace(
new RegExp('(_' + parentNames[i] + ')_.+?_', 'g'),
'$1_' + parentIds[i] + '_');
content = content.replace(
new RegExp('(\\[' + parentNames[i] + '\\])\\[.+?\\]', 'g'),
'$1[' + parentIds[i] + ']');
}
}
}
// Make a unique ID for the new child
var regexp = new RegExp('new_' + assoc, 'g');
var new_id = new Date().getTime();
content = content.replace(regexp, "new_" + new_id);
var field = this.insertFields(content, assoc, link);
$(link).closest("form")
.trigger({ type: 'nested:fieldAdded', field: field })
.trigger({ type: 'nested:fieldAdded:' + assoc, field: field });
return false;
},
insertFields: function(content, assoc, link) {
return $(content).insertBefore(link);
},
removeFields: function(e) {
var link = e.currentTarget;
var hiddenField = $(link).prev('input[type=hidden]');
hiddenField.val('1');
// if (hiddenField) {
// $(link).v
// hiddenField.value = '1';
// }
var field = $(link).closest('.fields');
field.hide();
$(link).closest("form").trigger({ type: 'nested:fieldRemoved', field: field });
return false;
}
};
window.nestedFormEvents = new NestedFormEvents();
$('form a.add_nested_fields').live('click', nestedFormEvents.addFields);
$('form a.remove_nested_fields').live('click', nestedFormEvents.removeFields);
});
// http://plugins.jquery.com/project/closestChild
/*
* Copyright 2011, Tobias Lindig
*
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
*
*/
(function($) {
$.fn.closestChild = function(selector) {
// breadth first search for the first matched node
if (selector && selector != '') {
var queue = [];
queue.push(this);
while(queue.length > 0) {
var node = queue.shift();
var children = node.children();
for(var i = 0; i < children.length; ++i) {
var child = $(children[i]);
if (child.is(selector)) {
return child; //well, we found one
}
queue.push(child);
}
}
}
return $();//nothing found
};
})(jQuery);
new.html.erb
<%= f.fields_for :audiences do |audience_form| %>
<div class="audiencefields">
<span></span>
<p>
<%= audience_form.label :number_of_people %><br />
<%= audience_form.text_field :number_of_people %>
</p>
<p>
<%= audience_form.label :gender %><br />
<%= audience_form.text_field :gender %>
</p>
<p>
<%= audience_form.label :ethnicity %><br />
<%= audience_form.text_field :ethnicity %>
</p>
<p>
<%= audience_form.label :age %><br />
<%= audience_form.text_field :age %>
</p>
</div>
<%= audience_form.link_to_remove "Remove this", :id => "removelink" %>
<% end %>
<p><%= f.link_to_add "Add this", :audiences, :id => "addlink" %></p>
I create another answer as comments don’t allow formatting code
If that is the file you are using then there on lines 69-71 you can find the following code
This bind click events to the add and remove links. In your custom script bind events in the same way. It will be executed once the above is completed. So your code should like this