From b4e7bf5284f8869bee38c48c15f77c1808774525 Mon Sep 17 00:00:00 2001 From: Hasan Ramezani Date: Fri, 10 Apr 2020 16:52:56 +0200 Subject: [PATCH] Refs #31441 -- Added red border to inputs with errors for TabluarInline. --- .../contrib/admin/static/admin/css/base.css | 3 +- tests/admin_inlines/admin.py | 27 +++++++++++--- tests/admin_inlines/models.py | 23 ++++++++++++ tests/admin_inlines/tests.py | 37 +++++++++++++++++++ 4 files changed, 83 insertions(+), 7 deletions(-) diff --git a/django/contrib/admin/static/admin/css/base.css b/django/contrib/admin/static/admin/css/base.css index a972fc68f5..5b0a2a1385 100644 --- a/django/contrib/admin/static/admin/css/base.css +++ b/django/contrib/admin/static/admin/css/base.css @@ -625,7 +625,8 @@ td ul.errorlist li { padding-left: 0; } -.errors input, .errors select, .errors textarea { +.errors input, .errors select, .errors textarea, +td ul.errorlist + input, td ul.errorlist + select, td ul.errorlist + textarea { border: 1px solid #ba2121; } diff --git a/tests/admin_inlines/admin.py b/tests/admin_inlines/admin.py index f4071efa4e..72a32e4d17 100644 --- a/tests/admin_inlines/admin.py +++ b/tests/admin_inlines/admin.py @@ -5,12 +5,12 @@ from django.db import models from .models import ( Author, BinaryTree, CapoFamiglia, Chapter, Child, ChildModel1, ChildModel2, Consigliere, EditablePKBook, ExtraTerrestrial, Fashionista, FootNote, - Holder, Holder2, Holder3, Holder4, Inner, Inner2, Inner3, Inner4Stacked, - Inner4Tabular, NonAutoPKBook, NonAutoPKBookChild, Novel, - NovelReadonlyChapter, OutfitItem, ParentModelWithCustomPk, Poll, Profile, - ProfileCollection, Question, ReadOnlyInline, ShoppingWeakness, Sighting, - SomeChildModel, SomeParentModel, SottoCapo, Teacher, Title, - TitleCollection, + Holder, Holder2, Holder3, Holder4, Holder5, Inner, Inner2, Inner3, + Inner4Stacked, Inner4Tabular, Inner5Stacked, Inner5Tabular, NonAutoPKBook, + NonAutoPKBookChild, Novel, NovelReadonlyChapter, OutfitItem, + ParentModelWithCustomPk, Poll, Profile, ProfileCollection, Question, + ReadOnlyInline, ShoppingWeakness, Sighting, SomeChildModel, + SomeParentModel, SottoCapo, Teacher, Title, TitleCollection, ) site = admin.AdminSite(name="admin") @@ -126,6 +126,20 @@ class Holder4Admin(admin.ModelAdmin): inlines = [Inner4StackedInline, Inner4TabularInline] +class Inner5StackedInline(admin.StackedInline): + model = Inner5Stacked + classes = ('collapse',) + + +class Inner5TabularInline(admin.TabularInline): + model = Inner5Tabular + classes = ('collapse',) + + +class Holder5Admin(admin.ModelAdmin): + inlines = [Inner5StackedInline, Inner5TabularInline] + + class InlineWeakness(admin.TabularInline): model = ShoppingWeakness extra = 1 @@ -291,6 +305,7 @@ site.register(Novel, NovelAdmin) site.register(NovelReadonlyChapter, NovelReadonlyChapterAdmin) site.register(Fashionista, inlines=[InlineWeakness]) site.register(Holder4, Holder4Admin) +site.register(Holder5, Holder5Admin) site.register(Author, AuthorAdmin) site.register(CapoFamiglia, inlines=[ConsigliereInline, SottoCapoInline, ReadOnlyInlineInline]) site.register(ProfileCollection, inlines=[ProfileInline]) diff --git a/tests/admin_inlines/models.py b/tests/admin_inlines/models.py index 1a705c55c7..501020f188 100644 --- a/tests/admin_inlines/models.py +++ b/tests/admin_inlines/models.py @@ -125,6 +125,29 @@ class Inner4Tabular(models.Model): models.UniqueConstraint(fields=['dummy', 'holder'], name='unique_tabular_dummy_per_holder') ] +# Models for ticket #31441 + + +class Holder5(models.Model): + dummy = models.IntegerField() + + +class Inner5Stacked(models.Model): + name = models.CharField(max_length=10) + select = models.CharField(choices=(('1', 'One'), ('2', 'Two')), max_length=10) + text = models.TextField() + dummy = models.IntegerField() + holder = models.ForeignKey(Holder5, models.CASCADE) + + +class Inner5Tabular(models.Model): + name = models.CharField(max_length=10) + select = models.CharField(choices=(('1', 'One'), ('2', 'Two')), max_length=10) + text = models.TextField() + dummy = models.IntegerField() + holder = models.ForeignKey(Holder5, models.CASCADE) + + # Models for #12749 diff --git a/tests/admin_inlines/tests.py b/tests/admin_inlines/tests.py index 2ddad4f5e7..9e280fb660 100644 --- a/tests/admin_inlines/tests.py +++ b/tests/admin_inlines/tests.py @@ -1241,3 +1241,40 @@ class SeleniumTests(AdminSeleniumTestCase): self.wait_until_visible(field_name) hide_links[hide_index].click() self.wait_until_invisible(field_name) + + def test_inline_formset_error_input_border(self): + self.admin_login(username='super', password='secret') + self.selenium.get(self.live_server_url + reverse('admin:admin_inlines_holder5_add')) + self.wait_until_visible('#id_dummy') + self.selenium.find_element_by_id('id_dummy').send_keys(1) + fields = ['id_inner5stacked_set-0-dummy', 'id_inner5tabular_set-0-dummy'] + show_links = self.selenium.find_elements_by_link_text('SHOW') + for show_index, field_name in enumerate(fields): + show_links[show_index].click() + self.wait_until_visible('#' + field_name) + self.selenium.find_element_by_id(field_name).send_keys(1) + + # Before save all inputs have default border + for inline in ('stacked', 'tabular'): + for field_name in ('name', 'select', 'text'): + element_id = 'id_inner5%s_set-0-%s' % (inline, field_name) + self.assertEqual( + self.selenium.find_element_by_id(element_id).value_of_css_property('border'), + '1px solid rgb(204, 204, 204)', # 1px solid #cccccc + ) + self.selenium.find_element_by_xpath('//input[@value="Save"]').click() + # Test the red border around inputs by css selectors + stacked_selectors = ['.errors input', '.errors select', '.errors textarea'] + for selector in stacked_selectors: + self.assertEqual( + self.selenium.find_element_by_css_selector(selector).value_of_css_property('border'), + '1px solid rgb(186, 33, 33)', # 1px solid #ba2121 + ) + tabular_selectors = [ + 'td ul.errorlist + input', 'td ul.errorlist + select', 'td ul.errorlist + textarea' + ] + for selector in tabular_selectors: + self.assertEqual( + self.selenium.find_element_by_css_selector(selector).value_of_css_property('border'), + '1px solid rgb(186, 33, 33)', # 1px solid #ba2121 + )