Flask - Calling Python Function on Button Onclick Event

Flask - Calling python function which takes input parameters on button OnClick event

  1. Define a URL(route) that runs your script.
  2. In your JavaScript code, make an HTTP request to the URL defined in Step 1.

It's so simple, I wrote codes for you and I hope it help you:

I also made a gist at github.

main.py

from flask import Flask, render_template
from flask import request
import pdfkit


## ## ## ## ## ## ## ## ## ## ## ##
app = Flask(__name__)


## ## ## ## ## ## ## ## ## ## ## ##
# config wkhtmltopdf on my system
path_wkhtmltopdf = r'C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe'
config = pdfkit.configuration(wkhtmltopdf=path_wkhtmltopdf)


# function of rendering
def render_pdf(htmlstr):
pdfkit.from_string(htmlstr, './static/sample.pdf', configuration=config)


## ## ## ## ## ## ## ## ## ## ## ##
@app.route('/')
def index():
return render_template('index.html')


@app.route('/update-file/', methods=['POST'])
def convert_string_to_pdf():
try:
# geting the json request
json = request.get_json()

# call render_pdf function with new value
render_pdf(json['htmlstr'])

# '0' meaning no error
return '0'

except Exception as error:
return str(error)


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

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Convert HTML to PDF</title>
</head>
<body>

<p class="test">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Temporibus, beatae!
<span contenteditable="true" class="badge alert-info name" data-placeholder="Enter your name" data-focused-advice="Start typing"></span><i class="fa fa-lg fa-plus-circle"></i>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Perspiciatis, laboriosam?
</p>

<br><br>
<button onclick="commandServerToRender()">Convert to PDF</button>


<br><br>
<div id="downloadBox" hidden>
<p style="color: green;"><b>File is ready to download</b></p>
<a href="/static/sample.pdf" download="my_file">Download PDF File</a>
</div>

<div id="errorBox" hidden>
<p style="color:red"><b>There was an error:</b></p>
<p id="errorMessage" style="color:red"></p>
</div>


<script>
function commandServerToRender() {
test = document.getElementsByClassName("test")[0].innerHTML;
downloadBox = document.getElementById('downloadBox');
errorBox = document.getElementById('errorBox');
errorMessage = document.getElementById('errorMessage');

downloadBox.hidden = true;
errorBox.hidden = true;

// Sending data in JSON format using POST method
//
var xhr = new XMLHttpRequest();
var url = "/update-file/";

xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
// if print 0 meaning that it was successfull
if (xhr.responseText == '0') {
downloadBox.hidden = false;

} else {
errorMessage.innerHTML = xhr.responseText;
errorBox.hidden = false;

}
}
};

var data = JSON.stringify({"htmlstr": test});
xhr.send(data);
}
</script>
</body>
</html>

EDIT

To set encoding (You asked in comments) you must modify render_pdf() and add <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> to htmlstr, like below:

(If you are adding the whole html file, you need to add this code to your html's <head> tag)

def render_pdf(htmlstr):
pdfkit.from_string('<meta http-equiv="Content-type" content="text/html; charset=utf-8" />' + htmlstr, './static/sample.pdf', configuration=config)

Connecting python script with html button and flask

Using an HTML Anchor tag (i.e ) is the easiest way. Here is an example:

<a href="your_flask_route">This is a link</a>

But since you've chosen button, JavaScript will come in handy. Here's an example(inline):

<button onclick="window.location.href='your_flask_route';">
This is a link
</button>

and then in your flask main.py file you should have this:

@app.route('/your_flask_route')
def your_flask_route():
'''some lines of code'''

flask html button to call python function

You misspelled background. Notice you you wrote bacground_process_test:

$(function() {
$('a#test').bind('click', function() {
$.getJSON('/bacground_process_test', // << HERE
function(data) {
// do nothing
});
return false;
});
});

in the json.html file.

Python Flask calling functions using buttons

If you want to execute your function without generating a request to the server, then your function must be defined in JavaScript. Otherwise, you need to fire an HTTP request.

Now in your case, if all you're trying to do is enable/disable buttons, it would make sense to do all that in javascript (no need to go to the server).

Example:

<button type="button" onclick="disableButton(this)" name="enable">Enable</button>

javascript

function disableButtonState(elem) {
if(confirm('Are you sure you want to disable this button?') == true) {
elem.disabled = true;
alert("its done.");
}
else {
return false;
}
}

However if what you want is to call a method on your server that, for example, sends an email, then you should use a form POST/GET or AJAX POST/GET

Example:

app.py

@app.route('/foo', methods=['GET', 'POST'])
def foo(x=None, y=None):
# do something to send email
pass

template

<form action="/foo" method="post">
<button type="submit" value="Send Email" />
</form>

When you click the "Send Email" button an HTTP POST request is sent to "/foo" on your application. Your function foo can now extract some data from the request and do whatever it wants to do on the server side and then return a response to the client web browser.

It would suggest going through the Flask Tutorial to get a better understanding of client/server interactions when it comes to web applications built with Flask.

Calling a python function with a button

You want an HTML file input dialog.

<form action="/upload">
<input type="file" name="fileupload" value="fileupload" id="fileupload">
<label for="fileupload"> Select a file to upload</label>
<input type="submit" value="Klik">
</form>

How you handle that in Flask, is in the documentation

How Handle a button click on python/Flask

It should be within a form for it to be submitted.

Method-1:

`<div class="container">
<h2>Button Pressed: {{ButtonPressed}}</h2>
<form method="post">
<input type="submit" value="Click Me" >
</form>
</div>`

Python -

ButtonPressed = 0        
@app.route('/button', methods=["GET", "POST"])
def button():
if request.method == "POST":
return render_template("button.html", ButtonPressed = ButtonPressed)
# I think you want to increment, that case ButtonPressed will be plus 1.
return render_template("button.html", ButtonPressed = ButtonPressed)

Method 2 -

Use Ajax to submit form. Read the documentation here http://api.jquery.com/jquery.ajax/

Submit a post request and your Flask application will send ButtonPressed incremented value to the function, and you can process value however you want. Still, you need a form for this and you need to update ButtonPressed value using JavaScript. However, ButtonPressed value should be maintained in some database if you need it to be stored.

Method 3 -

Without a form, you can make link look like button using Bootstrap and update it directly on UI in case you don't need the ButtonPressed value stored somewhere which will also avoid unnecessary call to server (you don't want to store it). Bootstrap - http://getbootstrap.com/



Related Topics



Leave a reply



Submit