update with changes from Production branch
This commit is contained in:
114
app/assets/javascripts/nested_form.js
Normal file
114
app/assets/javascripts/nested_form.js
Normal file
@ -0,0 +1,114 @@
|
||||
(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).data('association'); // Name of child
|
||||
var blueprint = $('#' + $(link).data('blueprint-id'));
|
||||
var content = blueprint.data('blueprint'); // Fields template
|
||||
|
||||
// Make the context correct by replacing <parents> with the generated ID
|
||||
// of each of the parent objects
|
||||
var context = ($(link).closest('.fields').closestChild('input, textarea, select').eq(0).attr('name') || '').replace(new RegExp('\[[a-z_]+\]$'), '');
|
||||
|
||||
// context will be something like this for a brand new form:
|
||||
// project[tasks_attributes][1255929127459][assignments_attributes][1255929128105]
|
||||
// or for an edit form:
|
||||
// project[tasks_attributes][0][assignments_attributes][1]
|
||||
if (context) {
|
||||
var parentNames = context.match(/[a-z_]+_attributes(?=\]\[(new_)?\d+\])/g) || [];
|
||||
var parentIds = context.match(/[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 = this.newId();
|
||||
content = $.trim(content.replace(regexp, new_id));
|
||||
|
||||
var field = this.insertFields(content, assoc, link);
|
||||
// bubble up event upto document (through form)
|
||||
field
|
||||
.trigger({ type: 'nested:fieldAdded', field: field })
|
||||
.trigger({ type: 'nested:fieldAdded:' + assoc, field: field });
|
||||
return false;
|
||||
},
|
||||
newId: function() {
|
||||
return new Date().getTime();
|
||||
},
|
||||
insertFields: function(content, assoc, link) {
|
||||
var target = $(link).data('target');
|
||||
if (target) {
|
||||
return $(content).appendTo($(target));
|
||||
} else {
|
||||
return $(content).insertBefore(link);
|
||||
}
|
||||
},
|
||||
removeFields: function(e) {
|
||||
var $link = $(e.currentTarget),
|
||||
assoc = $link.data('association'); // Name of child to be removed
|
||||
|
||||
var hiddenField = $link.prev('input[type=hidden]');
|
||||
hiddenField.val('1');
|
||||
|
||||
var field = $link.closest('.fields');
|
||||
field.hide();
|
||||
|
||||
field
|
||||
.trigger({ type: 'nested:fieldRemoved', field: field })
|
||||
.trigger({ type: 'nested:fieldRemoved:' + assoc, field: field });
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
window.nestedFormEvents = new NestedFormEvents();
|
||||
$(document)
|
||||
.delegate('form a.add_nested_fields', 'click', nestedFormEvents.addFields)
|
||||
.delegate('form a.remove_nested_fields', 'click', nestedFormEvents.removeFields);
|
||||
})(jQuery);
|
||||
|
||||
// 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);
|
Reference in New Issue
Block a user