mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-24 03:30:50 +02:00
Rough JS for adding then enabling/disabling the related widget buttons on the horizontal multi-select
This commit is contained in:
parent
7904ca0cc4
commit
1c657a7704
4 changed files with 182 additions and 6 deletions
|
@ -455,7 +455,16 @@ class DomainInformationAdmin(ListHeaderAdmin):
|
||||||
"is_policy_acknowledged",
|
"is_policy_acknowledged",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# For each filter_horizontal, init in admin js extendFilterHorizontalWidgets
|
||||||
|
# to activate the edit/delete/view buttons
|
||||||
filter_horizontal = ("other_contacts",)
|
filter_horizontal = ("other_contacts",)
|
||||||
|
|
||||||
|
# lists in filter_horizontal are not sorted properly, sort them
|
||||||
|
# by first_name
|
||||||
|
def formfield_for_manytomany(self, db_field, request, **kwargs):
|
||||||
|
if db_field.name in ("other_contacts",):
|
||||||
|
kwargs["queryset"] = models.Contact.objects.all().order_by("first_name") # Sort contacts
|
||||||
|
return super().formfield_for_manytomany(db_field, request, **kwargs)
|
||||||
|
|
||||||
def get_readonly_fields(self, request, obj=None):
|
def get_readonly_fields(self, request, obj=None):
|
||||||
"""Set the read-only state on form elements.
|
"""Set the read-only state on form elements.
|
||||||
|
@ -593,6 +602,8 @@ class DomainApplicationAdmin(ListHeaderAdmin):
|
||||||
"is_policy_acknowledged",
|
"is_policy_acknowledged",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# For each filter_horizontal, init in admin js extendFilterHorizontalWidgets
|
||||||
|
# to activate the edit/delete/view buttons
|
||||||
filter_horizontal = ("current_websites", "alternative_domains")
|
filter_horizontal = ("current_websites", "alternative_domains")
|
||||||
|
|
||||||
# lists in filter_horizontal are not sorted properly, sort them
|
# lists in filter_horizontal are not sorted properly, sort them
|
||||||
|
@ -730,7 +741,16 @@ class DomainInformationInline(admin.StackedInline):
|
||||||
|
|
||||||
fieldsets = DomainInformationAdmin.fieldsets
|
fieldsets = DomainInformationAdmin.fieldsets
|
||||||
analyst_readonly_fields = DomainInformationAdmin.analyst_readonly_fields
|
analyst_readonly_fields = DomainInformationAdmin.analyst_readonly_fields
|
||||||
|
# For each filter_horizontal, init in admin js extendFilterHorizontalWidgets
|
||||||
|
# to activate the edit/delete/view buttons
|
||||||
filter_horizontal = ("other_contacts",)
|
filter_horizontal = ("other_contacts",)
|
||||||
|
|
||||||
|
# lists in filter_horizontal are not sorted properly, sort them
|
||||||
|
# by first_name
|
||||||
|
def formfield_for_manytomany(self, db_field, request, **kwargs):
|
||||||
|
if db_field.name in ("other_contacts",):
|
||||||
|
kwargs["queryset"] = models.Contact.objects.all().order_by("first_name") # Sort contacts
|
||||||
|
return super().formfield_for_manytomany(db_field, request, **kwargs)
|
||||||
|
|
||||||
def get_readonly_fields(self, request, obj=None):
|
def get_readonly_fields(self, request, obj=None):
|
||||||
return DomainInformationAdmin.get_readonly_fields(self, request, obj=None)
|
return DomainInformationAdmin.get_readonly_fields(self, request, obj=None)
|
||||||
|
|
|
@ -47,4 +47,164 @@ function openInNewTab(el, removeAttribute = false){
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareDjangoAdmin();
|
prepareDjangoAdmin();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IIFE to listen to changes on filter_horizontal and enable or disable the change/delete/view buttons as applicable
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
(function extendFilterHorizontalWidgets() {
|
||||||
|
// Grab a list of our custom filter_horizontal widgets
|
||||||
|
let filterHorizontalList = [];
|
||||||
|
checkElementThenAddToList('id_other_contacts_to', filterHorizontalList, 0);
|
||||||
|
checkElementThenAddToList('id_domain_info-0-other_contacts_to', filterHorizontalList, 0);
|
||||||
|
checkElementThenAddToList('id_current_websites_to', filterHorizontalList, 0);
|
||||||
|
checkElementThenAddToList('id_alternative_domains_to', filterHorizontalList, 0);
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Function to check for the existence of the element
|
||||||
|
function checkElementThenAddToList(id, listOfElements, attempts) {
|
||||||
|
let dynamicElement = document.getElementById(id);
|
||||||
|
attempts++;
|
||||||
|
|
||||||
|
if (attempts < 6) {
|
||||||
|
if ((dynamicElement !== null)) {
|
||||||
|
// Element found, handle it
|
||||||
|
// Add an event listener on the element
|
||||||
|
// Add disabled buttons on the element's great-grandparent
|
||||||
|
customizeSelectElement(dynamicElement, id);
|
||||||
|
} else {
|
||||||
|
// Element not found, check again after a delay
|
||||||
|
setTimeout(() => checkElementThenAddToList(id, listOfElements, attempts), 1000); // Check every 1000 milliseconds (1 second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createAndCustomizeLink(selectEl, selectElId, className, title, imgSrc, imgAlt, dataMappings, dataPopup, position) {
|
||||||
|
// Create a link element
|
||||||
|
var link = document.createElement('a');
|
||||||
|
|
||||||
|
// Set class attribute for the link
|
||||||
|
link.className = className;
|
||||||
|
|
||||||
|
// Set id
|
||||||
|
// Add 'change_' to the beginning of the string
|
||||||
|
let modifiedLinkString = className.split('-')[0] + '_' + selectElId;
|
||||||
|
// Remove '_to' from the end of the string
|
||||||
|
modifiedLinkString = modifiedLinkString.replace('_to', '');
|
||||||
|
link.id = modifiedLinkString;
|
||||||
|
|
||||||
|
// Set data-href-template
|
||||||
|
for (const [idPattern, template] of Object.entries(dataMappings)) {
|
||||||
|
if (selectElId.includes(idPattern)) {
|
||||||
|
link.setAttribute('data-href-template', template);
|
||||||
|
break; // Stop checking once a match is found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataPopup)
|
||||||
|
link.setAttribute('data-popup', 'yes');
|
||||||
|
|
||||||
|
link.title = title;
|
||||||
|
|
||||||
|
// Create an 'img' element
|
||||||
|
var img = document.createElement('img');
|
||||||
|
|
||||||
|
// Set attributes for the new image
|
||||||
|
img.src = imgSrc;
|
||||||
|
img.alt = imgAlt;
|
||||||
|
|
||||||
|
// Append the image to the link
|
||||||
|
link.appendChild(img);
|
||||||
|
|
||||||
|
// Insert the link at the specified position
|
||||||
|
selectEl.closest('.related-widget-wrapper').insertBefore(link, selectEl.closest('.related-widget-wrapper').children[position]);
|
||||||
|
|
||||||
|
// Return the link, which we'll use in the disable and enable functions
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
|
function customizeSelectElement(el, elId) {
|
||||||
|
let changeLink = createAndCustomizeLink(
|
||||||
|
el,
|
||||||
|
elId,
|
||||||
|
'related-widget-wrapper-link change-related',
|
||||||
|
'Change selected item',
|
||||||
|
'/public/admin/img/icon-changelink.svg',
|
||||||
|
'Change',
|
||||||
|
{
|
||||||
|
'contacts': '/admin/registrar/contact/__fk__/change/?_to_field=id&_popup=1',
|
||||||
|
'websites': '/admin/registrar/website/__fk__/change/?_to_field=id&_popup=1',
|
||||||
|
'alternative_domains': '/admin/registrar/draftdomain/__fk__/change/?_to_field=id&_popup=1',
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
let deleteLink = createAndCustomizeLink(
|
||||||
|
el,
|
||||||
|
elId,
|
||||||
|
'related-widget-wrapper-link delete-related',
|
||||||
|
'Delete selected item',
|
||||||
|
'/public/admin/img/icon-deletelink.svg',
|
||||||
|
'Delete',
|
||||||
|
{
|
||||||
|
'contacts': '/admin/registrar/contact/__fk__/delete/?_to_field=id&_popup=1',
|
||||||
|
'websites': '/admin/registrar/website/__fk__/delete/?_to_field=id&_popup=1',
|
||||||
|
'alternative_domains': '/admin/registrar/draftdomain/__fk__/delete/?_to_field=id&_popup=1',
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
2
|
||||||
|
);
|
||||||
|
|
||||||
|
let viewLink = createAndCustomizeLink(
|
||||||
|
el,
|
||||||
|
elId,
|
||||||
|
'related-widget-wrapper-link view-related',
|
||||||
|
'View selected item',
|
||||||
|
'/public/admin/img/icon-viewlink.svg',
|
||||||
|
'View',
|
||||||
|
{
|
||||||
|
'contacts': '/admin/registrar/contact/__fk__/change/?_to_field=id',
|
||||||
|
'websites': '/admin/registrar/website/__fk__/change/?_to_field=id',
|
||||||
|
'alternative_domains': '/admin/registrar/draftdomain/__fk__/change/?_to_field=id',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
3
|
||||||
|
);
|
||||||
|
|
||||||
|
el.addEventListener('click', function(event) {
|
||||||
|
// Access the target element that was clicked
|
||||||
|
var clickedElement = event.target;
|
||||||
|
|
||||||
|
// If one item is selected enable buttons, otherwise disable them
|
||||||
|
if (el.selectedOptions.length === 1) {
|
||||||
|
enableRelatedWidgetButtons(changeLink, deleteLink, viewLink, clickedElement.value);
|
||||||
|
} else {
|
||||||
|
disableRelatedWidgetButtons(changeLink, deleteLink, viewLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// Disable buttons when the selectors are interated with (items are moved from one column to the other)
|
||||||
|
let selectorButtons = [];
|
||||||
|
selectorButtons.push(el.closest(".selector").querySelector(".selector-chooseall"));
|
||||||
|
selectorButtons.push(el.closest(".selector").querySelector(".selector-add"));
|
||||||
|
selectorButtons.push(el.closest(".selector").querySelector(".selector-remove"));
|
||||||
|
|
||||||
|
selectorButtons.forEach((selector) => {
|
||||||
|
selector.addEventListener("click", ()=>{disableRelatedWidgetButtons(changeLink, deleteLink, viewLink)});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function disableRelatedWidgetButtons(changeLink, deleteLink, viewLink) {
|
||||||
|
changeLink.removeAttribute('href');
|
||||||
|
deleteLink.removeAttribute('href');
|
||||||
|
viewLink.removeAttribute('href');
|
||||||
|
}
|
||||||
|
|
||||||
|
function enableRelatedWidgetButtons(changeLink, deleteLink, viewLink, elementPk) {
|
||||||
|
changeLink.setAttribute('href', changeLink.getAttribute('data-href-template').replace('__fk__', elementPk));
|
||||||
|
deleteLink.setAttribute('href', deleteLink.getAttribute('data-href-template').replace('__fk__', elementPk));
|
||||||
|
viewLink.setAttribute('href', viewLink.getAttribute('data-href-template').replace('__fk__', elementPk));
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
<link rel="apple-touch-icon" size="180x180"
|
<link rel="apple-touch-icon" size="180x180"
|
||||||
href="{% static 'img/registrar/favicons/favicon-180.png' %}"
|
href="{% static 'img/registrar/favicons/favicon-180.png' %}"
|
||||||
>
|
>
|
||||||
|
<script type="application/javascript" src="{% static 'js/get-gov-admin.js' %}" defer></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
|
{% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
{% extends 'admin/change_form.html' %}
|
{% extends 'admin/change_form.html' %}
|
||||||
{% load i18n static %}
|
{% load i18n static %}
|
||||||
|
|
||||||
{% block extrahead %}
|
|
||||||
{{ block.super }}
|
|
||||||
<script type="application/javascript" src="{% static 'js/get-gov-admin.js' %}" defer></script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block field_sets %}
|
{% block field_sets %}
|
||||||
<div class="submit-row">
|
<div class="submit-row">
|
||||||
<input id="manageDomainSubmitButton" type="submit" value="Manage domain" name="_edit_domain">
|
<input id="manageDomainSubmitButton" type="submit" value="Manage domain" name="_edit_domain">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue