<?php
// Re-initialize Ays Pro Chartify charts used in a listing template, after a FacetWP refresh
// https://wordpress.org/plugins/chart-builder/
// https://ays-pro.com/wordpress/chart-builder
// Note: this only works in WP archive or custom WP_Query based templates, NOT in FacetWP Listing Builder listings. There is no solution for those.
// This solution works for both JS and Google charts
add_action('facetwp_scripts', function() {
?>
<script>
(function($) {
if (typeof FWP !== 'undefined') {
// Note: this only works in WP archive or custom WP_Query templates, NOT in FacetWP Listing Builder listings,
// because in those, the respons is not the whole body (only the listing content) and thus it has no access to
// the updated #chart-builder-chart-js-js-extra script, unfortunately
FWP.hooks.addFilter('facetwp/template_html', function(resp, params) {
// Create a temporary div to parse the new HTML response
let tempContainer = document.createElement('div');
tempContainer.innerHTML = params.response.template;
// Find the NEW script element from the AJAX response
// target #chart-builder-chart-js-js-extra or #chart-builder-charts-google-js-extra but NOT #chart-builder-chart-js-js and #chart-builder-charts-google-js
const newChartDataElements = tempContainer.querySelectorAll('#chart-builder-chart-js-js-extra, #chart-builder-charts-google-js-extra');
// also include #chart-builder-inline-css which contains chart specific CSS
const newChartCssElements = tempContainer.querySelectorAll('#chart-builder-inline-css');
if (newChartDataElements) {
newChartDataElements.forEach(function(newScript) {
const oldChartDataElements = document.getElementById(newScript.id);
// 1. Remove the old script element from the DOM
if (oldChartDataElements) {
oldChartDataElements.remove();
}
// 2. Create a brand new script element.
// Crucial because browsers execute scripts when they are appended
// as NEWLY created elements, not inserted via innerHTML or when using replaceWith(),
// which will cause TypeError: _this.dbData is undefined
const newScriptElement = document.createElement('script');
newScriptElement.id = newScript.id
// 4. Copy the JavaScript content (the variable definitions)
newScriptElement.textContent = newScript.textContent;
// 5. Append the newly created script element to the document body.
// This will trigger parsing and executing the script contents,
// thus defining the new 'aysChartOptions' variables globally.
document.body.appendChild(newScriptElement);
});
}
if (newChartCssElements) {
newChartCssElements.forEach(function(newCss) {
const oldChartCssElements = document.getElementById(newCss.id);
// 1. Remove the old style element from the DOM
if (oldChartCssElements) {
oldChartCssElements.remove();
}
// 2. Create a new style element.
const newInlineCSS = document.createElement('style');
newInlineCSS.id = newCss.id
// 4. Copy the CSS content
newInlineCSS.textContent = newCss.textContent;
// 5. Append the newly created style element to the document body.
document.body.appendChild(newInlineCSS);
});
}
return resp;
}, 1 );
// Retrigger the charts after a facetwp ajax refresh
FWP.hooks.addAction('facetwp/loaded', function() {
if ( FWP.loaded ) { // run only on refresh after first page load
// Reinitialize JS charts
if (typeof $.fn.ChartBuilderChartJsMain === 'function') {
$('.ays-chart-container-chartjs').each(function() {
try {
$(this).ChartBuilderChartJsMain();
} catch (e) {
console.warn('Chart initialization error:', e);
}
});
}
// Reinitialize Google charts
if (typeof $.fn.ChartBuilderGoogleChartsMain === 'function') {
$('.ays-chart-container-google').each(function() {
try {
$(this).ChartBuilderGoogleChartsMain();
} catch (e) {
console.warn('Chart initialization error:', e);
}
});
}
}
}, 100);
}
})(jQuery);
</script>
<?php
}, 100);