Home  >  Q&A  >  body text

Update the value of the dropdown filter based on the first filter's entry

I'm developing a Flask application that filters the values ​​of a Mysql database table and based on the selected value of the first dropdown, it will update the value of the second dropdown. Finally return some data

Now the code is working but there seems to be a bug in the code such that when I make a new selection from the first dropdown it populates the second dropdown with the value of the first dropdown as well as the expected value The value of the second drop-down list

It shouldn't be doing this, I want it to only populate the second dropdown with the expected value, not add the first dropdown's value along with it.

This is my flask application code:

from flask import jsonify, request
from flask import Flask, render_template  
import mysql.connector

app = Flask(__name__)

# Configure MySQL connection
cnx = mysql.connector.connect(
  host="xxxxxxx",
  user="xxxxxxxxx",
  password="xxxxxxxxx",
  database="xxxxxxxxxx")


@app.route('/', methods=['GET', 'POST'])
def index():
    try:
        cursor = cnx.cursor()
        query = "SELECT topic FROM text_table"
        cursor.execute(query)
        data = [row[0] for row in cursor.fetchall()] # Get the first column of all rows
        cursor.nextset() # consume any unread result
        cursor.close()


        if request.method == 'POST':
            selected_topic = request.form.get('selected_topic') # Get the selected topic from the form
            if selected_topic:
                cursor = cnx.cursor()
                query = "SELECT sub_topic FROM text_table WHERE topic = %s"
                cursor.execute(query, (selected_topic,))
                sub_topics = [row[0] for row in cursor.fetchall()] # Get the sub topics for the selected topic
                cursor.nextset()
                selected_sub_topic = request.form.get('selected_sub_topic') # Get the selected sub topic from the form
                if selected_sub_topic:
                    query = "SELECT text FROM text_table WHERE topic = %s AND sub_topic = %s"
                    cursor.execute(query, (selected_topic, selected_sub_topic))
                    result = cursor.fetchone()[0] # Get the value of the text for the selected sub topic
                    cursor.nextset()
                    cursor.close()
                    return render_template('index.html', topics=data, selected_topic=selected_topic, sub_topics=sub_topics, selected_sub_topic=selected_sub_topic, result=result)

                cursor.close()
                return render_template('index.html', topics=data, selected_topic=selected_topic, sub_topics=sub_topics)

        return render_template('index.html', topics=data)

    except Exception as e:
        # Return an error message if there's an exception
        return jsonify(error=str(e)), 500


if __name__ == '__main__':
    app.run()

This is my html code with a little JavaScript

<!DOCTYPE html>
<html>
  <head>
    <title>Drop Down Filter</title>
    <script>
        function updateSubTopics() {
            var selectTopic = document.getElementById("selected_topic");
            var selectSubTopic = document.getElementById("selected_sub_topic");
            var selectedTopicValue = selectTopic.value;

            // Send a POST request to update the sub topic options
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '/');
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.onload = function() {
                if (xhr.status === 200) {
                    // Update the sub topic options
                    selectSubTopic.innerHTML = xhr.responseText;

                    // Check if the currently selected sub topic is valid for the new selected topic
                    var subTopicOptions = selectSubTopic.options;
                    var foundSelectedSubTopic = false;
                    for (var i = 0; i < subTopicOptions.length; i++) {
                        if (subTopicOptions[i].value === selectSubTopic.value) {
                            foundSelectedSubTopic = true;
                            break;
                        }
                    }
                    if (!foundSelectedSubTopic) {
                        selectSubTopic.value = "";
                    }
                }
                else {
                    console.log('Request failed. Returned status of ' + xhr.status);
                }
            };
            xhr.send('selected_topic=' + selectedTopicValue);
        }
    </script>
  </head>
  <body>
    <form method="POST">
      <select name="selected_topic" id="selected_topic" onchange="updateSubTopics()">
        {% for topic in topics %}
          <option value="{{ topic }}"
            {% if selected_topic == topic %}selected{% endif %}>
            {{ topic }}
          </option>
        {% endfor %}
      </select>
      <select name="selected_sub_topic" id="selected_sub_topic">
        {% for sub_topic in sub_topics %}
          <option value="{{ sub_topic }}"
            {% if selected_sub_topic == sub_topic %}selected{% endif %}>
            {{ sub_topic }}
          </option>
        {% endfor %}
      </select>
      <input type="submit" value="Filter">
    </form>
    {% if result %}
      <h1>{{ result }}</h1>
    {% endif %}
  </body>
</html>

Thank you, any help would be greatly appreciated

P粉033429162P粉033429162408 days ago516

reply all(1)I'll reply

  • P粉141035089

    P粉1410350892023-09-09 10:14:00

    This issue occurs when you send a template response after filtering.

    You have rendered index.html, but when changing the selection option from that row, you are also rendering index.html.

    This basically means you paste all your html code into a select element which you can inspect by inspecting it in the browser.

    In my opinion, what should be done is that you should only send a Python dictionary as the response of the child topic.

    if selected_topic:
        cursor = cnx.cursor()
        query = "SELECT sub_topic FROM text_table WHERE topic = %s"
        cursor.execute(query, (selected_topic,))
        sub_topics = [row[0] for row in cursor.fetchall()] # Get the sub topics for the selected topic
        cursor.nextset()
        selected_sub_topic = request.form.get('selected_sub_topic') # Get the selected sub topic from the form
        if selected_sub_topic:
            query = "SELECT text FROM text_table WHERE topic = %s AND sub_topic = %s"
            cursor.execute(query, (selected_topic, selected_sub_topic))
            result = cursor.fetchone()[0] # Get the value of the text for the selected sub topic
            cursor.nextset()
            cursor.close()
            return render_template('index.html', topics=data, selected_topic=selected_topic, sub_topics=sub_topics, selected_sub_topic=selected_sub_topic, result=result)
    
            cursor.close()
            return sub_topics

    After successfully obtaining the dictionary, the response will be formatted, so it needs to be parsed into json. You can then use JS loops to create the loop and append it to your sub_topic selection.

    if (xhr.status === 200) {
        selectSubTopic.options.length = 0;
        
        var subTopicOptions = JSON.parse(xhr.responseText);
    
        for (var i = 0; i < subTopicOptions.length; i++) {
            var option = document.createElement('option');
            option.text = subTopicOptions[i];
            option.value = subTopicOptions[i];
            selectSubTopic.appendChild(option);
        }
        
        // Check if the currently selected sub topic is valid for the new selected topic
        var subTopicOptions = selectSubTopic.options;
        var foundSelectedSubTopic = false;
        for (var i = 0; i < subTopicOptions.length; i++) {
            if (subTopicOptions[i].value === selectSubTopic.value) {
                foundSelectedSubTopic = true;
                break;
            }
        }
        if (!foundSelectedSubTopic) {
            selectSubTopic.value = "";
        }
    }
    else {
        console.log('Request failed. Returned status of ' + xhr.status);
    }

    reply
    0
  • Cancelreply