Skip to content

Commit

Permalink
Fixed django#15760 -- Added JavaScript events for admin inline forms.
Browse files Browse the repository at this point in the history
  • Loading branch information
RamezIssac authored and timgraham committed Sep 21, 2015
1 parent 65a1055 commit 1335aa2
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 9 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,7 @@ answer newbie questions, and generally made Django that much better:
Rachel Willmer <http://www.willmer.com/kb/>
Radek Švarz <http://www.svarz.cz/translate/>
Rajesh Dhawan <[email protected]>
Ramez Ashraf <[email protected]>
Ramiro Morales <[email protected]>
Ram Rachum <[email protected]>
Randy Barlow <[email protected]>
Expand Down
2 changes: 2 additions & 0 deletions django/contrib/admin/static/admin/js/inlines.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
if (options.removed) {
options.removed(row);
}
$(document).trigger('formset:removed', [row, options.prefix]);
// Update the TOTAL_FORMS form count.
var forms = $("." + options.formCssClass);
$("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length);
Expand All @@ -120,6 +121,7 @@
if (options.added) {
options.added(row);
}
$(document).trigger('formset:added', [row, options.prefix]);
});
}
return this;
Expand Down
18 changes: 9 additions & 9 deletions django/contrib/admin/static/admin/js/inlines.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions docs/ref/contrib/admin/index.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Other topics

actions
admindocs
javascript

.. seealso::

Expand Down Expand Up @@ -1882,6 +1883,8 @@ The :doc:`staticfiles app </ref/contrib/staticfiles>` prepends
``None``) to any asset paths. The same rules apply as :ref:`regular asset
definitions on forms <form-asset-paths>`.

.. _contrib-admin-jquery:

jQuery
~~~~~~

Expand Down
75 changes: 75 additions & 0 deletions docs/ref/contrib/admin/javascript.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
======================================
JavaScript customizations in the admin
======================================

.. _admin-javascript-inline-form-events:

Inline form events
==================

.. versionadded:: 1.9

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:

* ``event`` is the ``jQuery`` event.
* ``$row`` is the newly added (or removed) row.
* ``formsetName`` is the formset the row belongs to.

The event is fired using the :ref:`django.jQuery namespace
<contrib-admin-jquery>`.

In your custom ``change_form.html`` template, extend the
``admin_change_form_document_ready`` block and add the event listener code:

.. code-block:: html+django

{% extends 'admin/change_form.html' %}

{% block admin_change_form_document_ready %}
{{ block.super }}
<script type="text/javascript">
(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);
</script>
{% endblock %}

Two points to keep in mind:

* The JavaScript code must go in a template block if you are inheriting
``admin/change_form.html`` or it won't be rendered in the final HTML.
* ``{{ 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, simply change how the code
listens for events. Instead of wrapping the listener in the ``django.jQuery``
namespace, just listen to the event triggered from there. For example:

.. code-block:: html+django

{% extends 'admin/change_form.html' %}

{% block admin_change_form_document_ready %}
{{ block.super }}
<script type="text/javascript">
django.jQuery(document).on('formset:added', function(event, $row, formsetName) {
// Row added
});

django.jQuery(document).on('formset:removed', function(event, $row, formsetName) {
// Row removed
});
</script>
{% endblock %}
3 changes: 3 additions & 0 deletions docs/releases/1.9.txt
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ Minor features
the display of empty values in admin change list. You can also customize the
value for each field.

* Added jQuery events :ref:`when an inline form is added or removed
<admin-javascript-inline-form-events>` on the change form page.

* The time picker widget includes a '6 p.m' option for consistency of having
predefined options every 6 hours.

Expand Down
21 changes: 21 additions & 0 deletions js_tests/admin/inlines.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,24 @@ test('add form', function(assert) {
addButton.click();
assert.ok(this.table.find('#first-1').hasClass('row2'));
});

test('add/remove form events', function(assert) {
assert.expect(6);
var $ = django.jQuery;
var $document = $(document);
var addButton = this.table.find('.add-row a');
$document.on('formset:added', function(event, $row, formsetName) {
assert.ok(true, 'event `formset:added` triggered');
assert.equal(true, $row.is($('.row2')));
assert.equal(formsetName, 'first');
});
addButton.click();
var deletedRow = $('.row2');
var deleteLink = this.table.find('.inline-deletelink');
$document.on('formset:removed', function(event, $row, formsetName) {
assert.ok(true, 'event `formset:removed` triggered');
assert.equal(true, $row.is(deletedRow));
assert.equal(formsetName, 'first');
});
deleteLink.click();
});

0 comments on commit 1335aa2

Please sign in to comment.