Home > OS >  Filter with Drop-Down Options in Python Flask App (with JavaScript)
Filter with Drop-Down Options in Python Flask App (with JavaScript)

Time:07-01

I'm trying to use drop-downs to filter results in a table. I've tried to make it work with addEventListener('click'), but I'm stuck on how to make it fully functional. I think I'm very close but missing something.

Could anyone help to provide a solution such that when the country values are clicked in the drop-down, it filters for all of those with corresponding country values in the table? This will need to work such that multiple drop-downs on multiple columns would be used.

enter image description here

Python

app = Flask(__name__)
test_data = [['jack', 23, 'china', 'https://www.google.com'],
             ['jill', 22, 'canada', 'https://www.cnn.com'],
             ['john', 24, 'canada', 'https://www.cnn.com'],
             ['jane', 30, 'australia', 'https://www.bbc.com']]

test_df = pd.DataFrame(test_data, columns=['name', 'age', 'country', 'link'])
test_df = test_df.to_dict(orient='index')
@app.route("/hello")
def index():
    return render_template("index.html", test_df=test_df)

HTML: in an index.html

<div >
    <label for="country">Countries</label>
    <form >
        <div >
            <select id="country" name="country" data-dropdown>
                <option value="">Please select a country</option>
                <option value="australia">Australia</option>
                <option value="canada">Canada</option>
                <option value="china">China</option>
            </select>
        </div>
    </form>
</div>

<table >
    <tbody id="myTable">
    </tbody>
</table>

JavaScript: within the index.html in script tags

var mydata = JSON.parse('{{ test_df|tojson }}');
var countrySelector = document.getElementById('country');
// but what next?

buildTable(mydata)
function buildTable(data) {
    var table = document.getElementById('myTable')
    table.innerHTML = ''
    for (var key in data) {
        var row = `<tr>
                    <td>${data[key].name}</td>
                    <td>${data[key].age}</td>
                    <td><a href="${data[key].link}" target='_blank'>${data[key].country}</a></td>
               </tr>`
        table.innerHTML  = row
    }
}

CodePudding user response:

Use the select element's change event to monitor user changes in the selection.
The following example shows you how to filter the rows by country. To make it easier to filter the rows in JavaScript, they are not passed as a dict but as a list using df.values.tolist().

from flask import (
    Flask, 
    render_template
)
import pandas as pd

app = Flask(__name__)

@app.route('/')
def index():
    test_df = pd.DataFrame(
        [
            ['jack', 23, 'china', 'https://www.google.com'],
            ['jill', 22, 'canada', 'https://www.cnn.com'],
            ['john', 24, 'canada', 'https://www.cnn.com'],
            ['jane', 30, 'australia', 'https://www.bbc.com']
        ],
        columns=['name', 'age', 'country', 'link']
    )
    return render_template('index.html', test_df=test_df.values.tolist())
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Index</title>
  </head>
  <body>
    <div >
      <label for="country">Countries</label>
      <form >
        <div >
          <select id="country" name="country" data-dropdown>
            <option value>Please select a country</option>
            <option value="australia">Australia</option>
            <option value="canada">Canada</option>
            <option value="china">China</option>
          </select>
        </div>
      </form>
    </div>

    <table >
      <tbody id="myTable">
      </tbody>
    </table>

    <script type="text/javascript">

      function buildTable(data) {
          const table = document.getElementById('myTable')
          table.innerHTML = data.map(row => {
            let [name, age, country, link] = row;
            return `<tr>
                <td>${name}</td>
                <td>${age}</td>
                <td><a href="${link}" target='_blank'>${country}</a></td>
              </tr>`;
          }).join('');
      }

      const data = {{ test_df|tojson }};
      const countrySelector = document.getElementById('country');
      countrySelector.addEventListener('change', evt => {
        const value = evt.target.value;
        if (value) {
          buildTable(data.filter(row => {
            let [name, age, country, link] = row;
            return country === value
          }));
        } else {
          buildTable(data);
        }
      });

      buildTable(data)

    </script>

  </body>
</html>
  • Related