Commit 0decef33 authored by Riccardo Magliocchetti's avatar Riccardo Magliocchetti Committed by Tim Graham
Browse files

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.
parent 80e3444e
Loading
Loading
Loading
Loading
+26 −17
Original line number Diff line number Diff line
@@ -27,22 +27,24 @@ 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 (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();
    return false;
}

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);
    }
+0 −23
Original line number Diff line number Diff line
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();
    });
});
+29 −2
Original line number Diff line number Diff line
@@ -73,12 +73,39 @@
            $(document).ready(function() {
                $('.add-another').click(function(e) {
                    e.preventDefault();
                    var event = $.Event('django:add-another-related');
                    $(this).trigger(event);
                    if (!event.isDefaultPrevented()) {
                        showAddAnotherPopup(this);
                    }
                });
                $('.related-lookup').click(function(e) {
                    e.preventDefault();
                    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 %}
+2 −3
Original line number Diff line number Diff line
@@ -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,)),