Run queries execution in Jinja template - javascript

How can get db.execute("SELECT * FROM table ...") in this html?
app = Flask(__name__)
db_admin = SQL("sqlite:///administration.db")
#app.route("/settings", methods=["GET", "POST"])
def setting():
if request.method == "POST":
return render_template("settings.html")
I have a database and need in my template (settings.html) UPDATE table SET ... value in database whenonchange event happens in td.
<td onclick="query();">{{ cell }}</td>
I have try:
function query()
{
let sqlite3 = require('sqlite3');
let db = new sqlite3.Database('./administration.db');
row= db.execute("UPDATE table SET user_group=? WHERE ...", value);
}
Please assume the value is inpute text value.

I think your approach is getting a lot of traffic. I think it makes more sense to point out to the user that they left unsaved data. You could use a beforeunload event for this. However, this hits a limit when the user closes the window.
The code could look something like this.
<script type="text/javascript">
(function() {
window.addEventListener('DOMContentLoaded', () => {
let isChanged = false;
document.querySelectorAll('input').forEach(elem => {
elem.addEventListener('change', () => {
isChanged = true;
});
});
document.querySelector('form').addEventListener('submit', () => {
isChanged = false;
})
window.addEventListener('beforeunload', (evt) => {
if (isChanged) {
evt.returnValue = isChanged;
}
});
});
})();
</script>
It is still possible, as you have thought, to use AJAX to send the form data to the server in the background for each fired event.
#app.route('/settings', methods=['GET', 'POST'])
def settings():
if request.method == 'POST':
print(request.form)
# Update your database here.
return render_template('settings.html', **locals())
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Index</title>
</head>
<body>
<form method="post">
<input type="text" name="name" />
<button type="submit">Submit</button>
</form>
<script type="text/javascript">
// Call the function when available.
(function() {
// Wait for the document to load completely.
window.addEventListener('DOMContentLoaded', () => {
// Search for all input fields and iterate over them.
document.querySelectorAll('input').forEach(elem => {
// Register an EventListener for 'change' events for each input field.
elem.addEventListener('change', function() {
// Send the entire form to the server as soon as an event is fired.
fetch('/settings', {
method: 'post',
body: new FormData(this.form)
});
});
});
});
})();
</script>
</body>
</html>
If you only want to send the changed input and not the whole form, the code is easy to modify.
<script type="text/javascript">
(function() {
window.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('input').forEach(elem => {
elem.addEventListener('change', function() {
const formData = new FormData();
formData.append(this.name, this.value);
fetch('/settings', {
method: 'post',
body: formData
});
});
});
});
})();
</script>

Related

get parameter input from website, run python script and get output to server

I'd like to preface this by saying that I have ZERO javascript or flask knowledge.
Basically, I have made an html interface from which I am retrieving some user input. I would like to use this input as a parameter in a python function, run this function and then somehow retrieve the output of this function (which is a string btw) to display it on the website.
Here is my code (which obviously doesn't work):
python:
import get_response
app= Flask(__name__)
#app.route('/rep_bot',methods=['GET','POST'])
def bot_rep_py():
outputpy=get_response(request.data)
return render_template("output.html",output=outputpy)
the javascript function that I want to perform the sending and retrieving of information:
function bot_rep_js(input) {
$.post("http://127.0.0.1:5000/rep_bot", {
js_input:input
});
return console.log(data)
}
I have tried a few other things that didn't work anyway so I'm not gonna write them here so as not to hurt your eyes anymore.
If anyone would be so kind as to show and explain to me what I have to change in order for my code to behave the way I want it to I'd be very grateful.
$.post has option to assign function which will be executed when it get response. And inside this function you should get data and use it to (re)place it in HTML.
$.post("http://127.0.0.1:5000/rep_bot",
{js_input: input},
function(data){console.log(data);}
)
Minimal working example
$.post sends POST data with "Hi" to flask and flask sends back JSON data with answer "Hello World!" which $.post gets in assigned function and it puts this answer in <div>
I used render_template_string instead of render_template so all data are in one file and everyone can simply copy and run it.
from flask import Flask, request, render_template_string, jsonify
app= Flask(__name__)
def get_response(data):
print('data:', data) # "Hi"
return "Hello World!"
#app.route('/rep_bot', methods=['GET','POST'])
def bot_rep_py():
if request.method == 'POST':
input_text = request.form["js_input"]
print('input_text :', input_text)
output_text = get_response(input_text)
print('output_text:', output_text)
return jsonify({'answer': output_text})
else:
return "???"
#app.route('/')
def index():
return render_template_string('''
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<button>Send "Hi"</button>
<div id="answer"></div>
<script>
$(function(){
console.log("ready 1");
function bot_rep_js(input) {
console.log(input)
$.post("http://127.0.0.1:5000/rep_bot",
{js_input: "Hi"},
function(data){
console.log(data);
$("#answer").text(data.answer);
},
);
}
$("button").click(bot_rep_js);
console.log("ready 2");
});
</script>
</body>
</html>
''')
if __name__ == '__main__':
app.run(debug=True)#, use_reloader=False)
EDIT:
The same without jQuery using standard fetch() and .then() to execute function when it gets response from server.
from flask import Flask, request, render_template_string, jsonify
app= Flask(__name__)
def get_response(data):
print('data:', data) # "Hi"
return "Hello World!"
#app.route('/rep_bot', methods=['GET','POST'])
def bot_rep_py():
if request.method == 'POST':
input_text = request.form["js_input"]
print('input_text :', input_text)
output_text = get_response(input_text)
print('output_text:', output_text)
return jsonify({'answer': output_text})
else:
return "???"
#app.route('/')
def index():
return render_template_string('''
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
// function `bot_rep_js` has to be before `onclick="bot_rep_js()"`
console.log("ready 1");
function bot_rep_js(input) {
console.log("input: " + input)
// create form and add file
var formdata = new FormData();
formdata.append("js_input", "Hi");
// create AJAX connection
fetch("http://127.0.0.1:5000/rep_bot", {
method: 'POST',
body: formdata,
//headers: {"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"} // makes only problem
}).then(function(response) {
return response.json(); // get JSON from response
}).then(function(data) {
console.log(data);
document.querySelector("#answer").innerText = data.answer;
}).catch(function(err) {
console.log("Fetch problem: " + err.message);
});
}
console.log("ready 2");
</script>
<button onclick="bot_rep_js()">Send "Hi"</button>
<div id="answer"></div>
</body>
</html>
''')
if __name__ == '__main__':
app.run(debug=True)#, use_reloader=False)
fetch() could send data as JSON but I send as FORM to make it similar to previous code.

Why is this HTML code typed in URL bar as 'data:text/html' not working?

I have this html code (below), which works perfectly as a hosted file (meaning the code is working) -
<!DOCTYPE html>
<html>
<head>
<title>Read Text File</title>
<!--<script src="https://thunkable.github.io/webviewer-extension/thunkableWebviewerExtension.js" type="text/javascript"></script>-->
<script>
var ThunkableWebviewerExtension = (function () {
const postMessageToWebview = (message) => {
if (window.ReactNativeWebView) {
window.ReactNativeWebView.postMessage(message);
} else {
window.parent.postMessage(message, '*');
}
};
const getReceiveMessageCallback = (fxn, hasReturnValue) => (event) => {
if (typeof fxn === 'function') {
if (event.data) {
let dataObject;
try {
dataObject = JSON.parse(event.data);
} catch (e) {
// message is not valid json
}
if (dataObject && dataObject.type === 'ThunkablePostMessage' && hasReturnValue) {
fxn(dataObject.message, (returnValue) => {
const returnMessageObject = { type: 'ThunkablePostMessageReturnValue', uuid: dataObject.uuid, returnValue };
postMessageToWebview(JSON.stringify(returnMessageObject));
});
} else if (!hasReturnValue && (!dataObject || dataObject.type !== 'ThunkablePostMessage')) {
fxn(event.data);
}
}
}
};
return {
postMessage: postMessageToWebview,
receiveMessage: function(fxn) {
const callbackFunction = getReceiveMessageCallback(fxn, false);
document.addEventListener('message', callbackFunction, false);
window.addEventListener('message', callbackFunction, false);
},
receiveMessageWithReturnValue: function(fxn) {
const callbackFunction = getReceiveMessageCallback(fxn, true);
document.addEventListener('message', callbackFunction, false);
window.addEventListener('message', callbackFunction, false);
},
};
})();
</script>
</head>
<body>
<input type="file" name="inputfile" id="inputfile">
<br>
<pre id="output"></pre>
<script type="text/javascript">
document.getElementById('inputfile')
.addEventListener('change', function() {
var fr=new FileReader();
fr.onload=function(){
//document.getElementById('output').textContent=fr.result;
var msg = fr.result;
ThunkableWebviewerExtension.postMessage(msg);
}
fr.readAsText(this.files[0]);
})
</script>
</body>
</html>
What I want to do is, turn this whole code into a long URL, and I found that by using 'data:text/html,<meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>' at the start, then adding the code.
So the HTML url would become something like - 'data:text/html,<meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"/><!DOCTYPE html><html><head> ...'
I can see the file upload button, and even can select and upload a file. But, the script parts are not working - I am unable to catch the error here 😪
Kindly guide/advice me here... Thanks!
After experimenting a little bit, I think the problem might be that you haven't url-encoded it. Try using this instead of just pasting in the whole thing directly
(or copy it from here)
data:text/html,%3C!DOCTYPE%20html%3E%0A%3Chtml%3E%0A%3Chead%3E%0A%20%20%20%20%3Ctitle%3ERead%20Text%20File%3C/title%3E%0A%20%20%20%20%3C!--%3Cscript%20src=%22https://thunkable.github.io/webviewer-extension/thunkableWebviewerExtension.js%22%20type=%22text/javascript%22%3E%3C/script%3E--%3E%0A%20%20%20%20%3Cscript%3E%0A%20%20%20%20var%20ThunkableWebviewerExtension%20=%20(function%20()%20%7B%0A%20%20%20%20%20%20const%20postMessageToWebview%20=%20(message)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20if%20(window.ReactNativeWebView)%20%7B%0A%20%20%20%20%20%20%20%20%20%20window.ReactNativeWebView.postMessage(message);%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20window.parent.postMessage(message,%20'*');%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D;%0A%20%20%20%20%0A%20%20%20%20%20%20const%20getReceiveMessageCallback%20=%20(fxn,%20hasReturnValue)%20=%3E%20(event)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20if%20(typeof%20fxn%20===%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20if%20(event.data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20dataObject;%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20dataObject%20=%20JSON.parse(event.data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20message%20is%20not%20valid%20json%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(dataObject%20&&%20dataObject.type%20===%20'ThunkablePostMessage'%20&&%20hasReturnValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20fxn(dataObject.message,%20(returnValue)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20returnMessageObject%20=%20%7B%20type:%20'ThunkablePostMessageReturnValue',%20uuid:%20dataObject.uuid,%20returnValue%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20postMessageToWebview(JSON.stringify(returnMessageObject));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(!hasReturnValue%20&&%20(!dataObject%20%7C%7C%20dataObject.type%20!==%20'ThunkablePostMessage'))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20fxn(event.data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D;%0A%20%20%20%20%0A%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20postMessage:%20postMessageToWebview,%0A%20%20%20%20%20%20%20%20receiveMessage:%20function(fxn)%20%7B%0A%20%20%20%20%20%20%20%20%20%20const%20callbackFunction%20=%20getReceiveMessageCallback(fxn,%20false);%0A%20%20%20%20%20%20%20%20%20%20document.addEventListener('message',%20callbackFunction,%20false);%0A%20%20%20%20%20%20%20%20%20%20window.addEventListener('message',%20callbackFunction,%20false);%0A%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20receiveMessageWithReturnValue:%20function(fxn)%20%7B%0A%20%20%20%20%20%20%20%20%20%20const%20callbackFunction%20=%20getReceiveMessageCallback(fxn,%20true);%0A%20%20%20%20%20%20%20%20%20%20document.addEventListener('message',%20callbackFunction,%20false);%0A%20%20%20%20%20%20%20%20%20%20window.addEventListener('message',%20callbackFunction,%20false);%0A%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%7D;%0A%20%20%20%20%7D)();%0A%20%20%20%20%3C/script%3E%0A%3C/head%3E%0A%0A%3Cbody%3E%0A%20%20%20%20%3Cinput%20type=%22file%22%20name=%22inputfile%22%20id=%22inputfile%22%3E%0A%20%20%20%20%3Cbr%3E%0A%0A%20%20%20%20%3Cpre%20id=%22output%22%3E%3C/pre%3E%0A%20%20%20%20%0A%20%20%20%20%3Cscript%20type=%22text/javascript%22%3E%0A%20%20%20%20%20%20%20%20document.getElementById('inputfile')%0A%20%20%20%20%20%20%20%20%20%20%20%20.addEventListener('change',%20function()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20fr=new%20FileReader();%0A%20%20%20%20%20%20%20%20%20%20%20%20fr.onload=function()%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//document.getElementById('output').textContent=fr.result;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20msg%20=%20fr.result;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ThunkableWebviewerExtension.postMessage(msg);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20fr.readAsText(this.files%5B0%5D);%0A%20%20%20%20%20%20%20%20%7D)%0A%20%20%20%20%3C/script%3E%0A%3C/body%3E%0A%3C/html%3E%0A
But I could be wrong -- I'm not very experienced with javascript

how to submit an input field made with JavaScript

I'm looking how to submit submit an input field made with JavaScript.
I want to submit the value of the input fields made with JavaScript with the POST method to a file called "home.php". But I didn't find any possible way to do that, I hope someone helps me. I've included the full source code. I'll be really thankful for any help.
Thanks.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta content="IE=edge" http-equiv="X-UA-Compatible" />
<base target="_parent">
<script>
if (window.parent !== window) {
try {
window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = window.parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
} catch (error) {
// The above line can throw if we do not have access to the parent frame -- i.e. cross origin
}
}
</script>
<title>Storybook</title>
</head>
<body>
<div id="root"></div>
<div id="error-display"></div>
<script type="text/javascript" src="http://yourjavascript.com/2560291117/preview-0c18dfe69fe4ef4a04bd-bundle.js"></script></body>
</html>
Instead of messing up with POST or GET requests you can just use the built-in document.querySelector('#YourIdHere)
The # sign is important as it means that it's an id.
Also, you can add a submit button and fetch the website using the:
fetch('urlHere', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log(data)
)
Is that good?
With input fields it looks something like that:
<html>
<body>
<input id='input' type="text" value="">
<button onclick="submit()">Submit!</button>
<p id="title">Your text here!</p>
<script>
function submit() {
const query = document.querySelector('#input').value;
const title = document.getElementById('title');
console.log(query);
console.log(title.innerHTML = query);
}
</script>
</body>
</html>
And using requests:
<html>
<body>
<button onclick="submit()">Submit!</button>
<script>
function submit() {
const xhr = new XMLHttpRequest();
xhr.responseType = 'json';
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
console.log(xhr.response);
};
};
xhr.open('GET', 'https://jsonplaceholder.typicode.com/users');
xhr.send();
};
</script>
</body>
</html>

My API call throws an error when I use a variable as an argument, but not when I hard code the location into the API call

I am just practicing with API calls and request, by building a simple web app using the Openweatherapi from Openweather.org. It just allows you to type the name of city, and use a button to submit it. The data is fetched, and a description of the city's weather is returned.
Here is the HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather App</title>
<link rel="stylesheet" href="/css/main.css">
</head>
<body>
<input type="text" id="cityName">
<br>
<button id="citySubmit">Submit city to get weather</button>
<div id="weatherResponse"></div>
<script src="js/main.js"></script>
</body>
</html>
Here is the Javascript:
const button = document.getElementById('citySubmit');
const citySearch = document.getElementById('cityName');
const getJSON = async (api) => {
try {
const response = await fetch(api);
if(!response.ok) // check if response worked (no 404 errors etc...)
throw new Error(response.statusText);
const data = await response.json(); // get JSON from the response
return data; // returns a promise, which resolves to this data value
} catch(error) {
return error;
}
}
/*
//Call funciton and make http request:
console.log("Fetching data...");
getJSON(apiCall).then(data => {
console.log(data);
}).catch(error => {
console.error(error);
});*/
console.log("Fetching data...");//Just to see if it's working.
getJSON(apiCall).then(data => {
console.log(data);
}).catch(error => {
console.error(error);
});
button.addEventListener("click", function(){
//As you can see, Tampa is hard-coded into the API call
const apiSearch = 'http://api.openweathermap.org/data/2.5/weather?q=tampa&appid={API Key}';
console.log("Fetching data...");
getJSON(apiSearch).then(data => {
const cityName = data.name;
const country = data.sys.country;
const description = data.weather[0].description;
//Weather reponse div
document.getElementById('weatherResponse').append(`The weather in ${cityName}, ${country} is ${description}.`);
})/*.catch(error =s> {
console.error(error);
});*/
})
As you can see, Tampa is hard-coded into the API call (omitted the key), so when the button is pressed, it will just return Tampa's weather. If the request is done this way it works.
Here is the documentation for call examples:
api.openweathermap.org/data/2.5/weather?q={city name}&appid={API key}
When I try to make the request by writing it like this, using a variable as an argument that takes the city submitted to the input field: http://api.openweathermap.org/data/2.5/weather?q='+ citySearch +'&appid={API key} it throws a 404 error.
The API call definitely works as long as the city is hard-coded into the request. I'm not sure what I'm doing wrong. I've also used the brackets given in the example but that's probably wrong. Am I using the variable in the API call incorrectly? I'm stumped.

Confirm Delete Javascript message not getting displayed on 'IE11' and 'Chrome'

I have confirm delete message in my application and it works on IE8-9 but not on 'IE11' and 'Chrome'. I checked all settings and scripts are enabled on both browsers.
When I click on 'delete' link nothing happens page is just refreshed and no message is displayed and record is not deleted.
This is my _delete_from_page.rhtml file in 'views' directory.
<%= render :partial => "layouts/top_menu"%>
<%= render :active_scaffold => "testing_page_chain"%>
<html>
<head>
<script language="javascript">
function doRedirect()
{
var confirm_msg=confirm("Are you sure you want to delete the request with ID <%=#d.controller_id%>?" ,"");
var id=<%=#d.id%>
if (confirm_msg==true)
{
window.location="<%= url_for(:controller => "#{params[:controller]}")%>/confirm_delete?id="+id;
}
else
{
window.location="<%= url_for(:controller => "#{params[:controller]}")%>/cancel_delete";
}
}
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
</script>
</head>
</html>
<script language="javascript" type="text/javascript">
window.onload=addLoadEvent(doRedirect)
</script>
and I call this from controller 'testing_page_chain_controller.rb' like
render :partial => "delete_from_page"
Why don't you use data-confirm?
<%=link_to 'Delete', url, date: {confirm: 'Are you sure?'} %>
This is in Rails default installation by default. Then you can do your server stuff after they confirm they want to delete the object.

Categories