2

First time with Flask. I am trying to add a confirmation dialog for a form but only on certain conditions. So I am not able to do this on the client side. I was able to add it for the GET request but I wasn't able to do it for POST requests because I need to pass around the form data. Here is what I have done.

This is the form submit of the main form. On Cancel, it just refreshes the data on the current page by doing get request for config. But on Apply, it issues a POST request to /confirm route

main.html

<form class="module-form pure-form pure-form-aligned" autocomplete="off" id="uguu">
<fieldset>
   <div id="export-settings" class="module-block insight-border">
         <div class="pure-control-group">
            {{ form.export_server.label }}
            {{ form_input(form.export_server, maxlength=255) }}
         </div> 
         <div class="pure-control-group">
            {{ form.export_port.label }}
            {{ form_input(form.export_port) }}
         </div>
         <div class="submit-button-group">
            <button class="pure-button pure-button-primary" type="submit" 
                    formaction="confirm" formmethod="post">Apply</button>
            <button class="pure-button pure-button-primary cancel" type="submit"
                    formaction="config" formmethod="get">Cancel</button>
          </div>
    </div>
</fieldset>
</form>

This is the code segment in the flask server

@config_page.route("/config", methods=["GET", "POST"])
def config():
    if request.method == "POST":
         return post_config() #Uses request.form
    return get_config()


@config_page.route("/confirm", methods=["POST"])
def confirm():
    with ClassA() as class_a:
        class_a.load()
        #Need to show the confirmation only on this condition
        if class_a.is_val_x and request.form['is_val_x'] == 'on':
            #Is this the right way to go about it?
            return render_template('confirm.html', form=request.form ) 

    return redirect(url_for('.config',form=request.form),code=307) 

An finally the code segment in confirm.html. The get request works fine but I am not sure how to post the form data from the flask /confirm route to /config. I am not even sure if this is the right way to do it. Any help would be really welcome? Any solution possible in jQuery or javaScript is also welcome.

<div> Are you sure kind of dialog? </div>
<form>
   <button class="pure-button pure-button-primary deny" type="submit"  
                formaction="config" formmethod="get">Cancel</button>

   <button class="pure-button button-warning confirm" type="submit" 
                formaction="config" formmethod="post">Confirm</button>
</form>
user1429322
  • 1,266
  • 2
  • 24
  • 38

2 Answers2

2

As you have said the get request works fine. So you must be seeing the template confirm.html. Edit the form tag.

<form method="POST" action="./config">
<button class="pure-button pure-button-primary deny" type="submit"  
            formaction="config" formmethod="get">Cancel</button>

<button class="pure-button button-warning confirm" type="submit" 
            formaction="config" formmethod="post">Confirm</button>
</form>

Now once you click confirm on code segment , you can by printing request data debug the form fields.

@config_page.route("/config", methods=["GET", "POST"])
def config():
if request.method == "POST":
 print(request)
 return post_config() #Uses request.form
return get_config()

If you want to submit form using ajax/jquery, you can do this.

<script type="text/javascript">
  $('.confirm').click(function (e) {
    e.preventDefault();
    $.ajax({
        url: "./config",
        type: 'post',
        dataType: "json",
        data: {
            search: request.term, request: 1
        },
        success: function (data) {
            response(data);
        }
    });
   }
</script>
somsgod
  • 357
  • 2
  • 11
  • Didn't get whats the inital form, can you provide that too. – somsgod Oct 11 '18 at 06:59
  • @sorry for the name. It is the form in main.html – user1429322 Oct 11 '18 at 07:01
  • let us clear something here you want your form on clicking sumbit to go to confirm url and on clicking cancel to config url. – somsgod Oct 11 '18 at 07:17
  • yes. kind of. form on clicking submit must post to config url but must go to confirm url only on certain conditions. In confirm url, clicking cancel will do get config url, Yes will post to config url. – user1429322 Oct 11 '18 at 07:29
  • why you just sending it to other url and rendering different view to just ask the user for confirm or cancel, it will make things complicated for you. That you can open in a modal popup in the main.html itself : so on this button click ``. Open a the required modal popu having confirm and cancel button and on that confirm button run the ajax function with the main.html data be passed like form.serialize(); – somsgod Oct 11 '18 at 10:01
0

Well in the flask way of doing you should have separate forms.py file where you would build all your forms and use jinja2 templating.

How I would do something like that is by creating these things:

1. app/forms.py

from flask_wtf import FlaskForm
from wtforms import StringField, BooleanField, SubmitField
from wtforms.validators import DataRequired

class ConfigForm:
    conf1 = StringField('Config 1', validators=[DataRequired()])
    conf2 = StringField('Config 2', validators=[DataRequired()])
    confirm = BooleanField('Cnfirm')
    submit = SubmitField('Submit')

2. app/templates/config.py

<html>
<body>
    <h1>Config</h1>
    <p>
        {{ form.conf1.label }}<br>
        {{ form.conf1(size=(42) }}
        {% for error in form.conf1.errors %}
        <span style="color: red;">[{{ error }}]</span>
        {% endfor %}
    </p>
    <p>
        {{ form.conf2.label }}<br>
        {{ form.conf2(size=(42) }}
        {% for error in form.conf2.errors %}
        <span style="color: red;">[{{ error }}]</span>
        {% endfor %}
    </p>
    <p>{{ form.submit() }}</p>
</body>
</html>

3. app/routes.py

from flask import Flask render_template, redirect, url_for, request
from forms import ConfigForm


app = Flask(__name__)

@app.route('/config/<confirm>', methods=['GET', 'POST'])
def config(confirm):
    form = ConfigForm()
    if form.validate_on_submit():
        if form.validate_on_submit():
            db.get.value1.for.form = form.conf1.data
            db.get.value2.for.form = form.conf2.data
            if confirm:
                db.get.value3.form = form.confim.data

            db.session.commit()

            flash('You\'r changes have been saved!')
            return redirect(url_for('config'))
        elif request.method == 'GET':
            form.conf1.data = db.get.value1.for.form
            form.conf2.data = db.get.value2.for.form

    return render_template('config.html', form=form)


@app.route('/')
def index():
    confirm = True
    return redirect(url_for('config', confirm))

What I'm doing here is that I'm creating config page where data is loaded from database and in case the user wishes to update the data in the post method I will update the data to the database.

In my exaple if user enter to the /index page it redirects to cinfig page and passes the confim = True that will be updated together with post method without any user action needed.

I hope this example might atleast put you on the road to the solution you need. :)

simkusr
  • 770
  • 2
  • 11
  • 20
  • Bit unclear here. I actually wanted an user action where they can confirm the action. For example if form.conf1 is something sensitive if db.get.value1 is currently on and say the user is turning off conf1 from on.I want to prompt the user if they really want to do that. Your suggestion looks like it does without user interaction. – user1429322 Oct 11 '18 at 07:00
  • Ahh, ok. Sorry for the unclear responese, try this as there is what you need I think: https://stackoverflow.com/questions/32911578/flask-confirm-action – simkusr Oct 11 '18 at 07:02