1

I would like to select a value from a drop down and display the web page accordingly. Currently I am able to access each value of the drop down by typing it out at the end of the URL. What exactly am I missing? I am able to access /metadata/table_name1 metadata/table_name2 when I type it out in the browser. But I am not able to get it when I select the option from the dropdown. The dropdown should redirect to the metadata/drop_down_value.

I have tested by printing out individual url routing links. By clicking the links, it works. I need to select from dropdown.

Views:

@app.route('/metadata', methods=['GET', 'POST'])
def metadata():
    cols = None
    table = None
    db_uri = session.get('db_uri', None)
    eng = create_engine(db_uri)
    insp = reflection.Inspector.from_engine(eng)
    tablenames = insp.get_table_names()
    form = SelectTableForm()
    form.table_name.choices = tablenames
    cols = insp.get_columns(table_name=tablenames[0])
    eng.dispose()
    return render_template('tables.html', cols=cols, table=tablenames[0], form=form)

@app.route('/metadata/<table>', methods=['GET', 'POST'])
def select_table(table):
    form = SelectTableForm()
    db_uri = session.get('db_uri', None)
    eng = create_engine(db_uri)
    insp = reflection.Inspector.from_engine(eng)
    tablenames = insp.get_table_names()
    form.table_name.choices = tablenames
    cols = insp.get_columns(table_name=table)
    return render_template('tables.html', cols=cols, table=table, form=form)

Form:

class SelectTableForm(FlaskForm):

    table_name = SelectField(label='Table name', choices=[], coerce=int)

Jinja html:

<!-- This works -->
{% for table in form.table_name.choices %}
    <a href="{{ url_for('select_table', table=table) }}">{{ table }}</a>
{% endfor %}

<!-- This does not -->

<form action="">
    <select name="tables" method="POST" type="submit">
      {% for table in form.table_name.choices %}
          <option value="{{ url_for('select_table', table=table) }}">{{ table }}</option>
      {% endfor %}
    </select>
</form>

<table>
    <tr>
        <th>table</th>
        <th>name</th>
        <th>type</th>
        <th>nullable</th>
        <th>default</th>
        <th>autoincrement</th>
        <th>comment</th>
    </tr>
    {% for col in cols %}
        <tr>
        <td>{{ table }}</td>
        {% for val in col.values() %}
            <td>{{ val }}</td>
        {% endfor %}
        </tr>
    {% endfor %}
</table>

1 Answers1

5

You need a bit of js where you set the url to the current page to the value of the selected option in the select element: onchange="location = this.value;".

from flask import Flask, render_template_string

app = Flask(__name__)

@app.route('/')
def homepage():
    return render_template_string('''
        <select name="form" onchange="location = this.value;">
          {% for table in tables %}
              <option value="{{ url_for('select_table', table=table) }}">{{ table }}</option>
          {% endfor %}
        </select>
''', tables = ['a', 'b'])


@app.route('/select_table/<table>', methods=['GET', 'POST'])
def select_table(table):
    return table
Joost
  • 3,609
  • 2
  • 12
  • 29
  • Hey thank you very much. This works. Can you help me with one more minor thing? Say I select `val_3` from drop down. How can I have the drop down list show `val_3` at the `val_3 page` instead of `val_1`? – scientific_explorer Dec 14 '18 at 11:06
  • 1
    In the jinja for loop, you do a ` – Joost Dec 14 '18 at 11:09
  • ID is the `id` attribute in the `` tag? If yes, then it doesn't work that way. When I press back button, the `val_3` is displayed at the previous page rather than the current page. The current page still shows only the first value.
    – scientific_explorer Dec 14 '18 at 11:17
  • 1
    No, the id is whatever you're using to identify a table yourself. It has nothing to do with html attributes. So you just check if the table you're currently looping over is the same table you've potentially rendered. – Joost Dec 14 '18 at 11:20
  • Got it thanks. Had to rename a few variables to make it work properly. One more question, Can you point me to resources to learn about js? How would I recognize that I would need js? For this instance, I didn't know what I didn't know. .. – scientific_explorer Dec 14 '18 at 11:28
  • 1
    Yeah, providing a variable named `table`, and also doing `{% for table in tables %}` was the reason why I worded it the way I did (I was too lazy to rename them myself). Regarding learning js, I didn't know it myself either, I just googled it and stumbled upton [this question](https://stackoverflow.com/questions/2000656/using-href-links-inside-option-tag) :) – Joost Dec 14 '18 at 11:33