diff --git a/django/contrib/admin/templates/admin/change_form.html b/django/contrib/admin/templates/admin/change_form.html
a
|
b
|
|
17 | 17 | {% block breadcrumbs %}{% if not is_popup %} |
18 | 18 | <div class="breadcrumbs"> |
19 | 19 | <a href="../../../">{% trans "Home" %}</a> › |
20 | | <a href="../../">{{ app_label|capfirst|escape }}</a> › |
21 | | {% if has_change_permission %}<a href="../">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %} › |
| 20 | <a href="../../">{{ app_label|capfirst|escape }}</a> › |
| 21 | {% if has_change_permission %}<a href="../">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %} › |
22 | 22 | {% if add %}{% trans "Add" %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %} |
23 | 23 | </div> |
24 | 24 | {% endif %}{% endblock %} |
… |
… |
|
60 | 60 | {% submit_row %} |
61 | 61 | |
62 | 62 | {% if adminform and add %} |
63 | | <script type="text/javascript">document.getElementById("{{ adminform.first_field.auto_id }}").focus();</script> |
| 63 | <script type="text/javascript">document.getElementById("{{ adminform.first_field.stable_id }}").focus();</script> |
64 | 64 | {% endif %} |
65 | 65 | |
66 | 66 | {# JavaScript for prepopulated fields #} |
diff --git a/django/forms/forms.py b/django/forms/forms.py
a
|
b
|
|
522 | 522 | return self.html_name |
523 | 523 | return '' |
524 | 524 | auto_id = property(_auto_id) |
| 525 | |
| 526 | def _stable_id(self): |
| 527 | """ |
| 528 | Returns a form control ID usable for focusing this field, without |
| 529 | regard to it having a single widget or a MutiWidget. |
| 530 | """ |
| 531 | widget = self.field.widget |
| 532 | id_ = widget.attrs.get('id') or self.auto_id |
| 533 | return widget.id_for_label(id_) |
| 534 | stable_id = property(_stable_id) |
diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py
a
|
b
|
|
611 | 611 | owner = models.ForeignKey(User) |
612 | 612 | title = models.CharField(max_length=30) |
613 | 613 | |
| 614 | class Reservation(models.Model): |
| 615 | start_date = models.DateTimeField() |
| 616 | |
614 | 617 | admin.site.register(Article, ArticleAdmin) |
615 | 618 | admin.site.register(CustomArticle, CustomArticleAdmin) |
616 | 619 | admin.site.register(Section, save_as=True, inlines=[ArticleInline]) |
… |
… |
|
642 | 645 | admin.site.register(PlotDetails) |
643 | 646 | admin.site.register(CyclicOne) |
644 | 647 | admin.site.register(CyclicTwo) |
| 648 | admin.site.register(Reservation) |
645 | 649 | |
646 | 650 | # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2. |
647 | 651 | # That way we cover all four cases: |
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
a
|
b
|
|
349 | 349 | deactivate() |
350 | 350 | |
351 | 351 | |
| 352 | class AdminJavaScriptTest(AdminViewBasicTest): |
| 353 | def testMultiWidgetFirsFieldFocus(self): |
| 354 | """ |
| 355 | JavaScript-assisted auto-focus should work if a model/ModelAdmin setup |
| 356 | is such that the first form field has a MultiWidget. |
| 357 | """ |
| 358 | response = self.client.get('/test_admin/%s/admin_views/reservation/add/' % self.urlbit) |
| 359 | self.assertContains( |
| 360 | response, |
| 361 | '<script type="text/javascript">document.getElementById("id_start_date_0").focus();</script>' |
| 362 | ) |
| 363 | |
| 364 | |
352 | 365 | class SaveAsTests(TestCase): |
353 | 366 | fixtures = ['admin-views-users.xml','admin-views-person.xml'] |
354 | 367 | |