-1

I try to receive a name and value from button in Flask by request.form after clicked a Save or Search button. I get tuple from select and option but not for button. I wonder what I am doing wrong?

signup.html:

<form class="form-signin" action="" method="post">
  <div class="form-group">
    <label for="exampleFormControlSelect1">Choose</label>
    <select class="form-control" id="exampleFormControlSelect1" name="select">
      <option value="o1">o1</option>
      <option value="o2">o2</option>
      <option value="o3">o3</option>
    </select>
    <label type="button" id="search" name="search" value="Search" class="btn btn-lg btn-primary btn-block">Search</label>
    <label type="button" id="save" name="save" value="Save" class="btn btn-lg btn-primary btn-block">Save</label>
  </div>
</form>

Python code:

from flask import Flask, render_template, request
import json
from my_func import my_func

app = Flask(__name__)


@app.route('/')
@app.route('/', methods=['POST'])
def signUpUser():
    if request.method == 'POST':
        print(request.form)
        select = request.form['select']  
        dict_to_json = {'status': 'OK', 'select': select}
        if select == "my_func":
            result = my_func('my_input')
            dict_to_json['my_func'] = result
        return json.dumps(dict_to_json)
     return render_template('signup.html')


if __name__ == "__main__":
    app.run(debug=True)
    app.run()

Javascript:

$(function () {
    $('#search').click(function () {
        $.ajax({
            url: '/',
            data: $('form').serialize(),
            type: 'POST',
            success: function (response) {
                console.log('success')
            }
        });
    });
});

And from this I receive: ImmutableMultiDict([('select', 'o1')]) but I expected: ImmutableMultiDict([('select', 'o1'),('search','Search')])

mackow
  • 158
  • 2
  • 11

1 Answers1

1

The post method will send you only the input fields (input, textarea, select, radio-buttons, etc).

So, to do what you want, you would have to transform the label element, into an input element, and make it behave like a submit button.

You can do so by doing:

<form class="form-signin" action="" method="post">
  <div class="form-group">
    <label for="exampleFormControlSelect1">Choose</label>
    <select class="form-control" id="exampleFormControlSelect1" name="select">
      <option value="o1">o1</option>
      <option value="o2">o2</option>
      <option value="o3">o3</option>
    </select>
    <input type="submit" id="search" name="action" value="Search" class="btn btn-lg btn-primary btn-block"/>
    <input type="submit" id="save" name="action" value="Save" class="btn btn-lg btn-primary btn-block"/>
  </div>
</form>

Since you have the same name, you can access the info as response.form['action'] that will be or "Search" or "Save".

Solving as you said:

HTML:

<form class="form-signin" action="" method="post">
  <div class="form-group">
    <label for="exampleFormControlSelect1">Choose</label>
    <select class="form-control" id="exampleFormControlSelect1" name="select">
      <option value="o1">o1</option>
      <option value="o2">o2</option>
      <option value="o3">o3</option>
    </select>
    <input type="button" id="search" name="action" value="Search" class="btn btn-lg btn-primary btn-block"/>
    <input type="button" id="save" name="action" value="Save" class="btn btn-lg btn-primary btn-block"/>
  </div>
</form>

JavaScript:

$(function () {
    $('[name="action"]').click(function () {
        $.ajax({
            url: '/',
            data: $('form').serialize(),
            type: 'POST',
            success: function (response) {
                $("where you want to insert").html(response)
            }
        });
    });
});
  • Thank you! It work. But I still wonder, how to do that with `type="button"`. I wanna put response in the same page. – mackow Apr 04 '19 at 12:38
  • Can you detail more what you mean by "put response in the same page"? – Felipe Gonçalves Marques Apr 04 '19 at 12:51
  • After click "Search" all content lost and only result appear. Instead of this I wanna after click "Search" have the same content like first page and put result of search in the div. – mackow Apr 04 '19 at 13:07
  • In this case, I think you'll need JavaScript. To the `type=button` element, you'll have to bind a javascript function that will be executed every time it is clicked. This JavaScript will to the request and will receive the HTML, then, you'll inject this HTML into the document in the section you want. Maybe Flask provides an easier way to do so. But I don't know for sure. – Felipe Gonçalves Marques Apr 04 '19 at 13:12
  • To see how to make the request from JavaScript, you can take a look at this link: https://www.ajax-tutor.com/ . To see how to add HTML string into the document, you can follow this link: https://stackoverflow.com/questions/7327056/appending-html-string-to-the-dom/7327125 – Felipe Gonçalves Marques Apr 04 '19 at 13:14
  • Sorry, I completed misread the question and provided you with a answer that didn't solve what you asked. I'm editing my answer to solve it. – Felipe Gonçalves Marques Apr 04 '19 at 13:16