I have a HTML control panel with various buttons and sliders. All of the buttons are operational and when clicked send a post request which my Python app receives and then executes functions.
I cannot seem to get the slider controls to work, When I adjust the slider I get the following error:
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'button'
This is promising as at least I can see it trying to do something and failing, which is the best result achieved thus far. My javascript and AJAX knowledge is limited and I need a solution for the slider to POST request on any onchange value that python can then interpret.
I initially had the following HTML:
<input id="slider" type="range" min="0" max="100" value="50" onchange="updateVolume(getElementById('slider').value); return false;">
Javascript:
<script>
function updateVolume (vol) {
$.ajax({
method: "POST",
url: '{{ url_for('main.control_panel', video_id=video.id) }}',
data: { volume: vol}
})
.done(function( msg ) {
// optional callback stuff if needed
// alert( "Data Saved: " + msg );
});
}
</script>
This threw up the same error.
This is my current code that also throws the same error:
HTML:
<input id="slide" type="range" min="1" max="100" step="1" value="10" name="slide">
<div id="sliderAmount"></div>
Javascript:
var slide = document.getElementById('slide'),
sliderDiv = document.getElementById("sliderAmount");
slide.onchange = function() {
sliderDiv.innerHTML = this.value;
$.ajax({
url: '{{ url_for('main.control_panel', video_id=video.id) }}',
data: $('form').serialize(),
type: 'POST',
success: function(response){
console.log(response);
},
error: function(error){
console.log(error);
}
});
}
Python:
#main.route("/control_panel/<int:video_id>", methods=['GET', 'POST'])
def control_panel(video_id):
video = video.query.get_or_404(video_id)
if request.method == 'POST':
... #IF ELIF for various button functions here
volume = request.form['slider']
return json.dumps({'volume': volume})
return render_template('/control_panel.html', title=video.video, video=video)
Any support would be greatly appreciated as I'm struggling to find solutions on the web along with me aforementioned js/ajax knowledge.
Thanks
EDIT:
This is a recreation of the problem:
python:
from flask import Flask, request, redirect, url_for, render_template, json
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def control_panel():
if request.method == 'POST':
if request.form['button'] == 'button-play':
print("play button pressed")
elif request.form['button'] == 'button-exit':
print("exit button pressed")
elif request.form['slider']:
volume = request.form['slider']
return json.dumps({'volume': volume})
print(volume)
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
HTML:
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<title>Slider</title>
</head>
<body>
<div class="container" id="control_panel_1">
<form action="/" method ="post" enctype="multipart/form-data" id="form">
<div class="row">
<div class="col">
<button class="btn btn-primary" button type="submit" name="button" value="button-play">PLAY</button>
<button class="btn btn-primary" button type="submit" name="button" value="button-exit">EXIT</button>
<input id="slide" type="range" min="1" max="100" step="1" value="10" name="slide">
<div id="sliderAmount"></div>
</div>
</div>
</form>
<!--- SCRIPTS --->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</body>
<script>
var slide = document.getElementById('slide'),
sliderDiv = document.getElementById("sliderAmount");
slide.onchange = function() {
sliderDiv.innerHTML = this.value;
$.ajax({
url: '/index.html',
data: $('form').serialize(),
type: 'POST',
success: function(response){
console.log(response);
},
error: function(error){
console.log(error);
}
});
}
</script>
</html>
Problem is because $('form').serialize() sends only values from <input> but not from <button> but in Flask you check request.form['button'] and it raises error because key button doesn't exists in dictionary request.form.
You have to use
request.form.get('button')
and then it returns None when button doesn't exists in dictionary
BTW:
you have only #app.route("/", ...) so AJAX has to send to /, not to
/index.html
using print(volume) after return ... is useless becuse return ends function
in Flask you can use return jsonify(dict) instead of return json.dumps(dict) and then it sends special headers and JavaScript converts it to object and you can get response.volume. Using json.dumps(dict) it sends it as html/text and you would have to use JSON.parse(response).volume
Working code in one file (using template_render_string instead of template_render) so everyone can easily test it.
from flask import Flask, request, redirect, url_for, render_template, json, render_template_string, jsonify
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def control_panel():
print('request.form:', request.form)
if request.method == 'POST':
if request.form.get('button') == 'button-play':
print("play button pressed")
elif request.form.get('button') == 'button-exit':
print("exit button pressed")
elif request.form.get('slide'):
volume = request.form.get('slide')
print('volume:', volume)
#return jsonify({'volume': volume})
return json.dumps({'volume': volume})
print('render')
return render_template_string('''<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<title>Slider</title>
</head>
<body>
<div class="container" id="control_panel_1">
<form action="/" method ="post" enctype="multipart/form-data" id="form">
<div class="row">
<div class="col">
<button class="btn btn-primary" button type="submit" name="button" value="button-play">PLAY</button>
<button class="btn btn-primary" button type="submit" name="button" value="button-exit">EXIT</button>
<input id="slide" type="range" min="1" max="100" step="1" value="10" name="slide">
<div id="sliderAmount"></div>
</div>
</div>
</form>
<!--- SCRIPTS --->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</body>
<script>
var slide = document.getElementById('slide'),
sliderDiv = document.getElementById("sliderAmount");
slide.onchange = function() {
sliderDiv.innerHTML = this.value;
$.post({
url: '/',
data: $('form').serialize(),
success: function(response){
alert(response);
alert(response.volume); // works with jsonify()
alert(JSON.parse(response).volume); // works with json.dumps()
console.log(response);
},
error: function(error){
alert(response);
console.log(error);
}
});
}
</script>
</html>''')
if __name__ == '__main__':
app.run(debug=True, use_reloader=False)
Related
The following code allows you to submit forms and return a variation of the text from Flask using AJAX and JQuery:
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
#app.route('/')
def index():
return render_template('form.html')
#app.route('/process', methods=['POST'])
def process():
email = request.form['email']
name = request.form['name']
if name and email:
newName = name[::-1]
return jsonify({'name' : newName})
return jsonify({'error' : 'Missing data!'})
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html>
<head>
<title>AJAX Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
<script src="{{ url_for('static', filename='js/form.js') }}"></script>
</head>
<body>
<div class="container">
<br><br><br><br>
<form class="form-inline">
<div class="form-group">
<label class="sr-only" for="emailInput">Email address</label>
<input type="email" class="form-control" id="emailInput" placeholder="Email">
</div>
<div class="form-group">
<label class="sr-only" for="nameInput">Name</label>
<input type="text" class="form-control" id="nameInput" placeholder="First Name">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<br>
<div id="successAlert" class="alert alert-success" role="alert" style="display:none;"></div>
<div id="errorAlert" class="alert alert-danger" role="alert" style="display:none;"></div>
</div>
</body>
</html>
$(document).ready(function() {
$('form').on('submit', function(event) {
$.ajax({
data : {
name : $('#nameInput').val(),
email : $('#emailInput').val()
},
type : 'POST',
url : '/process'
})
.done(function(data) {
if (data.error) {
$('#errorAlert').text(data.error).show();
$('#successAlert').hide();
}
else {
$('#successAlert').text(data.name).show();
$('#errorAlert').hide();
}
});
event.preventDefault();
});
});
But when I slightly modify the code to do the same thing with a uploaded file's name it doesn't work. All I have done is changed the type of form so that it takes in files and then made it so that it reverses the filename rather than the inputted text from the previous version. Do you know what I am doing wrong here?
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
#app.route('/')
def index():
return render_template('form.html')
#app.route('/process', methods=['POST'])
def process():
filename = request.files['file'].filename
if filename:
newName = filename[::-1]
return jsonify({'name' : newName})
return jsonify({'error' : 'Missing data!'})
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html>
<head>
<title>AJAX Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
<script src="{{ url_for('static', filename='js/form.js') }}"></script>
</head>
<body>
<div class="container">
<br><br><br><br>
<form method="POST" action='/process' enctype="multipart/form-data">
<div>
<label for="file">Choose file to upload</label>
<input type="file" id="file" name="file">
</div>
<div>
<button type="submit" class="btn btn-default">Submit</button>
</div>
</form>
<br>
<div id="successAlert" class="alert alert-success" role="alert" style="display:none;"></div>
<div id="errorAlert" class="alert alert-danger" role="alert" style="display:none;"></div>
</div>
</body>
</html>
$(document).ready(function() {
$('form').on('submit', function(event) {
$.ajax({
data : {
file : $('#file')
},
type : 'POST',
url : '/process'
})
.done(function(data) {
if (data.error) {
$('#errorAlert').text(data.error).show();
$('#successAlert').hide();
}
else {
$('#successAlert').text(data.name).show();
$('#errorAlert').hide();
}
});
event.preventDefault();
});
});
If you use an object of the type FormData to serialize and transfer the data of the form it should work.
$(document).ready(function() {
$('form').submit(function(event) {
let formData = new FormData(event.target);
$.ajax({
data: formData,
type : 'POST',
url : '/process',
contentType: false,
processData: false
})
.done(function(data) {
if (data.error) {
$('#errorAlert').text(data.error).show();
$('#successAlert').hide();
} else {
$('#successAlert').text(data.name).show();
$('#errorAlert').hide();
}
});
event.preventDefault();
});
});
I'm working on a standalone application and I'm trying to pass a string which is an output of change event, to the spring controller using the code below
HTML CODE
<!DOCTYPE HTML>
<html xmnls:th="http://www.thymeleaf.org">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<title>ADD NEW BILL</title>
<!-- jquery -->
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script type="text/javascript">
$(function() {
$("#Mandy_Name").autocomplete({
source: "autocomplete",
minLength: 3
});
});
</script>
<script type="text/javascript">
$(document).ready(function(){
$("#Mandy_Name").change(function(){
var changed = $(this).val();
console.log(changed);
$.ajax({
type : "POST",
dataType : 'json',
url : "mandyname",
data: {name:changed},
success: function(data) {
console.log(data);
return false;
}
});
});
});
</script>
</head>
<body>
<div class="container">
<hr>
<p class="h4 mb-4">SAVE NEW PURCHASE BILL</p>
<form action="#" th:action="#{/savePurchase}"
th:object="${purchase}" method="post">
<!-- add a hidden field to handle update -->
<!-- <input type="hidden" th:field="*{idPurchaseDetails}"> -->
<input type="hidden" th:field="*{ID}">
MANDY NAME : <input id="Mandy_Name" type="text" th:field="*{mandyName}"
class="form-control mb-4 col-4" placeholder="Mandy Name">
GSTIN : <input type="text" th:field="*{gstin}"
class="form-control mb-4 col-4" value = gst() placeholder="GSTIN">
<button type="submit" class="btn btn-info col-2">SAVE</button>
</form>
<br><br>
<a th:href="#{/purchaselist}">BACK TO PURCHASE LIST</a>
</div>
</body>
</html>
controller code
#RequestMapping(value = "mandyName", method = RequestMethod.POST)
public ModelAndView getSearchResultViaAjax(#RequestBody Purchase purchase, HttpServletRequest request,
HttpServletResponse response)
{
ModelAndView mv = new ModelAndView();
String name = purchase.getMandyName();
System.out.println(name);
return mv;
}
I'm getting an error "Failed to load resource: the server responded with a status of 404 ()" in the browser console.
Help me to pass the string "changed" to the controller.
I'm using these dependencies
jquery from "org.webjars" ,
spring-boot-starter-actuator ,
spring-boot-starter-data-jpa ,
spring-boot-starter-web ,
spring-boot-starter-data-rest ,
spring-boot-starter-thymeleaf ,
spring-boot-devtools ,
spring-boot-starter-json ,
mysql-connector-java ,
spring-boot-starter-test ,
junit-vintage-engine ,
spring-boot-maven-plugin
Should I be using any other dependencies ??
The HTTP Status 404 means that the URL provided, cannot be found on the server.
I see that you make the Ajax call with an incorrect URL. Change it to the correct one depending on your Spring App and port.
Normally it should be under: http://localhost:8080/mandyName. But this you have to check and examine.
Sample JS code:
$(document).ready(function(){
$("#Mandy_Name").change(function(){
var changed = $(this).val();
console.log(changed);
$.ajax({
type : "POST",
dataType : 'json',
url : "http://localhost:8080/mandyName", // ~~ HERE ~~
data: {name:changed},
success: function(data) {
console.log(data);
return false;
}
});
});
});
The below code seems to work correctly. The post goes through and I even see a GET message on the console for the page I am redirecting to. But my browser doesn't switch to the new page saying "Hello". If I browse to /PostTest directly then it works.
I get the "Welcome" message too.
</script>
<!DOCTYPE html>
<head>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<html>
<body>
<div class="row"></div>
Any Day Drinking Club's Six Nations Table Generator
<div class="row">
<div class="input-field col s6 offset-m2 offset-l4 m4 l2">
<input placeholder="Username" id="username" type="text" />
</div>
<div class="input-field col s6 m4 l2">
<input placeholder="Password" id="password" type="password" />
</div>
</div>
<div class="row">
<a class="waves-effect waves-light btn" id="loginbutton">Login</a>
</div>
<script>$("#loginbutton").click(function(){
$.ajax({
type: 'POST',
url: "/loginsubmit",
success: function(){
alert("Welcome ");
}
}
)
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script></body>
</html>
from flask import Flask, request, redirect, url_for
import yaTemplates as Templates
app = Flask(__name__)
#app.route('/')
def index():
return Templates.login()
#app.route('/PostTest')
def test():
return 'Hello'
#app.route("/loginsubmit", methods=["POST"])
def loginsubmit():
# + request.json["username"]
return redirect(url_for('test'))
app.run(debug=True)
This is because you are using AJAX.. You are programmatically sending a request via the browser, behind the scenes, that is separate and unrelated to what you see on the screen.
In Flask, you'll need to respond with the URL to redirect to. On the client side, you'll need to set the window.location to that URL.
EDIT: as a little demo, you can open up your browsers Developer Tools (right click any webpage, select "Inspect Element"), then select the "Console" tab, and type window.location = "https://google.com" then press enter, and your browser will then change the URL and browse to Google.
from flask import Flask, request, redirect, url_for
import yaTemplates as Templates
app = Flask(__name__)
#app.route('/')
def index():
return Templates.login()
#app.route('/PostTest')
def test():
return 'Hello'
#app.route("/loginsubmit", methods=["POST"])
def loginsubmit():
# + request.json["username"]
return url_for('test')
app.run(debug=True)
Client side:
<script>
$("#loginbutton").click(function () {
$.ajax({
type: 'POST',
url: "/loginsubmit",
success: function (url) {
window.location = url;
}
})
});
</script>
I have a college assignment in which I need to create a small chatting web site. I'm using Python for the back-end code and Flask as the framework.
Basically, I want to get the user input from the front-end, run it with a Python code I developed, and send it back as an answer. How would be the easiest way to do that?
I've read a lot about jQuery and AJAX, but I'm very bad at JS. Any tips?
What I need is to,after processing this string, send to the site whatever was processed. I tried to follow this post How do I send data from JS to Python with Flask? and it worked for my POST, but not my GET. It always returns as undefined. I tried changing to dict, trying to make different calls, but I can't find what will work specifically with what I actually need. Thanks!
EDIT!:
After trying out #arsho 's code, I got kind of lost. It works and I saw how it was implemented, but couldn't exactly make it work with what I have.
This is what I came up with:
test
https://pastebin.com/4i2hDRSJ
Sorry if I'm not being very clear. I translated the variable names for easier understanding.
Pastebin with the html my friend made me:
test
https://pastebin.com/m7FQCgAm
Scripts.js:
test
https://pastebin.com/pM1L77p7
Thanks again.
I am giving a head start for your project. I am giving a simple AJAX search example using Flask.
The application.py contains:
from flask import Flask, render_template, request, url_for, redirect
app = Flask(__name__)
#app.route('/show_search_result', methods=['GET','POST'])
def show_search_result():
if request.method == "POST":
word = request.form.get("word")
word_lower = word.lower()
data = {
"name" : "Ahmedur Rahman Shovon",
"country": "Bangladesh",
"gender": "Male"
}
if word_lower in data:
value = data[word_lower]
return value
else:
return "No data found"
else:
return redirect(url_for('show_index'))
#app.route('/')
#app.route('/index')
def show_index():
return render_template("ajax.html")
if __name__ == '__main__':
app.run(debug=True)
And in ajax.html we call the ajax requests like below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="author" content="Ahmedur Rahman Shovon">
<title>Ajax Example</title>
<link href="https://fonts.googleapis.com/css?family=Exo+2:400,400i,500,500i,600,600i,700,700i,800,800i,900,900i"
rel="stylesheet">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
<!-- Font Awesome CSS -->
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-10">
<div class="card bg-light mb-3 content">
<h5 class="card-header">
<i class="fa fa-globe"></i>
Search Developer's Information (e.g.: name, country, gender etc.)
</h5>
<div class="card-body message_area" id="message_area">
</div>
<div class="card-footer">
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-book"></i>
</span>
<input type="text" class="form-control" id="search_word_text"
placeholder="Search a word and press enter"/>
<span class="input-group-btn">
<button class="btn btn-dark" id="search_btn" type="button">
<i class="fa fa-search"></i> Search
</button>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- jQuery -->
<script
src="https://code.jquery.com/jquery-1.12.4.min.js"
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<!-- Bootstrap -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
<script type="text/javascript">
$(document).ready(function () {
function create_message_div($original_word, $ajax_data){
$html_data = "<div><p><b>Search Term: </b><i>"+$original_word+"</i></p>";
$html_data += "<p><b>Result: </b><i>"+$ajax_data+"</i></p>";
$html_data += "<hr/></div>";
return $html_data;
}
function search_word(){
$search_word_value = $("#search_word_text").val();
$("#search_word_text").val("");
$.ajax({
url: '{{ url_for("show_search_result") }}',
data: {
"word" : $search_word_value,
},
type: 'POST',
success: function(response) {
$new_div = create_message_div($search_word_value, response);
$("#message_area").prepend($new_div);
},
error: function(error) {
console.log("Error");
}
});
}
$("#search_btn").on("click", function () {
search_word();
});
$('#search_word_text').on('keypress', function (e) {
if(e.which === 13){
search_word();
}
});
})
</script>
</body>
</html>
The output:
N.B.: I have posted the full working code to show a complete view how AJAX works with Flask. Modify it as per your requirement.
I am newer on developing flask-python based applications and got stuck in some point. The problem is that I cannot retrieve data from mysql.
First of all, let me share my some files' contents, at least some parts of them. For html, I am using bootstrap.
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="../static/css/search-bar.css">
<script type=text/javascript src="{{ url_for('static', filename='js/jquery-1.11.2.js') }}"></script>
<script type=text/javascript src="{{ url_for('static', filename='js/wordQuery.js') }}"></script>
</head>
<body>
<div class="jumbotron">
<h1>Search</h1>
<div class="container">
<div class="row">
<div id="custom-search-input">
<div class="input-group col-md-12">
<input type="text" id="wordInput" class="form-control input-lg" placeholder="Please type the word you want to search" />
<span class="input-group-btn">
<button class="btn btn-info btn-lg" type="button" id="btnWordSearch">
<i class="glyphicon glyphicon-search"></i>
</button>
</span>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
app.py:
from flask import Flask, render_template, json, jsonify, request
from flaskext.mysql import MySQL
from werkzeug import generate_password_hash, check_password_hash
mysql = MySQL()
app = Flask(__name__)
# MySQL configurations
app.config['MYSQL_DATABASE_USER'] = 'USER_NAME'
app.config['MYSQL_DATABASE_PASSWORD'] = 'PASSWORD'
app.config['MYSQL_DATABASE_DB'] = 'DATABASE_NAME'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)
#app.route('/')
def main():
return render_template('index.html')
#app.route('/wordQuery', methods=['POST', 'GET'])
def checkWord():
word = request.form['wordInput']
success = "OK"
error = "NOK"
word = word.lower()
try:
with connection.cursor() as cursor:
# Read a single record
sql = "SELECT `word` FROM `allwords` \
WHERE `word` like %s"
cursor.execute(sql, (word + "%",))
result = cursor.fetchone()
if result is not None:
return json.dumps({'message': 'The word exists in the database !'})
else:
return json.dumps({'error': str(data[0])})
except Exception as e:
return json.dumps({'error': str(e)})
finally:
cursor.close()
conn.close()
if __name__ == "__main__":
app.run(debug=True, port=5005)
wordQuery.js:
$(function(){
$('#btnWordSearch').click(function(){
$.ajax({
url: '/wordQuery',
data: $('form').serialize(),
type: 'POST',
success: function(response){
console.log(response);
},
error: function(error){
console.log(error);
}
});
});
});
I want to see that when a word is searched, it should be found on the database and browser console should write the message 'The word exists in the database !'. Later, I want to implement another html page which gives results.
Thank you in advance for your help!
UPDATE:
I was getting the below error when I first posted this problem here;
jquery-1.11.2.js:9659 POST 127.0.0.1:5005/wordQuery 400 (BAD REQUEST)
However, now I changed a part in my html file. There was an id element like this: id="wordInput" and I changed it like this: name="wordInput". After this change, I am getting a new error like this following;
jquery-1.11.2.js:9659 POST http://127.0.0.1:5005/wordQuery 500 (INTERNAL SERVER ERROR)
I don't see a form element in your HTML. You're probably POSTing empty data