I have a web app that collects some data in text boxes then sends them to a python script that is running with flask
I have found two ways of submitting the form.
my button manages to collect the data and send it of to python and retires the answer from python but does not validate the inputs
my input tag manages to validate the text buttons but clears the form and does not manage to send the data of to the python script for processing.
I would like to do aspects of both buttons , I would like to validate , send data to python and retired the data.
Any ideas how to combine the function of the input submit and the button into one clickable item that validates and submits?
Any help much appreachiated
{% extends "layout.html" %}
{% block body %}
<script type="text/javascript">
$(function() {
var submit_form = function(e) {
$.getJSON($SCRIPT_ROOT + '/add_numbers', {
nm_height: $('input[name="nm_height"]').val(),
mn_material: $('input[name="mn_material"]').val(),
lc_height: $('input[name="lc_height"]').val(),
li6_enrichment_fraction: $('input[name="li6_enrichment_fraction"]').val()
}, function(data) {
$('#result').text(data.result);
$('input[name=nm_height]').focus().select();
});
return false;
};
$('#calculate').bind('click', submit_form);
//$("#myform").bind('ajax:complete', submit_form);
$('input[type=text]').bind('keydown', function(e) {
if (e.keyCode == 13) {
submit_form(e);
}
});
$('input[name=a]').focus();
});
</script>
<p>
<form name="myform" id="myform" >
<!--<form action="#" method='POST GET'>-->
<p>Height of neutron multiplier pebble bed <input type="number" size="10" name="nm_height" min="10" max="140" step="any" required placeholder='10 to 120'> mm </p>
<p>Neutron multiplier material <input type="text" size="10" name="mn_material" required placeholder='Be or Be12Ti'> Be or Be12Ti</p>
<p>Height of lithium ceramic pebble bed <input type="number" size="10" name="lc_height" min="10" max="140" step="any" required placeholder='1 to 60'> mm </p>
<p>Lithium 6 enrichment <input type="number" size="10" name="li6_enrichment_fraction" min="0" max="100" step="any" required placeholder='60 to 100'> %</p>
<button id="calculate" type="submit">predict TBR</button>
<input id="calculate" type="submit"></input>
</form>
TBR =<span id="result">?</span>
<br>
The TBR is quoted with a 95% <a href='http://www.stat.yale.edu/Courses/1997-98/101/confint.htm'> confidence interval </a>
<!--<p>calculate server side-->
{% endblock %}
I am in the same case and I have decided to use either regular expressions in the validation or just javascript .
regular expression is more powerful and faster but needs time, javascript is easier and slower. so it is a deal.
Let the backend handle the validation using something like WTFForms. Then all you need to worry about is submitting the data to the API endpoint and dealing with the responses that come back.
Avoid doing any validation strictly on the frontend because it's not secure and more likely to be tricked compared to backend validation.
{% extends "layout.html" %}
{% block body %}
<script type="text/javascript">
$('#myform').on('submit', function() {
var res = $.ajax({
url: '/add-numbers'
data: $(this).serialize(),
...
});
res.done(function(data) {
// get successful calculation back...
});
res.fail(function() {
// handle validation or calculation errors...
});
});
</script>
{% endblock %
Related
I am new to python. I need to get data from a html input to a python variable. But I can't find a way to do this. It shows output as None, None, None for output.
It doesn't print out the data too. How can I fix this issue?
This is the code in html file.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type=text/javascript>
$(function() {
$('button#add-income').bind('click', function() {
$.getJSON('/add_income',
function(data) {
//do nothing
});
return false;
});
});
</script>
<form class="add-income-box" method="POST" action="">
<div class="add-income-expences-top-div">
<label>INCOME</label>
</div>
<div class="add-income-expences-label-div">
<label class="add-income-expences-date-lbl">Date : </label>
<label class="add-income-expences-details-lbl">Details : </label>
<label class="add-income-expences-amount-lbl">Amount : </label>
</div>
<div class="add-income-expences-input-div" id="div1">
<input class="add-income-expences-date-input" name="i_date" value="{{request.form.i_date}}">
<input class="add-income-expences-details-input" name="i_details" value="{{request.form.i_details}}">
<input class="add-income-expences-amount-input" name="i_amount" value="{{request.form.i_amount}}">
</div>
<button class="add-income-expences-bottom" id="add-income">ADD</button>
</form>
this is the code in python file
#app.route('/add_income', methods=["GET", "POST"])
def add_income():
i_date = request.form.get('i_date')
i_details = request.form.get('i_details')
i_amount = request.form.get('i_amount')
print(i_date)
print(i_details)
print(i_amount)
return "nothing"
output :-
None
None
None
127.0.0.1 - - [31/May/2020 16:56:07] "GET /add_income HTTP/1.1" 200 -
Change this form tag action attribute
<form class="add-income-box" method="POST" action="{{ url_for('update_project')}}">
In this way, when you click on button it will call the method specified in action attribute.
and if you want to call this API using AJAX then make use of JSON to send data. And if you want to send data using form then remove the Ajax code and change the code as above suggested and click on the button and you will not get the form data.
<html>
<head>
<title>Addition</title>
<script>
function display(id_name,result_name){
document.getElementById(result_name).innerHTML = document.getElementById(id_name).value;
}
function calculate(id1,id2,result_id) {
document.getElementById(result_id).innerHTML = parseInt(document.getElementById(id1).value)+parseInt(document.getElementById(id2).value)
}
</script>
</head>
<body>
<div class="input">
Enter 1st Number:
<input type="text" id="input1_text">
<button type="button" onclick="display('input1_text','input1')">Enter 1st Number</button>
<span id="input1"></span>
</div>
<div class="input">
Enter 2nd Number:
<input type="text" id="input2_text">
<button type="button" onclick="display('input2_text','input2')">Enter 2nd Number</button>
<span id="input2"></span>
</div>
<div class="result">
<button type="button" onclick="calculate('input1_text','input2_text','result_value')">Calculate</button>
<span id="result_value"></span>
</div>
</body>
</html>
so in the above code i am not only adding 2 nubmers but also displaying the numbers after pressing the button.so now what i am looking for is to make this using flask framework on pressing buttons their respective functions should be fired up and data should be updated.I have tried using forms so the problem is on clicking button of 1st number to display is whole page is refreshing and i am losing whole data.so now how do i write those functions in python and also making sure that the page should not reload.Also is it possible to reuse the display function based on the paramters rather than hard coding and writing 2 display functions for 2 numbers seperately
Unless you need to use the user inputted values in the backend of your application, you can simply perform the calculations in the front-end:
<html>
<body>
<p>Input first number:</p>
<input type='text' class='first_val'>
<p>Input second number:</p>
<input type='text' class='second_val'>
<div class='results'></div>
<button type='button' class='calculate'>Calculate</button>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('.calculate').click(function() {
var val1 = parseInt($('.first_val').val());
var val2 = parseInt($('.second_val').val());
var val3 = val1+val2;
$('.results').html('The result is '+val3);
});
});
</script>
</html>
Edit: using Python in the backend, ajax can be utilized:
index.html:
<html>
<body>
<p>Input first number:</p>
<input type='text' class='first_val'>
<p>Input second number:</p>
<input type='text' class='second_val'>
<div class='results'></div>
<button type='button' class='calculate'>Calculate</button>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js">
</script>
<script>
$(document).ready(function() {
$('.calculate').click(function() {
var val1 = $('.first_val').val();
var val2 = $('.second_val').val();
$.ajax({
url: "/get_numbers",
type: "get",
data: {val1: val1, val2:val2},
success: function(response) {
$(".results").html(response.packet);
},
error: function(xhr) {
//Do Something to handle error
}
});
});
});
</script>
</html>
Then, in the Python app:
#app.route('/', methods=['GET', 'POST'])
def home():
return flask.render_template('index.html')
#app.route('/get_numbers')
def get_values():
value1 = flask.request.args.get('val1')
value2 = flask.request.args.get('val2')
return flask.jsonify({'data':f'<p>The result is: {value1+value2}</p>'})
You should build an flask API function: a GET route which accepts the argument from your form and returns a JSON response object.
Then in your HTML when you click the button that should perform an AJAX GET quesry accessing your API route and return the values to that page. This avoids having Flask re-render your page and returns the data directly to your existing client web browser.
To make it easy to manipulate data dynamically in the webpage I suggest a JS framework like angular, react or vue. Personally I prefer vue since it can be self contained, loaded as script into the page and the setup is often minimal. The docs are also very easy and you can easily see how to link form input controls.
Sorry guys, maybe this has been asked before. But I googled around for several days and still cannot solve the problem. I am developing a chatting system using Google App Engine with Python. I would like the user to enter her/his message and click "Submit" button. That action will trigger an Ajax post function "addMsg()" to POST the message to class Chat (URL: "/chat"), which will add the message to datastore. There is another Ajax function "updateMsg()" which will update the message list periodically.
The code works fine for message updating, however, I am not able to post the message correctly. Can anybody help me? Thanks. Here are my codes:
chat.html:
<p>
<form method="" action="">
<input type="text" name="message" size="60" /><br />
<input type="button" value="Submit" onclick="addMsg('message')" />
</form>
</p>
<div id="chatcontent"> </div>
<script>
function addMsg(message) {
$.ajax({
type: "POST",
url: "/chat",
data: {'message': message},
cache: false
});
}
</script>
<script>
$(document).ready(function() {
function updateMsg() {
$.ajax({
url: "/message",
cache: false,
success: function(returndata){
$("#chatcontent").html(returndata);
}
});
setTimeout(updateMsg, 4000);
}
updateMsg();
});
</script>
message.html:
{% for chat in chatlist %}
<p>
{{ chat.text }} ({{ chat.user.account }}) {{chat.created|date:"D d M Y" }}
</p>
{% endfor %}
chat.py:
# Called by URL "/chat"
class Chat(webapp2.RequestHandler):
def post(self):
message = self.request.get('message')
newchat = ChatMessage(user=self.session['userkey'], text=message, created=datetime.datetime.now())
newchat.put()
# Called by URL "/message"
class Message(webapp2.RequestHandler):
def get(self):
que = db.Query(ChatMessage).order('-created')
chatlist = que.fetch(limit=100)
render(self, 'message.html', {'chatlist': chatlist})
# Note: render() is a function to be imported, which is just a normal template rendering function. It works fine and is omitted here.
Chat.html
<p>
<input type="text" name="message" size="60" /><br />
<input type="button" value="Submit" onclick="addMsg()" />
</p>
<div id="chatcontent"> </div>
<script>
function addMsg() {
var message = $('input[name=message]').val();
$.ajax({
type: "POST",
url: "/chat",
data: {'message': message},
cache: false
});
}
</script>
I'm trying to create a turn-based strategy game (think Dominion) in Python. The core game objects and methods are Python classes with methods in them (just typical OO stuff). The UI is an HTML client using Bottle. I'm aiming for an entirely asynchronous approach. So the sole page's content is generated from the Python objects, and I want submits from the page to update those objects without ever leaving the page by going back through the bottle webserver (using jQuery AJAX for this).
At the moment I'm working on a basic chat system that retrieves player-written messages and stores them as Chat objects (containing player and text data, nothing else). These objects are then written to a chat window using AJAX that updates the windows once every second. The HTML format of the chat lines is <div class="chatLine"><p>Player > </p><p>Text</p></div> Pretty standard stuff.
This basic diagram might make it a little clearer, even though it isn't really technical, more conceptual:
My BottleUI.py (this is what I run to start the server):
from Populate import * # Everything in Populate can now be directly called.
# NOTE: Populate allows access to "bottle" and "Main"
# This ensures the css file is available
#route('/theCSS')
def static():
return static_file('main.css', root='static')
#route('/citadel/:game/:player')
def gamePage(game, player):
if not (game.isdigit()) or not (player.isdigit()):
return "Invalid page."
game = int(game)
player = int(player)
if ((game >= 0) and (game < listOfGames.__len__())) and ((player >= 0) and (player < listOfGames[game].listOfPlayers.__len__())):
return '''
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/theCSS">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<!-- Sample AJAX script below, change as needed -->
<script type="text/javascript">
$(document).ready(function() {
$('#chatForm').submit(function(e) {
$.ajax({
type: 'POST',
url: "/AddToChat/''' + str(game) + '''/''' + str(player) + '''",
success: function() {
$('#chatInput').val("");
}
});
e.preventDefault();
});
});
setInterval("updateChat();", 1000);
$(function() {
updateChat = function() {
$('#chatText').load('/GenerateChat/''' + str(game) + '''');
};
});
</script>
<!-- Script to scroll to bottom of divs - needs to be changed into called function -->
<script type="text/javascript">
window.onload = function () {
var objDiv = document.getElementById("gameFlow");
objDiv.scrollTop = objDiv.scrollHeight;
objDiv = document.getElementById("chatText");
objDiv.scrollTop = objDiv.scrollHeight;
};
</script>
</head>
<body>
<div id="container">
<!-- Make this have background-image with the game number displaying programmatically -->
<div id="banner">
<h1>Citadel - Game ''' + str(game) + ''', Player ''' + str(player) + '''</h1>
</div>
<div id="main">
<div id="leftPanel">
<div id="playerTotals">
<h4>Player Totals:</h4>
<div id="totalsText">
<p>Money:</p>
<p>Population:</p>
<p>Troops:</p>
<p>Friend:</p>
<p>Enemy:</p>
</div>
<!-- Player totals go here (money, population/limit, troops, friend, enemy) -->
<div id="totalsNums">
</div>
<div class="clear"></div>
</div>
<div class="leftSegment">
<h4>Troop Cards:</h4>
<!-- Player's troopCards here -->
<select size=2>
</select>
</div>
<div class="leftSegment">
<h4>Territory Cards:</h4>
<!-- Player's territoryCards here -->
<select size=2>
</select>
</div>
<div class="leftSegment">
<h4>Region Cards:</h4>
<!-- Player's regionCards here -->
<select size=2>
</select>
</div>
<div class="leftSegment">
<h4>Resource Cards:</h4>
<!-- Player's resourceCards here -->
<select size=2>
</select>
</div>
<div class="leftSegment">
<h4>Diplomacy Cards:</h4>
<!-- Player's diplomacyCards here -->
<select size=2>
</select>
</div>
<div id="chatPane">
<form id="chatForm" method="POST" action="/AddToChat/''' + str(game) + '''/''' + str(player) + '''">
<textarea name="theChatText" id="chatInput"></textarea>
<input id="chatSubmit" class="button" type="submit" value="Send" />
</form>
</div>
<div class="clear"></div>
</div>
<div id="rightPanel">
<!-- Game flow goes here (shows current player/phase, attacks with results, etc) -->
<div id="gameFlow">
</div>
<!-- Player turn stuff goes here (changes depending on which phase, etc) -->
<div id="playerActions">
</div>
<!-- Chat goes here (implement last) -->
<div id="chatText">
</div>
<div class="clear"></div>
</div>
</div>
</div>
</body>
</html>
'''
else:
return "Invalid page."
run(host='localhost', port=8080)
And here's my Populate.py (this is where my AJAX #route methods are stored):
"""
This module contains the bottle routs for AJAX population of the various parts
of the game page.
"""
from bottle import route, run, template, static_file, request
from Main import * # Everything in Main can now be directly called.
globalBegin()
#route('/AddToChat/:game/:player', method='POST')
def AddToChat(game, player):
theText = request.POST.get('theChatText', '').strip()
game = int(game)
player = int(player)
listOfGames[game].listOfPlayers[player].addChat(theText)
#route('/GenerateChat/:game')
def GenerateChat(game):
chatText = ""
game = int(game)
for line in listOfGames[game].chatList:
chatText += '<div class="chatLine"><p>'
chatText += line.player.name
chatText += ' > </p><p>'
chatText += line.text
chatText += '</p></div>'
return chatText
The problem is, the 'chatForm' form isn't working as intended. AddToChat() seems to think that request.POST.get('theChatText', '') is a NoneType when I try to submit text.
So yeah, I'm stumped as to why it's doing this. As far as I can see, 'theChatText' should be a valid key in the POST dict.
I'll also just state that all my core game logic works (even though it's pretty clear that isn't the problem here).
Any help is appreciated.
Original jQuery function:
$(document).ready(function() {
$('#chatForm').submit(function(e) {
$.ajax({
type: 'POST',
url: "/AddToChat/''' + str(game) + '''/''' + str(player) + '''",
success: function() {
$('#chatInput').val("");
}
});
e.preventDefault();
});
});
data: $(this).serialize(), needed to be added, like so:
$(document).ready(function() {
$('#chatForm').submit(function(e) {
$.ajax({
type: 'POST',
url: "/AddToChat/''' + str(game) + '''/''' + str(player) + '''",
data: $(this).serialize(),
success: function() {
$('#chatInput').val("");
}
});
e.preventDefault();
});
});
Otherwise the server (or Bottle in this case) won't be able to read the submitted form.
I'm trying to add an item (fund). The autocomplete succeeds in showing all the funds. It should retrieve the fund.id corresponding to that 'fund'. If I could get another set of eyes on this, it would be greatly appreciated...
Just to be clear: I'm not getting a specific error. My view just redirects if there is no 'fund' in the POST. I'm just trying to figure out why my autocomplete isn't posting the fund POST value' (fund.id).
-- Thank you advance
Template:
<script type="text/javascript" src="{{ STATIC_URL }}js/autocomplete/add_fund_autocomplete.js"></script>
...
<form method="POST" action="/profile/edit/">
{% csrf_token %}
<input type="hidden" name="fund" id="id_fund" />
<div class="inline-block">
<label for="id_omnibox">Fund</label>
<input id="id_omnibox" name="omnibox" placeholder="Enter a fund name or search for an existing..." type="text" />
</div>
<div class="input-prepend inline-block">
<label for="id_amount">Allocation</label>
<span>$</span>
<input id="id_amount" name="amount" type="text" placeholder="Enter amount" />
</div>
<button class="add" type="submit" name="add_position">Add</button>
</form>
add_fund_autocomplete.js:
$(document).ready(function() {
$.get('/autocomplete/funds/', function(data) {
var completions = new Array();
var dict = JSON.parse(data, function(key, value) {
completions.push(key);
return value;
});
$('#id_omnibox').autocomplete({
source: completions,
minLength: 2,
select: function(event, ui) {
$('#id_fund').val(dict[ui.item.value]);
}
});
});
});
(autocomplete)View:
#login_required
def funds(request):
funds = Fund.objects.exclude(name='Placeholder')
result = {}
for fund in funds:
result[fund.name] = str(fund.id)
return HttpResponse(json.dumps(result))
For example:
Adding the fund Hoth Ltd with an amount of $123.
Hoth Ltd's fund.id should be 1.
POST data
POST
---------------------------------------------------------
Variable Value
---------------------------------------------------------
fund u'' #empty? :\
csrfmiddlewaretoken u'436f77eb2023043be2f5242bb0443d80'
omnibox u'Hoth Ltd'
amount u'123'
add_position u'' #Just a trigger used in my view
The variable dict is undefined when the select callback function is called.
You can just use ui.item.value.