﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
14830	Default value for radio button not preserved when dynamically creating new inlines	Julien Phalip	nobody	"Here is a simple test case illustrating the problem:

Models:

{{{
    from django.db import models

    class MyModel(models.Model):
        name = models.CharField(max_length=100, blank=True)
    
    CHOICES = (
        (u'1', u'blue'),
        (u'2', u'red'),
    )
    
    class RelatedModel(models.Model):
        MyModel = models.ForeignKey(MyModel)
        color = models.CharField(max_length=1, choices=CHOICES, default='1')
}}}

Admin:

{{{
    from django.contrib import admin
    from .models import MyModel, RelatedModel
    
    class RelatedModelInline(admin.TabularInline):
        model = RelatedModel
        radio_fields = {""color"": admin.HORIZONTAL}
    
    class MyModelAdmin(admin.ModelAdmin):
        inlines = [RelatedModelInline]
    
    admin.site.register(MyModel, MyModelAdmin)
}}}

The problem is that after clicking ""Add another Related Model"" more than once in the admin, the default value for the radio button (i.e. 'blue' checked) is not preserved. What's happening is that when the hidden inline form template is cloned the first time, it loses that default value. The first clone does get the default value, but every subsequent clone doesn't have it because the template has lost it during the first cloning.

I narrowed it down to the following lines in inlines.js:

{{{
    var template = $(""#"" + options.prefix + ""-empty"");
    var row = template.clone(true);
    row.removeClass(options.emptyCssClass)
        .addClass(options.formCssClass)
        .attr(""id"", options.prefix + ""-"" + nextIndex)
        .insertBefore($(template));
}}}

As soon as the first clone is inserted into the DOM, the template loses the default value. Really weird. Now what's even weirder is that the following simple test case does work, however:

{{{
    <html xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en"">
    <head>
        <style>
            .empty-form {
                display:none;
            }
        </style>
    <title></title>
    <script type=""text/javascript"" src=""jquery.js""></script>
    </head>
    <body>    
    
    <form id=""original-form"" class=""empty-form"" action="""" method=""post"">
        <input type=""radio"" name=""radio-test"" value=""I'm a checked radio button"" checked=""checked"" />
        <input type=""radio"" name=""radio-test"" value=""I'm another checked radio button"" />
    </form>
    
    <a href=""#"" alt="""" id=""clone-form"">Clone</a>
    
    <script type=""text/javascript"" language=""Javascript"">
        $(document).ready(function() {
            var counter = 0;
            $('#clone-form').click(function(){
                counter += 1;
                var template = $('#original-form');
                var row = template.clone(true);
                row.removeClass('empty-form')
    				    .addClass('cloned-form')
    				    .attr(""id"", 'clone-' + counter)
    				    .insertBefore($(template));
            });
        });
    </script>
    
    </body>
    </html>
}}}

The code above tries to match the Django inline jquery business as close as possible (e.g. using same jquery.js), but the cloning here is working perfectly... So my guess is that there must be some strange side effects happening in inlines.js or in other javascript code loaded in the admin.

A related issue has been wontfixed for jquery itself: http://bugs.jquery.com/ticket/3879
The issue observed here is slightly different though, as it is the cloned object that loses the default value, not the clonee.

Anyway, it's hard to figure out whether it is a Django or jQuery issue at this stage."		closed	contrib.admin	1.2		fixed	sprintdec2010		Ready for checkin	1	0	0	0	0	0
