summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRiccardo Magliocchetti <riccardo.magliocchetti@gmail.com>2015-02-22 13:03:28 +0100
committerTim Graham <timograham@gmail.com>2015-03-24 11:51:37 -0400
commit0decef337f7f00d73b380531ac22cbc843d6e806 (patch)
treef480b61ac074a5fb1539fd80a6a82460fc749542
parent80e3444eca045799cc40e50c92609e852a299d38 (diff)
Fixed #24405 -- Made admin related object JavaScript overridable
Consolidated it in one file and move the DOM related stuff to the template so it is easily overridable. To override the popup behavior you need to add handlers for the custom events triggered in the admin_change_form_document_ready template block.
-rw-r--r--django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js43
-rw-r--r--django/contrib/admin/static/admin/js/related-widget-wrapper.js23
-rw-r--r--django/contrib/admin/templates/admin/change_form.html31
-rw-r--r--django/contrib/admin/widgets.py5
4 files changed, 57 insertions, 45 deletions
diff --git a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js
index ffba7cdf24..4a577c4187 100644
--- a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js
+++ b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js
@@ -27,14 +27,16 @@ function windowname_to_id(text) {
return text;
}
-function showAdminPopup(triggeringLink, name_regexp) {
+function showAdminPopup(triggeringLink, name_regexp, add_popup) {
var name = triggeringLink.id.replace(name_regexp, '');
name = id_to_windowname(name);
var href = triggeringLink.href;
- if (href.indexOf('?') == -1) {
- href += '?_popup=1';
- } else {
- href += '&_popup=1';
+ if (add_popup) {
+ if (href.indexOf('?') == -1) {
+ href += '?_popup=1';
+ } else {
+ href += '&_popup=1';
+ }
}
var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
win.focus();
@@ -42,7 +44,7 @@ function showAdminPopup(triggeringLink, name_regexp) {
}
function showRelatedObjectLookupPopup(triggeringLink) {
- return showAdminPopup(triggeringLink, /^lookup_/);
+ return showAdminPopup(triggeringLink, /^lookup_/, true);
}
function dismissRelatedLookupPopup(win, chosenId) {
@@ -57,12 +59,22 @@ function dismissRelatedLookupPopup(win, chosenId) {
}
function showRelatedObjectPopup(triggeringLink) {
- var name = triggeringLink.id.replace(/^(change|add|delete)_/, '');
- name = id_to_windowname(name);
- var href = triggeringLink.href;
- var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
- win.focus();
- return false;
+ return showAdminPopup(triggeringLink, /^(change|add|delete)_/, false);
+}
+
+function updateRelatedObjectLinks(triggeringLink) {
+ var $this = django.jQuery(triggeringLink);
+ var siblings = $this.nextAll('.change-related, .delete-related');
+ if (!siblings.length) return;
+ var value = $this.val();
+ if (value) {
+ siblings.each(function() {
+ var elm = django.jQuery(this);
+ elm.attr('href', elm.attr('data-href-template').replace('__fk__', value));
+ });
+ } else {
+ siblings.removeAttr('href');
+ }
}
function dismissAddRelatedObjectPopup(win, newId, newRepr) {
@@ -72,13 +84,10 @@ function dismissAddRelatedObjectPopup(win, newId, newRepr) {
newRepr = html_unescape(newRepr);
var name = windowname_to_id(win.name);
var elem = document.getElementById(name);
- var o;
if (elem) {
var elemName = elem.nodeName.toUpperCase();
if (elemName == 'SELECT') {
- o = new Option(newRepr, newId);
- elem.options[elem.options.length] = o;
- o.selected = true;
+ elem.options[elem.options.length] = new Option(newRepr, newId, true, true);
} else if (elemName == 'INPUT') {
if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
elem.value += ',' + newId;
@@ -90,7 +99,7 @@ function dismissAddRelatedObjectPopup(win, newId, newRepr) {
django.jQuery(elem).trigger('change');
} else {
var toId = name + "_to";
- o = new Option(newRepr, newId);
+ var o = new Option(newRepr, newId);
SelectBox.add_to_cache(toId, o);
SelectBox.redisplay(toId);
}
diff --git a/django/contrib/admin/static/admin/js/related-widget-wrapper.js b/django/contrib/admin/static/admin/js/related-widget-wrapper.js
deleted file mode 100644
index dbb1f58c8c..0000000000
--- a/django/contrib/admin/static/admin/js/related-widget-wrapper.js
+++ /dev/null
@@ -1,23 +0,0 @@
-django.jQuery(function($){
- function updateLinks() {
- var $this = $(this);
- var siblings = $this.nextAll('.change-related, .delete-related');
- if (!siblings.length) return;
- var value = $this.val();
- if (value) {
- siblings.each(function(){
- var elm = $(this);
- elm.attr('href', elm.attr('data-href-template').replace('__fk__', value));
- });
- } else siblings.removeAttr('href');
- }
- var container = $(document);
- container.on('change', '.related-widget-wrapper select', updateLinks);
- container.find('.related-widget-wrapper select').each(updateLinks);
- container.on('click', '.related-widget-wrapper-link', function(event){
- if (this.href) {
- showRelatedObjectPopup(this);
- }
- event.preventDefault();
- });
-});
diff --git a/django/contrib/admin/templates/admin/change_form.html b/django/contrib/admin/templates/admin/change_form.html
index 5e6c0c6321..0e2255f6ec 100644
--- a/django/contrib/admin/templates/admin/change_form.html
+++ b/django/contrib/admin/templates/admin/change_form.html
@@ -73,12 +73,39 @@
$(document).ready(function() {
$('.add-another').click(function(e) {
e.preventDefault();
- showAddAnotherPopup(this);
+ var event = $.Event('django:add-another-related');
+ $(this).trigger(event);
+ if (!event.isDefaultPrevented()) {
+ showAddAnotherPopup(this);
+ }
});
$('.related-lookup').click(function(e) {
e.preventDefault();
- showRelatedObjectLookupPopup(this);
+ var event = $.Event('django:lookup-related');
+ $(this).trigger(event);
+ if (!event.isDefaultPrevented()) {
+ showRelatedObjectLookupPopup(this);
+ }
});
+ $('body').on('click', '.related-widget-wrapper-link', function(e) {
+ e.preventDefault();
+ if (this.href) {
+ var event = $.Event('django:show-related', {href: this.href});
+ $(this).trigger(event);
+ if (!event.isDefaultPrevented()) {
+ showRelatedObjectPopup(this);
+ }
+ }
+ });
+ $('body').on('change', '.related-widget-wrapper select', function(e) {
+ var event = $.Event('django:update-related');
+ $(this).trigger(event);
+ if (!event.isDefaultPrevented()) {
+ updateRelatedObjectLinks(this);
+ }
+ });
+ $('.related-widget-wrapper select').trigger('change');
+
{% if adminform and add %}
$('form#{{ opts.model_name }}_form :input:visible:enabled:first').focus()
{% endif %}
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
index 2e88e930bd..251cc0ef1c 100644
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -10,7 +10,7 @@ from django.contrib.admin.templatetags.admin_static import static
from django.core.urlresolvers import reverse
from django.db.models.deletion import CASCADE
from django.forms.utils import flatatt
-from django.forms.widgets import Media, RadioFieldRenderer
+from django.forms.widgets import RadioFieldRenderer
from django.template.loader import render_to_string
from django.utils import six
from django.utils.encoding import force_text
@@ -272,8 +272,7 @@ class RelatedFieldWidgetWrapper(forms.Widget):
@property
def media(self):
- media = Media(js=['admin/js/related-widget-wrapper.js'])
- return self.widget.media + media
+ return self.widget.media
def get_related_url(self, info, action, *args):
return reverse("admin:%s_%s_%s" % (info + (action,)),