mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-22 02:36:02 +02:00
init refactor of portfolio form js
This commit is contained in:
parent
42c62c2ba0
commit
41c148b15e
2 changed files with 186 additions and 177 deletions
|
@ -4,41 +4,41 @@ import { hideElement, showElement } from './helpers-admin.js';
|
||||||
* Helper function that handles business logic for the suborganization field.
|
* Helper function that handles business logic for the suborganization field.
|
||||||
* Can be used anywhere the suborganization dropdown exists
|
* Can be used anywhere the suborganization dropdown exists
|
||||||
*/
|
*/
|
||||||
export function handleSuborganizationFields(
|
// export function handleSuborganizationFields(
|
||||||
portfolioDropdownSelector="#id_portfolio",
|
// portfolioDropdownSelector="#id_portfolio",
|
||||||
suborgDropdownSelector="#id_sub_organization",
|
// suborgDropdownSelector="#id_sub_organization",
|
||||||
requestedSuborgFieldSelector=".field-requested_suborganization",
|
// requestedSuborgFieldSelector=".field-requested_suborganization",
|
||||||
suborgCitySelector=".field-suborganization_city",
|
// suborgCitySelector=".field-suborganization_city",
|
||||||
suborgStateTerritorySelector=".field-suborganization_state_territory"
|
// suborgStateTerritorySelector=".field-suborganization_state_territory"
|
||||||
) {
|
// ) {
|
||||||
// These dropdown are select2 fields so they must be interacted with via jquery
|
// // These dropdown are select2 fields so they must be interacted with via jquery
|
||||||
const portfolioDropdown = django.jQuery(portfolioDropdownSelector)
|
// const portfolioDropdown = django.jQuery(portfolioDropdownSelector)
|
||||||
const suborganizationDropdown = django.jQuery(suborgDropdownSelector)
|
// const suborganizationDropdown = django.jQuery(suborgDropdownSelector)
|
||||||
const requestedSuborgField = document.querySelector(requestedSuborgFieldSelector);
|
// const requestedSuborgField = document.querySelector(requestedSuborgFieldSelector);
|
||||||
const suborgCity = document.querySelector(suborgCitySelector);
|
// const suborgCity = document.querySelector(suborgCitySelector);
|
||||||
const suborgStateTerritory = document.querySelector(suborgStateTerritorySelector);
|
// const suborgStateTerritory = document.querySelector(suborgStateTerritorySelector);
|
||||||
if (!suborganizationDropdown || !requestedSuborgField || !suborgCity || !suborgStateTerritory) {
|
// if (!suborganizationDropdown || !requestedSuborgField || !suborgCity || !suborgStateTerritory) {
|
||||||
console.error("Requested suborg fields not found.");
|
// console.error("Requested suborg fields not found.");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
function toggleSuborganizationFields() {
|
// function toggleSuborganizationFields() {
|
||||||
if (portfolioDropdown.val() && !suborganizationDropdown.val()) {
|
// if (portfolioDropdown.val() && !suborganizationDropdown.val()) {
|
||||||
if (requestedSuborgField) showElement(requestedSuborgField);
|
// if (requestedSuborgField) showElement(requestedSuborgField);
|
||||||
if (suborgCity) showElement(suborgCity);
|
// if (suborgCity) showElement(suborgCity);
|
||||||
if (suborgStateTerritory) showElement(suborgStateTerritory);
|
// if (suborgStateTerritory) showElement(suborgStateTerritory);
|
||||||
}else {
|
// }else {
|
||||||
if (requestedSuborgField) hideElement(requestedSuborgField);
|
// if (requestedSuborgField) hideElement(requestedSuborgField);
|
||||||
if (suborgCity) hideElement(suborgCity);
|
// if (suborgCity) hideElement(suborgCity);
|
||||||
if (suborgStateTerritory) hideElement(suborgStateTerritory);
|
// if (suborgStateTerritory) hideElement(suborgStateTerritory);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Run the function once on page startup, then attach an event listener
|
// // Run the function once on page startup, then attach an event listener
|
||||||
toggleSuborganizationFields();
|
// toggleSuborganizationFields();
|
||||||
suborganizationDropdown.on("change", toggleSuborganizationFields);
|
// suborganizationDropdown.on("change", toggleSuborganizationFields);
|
||||||
portfolioDropdown.on("change", toggleSuborganizationFields);
|
// portfolioDropdown.on("change", toggleSuborganizationFields);
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,69 +4,87 @@ import { hideElement, showElement } from './helpers-admin.js';
|
||||||
* A function for dynamically changing some fields on the portfolio admin model
|
* A function for dynamically changing some fields on the portfolio admin model
|
||||||
* IMPORTANT NOTE: The logic in this function is paired handlePortfolioSelection and should be refactored once we solidify our requirements.
|
* IMPORTANT NOTE: The logic in this function is paired handlePortfolioSelection and should be refactored once we solidify our requirements.
|
||||||
*/
|
*/
|
||||||
export function initDynamicPortfolioFields(){
|
function handlePortfolioFields(){
|
||||||
|
|
||||||
// the federal agency change listener fires on page load, which we don't want.
|
let isPageLoading = true
|
||||||
var isInitialPageLoad = true
|
let seniorOfficialContactList = document.querySelector(".field-senior_official .dja-address-contact-list");
|
||||||
|
const federalAgency = document.querySelector(".field-federal_agency");
|
||||||
|
// $ symbolically denotes that this is using jQuery
|
||||||
|
let $federalAgency = django.jQuery("#id_federal_agency");
|
||||||
|
let organizationType = document.getElementById("id_organization_type");
|
||||||
|
let readonlyOrganizationType = document.querySelector(".field-organization_type .readonly");
|
||||||
|
let organizationName = document.querySelector(".field-organization_name");
|
||||||
|
let federalType = document.querySelector(".field-federal_type");
|
||||||
|
let urbanization = document.querySelector(".field-urbanization");
|
||||||
|
let stateTerritory = document.getElementById("id_state_territory");
|
||||||
|
let $seniorOfficial = django.jQuery("#id_senior_official");
|
||||||
|
let readonlySeniorOfficial = document.querySelector(".field-senior_official .readonly");
|
||||||
|
|
||||||
// This is the additional information that exists beneath the SO element.
|
function getFederalTypeFromAgency(agency) {
|
||||||
var contactList = document.querySelector(".field-senior_official .dja-address-contact-list");
|
let federalPortfolioApi = document.getElementById("federal_and_portfolio_types_from_agency_json_url").value;
|
||||||
const federalAgencyContainer = document.querySelector(".field-federal_agency");
|
return fetch(`${federalPortfolioApi}?&agency_name=${agency}`)
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
.then(response => {
|
||||||
|
const statusCode = response.status;
|
||||||
let isPortfolioPage = document.getElementById("portfolio_form");
|
return response.json().then(data => ({ statusCode, data }));
|
||||||
if (!isPortfolioPage) {
|
})
|
||||||
return;
|
.then(({ statusCode, data }) => {
|
||||||
}
|
if (data.error) {
|
||||||
|
console.error("Error in AJAX call: " + data.error);
|
||||||
// $ symbolically denotes that this is using jQuery
|
return;
|
||||||
let $federalAgency = django.jQuery("#id_federal_agency");
|
}
|
||||||
let organizationType = document.getElementById("id_organization_type");
|
return data.federal_type
|
||||||
let readonlyOrganizationType = document.querySelector(".field-organization_type .readonly");
|
})
|
||||||
|
.catch(error => {
|
||||||
let organizationNameContainer = document.querySelector(".field-organization_name");
|
console.error("Error fetching federal and portfolio types: ", error);
|
||||||
let federalType = document.querySelector(".field-federal_type");
|
return null
|
||||||
|
|
||||||
if ($federalAgency && (organizationType || readonlyOrganizationType)) {
|
|
||||||
// Attach the change event listener
|
|
||||||
$federalAgency.on("change", function() {
|
|
||||||
handleFederalAgencyChange($federalAgency, organizationType, readonlyOrganizationType, organizationNameContainer, federalType);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle dynamically hiding the urbanization field
|
function getSeniorOfficialFromAgency(agency, seniorOfficialAddUrl) {
|
||||||
let urbanizationField = document.querySelector(".field-urbanization");
|
let seniorOfficialApi = document.getElementById("senior_official_from_agency_json_url").value;
|
||||||
let stateTerritory = document.getElementById("id_state_territory");
|
return fetch(`${seniorOfficialApi}?agency_name=${agency}`)
|
||||||
if (urbanizationField && stateTerritory) {
|
.then(response => {
|
||||||
// Execute this function once on load
|
const statusCode = response.status;
|
||||||
handleStateTerritoryChange(stateTerritory, urbanizationField);
|
return response.json().then(data => ({ statusCode, data }));
|
||||||
|
})
|
||||||
|
.then(({ statusCode, data }) => {
|
||||||
|
if (data.error) {
|
||||||
|
if (statusCode === 404) {
|
||||||
|
|
||||||
// Attach the change event listener for state/territory
|
if ($seniorOfficial && $seniorOfficial.length > 0) {
|
||||||
stateTerritory.addEventListener("change", function() {
|
$seniorOfficial.val("").trigger("change");
|
||||||
handleStateTerritoryChange(stateTerritory, urbanizationField);
|
} else {
|
||||||
|
// Show the "create one now" text if this field is none in readonly mode.
|
||||||
|
readonlySeniorOfficial.innerHTML = `<a href="${seniorOfficialAddUrl}">No senior official found. Create one now.</a>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn("Record not found: " + data.error);
|
||||||
|
} else {
|
||||||
|
console.error("Error in AJAX call: " + data.error);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error("Error fetching senior official: ", error)
|
||||||
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle hiding the organization name field when the organization_type is federal.
|
|
||||||
// Run this first one page load, then secondly on a change event.
|
|
||||||
handleOrganizationTypeChange(organizationType, organizationNameContainer, federalType);
|
|
||||||
organizationType.addEventListener("change", function() {
|
|
||||||
handleOrganizationTypeChange(organizationType, organizationNameContainer, federalType);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function handleOrganizationTypeChange(organizationType, organizationNameContainer, federalType) {
|
function handleOrganizationTypeChange(organizationType, organizationNameContainer, federalType) {
|
||||||
if (organizationType && organizationNameContainer) {
|
if (organizationType && organizationNameContainer) {
|
||||||
let selectedValue = organizationType.value;
|
let selectedValue = organizationType.value;
|
||||||
if (selectedValue === "federal") {
|
if (selectedValue === "federal") {
|
||||||
hideElement(organizationNameContainer);
|
hideElement(organizationNameContainer);
|
||||||
showElement(federalAgencyContainer);
|
showElement(federalAgency);
|
||||||
if (federalType) {
|
if (federalType) {
|
||||||
showElement(federalType);
|
showElement(federalType);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showElement(organizationNameContainer);
|
showElement(organizationNameContainer);
|
||||||
hideElement(federalAgencyContainer);
|
hideElement(federalAgency);
|
||||||
if (federalType) {
|
if (federalType) {
|
||||||
hideElement(federalType);
|
hideElement(federalType);
|
||||||
}
|
}
|
||||||
|
@ -75,106 +93,62 @@ export function initDynamicPortfolioFields(){
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleFederalAgencyChange(federalAgency, organizationType, readonlyOrganizationType, organizationNameContainer, federalType) {
|
function handleFederalAgencyChange(federalAgency, organizationType, readonlyOrganizationType, organizationNameContainer, federalType) {
|
||||||
// Don't do anything on page load
|
if (!isPageLoading) {
|
||||||
if (isInitialPageLoad) {
|
|
||||||
isInitialPageLoad = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the org type to federal if an agency is selected
|
let selectedFederalAgency = federalAgency.find("option:selected").text();
|
||||||
let selectedText = federalAgency.find("option:selected").text();
|
// There isn't a federal senior official associated with null records
|
||||||
|
if (!selectedFederalAgency) {
|
||||||
// There isn't a federal senior official associated with null records
|
|
||||||
if (!selectedText) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let organizationTypeValue = organizationType ? organizationType.value : readonlyOrganizationType.innerText.toLowerCase();
|
|
||||||
if (selectedText !== "Non-Federal Agency") {
|
|
||||||
if (organizationTypeValue !== "federal") {
|
|
||||||
if (organizationType){
|
|
||||||
organizationType.value = "federal";
|
|
||||||
}else {
|
|
||||||
readonlyOrganizationType.innerText = "Federal"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
if (organizationTypeValue === "federal") {
|
|
||||||
if (organizationType){
|
|
||||||
organizationType.value = "";
|
|
||||||
}else {
|
|
||||||
readonlyOrganizationType.innerText = "-"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleOrganizationTypeChange(organizationType, organizationNameContainer, federalType);
|
|
||||||
|
|
||||||
// Determine if any changes are necessary to the display of portfolio type or federal type
|
|
||||||
// based on changes to the Federal Agency
|
|
||||||
let federalPortfolioApi = document.getElementById("federal_and_portfolio_types_from_agency_json_url").value;
|
|
||||||
fetch(`${federalPortfolioApi}?&agency_name=${selectedText}`)
|
|
||||||
.then(response => {
|
|
||||||
const statusCode = response.status;
|
|
||||||
return response.json().then(data => ({ statusCode, data }));
|
|
||||||
})
|
|
||||||
.then(({ statusCode, data }) => {
|
|
||||||
if (data.error) {
|
|
||||||
console.error("Error in AJAX call: " + data.error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateReadOnly(data.federal_type, '.field-federal_type');
|
|
||||||
})
|
|
||||||
.catch(error => console.error("Error fetching federal and portfolio types: ", error));
|
|
||||||
|
|
||||||
// Hide the contactList initially.
|
let organizationTypeValue = organizationType ? organizationType.value : readonlyOrganizationType.innerText.toLowerCase();
|
||||||
// If we can update the contact information, it'll be shown again.
|
if (selectedFederalAgency !== "Non-Federal Agency") {
|
||||||
hideElement(contactList.parentElement);
|
if (organizationTypeValue !== "federal") {
|
||||||
|
if (organizationType){
|
||||||
let seniorOfficialAddUrl = document.getElementById("senior-official-add-url").value;
|
organizationType.value = "federal";
|
||||||
let $seniorOfficial = django.jQuery("#id_senior_official");
|
|
||||||
let readonlySeniorOfficial = document.querySelector(".field-senior_official .readonly");
|
|
||||||
let seniorOfficialApi = document.getElementById("senior_official_from_agency_json_url").value;
|
|
||||||
fetch(`${seniorOfficialApi}?agency_name=${selectedText}`)
|
|
||||||
.then(response => {
|
|
||||||
const statusCode = response.status;
|
|
||||||
return response.json().then(data => ({ statusCode, data }));
|
|
||||||
})
|
|
||||||
.then(({ statusCode, data }) => {
|
|
||||||
if (data.error) {
|
|
||||||
// Clear the field if the SO doesn't exist.
|
|
||||||
if (statusCode === 404) {
|
|
||||||
if ($seniorOfficial && $seniorOfficial.length > 0) {
|
|
||||||
$seniorOfficial.val("").trigger("change");
|
|
||||||
}else {
|
}else {
|
||||||
// Show the "create one now" text if this field is none in readonly mode.
|
readonlyOrganizationType.innerText = "Federal"
|
||||||
readonlySeniorOfficial.innerHTML = `<a href="${seniorOfficialAddUrl}">No senior official found. Create one now.</a>`;
|
|
||||||
}
|
}
|
||||||
console.warn("Record not found: " + data.error);
|
}
|
||||||
|
} else {
|
||||||
|
if (organizationTypeValue === "federal") {
|
||||||
|
if (organizationType){
|
||||||
|
organizationType.value = "";
|
||||||
|
}else {
|
||||||
|
readonlyOrganizationType.innerText = "-"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOrganizationTypeChange(organizationType, organizationNameContainer, federalType);
|
||||||
|
|
||||||
|
// Determine if any changes are necessary to the display of portfolio type or federal type
|
||||||
|
// based on changes to the Federal Agency
|
||||||
|
getFederalTypeFromAgency(selectedFederalAgency).then((federalType) => updateReadOnly(federalType, '.field-federal_type'));
|
||||||
|
|
||||||
|
hideElement(seniorOfficialContactList.parentElement);
|
||||||
|
let seniorOfficialAddUrl = document.getElementById("senior-official-add-url").value;
|
||||||
|
getSeniorOfficialFromAgency(selectedFederalAgency, seniorOfficialAddUrl).then((data) => {
|
||||||
|
// Update the "contact details" blurb beneath senior official
|
||||||
|
updateContactInfo(data);
|
||||||
|
showElement(seniorOfficialContactList.parentElement);
|
||||||
|
// Get the associated senior official with this federal agency
|
||||||
|
let seniorOfficialId = data.id;
|
||||||
|
let seniorOfficialName = [data.first_name, data.last_name].join(" ");
|
||||||
|
if ($seniorOfficial && $seniorOfficial.length > 0) {
|
||||||
|
// If the senior official is a dropdown field, edit that
|
||||||
|
updateSeniorOfficialDropdown($seniorOfficial, seniorOfficialId, seniorOfficialName);
|
||||||
}else {
|
}else {
|
||||||
console.error("Error in AJAX call: " + data.error);
|
if (readonlySeniorOfficial) {
|
||||||
|
let seniorOfficialLink = `<a href=/admin/registrar/seniorofficial/${seniorOfficialId}/change/>${seniorOfficialName}</a>`
|
||||||
|
readonlySeniorOfficial.innerHTML = seniorOfficialName ? seniorOfficialLink : "-";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// Update the "contact details" blurb beneath senior official
|
} else {
|
||||||
updateContactInfo(data);
|
isPageLoading = false;
|
||||||
showElement(contactList.parentElement);
|
}
|
||||||
|
|
||||||
// Get the associated senior official with this federal agency
|
|
||||||
let seniorOfficialId = data.id;
|
|
||||||
let seniorOfficialName = [data.first_name, data.last_name].join(" ");
|
|
||||||
if ($seniorOfficial && $seniorOfficial.length > 0) {
|
|
||||||
// If the senior official is a dropdown field, edit that
|
|
||||||
updateSeniorOfficialDropdown($seniorOfficial, seniorOfficialId, seniorOfficialName);
|
|
||||||
}else {
|
|
||||||
if (readonlySeniorOfficial) {
|
|
||||||
let seniorOfficialLink = `<a href=/admin/registrar/seniorofficial/${seniorOfficialId}/change/>${seniorOfficialName}</a>`
|
|
||||||
readonlySeniorOfficial.innerHTML = seniorOfficialName ? seniorOfficialLink : "-";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => console.error("Error fetching senior official: ", error));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +158,6 @@ export function initDynamicPortfolioFields(){
|
||||||
dropdown.val("").trigger("change");
|
dropdown.val("").trigger("change");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the senior official to the dropdown.
|
// Add the senior official to the dropdown.
|
||||||
// This format supports select2 - if we decide to convert this field in the future.
|
// This format supports select2 - if we decide to convert this field in the future.
|
||||||
if (dropdown.find(`option[value='${seniorOfficialId}']`).length) {
|
if (dropdown.find(`option[value='${seniorOfficialId}']`).length) {
|
||||||
|
@ -227,11 +200,11 @@ export function initDynamicPortfolioFields(){
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateContactInfo(data) {
|
function updateContactInfo(data) {
|
||||||
if (!contactList) return;
|
if (!seniorOfficialContactList) return;
|
||||||
|
|
||||||
const titleSpan = contactList.querySelector(".contact_info_title");
|
const titleSpan = seniorOfficialContactList.querySelector(".contact_info_title");
|
||||||
const emailSpan = contactList.querySelector(".contact_info_email");
|
const emailSpan = seniorOfficialContactList.querySelector(".contact_info_email");
|
||||||
const phoneSpan = contactList.querySelector(".contact_info_phone");
|
const phoneSpan = seniorOfficialContactList.querySelector(".contact_info_phone");
|
||||||
|
|
||||||
if (titleSpan) {
|
if (titleSpan) {
|
||||||
titleSpan.textContent = data.title || "None";
|
titleSpan.textContent = data.title || "None";
|
||||||
|
@ -239,10 +212,10 @@ export function initDynamicPortfolioFields(){
|
||||||
|
|
||||||
// Update the email field and the content for the clipboard
|
// Update the email field and the content for the clipboard
|
||||||
if (emailSpan) {
|
if (emailSpan) {
|
||||||
let copyButton = contactList.querySelector(".admin-icon-group");
|
let copyButton = seniorOfficialContactList.querySelector(".admin-icon-group");
|
||||||
emailSpan.textContent = data.email || "None";
|
emailSpan.textContent = data.email || "None";
|
||||||
if (data.email) {
|
if (data.email) {
|
||||||
const clipboardInput = contactList.querySelector(".admin-icon-group input");
|
const clipboardInput = seniorOfficialContactList.querySelector(".admin-icon-group input");
|
||||||
if (clipboardInput) {
|
if (clipboardInput) {
|
||||||
clipboardInput.value = data.email;
|
clipboardInput.value = data.email;
|
||||||
};
|
};
|
||||||
|
@ -256,4 +229,40 @@ export function initDynamicPortfolioFields(){
|
||||||
phoneSpan.textContent = data.phone || "None";
|
phoneSpan.textContent = data.phone || "None";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initializePortfolioSettings() {
|
||||||
|
if (urbanization && stateTerritory) {
|
||||||
|
handleStateTerritoryChange(stateTerritory, urbanization);
|
||||||
|
}
|
||||||
|
handleOrganizationTypeChange(organizationType, organizationName, federalType);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setEventListeners() {
|
||||||
|
if ($federalAgency && (organizationType || readonlyOrganizationType)) {
|
||||||
|
$federalAgency.on("change", function() {
|
||||||
|
handleFederalAgencyChange($federalAgency, organizationType, readonlyOrganizationType, organizationName, federalType);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (urbanization && stateTerritory) {
|
||||||
|
stateTerritory.addEventListener("change", function() {
|
||||||
|
handleStateTerritoryChange(stateTerritory, urbanization);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
organizationType.addEventListener("change", function() {
|
||||||
|
handleOrganizationTypeChange(organizationType, organizationName, federalType);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run initial setup functions
|
||||||
|
initializePortfolioSettings();
|
||||||
|
setEventListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initPortfolioFields() {
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
let isPortfolioPage = document.getElementById("portfolio_form");
|
||||||
|
if (isPortfolioPage) {
|
||||||
|
handlePortfolioFields();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue