Created
June 17, 2009 19:53
-
-
Save tkaemming/131455 to your computer and use it in GitHub Desktop.
Simple inlineformset plugin for jQuery and Django. This is a work in progress and not ready for a production environment, but a good starting point for forks to add additional functionality.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;(function($){ | |
$.inlineformset = { | |
defaults: { | |
extra: 3, | |
formSelector: '.form', | |
formsetSelector: '.formset', | |
hideOnDeletion: true, | |
}, | |
}; | |
$.fn.inlineformset = function(options) | |
{ | |
if ($(this).data('inlineformset-instance')) | |
{ | |
return $(this).data('inlineformset-instance'); | |
} | |
else | |
{ | |
function InlineFormSet(container, options) | |
{ | |
var container = container; | |
var settings = $.extend($.inlineformset.defaults, options); | |
var formset = $(container).find(settings.formsetSelector).get(0); | |
var totalForms = $(container).find('input[name$="TOTAL_FORMS"]').get(0); | |
var initialForms = $(container).find('input[name$="INITIAL_FORMS"]').get(0); | |
var prototypeForm = $(container).find(settings.formSelector + ':last').clone(true); | |
var initialize = function(self) | |
{ | |
$(formset).find(settings.formSelector).each(function(i){ | |
// Delete each form that does not have an ID or parent object associated with it. | |
if(!$(this).find('input[name$="-id"]').val() && !$(this).find('input[name$="_ptr"]').val()) | |
{ | |
$(this).remove(); | |
} | |
else | |
{ | |
// Add the deletion handler to the form if necessary. | |
if (settings.hideOnDeletion) { | |
addDeletionHandler($(this)); | |
} | |
} | |
}); | |
$(initialForms).val($(formset).find(settings.formSelector).length); | |
// Add the extra forms as neccessary. | |
for (var i = 0; i < settings.extra; i++) | |
{ | |
self.addForm(false); | |
} | |
refreshFormset(); | |
} | |
var addDeletionHandler = function(form) | |
{ | |
$(form).find('input[name$="DELETE"]').bind('change', {'settings': settings}, function(event){ | |
var settings = event.data.settings; | |
$(this).closest(settings.formSelector).addClass('deleted').hide(); | |
}); | |
} | |
var getFormset = function() | |
{ | |
return formset; | |
} | |
var getPrototypeForm = function() | |
{ | |
var form = $(prototypeForm).clone(true); | |
if (settings.hideOnDeletion) { addDeletionHandler(form); } | |
return form; | |
} | |
var refreshFormset = function() | |
{ | |
var forms = {} | |
var fieldname_regex = new RegExp('^([a-zA-Z0-9_-]+)-([0-9]+)-([a-zA-Z0-9_]+)$'); | |
$(container).find(settings.formSelector).each(function(i){ | |
var prefix = null; | |
$(this).find('input, select').each(function(i){ | |
var matches = $(this).attr('name').match(fieldname_regex); | |
if (matches) | |
{ | |
prefix = matches[1]; | |
return false; | |
} | |
}); | |
if (prefix) | |
{ | |
if (typeof forms[prefix] == "number") | |
{ | |
forms[prefix] = forms[prefix] + 1; | |
} | |
else | |
{ | |
forms[prefix] = 0; | |
} | |
} | |
$(this).find('input, select').each(function(i){ | |
var matches = $(this).attr('name').match(fieldname_regex); | |
if (matches) | |
{ | |
var new_field_name = prefix + '-' + forms[prefix] + '-' + matches[3]; | |
$(this).attr('id', 'id_' + new_field_name); | |
$(this).attr('name', new_field_name); | |
} | |
}); | |
$(this).find('label').each(function(i){ | |
var matches = $(this).attr('for').match(fieldname_regex); | |
if (matches) | |
{ | |
var new_field_name = prefix + '-' + forms[prefix] + '-' + matches[3]; | |
$(this).attr('for', 'id_' + new_field_name); | |
} | |
}); | |
}); | |
$(totalForms).val($(container).find(settings.formSelector).length); | |
} | |
this.addForm = function(refresh) | |
{ | |
// Default the value of the refresh argument to "true". | |
if (refresh == undefined) { refresh = true; } | |
form = getPrototypeForm(); | |
formset = getFormset(); | |
$(formset).append(form); | |
if (refresh) { refreshFormset(); } | |
}; | |
initialize(this); | |
return this; | |
}; | |
$(this).data('inlineformset-instance', new InlineFormSet(this, options)); | |
return $(this).data('inlineformset-instance'); | |
} | |
} | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment