From 7b796c51c840cdd0c8d87c4d040e626801bc7f8a Mon Sep 17 00:00:00 2001 From: rob Date: Sun, 8 Mar 2026 03:33:45 -0300 Subject: [PATCH] Fix indicator toggle functionality and add loading feedback - Fix JSON parsing bug: JavaScript FormData sends indicator list as JSON string inside a list, now properly parsed on backend - Move form event listener setup to _setupIndicatorForm() called from addToCharts() so it's always attached regardless of indicator data - Add immediate visual feedback: popup hides instantly on submit and button shows "Updating..." text Co-Authored-By: Claude Opus 4.5 --- src/BrighterTrades.py | 16 +++++++++++++++- src/static/indicators.js | 34 +++++++++++++++++++++++++++++----- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/BrighterTrades.py b/src/BrighterTrades.py index 2397a77..8b2bd36 100644 --- a/src/BrighterTrades.py +++ b/src/BrighterTrades.py @@ -1382,7 +1382,21 @@ class BrighterTrades: # Get indicator names - can be a list (from form checkboxes) or JSON string indicator_param = params.get('indicator', []) if isinstance(indicator_param, list): - indicators_to_toggle = indicator_param + # Check if it's a list with a single JSON string element (from JavaScript FormData) + if len(indicator_param) == 1 and isinstance(indicator_param[0], str): + try: + # Try to parse as JSON array + parsed = json.loads(indicator_param[0]) + if isinstance(parsed, list): + indicators_to_toggle = parsed + else: + indicators_to_toggle = indicator_param + except json.JSONDecodeError: + # Not JSON, use as-is (single indicator name) + indicators_to_toggle = indicator_param + else: + # Multiple checkbox values from standard form submission + indicators_to_toggle = indicator_param elif isinstance(indicator_param, str): # Try to parse as JSON for backwards compatibility try: diff --git a/src/static/indicators.js b/src/static/indicators.js index d9323f0..b49f915 100644 --- a/src/static/indicators.js +++ b/src/static/indicators.js @@ -597,6 +597,9 @@ class Indicators { Receives indicator data, creates and stores the indicator objects, then inserts the data into the charts. */ + // Always set up the visibility form event handler + this._setupIndicatorForm(); + if (idata.indicators && Object.keys(idata.indicators).length > 0) { this.create_indicators(idata.indicators, charts); // Initialize each indicator with the data directly @@ -610,6 +613,15 @@ class Indicators { } } + _setupIndicatorForm(){ + // Set up the visibility form event handler + const form = document.getElementById('indicator-form'); + if (form && !form._hasSubmitListener) { + form.addEventListener('submit', this.handleFormSubmit.bind(this)); + form._hasSubmitListener = true; // Prevent duplicate listeners + } + } + init_indicators(data){ // Loop through all the indicators. @@ -621,11 +633,6 @@ class Indicators { } this.i_objs[name].init(data[name]); } - // Set up the visibility form event handler - const form = document.getElementById('indicator-form'); - - // Add a submit event listener to the form - form.addEventListener('submit', this.handleFormSubmit.bind(this)); } // This updates all the indicator data (re-initializes with full dataset) @@ -899,6 +906,18 @@ class Indicators { // Append all selected indicators as a single array-like structure formData.append('indicator', JSON.stringify(selectedIndicators)); + // Show loading feedback immediately + const submitBtn = form.querySelector('input[type="submit"]'); + const originalValue = submitBtn.value; + submitBtn.value = 'Updating...'; + submitBtn.disabled = true; + + // Hide the popup and show a brief loading indicator + const popup = document.getElementById('indicators'); + if (popup) { + popup.style.display = 'none'; + } + // Send form data via AJAX (fetch) fetch(form.action, { method: form.method, @@ -908,10 +927,15 @@ class Indicators { // Handle success (you can reload the page or update the UI) window.location.reload(); } else { + // Restore button on error + submitBtn.value = originalValue; + submitBtn.disabled = false; alert('Failed to update indicators.'); } }).catch(error => { console.error('Error:', error); + submitBtn.value = originalValue; + submitBtn.disabled = false; alert('An error occurred while updating the indicators.'); }); }