2

I'm using "basic tabs" from Twitter Bootstrap for my webapp

http://twitter.github.io/bootstrap/components.html#navs

I would like to use the Flask request object to send parameters to flask when one of the tabs is clicked.

<form action="{{ url_for('index') }}" method="post">
    <ul class="nav nav-tabs">
        <li class="active" input type="submit" name="test" value="0">
            <a href="#">A</a>
        </li>
        <li input type="submit" name="test" value="1"><a href="{{ url_for('index') }}">B</a></li>
        <li input type="submit" name="test" value="2"><a href="{{ url_for('index') }}">C</a></li>
    </ul>
</form>

There are 3 tabs in this example, and I would the corresponding "value" object to be defined and passed via the request object when one of the tabs is clicked. Each tab uses the same URL, so the difference needs to be passed through the request object. The code snippet above doesn't send anything via the request object, could someone please recommend a fix. Am I correct in using the "form" object?

Thanks!

vgoklani
  • 10,685
  • 16
  • 63
  • 101
  • Why don't you just submit the form? Links should always point to the same location, so I wouldn't use them in place of buttons. – Blender Apr 17 '13 at 01:34
  • not sure what you mean, how are they being used in place of buttons? The clicks load the correct URL, but nothing gets passed to the request object. – vgoklani Apr 17 '13 at 01:36
  • Nothing should be passed. Links are links. If you want to pass parameters, either add them to `url_for` or submit the form. – Blender Apr 17 '13 at 01:38
  • If I add them to url_for, then the actual URL has an "?argument" appended to it. Doesn't submitting a form require a submit button? – vgoklani Apr 17 '13 at 01:40

1 Answers1

3

The li element doesn't have an attribute input (or for that matter, type or value). You probably want something like this:

<form action="{{ url_for('index') }}" method="post">
<ul class="nav nav-tabs">
    <li class="active">
        <button type="submit" name="test" value="0">A</button>
    </li>
    <li><button type="submit" name="test" value="1">B</button></li>
    <li><button type="submit" name="test" value="2">C</button></li>
</ul>
</form>

You can then access the POSTed value via the request.form MultiDict:

@app.route("/")
def index():
    print request.form.get("test", "None provided")
    return render_template("index.html")

Be aware, there are bugs in old IE (<9)'s handling of button elements.

Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
  • This was my original solution, but I would like something that hides the parameters, I don't want to see them in the main URL. Is it possible to pass the parameters through the request object? – vgoklani Apr 17 '13 at 01:55
  • "The li element doesn't have an attribute input (or for that matter, type or value)." -> That's the key sentence, Thanks! Is there a reference I should be using? – vgoklani Apr 17 '13 at 02:00
  • 1
    @vgoklani - I'm partial to a combination of http://reference.sitepoint.com/html and https://developer.mozilla.org/en/ myself. – Sean Vieira Apr 17 '13 at 02:02
  • one more question, how do you update the class="active" flag? Are you updating the session object then checking it with an if statement in the template? Is there a better way? – vgoklani Apr 17 '13 at 02:36
  • You should have access to the `request` object in the template, so you can just check for the form entry there with an if statement - if it is too verbose you can create a Jinja2 macro to generate the list items instead. – Sean Vieira Apr 17 '13 at 02:38
  • I have a similar question, but in a slightly different context. Please take a look when you get a chance: http://stackoverflow.com/questions/16266701/processing-twitter-bootstrap-events-with-flask – vgoklani Apr 28 '13 at 19:27