Efficiently reloading JavaScript functionality after AJAX requests in backend?

I’m working on a plugin in OctoberCMS where I utilize the Select2 library to transform dropdowns into comboboxes, allowing users to input custom values. This works as expected on initial page load and when I add new fields via a repeater.

However, when I navigate between settings pages without fully refreshing the page, the JavaScript functionality for my combobox doesn’t apply correctly. Yet, if I manually refresh the page, everything works as expected.

To circumvent this, I’m currently using an interval that checks for the presence of a specific label every 2 seconds. Once this label is detected, I run my Select2 combobox initialization script. Here’s my current approach:

let labelDetectedLastTime = false;

let checkInterval = setInterval(() => {
    let label = document.querySelector('label[for="Form-field-Settings-scripts"]');
    if (label && !labelDetectedLastTime) {
        console.log("Label gevonden!");
        
        // Voer de gewenste functies uit
        runWhenLabelFound();
        
        labelDetectedLastTime = true;
    } else if (!label) {
        labelDetectedLastTime = false;
    }
}, 2000); // checkt elke 2 seconden

function runWhenLabelFound() {
    // window.location.reload();
    
    initializeSelect2OnNewElements();

    // Luister naar het ajaxDone event en initialiseer na een halve seconde
    $(document).on('ajaxDone', function() {
        setTimeout(initializeSelect2OnNewElements, 500);
    });
}

function initializeSelect2OnNewElements() {
    var dropdowns = $("div.custom-combobox select:not(.select2-applied)");

    dropdowns.each(function() {
        $(this).addClass('select2-applied');
        $(this).select2({
            tags: true
        });
    });
}

I’m wondering if there’s a more efficient way to tackle this within OctoberCMS. Is there perhaps a specific AJAX listener that I can utilize to perform this initialization only when required?

Any suggestions would be appreciated.

Thank you for your insights!

Hey @wouter

This is exactly what Hot Controls are used for: Hot Controls - October CMS - 3.x

oc.registerControl('custom-select2', class extends oc.ControlBase {
    connect() {
        // Select2 has appeared in DOM
    }

    disconnect() {
        // Select2 was removed from DOM
    }
});

I hope this helps!