diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py index 5e8e0caf697..d0350c3930a 100644 --- a/django/contrib/admin/helpers.py +++ b/django/contrib/admin/helpers.py @@ -81,12 +81,7 @@ class Fieldset: def media(self): if 'collapse' in self.classes: extra = '' if settings.DEBUG else '.min' - js = [ - 'vendor/jquery/jquery%s.js' % extra, - 'jquery.init.js', - 'collapse%s.js' % extra, - ] - return forms.Media(js=['admin/js/%s' % url for url in js]) + return forms.Media(js=['admin/js/collapse%s.js' % extra]) return forms.Media() def __iter__(self): diff --git a/django/contrib/admin/static/admin/js/SelectFilter2.js b/django/contrib/admin/static/admin/js/SelectFilter2.js index b6bcda0c3cf..4221778bb2b 100644 --- a/django/contrib/admin/static/admin/js/SelectFilter2.js +++ b/django/contrib/admin/static/admin/js/SelectFilter2.js @@ -166,13 +166,7 @@ Requires jQuery, core.js, and SelectBox.js. // In horizontal mode, give the same height to the two boxes. var j_from_box = $('#' + field_id + '_from'); var j_to_box = $('#' + field_id + '_to'); - var resize_filters = function() { j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight()); }; - if (j_from_box.outerHeight() > 0) { - resize_filters(); // This fieldset is already open. Resize now. - } else { - // This fieldset is probably collapsed. Wait for its 'show' event. - j_to_box.closest('fieldset').one('show.fieldset', resize_filters); - } + j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight()); } // Initial icon refresh diff --git a/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js b/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js index b7ca95bd674..8b7de5eed72 100644 --- a/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js +++ b/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js @@ -63,7 +63,6 @@ }, // Add a warning when the time zone in the browser and backend do not match. addTimezoneWarning: function(inp) { - var $ = django.jQuery; var warningClass = DateTimeShortcuts.timezoneWarningClass; var timezoneOffset = DateTimeShortcuts.timezoneOffset / 3600; @@ -73,7 +72,7 @@ } // Check if warning is already there. - if ($(inp).siblings('.' + warningClass).length) { + if (inp.parentNode.querySelectorAll('.' + warningClass).length) { return; } @@ -95,13 +94,11 @@ } message = interpolate(message, [timezoneOffset]); - var $warning = $(''); - $warning.attr('class', warningClass); - $warning.text(message); - - $(inp).parent() - .append($('
')) - .append($warning); + var warning = document.createElement('span'); + warning.className = warningClass; + warning.textContent = message; + inp.parentNode.appendChild(document.createElement('br')); + inp.parentNode.appendChild(warning); }, // Add clock widget to a given field addClock: function(inp) { @@ -115,7 +112,7 @@ inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); var now_link = document.createElement('a'); now_link.setAttribute('href', "#"); - now_link.appendChild(document.createTextNode(gettext('Now'))); + now_link.textContent = gettext('Now'); now_link.addEventListener('click', function(e) { e.preventDefault(); DateTimeShortcuts.handleClockQuicklink(num, -1); @@ -345,7 +342,7 @@ e.preventDefault(); DateTimeShortcuts.dismissCalendar(num); }); - django.jQuery(document).on('keyup', function(event) { + document.addEventListener('keyup', function(event) { if (event.which === 27) { // ESC key closes popup DateTimeShortcuts.dismissCalendar(num); diff --git a/django/contrib/admin/static/admin/js/collapse.js b/django/contrib/admin/static/admin/js/collapse.js index 4b296896d4f..3123878e10b 100644 --- a/django/contrib/admin/static/admin/js/collapse.js +++ b/django/contrib/admin/static/admin/js/collapse.js @@ -1,26 +1,52 @@ /*global gettext*/ -(function($) { +(function() { 'use strict'; - $(document).ready(function() { + var closestElem = function(elem, tagName) { + if (elem.nodeName === tagName.toUpperCase()) { + return elem; + } + if (elem.parentNode.nodeName === 'BODY') { + return null; + } + return elem.parentNode && closestElem(elem.parentNode, tagName); + }; + + window.addEventListener('load', function() { // Add anchor tag for Show/Hide link - $("fieldset.collapse").each(function(i, elem) { + var fieldsets = document.querySelectorAll('fieldset.collapse'); + for (var i = 0; i < fieldsets.length; i++) { + var elem = fieldsets[i]; // Don't hide if fields in this fieldset have errors - if ($(elem).find("div.errors").length === 0) { - $(elem).addClass("collapsed").find("h2").first().append(' (' + gettext("Show") + - ')'); + if (elem.querySelectorAll('div.errors').length === 0) { + elem.classList.add('collapsed'); + var h2 = elem.querySelector('h2'); + var link = document.createElement('a'); + link.setAttribute('id', 'fieldsetcollapser' + i); + link.setAttribute('class', 'collapse-toggle'); + link.setAttribute('href', '#'); + link.textContent = gettext('Show'); + h2.appendChild(document.createTextNode(' (')); + h2.appendChild(link); + h2.appendChild(document.createTextNode(')')); } - }); + } // Add toggle to anchor tag - $("fieldset.collapse a.collapse-toggle").on('click', function(ev) { - if ($(this).closest("fieldset").hasClass("collapsed")) { + var toggles = document.querySelectorAll('fieldset.collapse a.collapse-toggle'); + var toggleFunc = function(ev) { + ev.preventDefault(); + var fieldset = closestElem(this, 'fieldset'); + if (fieldset.classList.contains('collapsed')) { // Show - $(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]); + this.textContent = gettext('Hide'); + fieldset.classList.remove('collapsed'); } else { // Hide - $(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]); + this.textContent = gettext('Show'); + fieldset.classList.add('collapsed'); } - return false; - }); + }; + for (i = 0; i < toggles.length; i++) { + toggles[i].addEventListener('click', toggleFunc); + } }); -})(django.jQuery); +})(); diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index 4ce3e053f6c..5bf54da7d6a 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -51,16 +51,11 @@ class FilteredSelectMultiple(forms.SelectMultiple): class AdminDateWidget(forms.DateInput): - @property - def media(self): - extra = '' if settings.DEBUG else '.min' + class Media: js = [ - 'vendor/jquery/jquery%s.js' % extra, - 'jquery.init.js', - 'calendar.js', - 'admin/DateTimeShortcuts.js', + 'admin/js/calendar.js', + 'admin/js/admin/DateTimeShortcuts.js', ] - return forms.Media(js=["admin/js/%s" % path for path in js]) def __init__(self, attrs=None, format=None): attrs = {'class': 'vDateField', 'size': '10', **(attrs or {})} @@ -68,16 +63,11 @@ class AdminDateWidget(forms.DateInput): class AdminTimeWidget(forms.TimeInput): - @property - def media(self): - extra = '' if settings.DEBUG else '.min' + class Media: js = [ - 'vendor/jquery/jquery%s.js' % extra, - 'jquery.init.js', - 'calendar.js', - 'admin/DateTimeShortcuts.js', + 'admin/js/calendar.js', + 'admin/js/admin/DateTimeShortcuts.js', ] - return forms.Media(js=["admin/js/%s" % path for path in js]) def __init__(self, attrs=None, format=None): attrs = {'class': 'vTimeField', 'size': '8', **(attrs or {})}