0

I wrote an HTML template to send an email using Flask. In the HTML script, I have a form that has a "send" button and once it's clicked, it triggers an email in Flask.

HTML Script

<form class="form-container" action="{{ url_for('send_email') }}">
        <div class="form-group">
            <label for="to-address">To </label>
            <input id= "to-address" name="to-address" type="email" 
            placeholder="sample@email.com" class="form-input">
       </div>
       <div class="form-group">
             <label for="title">Title</label>
             <input id= "email-title" name="email-title" type="text" placeholder="Title" 
             class="form-input">
       </div>
       <div class="form-group">
            <label for="message">Message</label>
            <textarea id= "email-body" name="email-body" placeholder="Send Message" class="form- 
             text-area"></textarea>
       </div>

       <button id="email-send-btn" type ="submit" class="btn btn-primary"> Send </button>

      </form>

FLASK

@application.route('/send_email')
def send_email():    
    
    to_address = request.args.get('to-address')
    subject = request.args.get('email-title')
    text = request.args.get('email-body')

    
    msg= Message(
            subject,
            sender="abc@email.com",
            recipients=to_address,
 
        )

    msg.html = render_template("email.html", text=text)
    mail.send(msg)

    return("success")

The email itself is working well but I have an issue with redirecting the page after clicking the "Send" button. Once I click on the Send button, whose id="email-send-btn", I want to stay in the current page, probably showing a notification popup to indicate the email has been sent successfully. I put return('success)` in the last line of my Flask script, because I had to return something to avoid a blank page.

I tried this following to stay in the same page after hitting the Send button. It allows me to stay in the same page, but also blocks the action completely and doesn't send any email. Is there any way to stay in the same page after clicking the send button without blocking the action of sending email?

$(document).ready(function(){
    var $form = $('form');
    $form.submit(function(){
       $.post($(this).attr('action'), $(this).serialize(), function(response){
             // do something here on success
       },'json');
       return true;
    });
 });

sgrimes
  • 149
  • 2
  • 11

3 Answers3

0

Right now you just use another callback that does something when the form submits but you don't block the standard submitting. In order to achieve that you should managed the event defining that he should "prevent default" actions.

$form.submit(function(e){ //< add here "e" parameter
       e.preventDefault(); //< add this
       $.post($(this).attr('action'), $(this).serialize(), function(response){
             // do something here on success
       },'json');
       return false; //< change this
    });
Gicu Aftene
  • 502
  • 2
  • 9
  • Hi, do you mean I shouldn't send emails in Flask but need to include the email part under the JS function above? When I simply added the function above, it still redirects me to the page that has "success" (last line of the Flask code). – sgrimes Dec 07 '22 at 11:23
  • i edited the answer because i didn't notice the return true; it should be return false; – Gicu Aftene Dec 07 '22 at 11:40
  • @sgrimes btw you can't manage preventing page reloading or loading on form submit from flask but only from the client-side by adjusting your submit() callback in javascript – Gicu Aftene Dec 07 '22 at 11:41
  • so, in order to prevent the regular submitting and using your $.post you should insert the e.preventDefault() and return false statement. – Gicu Aftene Dec 07 '22 at 11:42
0

Historically returning false from a submit handler prevented form submission without needing to call submit event object methods such as preventDefault and/or stopPropagation

With careful reading you may be able to infer that jQuery documentation says the same thing:

If you'd like to prevent forms from being submitted unless a flag variable is set ... [return the value of the flag from the submit handler added using the jQuery .submit(handler) syntax]

means that if the flag variable is set true, form submission is not prevented.

Hence return false instead of true to stay on the page, letting jQuery handle cross browser compatibility issues.

traktor
  • 17,588
  • 4
  • 32
  • 53
  • But if I put false instead of true, the whole action gets blocked. For example, even after I click the Send button, the email is not sent in Flask. I was wondering if I could stay in the page, while still making the code in Flask run. – sgrimes Dec 07 '22 at 11:35
  • Returning false should not prevent the `$post..` code being executed and, I would assume, the server sending the email using the data posted if it arrives at the correct server endpoint. Check out the network tab in browser tools to see if the post is taking place. – traktor Dec 07 '22 at 11:39
  • You may need to construct a [`formData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects) object to send as the body of the post request. Posting `$(this)` may not be doing what you intended. – traktor Dec 07 '22 at 11:53
0

You can use render template + flash message.

https://flask.palletsprojects.com/en/2.2.x/tutorial/templates/

https://flask.palletsprojects.com/en/2.2.x/patterns/flashing/

from flask import render_template, flash

... your code here ...

flash('Email has been sent successfully.')
return render_template('yourtemplate.html')

And in your template you have to put this code, like in documentation:

% with messages = get_flashed_messages() %}
  {% if messages %}
    <ul class=flashes>
    {% for message in messages %}
      <li>{{ message }}</li>
    {% endfor %}
    </ul>
  {% endif %}
{% endwith %}

Of course you can use any HTML tag instead of unordered list with items.