I have a small flask app I am using it to:
Make an HTML page with a leaflet map
Take user input from the HTML page...
Run calculations on that input using certain python modules
Return those variable to JS functions in the page to populate the map
I cannot get ANYTHING but lat and lng to return into my HTML {{}} flask variables.
Here is my HTML page:
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css"
integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet.js"
integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw=="
crossorigin="">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<title>Page Title</title>
<meta charset="utf-8"/>
<style>
#mapid { height: 300px; }
</style>
<body>
<form method="POST">
Latitude to PY: <input name="lat" id="lat"/>
<br/>
Longitude to PY: <input name="lng" id="lng"/>
<br/>
<button>Get data</button>
</form>
{% if lat1 != None and lng1 != None %}
{{lat1}},{{lng1}}
<script>
var lat1 = {{lat1}}
var lng1 = {{lng1}}
</script>
{% endif %}
{% if point != None %}
<p>{{point}}</p>
{% endif %}
{% if GeJ != None %}
{{GeJ}}
<script>
var GeJ = {{GeJ}}
</script>
{% endif %}
<div id="mapid"></div>
<script>
var mymap = L.map('mapid').setView([51.505, -0.09], 13);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 18,
id: 'mapbox.high-contrast',
accessToken: 'pk.eyJ1IjoiY2dyb3RoIiwiYSI6ImNqZ2w4bWY5dTFueG0zM2w0dTNkazI1aWEifQ.55SWFVBYzs08EqJHAa3AsQ'
}).addTo(mymap);
function zoomTo() {
mymap.panTo(new L.LatLng(lat1, lng1));
}
function addGJ(){
var myLayer = L.geoJson(GeJ).addTo(mymap);
}
window.onload = zoomTo();
window.onload = addGJ();
</script>
</body>
</html>
Here is my Flask Python code:
from flask import Flask, render_template, request, flash, redirect, url_for,jsonify
from forms import RegistrationForm
import json
import osmnx as ox
import networkx as nx
import matplotlib.pyplot as plt
from networkx.readwrite import json_graph
import pandas as pd
import mplleaflet
app = Flask(__name__)
app.config.update(dict(
SECRET_KEY="powerful secretkey",
WTF_CSRF_SECRET_KEY="a csrf secret key"
))
#app.route('/')
def my_form():
return render_template('map.html')
#app.route('/', methods=['GET', 'POST'])
def my_form_post():
lat = (request.form['lat'])
lng = (request.form['lng'])
lat = lat
lng = lng
point = (lat,lng)
G = ox.core.graph_from_point(point, distance = 500, network_type='walk')
fig, ax = ox.plot_graph(G)
GJ = mplleaflet.fig_to_geojson(fig=ax.figure)
#return lat, ",", lng
return render_template('map.html', lat1=lat, lng1=lng, GeJ=GJ, point="test_string")`
if __name__ == "__main__":
app.run(host='0.0.0.0',port=5000,debug=True)
The Flask app is working fine so the file structure is not a concern. I just cannot get any other variables to return into my HTML. I even tried making little string dummy variables other that the real ones. No Dice.
Thanks
You could try using the builtin none value http://jinja.pocoo.org/docs/templates/#none
Then do something like:
{% if lat1 is not none and lng1 is not none %}
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css"
integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet.js"
integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw=="
crossorigin="">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<title>Page Title</title>
<meta charset="utf-8"/>
<style>
#mapid { height: 300px; }
</style>
<body>
<form method="POST">
Latitude to PY: <input name="lat" id="lat"/>
<br/>
Longitude to PY: <input name="lng" id="lng"/>
<br/>
<button>Get data</button>
</form>
{% if lat1 is not Null and lng1 is not Null %}
{{lat1}},{{lng1}}
<script>
var lat1 = {{lat1}}
var lng1 = {{lng1}}
</script>
{% endif %}
{% if point != None %}
<p>{{point}}</p>
{% endif %}
{% if GeJ != None %}
{{GeJ}}
<script>
var GeJ = {{GeJ}}
</script>
{% endif %}
<div id="mapid"></div>
<script>
var mymap = L.map('mapid').setView([51.505, -0.09], 13);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 18,
id: 'mapbox.high-contrast',
accessToken: 'pk.eyJ1IjoiY2dyb3RoIiwiYSI6ImNqZ2w4bWY5dTFueG0zM2w0dTNkazI1aWEifQ.55SWFVBYzs08EqJHAa3AsQ'
}).addTo(mymap);
function zoomTo() {
mymap.panTo(new L.LatLng(lat1, lng1));
}
function addGJ(){
var myLayer = L.geoJson(GeJ).addTo(mymap);
}
window.onload = zoomTo();
window.onload = addGJ();
</script>
</body>
</html>
It would help if you provided an example of what exactly happens when you pass all the values.
Otherwise, what according to me, could be causing the problem is that the 'Null' object in python is the singleton None. The best way to check things for "Noneness" is to use is not None or better still, something as simple as:
{%if lat%} {{lat}} {% endif %}
Also, can't you assign GeJ to the var GeJ within the div instead of putting a line of JS in an abrupt manner up there?
P.S. I wanted to add this as a comment, but don't have enough reputation. Apologies.
Related
`#views.route('/flight.html',methods = ['GET','POST'])
def flight():
if request.method == 'POST':
global no_of_passenger
no_of_passengers = request.form.get('no_of_passengers')`
In the above view, I'm getting the passenger count from an earlier html page which I'm using later. I need to get the input from the user as many times as the no_of_passengers.
`#views.route('/passengers.html',methods = ['GET','POST'])
def passenger():
if request.method == 'POST':
return render_template('passengers.html')
return render_template('passengers.html')
#views.route('/passengersinfo.html',methods = ['GET','POST'])
def passenger_information():
passengercount = no_of_passengers
passengercount = int(passengercount)
print(passengercount)
if request.method == 'POST':
for i in range(0,passengercount):
passenger_info = {}
passenger_info['passengername'] = request.form.get('Passenger_Name')
passenger_info['Street'] = request.form.get('Street')
passenger_info['City'] = request.form.get('City')
passenger_info['State'] = request.form.get('State')
passenger_info['ZipCode'] = request.form.get('ZipCode')
return redirect(url_for("views.passenger"))
return render_template('passengersinfo.html')`
In this view I'm trying to run the form as per the user input using a for loop.
The below attached code is the HTML form which is used to get the user form data.
`{% extends 'base.html'%}
{% block title %}Passenger Information Page{% endblock %}
{% block content %}
<form id="Form1" action = 'passengersinfo.html' method = 'POST'>
<div>
<label for ='Passenger_Name' >Passenger Name</label>
<input type = 'text' name = 'Passenger_Name' id='Passenger_Name' id="Form1">
<br>
<label for ='Street' >Street</label>
<input type = 'text' name = 'Street' id='Street' id="Form1">
<br>
<label for ='City' >City</label>
<input type = 'text' name = 'City' id='City' id="Form1">
<br>
<label for ='State' >State</label>
<input type = 'text' name = 'State' id='State' id="Form1">
<br>
<label for ='Zip' >Zip Code</label>
<input type = 'text' name = 'Zip' id='Zip' id="Form1">
</div>
<button type = 'submit' id="Form1" >Next</button>
</form>
{%endblock%}
`
An easy way to implement your requirements is to use Flask-WTF.
Using a FieldList and a FormField, it is possible to create a list of a predefined form.
In this way you create a form for your address details and, depending on the required number, you duplicate this. In addition, you can validate the entries made.
If you only want to display one nested form at a time, you can use JavaScript to navigate forward or back.
The following example uses the session to avoid using global variables and stay as close to your defaults as possible.
Flask
from flask import (
Flask,
redirect,
render_template,
request,
session,
url_for
)
from flask_wtf import FlaskForm, Form
from wtforms import (
FieldList,
FormField,
IntegerField,
StringField,
SubmitField
)
from wtforms.validators import (
InputRequired,
NumberRange
)
app = Flask(__name__)
app.secret_key = 'your secret here'
class PassengersForm(FlaskForm):
passenger_count = IntegerField('Ticket Count',
validators=[NumberRange(min=1)]
)
submit = SubmitField('Next')
class PassengerForm(Form):
name = StringField('Name',
validators=[InputRequired()]
)
street = StringField('Street/No')
city = StringField('City')
state = StringField('State')
zipcode = StringField('Zip')
class PassengerDetailsForm(FlaskForm):
passengers = FieldList(FormField(PassengerForm))
submit = SubmitField()
#app.route('/passengers', methods=['GET', 'POST'])
def passengers():
form = PassengersForm(request.form, data={'passenger_count': 1})
if form.validate_on_submit():
session['count'] = form.passenger_count.data
return redirect(url_for('.passengers_info'))
return render_template('passengers.html', **locals())
#app.route('/passengers-info', methods=['GET', 'POST'])
def passengers_info():
form = PassengerDetailsForm(request.form)
form.passengers.min_entries = max(1, int(session.get('count', 1)))
while len(form.passengers.entries) < form.passengers.min_entries:
form.passengers.append_entry()
if form.validate_on_submit():
for passenger in form.passengers.data:
print(passenger)
return redirect(url_for('.passengers'))
return render_template('passengers_info.html', **locals())
HTML (./templates/passengers.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Passengers</title>
</head>
<body>
<form method="post">
{{ form.csrf_token }}
<div>
{{ form.passenger_count.label() }}
{{ form.passenger_count() }}
{% if form.passenger_count.errors -%}
<ul>
{% for error in form.passenger_count.errors -%}
<li>{{ error }}</li>
{% endfor -%}
</ul>
{% endif -%}
</div>
{{ form.submit }}
</form>
</body>
</html>
HTML (./templates/passengers_info.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Passenger Informations</title>
<style type="text/css">
.step {
display: none;
}
.step.active {
display: block;
}
</style>
</head>
<body>
<form method="post">
{{ form.csrf_token }}
{% for subform in form.passengers -%}
<div class="step {%if loop.first %}active{% endif %}" id="step-{{loop.index0}}">
{% for field in subform -%}
<div>
{{ field.label() }}
{{ field() }}
{% if field.errors -%}
<ul>
{% for error in field.errors -%}
<li>{{ error }}</li>
{% endfor -%}
</ul>
{% endif -%}
</div>
{% endfor -%}
{%if not loop.first %}
<button type="button" class="btn-prev">Prev</button>
{% endif %}
{%if not loop.last %}
<button type="button" class="btn-next">Next</button>
{% else %}
{{ form.submit() }}
{% endif %}
</div>
{% endfor -%}
</form>
<script type="text/javascript">
(function() {
let step = 0;
const btns_next = document.querySelectorAll('.btn-next');
btns_next.forEach(btn => {
btn.addEventListener('click', evt => {
[`step-${step}`, `step-${++step}`].forEach(sel => {
const elem = document.getElementById(sel);
elem && elem.classList.toggle('active');
});
});
});
const btns_prev = document.querySelectorAll('.btn-prev');
btns_prev.forEach(btn => {
btn.addEventListener('click', function(evt) {
[`step-${step}`, `step-${--step}`].forEach(sel => {
const elem = document.getElementById(sel);
elem && elem.classList.toggle('active');
});
});
});
})();
</script>
</body>
</html>
How can I put the first value of the list in function make progress(i)? list is the value returned from flask!!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Changing the Value of Bootstrap 4 Progress Bar Dynamically</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/js/bootstrap.bundle.min.js"></script>
<style>
.bs-example{
margin: 20px;
}
</style>
</head>
<body>
<div class="bs-example">
<!-- Progress bar HTML -->
<div class="progress">
{{rist}}
<div class="progress-bar progress-bar-striped" style="min-width: 20px;"></div>
</div>
<form action="/list" method="POST">
<input type="hidden" name="ID" value="">
<input type="hidden" name="path" value="{{path}}">
</form>
<!-- jQuery Script -->
<script>
var i = rist;
function makeProgress(){
if(i < 100){
i = i + 1;
$(".progress-bar").css("width", i + "%").text(i + " %");
setTimeout("makeProgress()", 100);
}
// Wait for sometime before running this script again
else { document.forms[0].submit(); }
$.ajax({
type:'post',
async:'true',
url:'http://127.0.0.1:5000/ ',
data:{rist},
dataType: 'json',
success: function(data){rist
}
});
};
</script>
</div>
</body>
</html>
this is print(rist) // .py
list = [(h, e, dictionary[e]) for h, e in zip(category_name, category_id)]
x = []
for j in list:
x.append(j)
rist = str(100*(len(x) / len(list)))
print(rist)
1.1235955056179776
2.247191011235955
3.3707865168539324
4.49438202247191
5.617977528089887
6.741573033707865
7.865168539325842
8.98876404494382
10.112359550561797
11.235955056179774
12.359550561797752
13.48314606741573
14.606741573033707
15.730337078651685
16.853932584269664
17.97752808988764
19.101123595505616
20.224719101123593
21.34831460674157
22.47191011235955
23.595505617977526
24.719101123595504
25.842696629213485
26.96629213483146
28.08988764044944
29.213483146067414
30.337078651685395
31.46067415730337
32.58426966292135
33.70786516853933
34.831460674157306
35.95505617977528
37.07865168539326
38.20224719101123
39.325842696629216
40.44943820224719
41.57303370786517
42.69662921348314
43.82022471910113
44.9438202247191
46.06741573033708
47.19101123595505
48.31460674157304
49.43820224719101
50.56179775280899
51.68539325842697
52.80898876404494
53.93258426966292
55.0561797752809
56.17977528089888
57.30337078651685
58.42696629213483
59.55056179775281
60.67415730337079
61.79775280898876
62.92134831460674
64.04494382022472
65.1685393258427
66.29213483146067
67.41573033707866
68.53932584269663
69.66292134831461
70.78651685393258
71.91011235955057
73.03370786516854
74.15730337078652
75.28089887640449
76.40449438202246
77.52808988764045
78.65168539325843
79.7752808988764
80.89887640449437
82.02247191011236
83.14606741573034
84.26966292134831
85.39325842696628
86.51685393258427
87.64044943820225
88.76404494382022
89.8876404494382
91.01123595505618
92.13483146067416
93.25842696629213
94.3820224719101
95.50561797752809
96.62921348314607
97.75280898876404
98.87640449438202
100.0
and it is my flask code
from flask import Flask, render_template, request
from maratang import search
app = Flask(__name__)
#app.route('/')
def test():
return render_template('post.html')
#app.route('/progress', methods=['POST', 'GET'])
def loding():
global result, path, list, error
if request.method == 'POST':
result = request.form
path = request.form['path']
list, error, rist = search(path)
return render_template('progress.html', rist = rist)
#app.route('/list', methods=['POST'])
def post():
if request.method == 'POST':
print(list)
return render_template("result.html", result = result, list = list, error = error)
if __name__ == '__main__':
app.run()
I thought it was right, but there was an error, so I don't know what to do.
I am using full calendar in my in my Django project and I was wondering how I would get the model data to load as an event within the calendar. The issue is whenever I try to load the template into my code it loads up a white page with text in JSON format.
I was wondering if it was possible to get by this.
This is how my model looks like:
class CalenderEvent(models.Model):
event_name = models.CharField(max_length = 30)
start_date = models.DateTimeField(null=True,blank=True)
end_date = models.DateTimeField(null=True,blank=True)
event_description = models.TextField()
def __str__(self):
return self.event_name
This is how my view looks like:
def calender(request):
events = CalenderEvent.objects.all()
if request.method == 'GET':
form = ContactToAddEventForm()
event_arr = []
for i in events:
event_sub_arr = {}
event_sub_arr['title'] = i.event_name
start_date = datetime.datetime.strptime(str(i.start_date.date()), "%Y-%m-%d").strftime("%Y-%m-%d")
end_date = datetime.datetime.strptime(str(i.end_date.date()), "%Y-%m-%d").strftime("%Y-%m-%d")
event_sub_arr['start'] = start_date
event_sub_arr['end'] = end_date
event_arr.append(event_sub_arr)
return HttpResponse(json.dumps(event_arr))
context = {
"events" : events
}
return render(request, 'calender.htm', {'form': form}, context)
This is how my template looks like:
<link rel="stylesheet" href="{% static "fullcalender/daygrid/main.css" %}" >
<link rel="stylesheet" href="{% static "fullcalender/timegrid/main.css" %}" >
<link rel="stylesheet" href="{% static "fullcalender/core/main.css" %}" >
<script rel="stylesheet" href="{% static "fullcalender/core/main.js" %}" ></script>
<script src="{% static "fullcalender/core/main.js" %}"></script>
<script src="{% static "fullcalender/daygrid/main.js" %}"></script>
<script src="{% static "fullcalender/timegrid/main.js" %}"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: [ 'timeGrid' ],
defaultView: 'timeGridWeek',
events: [
{% for i in events %}
{
title: "{{ i.event_name}}",
start: '{{ i.start_date|date:"Y-m-d" }}',
end: '{{ i.end_date|date:"Y-m-d" }}',
},
{% endfor %}
]
});
calendar.render();
});
</script>
<section>
<div class="container">
<div id = "calendar"></div>
</div>
</section>
I was looking at this stack overflow answer:
FullCalendar in Django
I am using django to create a webpage and this is the first time I am doing so. I am trying to fetch the value of a variable from .py file at an interval of 5 seconds. Below is the HTML code:
<!DOCTYPE html>
<html>
<head>
<title>Like Post App</title>
<script
src="https://code.jquery.com/jquery-3.4.1.js"
integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
<div class = "display-3 color-red"><center>DataFlair AJAX Tutorial<br>Post APP</center></div>
{% for post in posts %}
<div class = 'container jumbotron'>
<h3 class="display-5">{{ forloop.counter }}. {{ post.post_heading }}</h3>
<p class="lead">{{ post.post_text }} </p>
<p>
<div type="text/css" class = "container">Author : {{ post.post_author }}</div>
<a class="likebutton btn btn-primary btn-lg" id="like{{ post.id }}" data-catid="{{ post.id }}">Like({{ post.like_ref.counter }})</a> </p> <p id="message{{post.id}}">
</p>
</div>
{% endfor %}
<script type="text/javascript">
setInterval(function() {
getvalue(); // Do something every 5 seconds
}, 5000);
getvalue();
function getvalue(){
var id;
id = $(this).attr("data-catid");
$.ajax(
{
type:"GET",
url: "like",
data:{
post_id: id
},
success: function( data )
{
$( '#like'+ id ).text("Like(" + data +")");
var i=parseInt(data);
console.log("Value= "+i);
}
}
)
}
</script>
</body>
</html>
Below is the views.py code:
import json
from django.shortcuts import render
from .models import Post, Like
from django.http import HttpResponse
# Create your views here.
#DataFlair #AJAX_tutorial
def index(request):
posts = Post.objects.all()
return render(request, 'post/index.html', { 'posts': posts })
def like(request):
if request.method == 'GET':
post_id = request.GET['post_id']
likedpost = Post.objects.get(id = post_id )
m = Like.objects.filter( post=likedpost ).first()
m.counter +=1
m.save()
value1= int(m.counter)
#data1= {'cmd': 'success', 'ctr': str(m.counter) }
return HttpResponse(value1)
#return HttpResponse(json.dumps(data1))
else:
return HttpResponse("unsuccesful")
I keep getting the following errors:
1) GET http://localhost:8000/ajax/like/ 500 (Internal Server Error)
2) GET http://localhost:8000/favicon.ico 404 (Not Found)
Please help.
I believe:
id = $(this).attr("data-catid");
is not pointing to the button... maybe you should try:
id = $(".likebutton").attr("data-catid");
My Flask app does calculations based on user form inputs. These calculation take about 10 seconds to complete. The output of those calculations need to be displayed in a div on the same page, next to the form (in a chart / table etc).
I have tried two aproaches. The first, using normal just Flask, reloads the whole page, which is far from ideal. The second approach, using Sijax, updates just the div. But in this case, i don't know how to access the form inputs.
I'm confused how to get this working. Would appreciate any directions!
Approach 1: just flask (downside: whole page reloads)
form_test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Testpage</title>
</head>
<body>
<form action="{{ url_for('do_the_math') }}" method="post">
A = <input type="number" name="input_A">
B = <input type="number" name="input_B">
<input type="submit" value="Submit">
</form>
<div id="destination_div">A + B = {{ result }}</div>
</body>
</html>
app_normal.py:
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route("/")
def show_home():
return render_template("form_test.html", result='unknown yet')
#app.route("/do_the_math", methods=['POST'])
def do_the_math():
A = request.form.get('input_A')
B = request.form.get('input_B')
sum = float(A) + float(B)
# reloads whole page
return render_template("form_test.html", result=sum)
# what i want: reload just update destination_div with new HTML
# return render_template("#destination_div", "A + B = " + str(sum))
if __name__ == '__main__':
app.run(debug=True)
Approach 2: use Sijax (updates div, but how to access form inputs?)
form_test_sijax.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Testpage with sijax</title>
<script type="text/javascript" src="/static/js/sijax/sijax.js"></script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
</head>
<body>
<form method="post">
A = <input type="number" name="input_A">
B = <input type="number" name="input_B">
<button type="button" onclick="Sijax.request('submit_form');">calc</button>
</form>
<div id="destination_div">A + B = unknown</div>
</body>
</html>
app_sijax.py
from flask import Flask, render_template, g
import flask_sijax
import os
app = Flask(__name__)
# init sijax
app.config["SIJAX_STATIC_PATH"] = os.path.join('.', os.path.dirname(__file__), 'static/js/sijax/')
app.config["SIJAX_JSON_URI"] = '/static/js/sijax/json2.js'
flask_sijax.Sijax(app)
def submit_form_handler(obj_response):
A = 5 # how do get to the values entered in the form?
B = 3
sum = A + B
obj_response.html("#destination_div", "A + B = " + str(sum))
#flask_sijax.route(app, "/")
def show_home():
result = 'unknown'
if g.sijax.is_sijax_request:
g.sijax.register_callback('submit_form', submit_form_handler)
return g.sijax.process_request()
return render_template("form_test_sijax.html")
if __name__ == '__main__':
app.run(debug=True)
You can use ajax with jquery to dynamically update the page with the computed result without having to refresh the page:
In the html file:
<html>
<header>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</header>
<body>
<div class='wrapper'>
A = <input type="number" id="input_A">
B = <input type="number" id="input_B">
<button class='get_result'>Calculate</button>
<div class='result'></div>
</div>
</body>
<script>
$(document).ready(function(){
$('.wrapper').on('click', '.get_result', function(){
var val1 = $("#input_A").val();
var val2 = $("#input_B").val();
$.ajax({
url: "/calculate_result",
type: "get",
data: {val1: val1, val2:val2},
success: function(response) {
$(".result").html('<p>'+response.result.toString()+'</p>');
},
});
});
});
</script>
</html>
Then, in the main app file, create the route to calculate the final result:
#app.route('/calculate_result')
def calculate_result():
a = int(flask.request.args.get('val1'))
b = int(flask.request.args.get('val2'))
return flask.jsonify({"result":a+b})