/**
* Django admin inlines
*
* Based on jQuery Formset 1.1
* @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com)
* @requires jQuery 1.2.6 or later
*
* Copyright (c) 2009, Stanislaus Madueke
* All rights reserved.
*
* Spiced up with Code from Zain Memon's GSoC project 2009
* and modified for Django by Jannis Leidel, Travis Swicegood and Julien Phalip.
*
* Licensed under the New BSD License
* See: http://www.opensource.org/licenses/bsd-license.php
*/
(function($) {
$.fn.formset = function(opts) {
var options = $.extend({}, $.fn.formset.defaults, opts);
var $this = $(this);
var $parent = $this.parent();
var updateElementIndex = function(el, prefix, ndx) {
var id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))");
var replacement = prefix + "-" + ndx;
if ($(el).prop("for")) {
$(el).prop("for", $(el).prop("for").replace(id_regex, replacement));
}
if (el.id) {
el.id = el.id.replace(id_regex, replacement);
}
if (el.name) {
el.name = el.name.replace(id_regex, replacement);
}
};
var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off");
var nextIndex = parseInt(totalForms.val(), 10);
var maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off");
// only show the add button if we are allowed to add more items,
// note that max_num = None translates to a blank string.
var showAddButton = maxForms.val() === '' || (maxForms.val()-totalForms.val()) > 0;
$this.each(function(i) {
$(this).not("." + options.emptyCssClass).addClass(options.formCssClass);
});
if ($this.length && showAddButton) {
var addButton;
if ($this.prop("tagName") == "TR") {
// If forms are laid out as table rows, insert the
// "add" button in a new table row:
var numCols = this.eq(-1).children().length;
$parent.append('
' + options.addText + " |
");
addButton = $parent.find("tr:last a");
} else {
// Otherwise, insert it immediately after the last form:
$this.filter(":last").after('");
addButton = $this.filter(":last").next().find("a");
}
addButton.click(function(e) {
e.preventDefault();
var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS");
var template = $("#" + options.prefix + "-empty");
var row = template.clone(true);
row.removeClass(options.emptyCssClass)
.addClass(options.formCssClass)
.attr("id", options.prefix + "-" + nextIndex);
if (row.is("tr")) {
// If the forms are laid out in table rows, insert
// the remove button into the last table cell:
row.children(":last").append('");
} else if (row.is("ul") || row.is("ol")) {
// If they're laid out as an ordered/unordered list,
// insert an after the last list item:
row.append('' + options.deleteText + "");
} else {
// Otherwise, just insert the remove button as the
// last child element of the form's container:
row.children(":first").append('' + options.deleteText + "");
}
row.find("*").each(function() {
updateElementIndex(this, options.prefix, totalForms.val());
});
// Insert the new form when it has been fully edited
row.insertBefore($(template));
// Update number of total forms
$(totalForms).val(parseInt(totalForms.val(), 10) + 1);
nextIndex += 1;
// Hide add button in case we've hit the max, except we want to add infinitely
if ((maxForms.val() !== '') && (maxForms.val()-totalForms.val()) <= 0) {
addButton.parent().hide();
}
// The delete button of each row triggers a bunch of other things
row.find("a." + options.deleteCssClass).click(function(e) {
e.preventDefault();
// Remove the parent form containing this button:
var row = $(this).parents("." + options.formCssClass);
row.remove();
nextIndex -= 1;
// If a post-delete callback was provided, call it with the deleted form:
if (options.removed) {
options.removed(row);
}
// Update the TOTAL_FORMS form count.
var forms = $("." + options.formCssClass);
$("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length);
// Show add button again once we drop below max
if ((maxForms.val() === '') || (maxForms.val()-forms.length) > 0) {
addButton.parent().show();
}
// Also, update names and ids for all remaining form controls
// so they remain in sequence:
for (var i=0, formCount=forms.length; i