From 967f5827f2e3e8be16d470f6f361625d6a2045bd Mon Sep 17 00:00:00 2001 From: Fabio Caccamo Date: Wed, 30 Nov 2022 19:06:52 +0100 Subject: [PATCH] [tabbed-changeform] Improve tabbed changeform feature. --- .../admin_interface/css/tabbed-changeform.css | 72 +++++----- .../admin_interface/js/tabbed_changeform.js | 14 -- .../tabbed-changeform/tabbed-changeform.js | 73 ++++++++++ .../templates/admin/change_form.html | 132 ++++++++++-------- 4 files changed, 185 insertions(+), 106 deletions(-) delete mode 100644 admin_interface/static/admin_interface/js/tabbed_changeform.js create mode 100644 admin_interface/static/admin_interface/tabbed-changeform/tabbed-changeform.js diff --git a/admin_interface/static/admin_interface/css/tabbed-changeform.css b/admin_interface/static/admin_interface/css/tabbed-changeform.css index 625a98e..d3608ac 100644 --- a/admin_interface/static/admin_interface/css/tabbed-changeform.css +++ b/admin_interface/static/admin_interface/css/tabbed-changeform.css @@ -1,43 +1,56 @@ -.admin-interface .tabbed-changeform-tab { +.admin-interface .tabbed-changeform-tabs { display: flex; flex-direction: row; flex-wrap: nowrap; overflow-x: auto; - padding-bottom: 8px; - scrollbar-width: 4px; + overflow-y: hidden; + scrollbar-width: thin; + padding-bottom: 15px; } -.admin-interface .tabbed-changeform-tab::-webkit-scrollbar { - height: 4px; - background-color: var(--border-color); +@-moz-document url-prefix() { + .admin-interface .tabbed-changeform-tabs { + padding-bottom: 13px; + } } -.admin-interface .tabbed-changeform-tab::-webkit-scrollbar-thumb { - background: #aaa; - } - -.admin-interface .tabbed-changeform-tab button { +.admin-interface .tabbed-changeform-tabs .tabbed-changeform-tablink { + appearance: none; -webkit-appearance: none; - border: none; - border-radius: 0; + border: 1px solid transparent; border-bottom: 1px solid var(--border-color); - flex-shrink: 0; - flex-grow: 0; - cursor: pointer; - padding: 8px 12px; - margin: 0; - background-color: var(--admin-interface-module-header-text-color); - color: var(--admin-interface-module-background-color); -} - -.admin-interface .tabbed-changeform-tab button.active { - outline: none; - font-weight: bold; - border: 1px solid var(--border-color); - border-bottom: none; border-radius: var(--admin-interface-module-border-radius); border-bottom-left-radius: 0px; border-bottom-right-radius: 0px; + flex-shrink: 0; + flex-grow: 0; + cursor: pointer; + padding: 10px 15px; + margin: 0; + background-color: var(--admin-interface-module-header-text-color); + color: var(--admin-interface-generic-link-color); + font-size: 13px; + font-weight: bold; + outline: none !important; +} + +.admin-interface .tabbed-changeform-tabs .tabbed-changeform-tablink + .tabbed-changeform-tablink { + margin-left: -1px; +} + +.admin-interface .tabbed-changeform-tabs .tabbed-changeform-tablink:hover { + color: var(--admin-interface-generic-link-hover-color); +} + +.admin-interface .tabbed-changeform-tabs .tabbed-changeform-tablink.active { + border: 1px solid var(--border-color); + border-bottom: 1px solid transparent; + color: var(--admin-interface-module-background-color); +} + +.admin-interface .tabbed-changeform-tabs-remaining-space { + flex: 1; + border-bottom: 1px solid var(--border-color); } .admin-interface .tabbed-changeform-tabcontent { @@ -48,8 +61,3 @@ .admin-interface .tabbed-changeform-tabcontent.active { display: block; } - -.admin-interface .tabbed-changeform-tabs-remaining-space { - flex: 1; - border-bottom: 1px solid var(--border-color); -} diff --git a/admin_interface/static/admin_interface/js/tabbed_changeform.js b/admin_interface/static/admin_interface/js/tabbed_changeform.js deleted file mode 100644 index ef679f3..0000000 --- a/admin_interface/static/admin_interface/js/tabbed_changeform.js +++ /dev/null @@ -1,14 +0,0 @@ - -function openTab(evt, tabName) { - var tabcontents, tablinks; - tabcontents = document.getElementsByClassName("tabbed-changeform-tabcontent"); - for (let tabcontent of tabcontents) { - tabcontent.classList.remove("active"); - } - tablinks = document.getElementsByClassName("tabbed-changeform-tablinks"); - for (let tablink of tablinks) { - tablink.classList.remove("active"); - } - document.getElementById(tabName).classList.add("active"); - evt.currentTarget.classList.add("active"); -} diff --git a/admin_interface/static/admin_interface/tabbed-changeform/tabbed-changeform.js b/admin_interface/static/admin_interface/tabbed-changeform/tabbed-changeform.js new file mode 100644 index 0000000..c5e6f0f --- /dev/null +++ b/admin_interface/static/admin_interface/tabbed-changeform/tabbed-changeform.js @@ -0,0 +1,73 @@ +(function (AdminInterface) { + + var scope = AdminInterface; + + scope.tabbedChangeForm = { + + openTab: function (event, tabName) { + this.openTabByName(tabName); + }, + + openTabByName: function(tabName) { + let tablinkEl = document.getElementById("tablink-" + tabName); + let tabcontentEl = document.getElementById("tabcontent-" + tabName); + if (!tablinkEl || !tabcontentEl) { + return false; + } + + let tablinks = document.getElementsByClassName("tabbed-changeform-tablink"); + let tabcontents = document.getElementsByClassName("tabbed-changeform-tabcontent"); + + // toggle tab link + for (let tablink of tablinks) { + tablink.classList.remove("active"); + } + tablinkEl.classList.add("active"); + + // toggle tab content + for (let tabcontent of tabcontents) { + tabcontent.classList.remove("active"); + } + tabcontentEl.classList.add("active"); + + // update location hash + let history = window.history; + if (history) { + history.replaceState(undefined, undefined, "#" + tabName); + } + + return true; + }, + + openTabByLocationHash: function() { + let hash = window.location.hash; + if (hash && hash !== "#") { + let tabName = hash.substring(1); + if (this.openTabByName(tabName)) { + this.scrollTabsToTabByName(tabName); + } + } + }, + + scrollTabsToTabByName: function(tabName) { + let tabsEl = document.getElementById("tabbed-changeform-tabs"); + let tablinkEl = document.getElementById("tablink-" + tabName); + if (!tabsEl || !tablinkEl) { + return; + } + let tablinkLeft = (tablinkEl.offsetLeft - tabsEl.offsetLeft); + let tabsScrollLeft = Math.ceil(tablinkLeft); + tabsEl.scrollTo({ + top: 0, + left: tabsScrollLeft, + behavior: "instant" + }); + } + }; + + // scope.tabbedChangeForm.openTabByLocationHash(); + document.addEventListener('DOMContentLoaded', function() { + scope.tabbedChangeForm.openTabByLocationHash(); + }, false); + +}(window.AdminInterface = window.AdminInterface || {})); diff --git a/admin_interface/templates/admin/change_form.html b/admin_interface/templates/admin/change_form.html index d1f9685..5f2c59f 100644 --- a/admin_interface/templates/admin/change_form.html +++ b/admin_interface/templates/admin/change_form.html @@ -1,76 +1,88 @@ {% extends "admin/change_form.html" %} {% load static admin_interface_tags %} - {% block field_sets %} -{% get_admin_interface_setting "show_fieldsets_as_tabs" as show_fieldsets_as_tabs %} -{% get_admin_interface_setting "show_inlines_as_tabs" as show_inlines_as_tabs %} -{% admin_interface_use_changeform_tabs adminform inline_admin_formsets as admin_interface_use_changeform_tabs %} + {% get_admin_interface_setting "show_fieldsets_as_tabs" as show_fieldsets_as_tabs %} + {% get_admin_interface_setting "show_inlines_as_tabs" as show_inlines_as_tabs %} + {% admin_interface_use_changeform_tabs adminform inline_admin_formsets as admin_interface_use_changeform_tabs %} -{% if not admin_interface_use_changeform_tabs %} + {% if not admin_interface_use_changeform_tabs %} -{{block.super}} + {{ block.super }} -{% else %} - -
- - {% if show_fieldsets_as_tabs %} - {% for fieldset in adminform %} - - {% endfor %} - {% else %} - - {% endif %} - - {% if show_inlines_as_tabs %} - {% for inline_admin_formset in inline_admin_formsets %} - - {% endfor %} - {% endif %} -
- -
- - {% if show_fieldsets_as_tabs %} - {% for fieldset in adminform %} -
- {% include "admin/includes/headerless_fieldset.html" %} -
- {% endfor %} {% else %} -
- {% for fieldset in adminform %} - {% include "admin/includes/fieldset.html" %} + +
+ + {% if show_fieldsets_as_tabs %} + {% for fieldset in adminform %} + {% with fieldset.name|default_if_none:opts.verbose_name as tab_name %} + + {% endwith %} + {% endfor %} + {% else %} + {% with opts.verbose_name as tab_name %} + + {% endwith %} + {% endif %} + + {% if show_inlines_as_tabs %} + {% for inline_admin_formset in inline_admin_formsets %} + {% with fieldset.name|default_if_none:opts.verbose_name as tab_name %} + + {% endwith %} + {% endfor %} + {% endif %} + + + +
+ + {% if show_fieldsets_as_tabs %} + {% for fieldset in adminform %} + {% with fieldset.name|default_if_none:opts.verbose_name as tab_name %} +
+ {% include "admin/includes/headerless_fieldset.html" %} +
+ {% endwith %} + {% endfor %} + {% else %} + {% with opts.verbose_name as tab_name %} +
+ {% for fieldset in adminform %} + {% include "admin/includes/fieldset.html" %} + {% endfor %} +
+ {% endwith %} + {% endif %} + + {% for inline_admin_formset in inline_admin_formsets %} + {% with inline_admin_formset.opts.verbose_name_plural as tab_name %} +
+ {% get_admin_interface_inline_template inline_admin_formset.opts.template as inline_template %} + {% include inline_template %} +
+ {% endwith %} {% endfor %} -
+ + + {% endif %} - {% for inline_admin_formset in inline_admin_formsets %} -
- {% get_admin_interface_inline_template inline_admin_formset.opts.template as inline_template %} - {% include inline_template %} -
- {% endfor %} - -{% endif %} {% endblock %} {% block inline_field_sets %} - {% get_admin_interface_setting "show_inlines_as_tabs" as show_inlines_as_tabs %} - {% if not show_inlines_as_tabs %} - {{block.super}} - {% endif %} + + {% get_admin_interface_setting "show_inlines_as_tabs" as show_inlines_as_tabs %} + {% if not show_inlines_as_tabs %} + {{ block.super }} + {% endif %} + {% endblock %}