/*! Django Formset - v0.3.0 - 2014-11-15
* https://github.com/mbertheau/jquery.django-formset
* Copyright (c) 2014 Markus Bertheau; Licensed MIT */
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
(function($) {
var FormsetError;
$.fn.djangoFormset = function(options) {
return new $.fn.djangoFormset.Formset(this, options);
};
FormsetError = (function(_super) {
__extends(FormsetError, _super);
function FormsetError() {
return FormsetError.__super__.constructor.apply(this, arguments);
}
return FormsetError;
})(Error);
$.fn.djangoFormset.Formset = (function() {
function Formset(base, options) {
var deletedForms, forms, inputName, placeholderPos;
this.opts = $.extend({}, $.fn.djangoFormset.defaultOptions, options);
if (base.length === 0) {
throw new FormsetError("Empty selector.");
}
this.template = base.filter("." + this.opts.formTemplateClass);
if (this.template.length === 0) {
throw new FormsetError("Can't find template (looking for ." + this.opts.formTemplateClass + ")");
}
inputName = this.template.find("input,select,textarea").first().attr('name');
if (!inputName) {
throw new FormsetError("Can't figure out form prefix because there's no form element in the form template. Please add one.");
}
placeholderPos = inputName.indexOf('-__prefix__');
if (placeholderPos === -1) {
throw new FormsetError("Can't figure out form prefix from template because it doesn't contain '-__prefix__'.");
}
this.prefix = inputName.substring(0, placeholderPos);
this.totalForms = $("#id_" + this.prefix + "-TOTAL_FORMS");
if (this.totalForms.length === 0) {
throw new FormsetError("Management form field 'TOTAL_FORMS' not found for prefix " + this.prefix + ".");
}
this._initTabs();
forms = base.not("." + this.opts.formTemplateClass);
this.initialForms = forms.length;
$(this).on(this.opts.on);
this.forms = forms.map((function(_this) {
return function(index, element) {
var newForm, tab, tabActivator;
if (_this.hasTabs) {
tabActivator = $.djangoFormset.getTabActivator(element.id);
tab = new _this.opts.tabClass(tabActivator.closest('.nav > *'));
}
newForm = new _this.opts.formClass($(element), _this, index, tab);
$(_this).trigger("formInitialized", [newForm]);
return newForm;
};
})(this));
if (this.forms.length !== parseInt(this.totalForms.val())) {
console.error("TOTAL_FORMS is " + (this.totalForms.val()) + ", but " + this.forms.length + " non-template elements found in passed selection.");
}
deletedForms = this.forms.filter(function() {
return this.deleteInput.val();
});
deletedForms.each(function() {
return this["delete"]();
});
this.insertAnchor = base.not("." + this.opts.formTemplateClass).last();
if (this.insertAnchor.length === 0) {
this.insertAnchor = this.template;
}
return;
}
Formset.prototype._initTabs = function() {
var tabActivator, tabNav;
this.hasTabs = this.template.is('.tab-pane');
if (!this.hasTabs) {
return;
}
tabActivator = $.djangoFormset.getTabActivator(this.template.attr('id'));
if (tabActivator.length === 0) {
throw new FormsetError("Template is .tab-pane but couldn't find corresponding tab activator.");
}
tabNav = tabActivator.closest('.nav');
if (tabNav.length === 0) {
throw new FormsetError("Template is .tab-pane but couldn't find corresponding .nav.");
}
this.tabTemplate = tabNav.children("." + this.opts.formTemplateClass);
if (this.tabTemplate.length === 0) {
throw new FormsetError("Tab nav template not found (looking for ." + this.opts.formTemplateClass + ").");
}
};
Formset.prototype.addForm = function() {
var newForm, newFormElem, newTab, newTabElem, tabInsertAnchor;
if (this.hasTabs) {
newTabElem = this.tabTemplate.clone().removeClass(this.opts.formTemplateClass);
newTab = new this.opts.tabClass(newTabElem);
if (this.forms.length > 0) {
tabInsertAnchor = this.forms[this.forms.length - 1].tab.elem;
} else {
tabInsertAnchor = this.tabTemplate;
}
newTabElem.insertAfter(tabInsertAnchor);
}
newFormElem = this.template.clone().removeClass(this.opts.formTemplateClass);
newForm = new this.opts.formClass(newFormElem, this, parseInt(this.totalForms.val()), newTab);
newFormElem.insertAfter(this.insertAnchor);
this.insertAnchor = newFormElem;
this.forms.push(newForm);
this.totalForms.val(parseInt(this.totalForms.val()) + 1);
if (this.hasTabs) {
newTab.activate();
}
$(this).trigger("formInitialized", [newForm]);
$(this).trigger("formAdded", [newForm]);
return newForm;
};
Formset.prototype.deleteForm = function(index) {
var form;
form = this.forms[index];
form["delete"]();
};
Formset.prototype.handleFormRemoved = function(index) {
var form, i, _i, _len, _ref;
this.totalForms.val(parseInt(this.totalForms.val()) - 1);
this.forms.splice(index, 1);
_ref = this.forms;
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
form = _ref[i];
form._updateFormIndex(i);
}
if (this.forms.length === 0) {
this.insertAnchor = this.template;
} else {
this.insertAnchor = this.forms[this.forms.length - 1].elem;
}
};
return Formset;
})();
$.fn.djangoFormset.Form = (function() {
function Form(elem, formset, index, tab) {
var isInitial;
this.elem = elem;
this.formset = formset;
this.index = index;
this.tab = tab;
this.elem.data('djangoFormset.Form', this);
if (this.index !== void 0) {
this._initFormIndex(this.index);
}
this.deleteInput = this.field('DELETE');
isInitial = this.index < this.formset.initialForms;
if (this.deleteInput.length > 0 || !isInitial) {
this._replaceDeleteCheckboxWithButton();
}
}
Form.prototype.getDeleteButton = function() {
return $("");
};
Form.prototype.insertDeleteButton = function() {
if (this.deleteInput.length > 0) {
this.deleteInput.after(this.deleteButton);
} else {
(this.elem.is('TR') ? this.elem.children().last() : this.elem.is('UL') || this.elem.is('OL') ? this.elem.append('li').children().last() : this.elem).append(this.deleteButton);
}
};
Form.prototype["delete"] = function() {
var isInitial, nextTab, tabElems;
isInitial = this.index < this.formset.initialForms;
if (this.deleteInput.length === 0 && isInitial) {
console.warn("Tried do delete non-deletable form " + this.formset.prefix + " #" + this.index + ".");
return;
}
if (this.tab && this.tab.elem.is('.active')) {
tabElems = this.formset.forms.map(function(index, form) {
return form.tab.elem[0];
});
nextTab = tabElems.slice(this.index + 1).filter(':visible').first();
if (nextTab.length === 0) {
nextTab = tabElems.slice(0, this.index).filter(':visible').last();
}
if (nextTab.length > 0) {
nextTab.data('djangoFormset.tab').activate();
}
}
if (isInitial) {
if (this.deleteInput.length > 0) {
this.deleteInput.val('on');
}
if (this.tab) {
this.tab.elem.hide();
}
this.hide();
} else {
if (this.tab) {
this.tab.elem.remove();
}
this.elem.remove();
this.formset.handleFormRemoved(this.index);
}
};
Form.prototype.hide = function() {
return this.elem.hide();
};
Form.prototype.field = function(name) {
return this.elem.find("[name='" + this.formset.prefix + "-" + this.index + "-" + name + "']");
};
Form.prototype.prev = function() {
var form, _i, _ref;
_ref = this.formset.forms.slice(0, +(this.index - 1) + 1 || 9e9);
for (_i = _ref.length - 1; _i >= 0; _i += -1) {
form = _ref[_i];
if (form.elem.is(':visible')) {
return form;
}
}
};
Form.prototype._replaceDeleteCheckboxWithButton = function() {
var label, newDeleteInput;
if (this.deleteInput.length > 0) {
newDeleteInput = $("");
label = this.elem.find("label[for='" + (this.deleteInput.attr('id')) + "']");
if (label.has(this.deleteInput).length > 0) {
label.replaceWith(newDeleteInput);
} else {
label.remove();
this.deleteInput.replaceWith(newDeleteInput);
}
this.deleteInput = newDeleteInput;
}
this.deleteButton = this.getDeleteButton();
this.deleteButton.on('click', (function(_this) {
return function(event) {
return _this["delete"]();
};
})(this));
this.insertDeleteButton();
};
Form.prototype._replaceFormIndex = function(oldIndexPattern, index) {
var newPrefix, prefixRegex, _replaceFormIndexElement;
this.index = index;
prefixRegex = new RegExp("" + this.formset.prefix + "-" + oldIndexPattern);
newPrefix = "" + this.formset.prefix + "-" + index;
_replaceFormIndexElement = function(elem) {
var attributeName, attributeNames, attributeNamesByTagName, tagName, _i, _len, _results;
attributeNamesByTagName = {
input: ['id', 'name'],
select: ['id', 'name'],
textarea: ['id', 'name'],
label: ['for'],
div: ['id'],
'*': ['href', 'data-target']
};
tagName = elem.get(0).tagName;
attributeNames = [];
if (tagName.toLowerCase() in attributeNamesByTagName) {
attributeNames = attributeNamesByTagName[tagName.toLowerCase()];
}
attributeNames.push.apply(attributeNames, attributeNamesByTagName['*']);
_results = [];
for (_i = 0, _len = attributeNames.length; _i < _len; _i++) {
attributeName = attributeNames[_i];
if (elem.attr(attributeName)) {
_results.push(elem.attr(attributeName, elem.attr(attributeName).replace(prefixRegex, newPrefix)));
} else {
_results.push(void 0);
}
}
return _results;
};
_replaceFormIndexElement(this.elem);
this.elem.find('input, select, textarea, label').each(function() {
_replaceFormIndexElement($(this));
});
if (this.tab) {
_replaceFormIndexElement(this.tab.elem);
this.tab.elem.find('a, button').each(function() {
_replaceFormIndexElement($(this));
});
}
};
Form.prototype._initFormIndex = function(index) {
this._replaceFormIndex("__prefix__", index);
};
Form.prototype._updateFormIndex = function(index) {
this._replaceFormIndex('\\d+', index);
};
return Form;
})();
$.fn.djangoFormset.Tab = (function() {
function Tab(elem) {
this.elem = elem;
this.elem.data('djangoFormset.tab', this);
}
Tab.prototype.activate = function() {
return this.elem.find("[data-toggle='tab']").trigger('click');
};
Tab.prototype.remove = function() {
return this.elem.remove();
};
return Tab;
})();
$.fn.djangoFormset.defaultOptions = {
formTemplateClass: 'empty-form',
formClass: $.fn.djangoFormset.Form,
tabClass: $.fn.djangoFormset.Tab,
deleteButtonText: 'Delete'
};
$.djangoFormset = {
getTabActivator: function(id) {
return $("[href='#" + id + "'], [data-target='#" + id + "']");
}
};
})(jQuery);
//# sourceMappingURL=django-formset.js.map