From 51398f8bd568a6324a8cafe20c068d0974913ad5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=9A=D0=B0=D0=B9=D1=80=D0=B0=D1=82=20=D0=9C=D0=B0=D0=BA?=
 =?UTF-8?q?=D1=8B=D0=BC?= <kairatmakym@kajrats-macbook-pro.local>
Date: Tue, 18 Feb 2025 09:48:13 +0100
Subject: [PATCH] Fixed #31170 -- Added change event trigger to
 dismissRelatedLookupPopup.

---
 .../admin/js/admin/RelatedObjectLookups.js    |  1 +
 js_tests/admin/RelatedObjectLookups.test.js   | 40 +++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js
index be37fda973..5395386087 100644
--- a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js
+++ b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js
@@ -57,6 +57,7 @@
         } else {
             elem.value = chosenId;
         }
+        $(elem).trigger('change');
         const index = window.relatedWindows.indexOf(win);
         if (index > -1) {
             window.relatedWindows.splice(index, 1);
diff --git a/js_tests/admin/RelatedObjectLookups.test.js b/js_tests/admin/RelatedObjectLookups.test.js
index 64433cb623..722aa7ae7b 100644
--- a/js_tests/admin/RelatedObjectLookups.test.js
+++ b/js_tests/admin/RelatedObjectLookups.test.js
@@ -36,3 +36,43 @@ QUnit.test('dismissRelatedLookupPopup removes window from relatedWindows array',
     window.dismissRelatedLookupPopup(mockWin, '123');
     assert.equal(window.relatedWindows.indexOf(mockWin), -1, 'Window should be removed from relatedWindows array');
 });
+
+QUnit.test('dismissRelatedLookupPopup triggers change event for single value field', function(assert) {
+    assert.timeout(1000);
+    const done = assert.async();
+    const $ = django.jQuery;
+    const testId = 'test_id';
+    const newValue = '123';
+    const mockWin = {
+        name: testId,
+        close: function() {}
+    };
+    let changeTriggered = false;
+    $('#test_id').on('change', function() {
+        changeTriggered = true;
+        assert.equal(this.value, newValue, 'Value should be updated');
+        done();
+    });
+    window.dismissRelatedLookupPopup(mockWin, newValue);
+    assert.true(changeTriggered, 'Change event should be triggered');
+});
+
+QUnit.test('dismissRelatedLookupPopup triggers change event for many-to-many field', function(assert) {
+    assert.timeout(1000);
+    const $ = django.jQuery;
+    const testId = 'many_test_id';
+    const existingValue = '1,2';
+    const newValue = '3';
+    $('#many_test_id').val(existingValue);
+    const mockWin = {
+        name: testId,
+        close: function() {}
+    };
+    let changeTriggered = false;
+    $('#many_test_id').on('change', function() {
+        changeTriggered = true;
+        assert.equal(this.value, existingValue + ',' + newValue, 'Value should be appended for many-to-many fields');
+    });
+    window.dismissRelatedLookupPopup(mockWin, newValue);
+    assert.true(changeTriggered, 'Change event should be triggered');
+});