summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2022-02-23 10:33:07 +0100
committerGitHub <noreply@github.com>2022-02-23 10:33:07 +0100
commiteabc22f919e6c1774842e628400b87ac56c47bce (patch)
treea3e5aefed46f8a7ba004dcfb669c42919643f59e
parent1f42a352e04d2e63117f067a1432594ffbb6a8b4 (diff)
Fixed #33328 -- Transformed formset:added/removed to native JS events.
-rw-r--r--django/contrib/admin/static/admin/js/autocomplete.js8
-rw-r--r--django/contrib/admin/static/admin/js/inlines.js13
-rw-r--r--docs/ref/contrib/admin/javascript.txt59
-rw-r--r--docs/releases/4.1.txt4
-rw-r--r--js_tests/admin/inlines.test.js24
5 files changed, 42 insertions, 66 deletions
diff --git a/django/contrib/admin/static/admin/js/autocomplete.js b/django/contrib/admin/static/admin/js/autocomplete.js
index 6095abe233..d3daeab890 100644
--- a/django/contrib/admin/static/admin/js/autocomplete.js
+++ b/django/contrib/admin/static/admin/js/autocomplete.js
@@ -27,9 +27,7 @@
$('.admin-autocomplete').not('[name*=__prefix__]').djangoAdminSelect2();
});
- $(document).on('formset:added', (function() {
- return function(event, $newFormset) {
- return $newFormset.find('.admin-autocomplete').djangoAdminSelect2();
- };
- })(this));
+ document.addEventListener('formset:added', (event) => {
+ $(event.target).find('.admin-autocomplete').djangoAdminSelect2();
+ });
}
diff --git a/django/contrib/admin/static/admin/js/inlines.js b/django/contrib/admin/static/admin/js/inlines.js
index 101fdc7b68..e9a1dfe122 100644
--- a/django/contrib/admin/static/admin/js/inlines.js
+++ b/django/contrib/admin/static/admin/js/inlines.js
@@ -88,7 +88,12 @@
if (options.added) {
options.added(row);
}
- $(document).trigger('formset:added', [row, options.prefix]);
+ row.get(0).dispatchEvent(new CustomEvent("formset:added", {
+ bubbles: true,
+ detail: {
+ formsetName: options.prefix
+ }
+ }));
};
/**
@@ -130,7 +135,11 @@
if (options.removed) {
options.removed(row);
}
- $(document).trigger('formset:removed', [row, options.prefix]);
+ document.dispatchEvent(new CustomEvent("formset:removed", {
+ detail: {
+ formsetName: options.prefix
+ }
+ }));
// Update the TOTAL_FORMS form count.
const forms = $("." + options.formCssClass);
$("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length);
diff --git a/docs/ref/contrib/admin/javascript.txt b/docs/ref/contrib/admin/javascript.txt
index 05731c57b0..ce94176691 100644
--- a/docs/ref/contrib/admin/javascript.txt
+++ b/docs/ref/contrib/admin/javascript.txt
@@ -8,15 +8,15 @@ Inline form events
==================
You may want to execute some JavaScript when an inline form is added or removed
-in the admin change form. The ``formset:added`` and ``formset:removed`` jQuery
-events allow this. The event handler is passed three arguments:
+in the admin change form. The ``formset:added`` and ``formset:removed`` events
+allow this. ``event.detail.formsetName`` is the formset the row belongs to.
+For the ``formset:added`` event, ``event.target`` is the newly added row.
-* ``event`` is the ``jQuery`` event.
-* ``$row`` is the newly added (or removed) row.
-* ``formsetName`` is the formset the row belongs to.
+.. versionchanged:: 4.1
-The event is fired using the :ref:`django.jQuery namespace
-<contrib-admin-jquery>`.
+ In older versions, the event was a ``jQuery`` event with ``$row`` and
+ ``formsetName`` parameters. It is now a JavaScript ``CustomEvent`` with
+ parameters set in ``event.detail``.
In your custom ``change_form.html`` template, extend the
``admin_change_form_document_ready`` block and add the event listener code:
@@ -34,17 +34,14 @@ In your custom ``change_form.html`` template, extend the
.. code-block:: javascript
:caption: app/static/app/formset_handlers.js
- (function($) {
- $(document).on('formset:added', function(event, $row, formsetName) {
- if (formsetName == 'author_set') {
- // Do something
- }
- });
-
- $(document).on('formset:removed', function(event, $row, formsetName) {
- // Row removed
- });
- })(django.jQuery);
+ document.addEventListener('formset:added', (event) => {
+ if (event.detail.formsetName == 'author_set') {
+ // Do something
+ }
+ });
+ document.addEventListener('formset:removed', (event) => {
+ // Row removed
+ });
Two points to keep in mind:
@@ -53,29 +50,3 @@ Two points to keep in mind:
* ``{{ block.super }}`` is added because Django's
``admin_change_form_document_ready`` block contains JavaScript code to handle
various operations in the change form and we need that to be rendered too.
-
-Sometimes you'll need to work with ``jQuery`` plugins that are not registered
-in the ``django.jQuery`` namespace. To do that, change how the code listens for
-events. Instead of wrapping the listener in the ``django.jQuery`` namespace,
-listen to the event triggered from there. For example:
-
-.. code-block:: html+django
-
- {% extends 'admin/change_form.html' %}
- {% load static %}
-
- {% block admin_change_form_document_ready %}
- {{ block.super }}
- <script src="{% static 'app/unregistered_handlers.js' %}"></script>
- {% endblock %}
-
-.. code-block:: javascript
- :caption: app/static/app/unregistered_handlers.js
-
- django.jQuery(document).on('formset:added', function(event, $row, formsetName) {
- // Row added
- });
-
- django.jQuery(document).on('formset:removed', function(event, $row, formsetName) {
- // Row removed
- });
diff --git a/docs/releases/4.1.txt b/docs/releases/4.1.txt
index 88f4069f40..46d0cf3540 100644
--- a/docs/releases/4.1.txt
+++ b/docs/releases/4.1.txt
@@ -412,6 +412,10 @@ Miscellaneous
* The ``type="text/css"`` attribute is no longer included in ``<link>`` tags
for CSS :doc:`form media </topics/forms/media>`.
+* ``formset:added`` and ``formset:removed`` JavaScript events are now pure
+ JavaScript events and don't depend on jQuery. See
+ :ref:`admin-javascript-inline-form-events` for more details on the change.
+
.. _deprecated-features-4.1:
Features deprecated in 4.1
diff --git a/js_tests/admin/inlines.test.js b/js_tests/admin/inlines.test.js
index 550add2fce..ee8567dbf4 100644
--- a/js_tests/admin/inlines.test.js
+++ b/js_tests/admin/inlines.test.js
@@ -38,26 +38,20 @@ QUnit.test('added form has remove button', function(assert) {
});
QUnit.test('add/remove form events', function(assert) {
- assert.expect(6);
- const $ = django.jQuery;
- const $document = $(document);
+ assert.expect(5);
const addButton = this.table.find('.add-row a');
- $document.on('formset:added', function(event, $row, formsetName) {
+ document.addEventListener('formset:added', (event) => {
assert.ok(true, 'event `formset:added` triggered');
- assert.equal(true, $row.is('#first-1'));
- assert.equal(formsetName, 'first');
- $document.off('formset:added');
- });
+ assert.equal(true, event.target.matches('#first-1'));
+ assert.equal(event.detail.formsetName, 'first');
+ }, {once: true});
addButton.click();
- const deletedRow = $('#first-1');
const deleteLink = this.table.find('.inline-deletelink');
- $document.on('formset:removed', function(event, $row, formsetName) {
+ document.addEventListener('formset:removed', (event) => {
assert.ok(true, 'event `formset:removed` triggered');
- assert.equal(true, $row.is(deletedRow));
- assert.equal(formsetName, 'first');
- $document.off('formset:removed');
- });
- deleteLink.trigger($.Event('click', {target: deleteLink}));
+ assert.equal(event.detail.formsetName, 'first');
+ }, {once: true});
+ deleteLink.click();
});
QUnit.test('existing add button', function(assert) {