My question is similar to Replacing input() portions of a Python program in a GUI. But I need a web UI not desktop UI(tkinter based solution as answered in the link)
You will have to create a webpage with HTML/CSS and create a form in it to get the input. Then, you will have to link the webpage with your backend (flask) to receive the input in python and manipulate as needed. Following a tutorial like this one will help you get started. Or, you can simply search the web for "Form handling in Flask" to find something that suits your needs.
Say you're asking for the user to input their username. You'd do something like this.
HTML
<body>
<form action="" method="post">
<input type="text" placeholder="" value="{{ request.form.username }}">
<input type="submit" value="Submit">
</form>
</body>
Whatever you want to call your variable, you put after request.form
In your program (where you import flask), also import request from flask like so:
from flask import request
Under your route's function, check if the request's method is POST and assign your form variable:
def index():
if request.method == "POST":
foo = request.form["username"]
return render_template("index.html")
So when the user clicks the submit button, foo will be whatever they put in the text box.
You can see more at https://flask.palletsprojects.com/en/1.1.x/quickstart/#accessing-request-data
Related
I am building a web-app using flask where I am trying to route some URLs
I have three routes with me
a) "/"
b) "/teacher"
c) "/student"
The routing works fine for "/" and"/student" The URL gets appended after clicking the submit button for student and"/student" gets appended in URL but on clicking the button associated with "/teacher" the URL doesn't gets appended and "/" page keeps on loading up.
Please help me out here and tell me what wrong I am doing
My Python code:
#app.route('/', methods=['GET', 'POST'])
def select():
return render_template("select.html")
#app.route('/teacher', methods=['GET', 'POST'])
def index():
return render_template("index_teacher.html", title="Faculty login")
#app.route('/student', methods=['GET', 'POST'])
def index1():
return render_template("index_student.html", title="Student login")
Part of my html code from select.html:
<form action="/teacher" method = "post">
<input type="submit" class="submit" value="Login as Teacher">
</form>
<br>
<form action="/student" method="post">
<input type="submit" class ="submit" value="Login as Student">
</form>
One more thing about the code, when I add a text box above the first submit button, both the button starts working and give desired results.
Thanks in advance!
I think you have just a little typo in the html. The input tag of teacher didn't close >.
<form action="/teacher" method = "post">
<input type="submit" class="submit" value="Login as Teacher">
</form>
<br>
<form action="/student" method="post">
<input type="submit" class ="submit" value="Login as Student">
</form>
EDIT:
In the case that the question was copied incorrectly, I don't know what should be wrong with your code. For me your sample code works just fine. So from my experience with flask and html forms the most common errors I made are the following, maybe it's one of them (the list may serve other too, so I will also add points that do not make sense for your case):
method name of two routes collide (e.g. both '/' and '/teacher' are assigned to function index, but that should give an error when starting the server, so not really possible)
an html tag is not closed properly, so the form in question is not parsed as a valid form (that was my guess with above answer, also makes sense with the text box, which may close the corrupt tag => in html an open tag is closed by the first following closing tag)
typo in the form action attribute (check the network tab in your browsers developer tools, maybe you get an error response to something like "taecher", which results in a redirect to "/", again not really plausible with the fact that it suddenly works when you add the text box)
typo in the route or the returned template (again not plausible with explained behavior with the added text box)
That's all I can think of at the moment. I hope it helps with the search. if you could add more of your html code, maybe I find something suspicious.
I am making a simple Flask web-app.
It will simply take text input.
The user will type in the text and click on the submit button.
I have created the textarea inside Form HTML tag for text input. And I have a Submit button created using a hyperlink tag .
How can I access the text inside the textarea when the Submit is clicked?
Note: I do not want to use the default submit option available within the form tag.
HTML for Textarea :
<form action="{{ url_for('publish') }}" method="post">
<textarea name="text" class="form-control" rows="1" placeholder="Enter your message"></textarea>
</form>
HTML for Submit button :
Submit
Flask code to retrieve textarea input from user :
#app.route('/publish', methods=['GET', 'POST'])
def publish():
message = request.form['text']
print(message)
print('well')
return render_template('index.html')
Based off this question Post Method to URL from a onclick function
Assign an id to your form, then an onclick event to your link as such:
<a onclick="document.getElementById('form-id').submit();" href="{{ url_for('publish') }}" method="post"> Submit </a>
You should be able to retain your flask code as normal afterwards.
It would be easier to use the submit button inside the form element. You can always style it to your liking with CSS. If you insist on not doing do, then you will have to add a 'click' event listener on your current Submit Button that posts the textarea data to your endpoint using AJAX. Your choice of either using vanilla JS, jquery, or the like.
Then within Flask, you can access the arguments by using
from flask import request
# ... Definitions
args = request.get_json()
text = args['textarea_text'] # the key is whatever you use in your AJAX call
# ... Rest of endpoint
Here is some more information regarding that: Get the data received in a Flask request
Is HTML for Textarea in the 'index.html'? Because I see that the route '/publish' has 'GET' method.
If yes, 'index.html' should be first rendered with the 'GET' method, and the text inside the form is NOT available at this moment. You can only get the text when the 'POST' method is called.
#app.route('/publish', methods=['GET', 'POST'])
def publish():
if request.method == 'POST':
message = request.form['text']
print(message, flush=True)
return render_template('index.html')
else:
print('well', flush=True)
return render_template('index.html')
By the way, you can try this to put text value into request.form['text']:
<form action="{{ url_for('publish') }}" method="post">
<textarea name="text" id="text" class="form-control" rows="1" placeholder="Enter your message">{{ request.form['text'] }}</textarea>
</form>
This question already has answers here:
Sending data from HTML form to a Python script in Flask
(2 answers)
Closed 3 years ago.
I'm creating a web app in Python/Flask to display tweets using twitters API using tweepy. I have set up an HTML form, and have got the script that finds the tweets with a certain input, currently, this is hard coded. I want the users to input a hashtag or similar, and then on submit, the script to run, with that as its parameter
I've created a form, with method GET and action is to run the script.
<form class="userinput" method="GET" action="Tweepy.py">
<input type="text" placeholder="Search..">
<button type="submit"></button>
</form>
I dont know how I would get the users input and store it in a variable to use for the tweepy code, any help would be greatly appreciated
templates/index.html
<form method="POST">
<input name="variable">
<input type="submit">
</form>
app.py
from flask import Flask, request, render_template
app = Flask(__name__)
#app.route('/')
def my_form():
return render_template('index.html')
#app.route('/', methods=['POST'])
def my_form_post():
variable = request.form['variable']
return variable
I guess you have set up and endpoint to run that script, an URL mapped to a function. In that case you need to call it from the form action.
for example
#app.route('/my-function')
def your_function(parameters):
"code to do something awesome"
return "the result of your function"
So, in your form you should:
<form class="userinput" method="GET" action="/my-function">
<input type="text" placeholder="Search..">
<button type="submit"></button>
</form>
That should do the trick.
Go to the Flask home page for more examples.
this is more of a question about where to find how I would do this rather than asking how to do this. I'm sure this is well covered, I'm just struggling to articulate the correct term which I could use to Google and find out the answer.
Anyway - I have a Python Flask web application. On a web page, there is an input box which requests user input. What I would like to happen, is for some magic to happen with the user input in the background. In my own scenario, I would like to take a URL, then use bs4 to pick off what I need and display this on the web page.
For simplicity, I'll ask for something for simple and I can then build on it from there: if I were to request the user to specify a number then press 'Submit', how could I multiply the number by 10?
If my code for the form was index.html:
<form class="form-horizontal" role="form" method="post" action="/">
{{ form.csrf_token }}
<fieldset>
<div class="form-group">
<label for="GetNum" class="col-lg-2 control-label">Enter Number</label>
<div class="col-lg-6">
<input type="text" id="GetNum" name="GetNum" class="form-control" value="">
</div>
<input class="btn btn-success" type="submit" value="Calculate">
</div>
</fieldset>
</form>
I noticed that I can get the input to print to a paragraph by <p>form.request.GetNum</p>.
Now for this question's example, the code for the backend functionality will be:
import math
GetNum = 10 #should be form.request.GetNum value
CalcResult = GetNum*1000
print CalcResult # or {{ CalcResult.data }} or something in index.html
My Controller (app.py) looks like:
#app.route('/', methods=['GET', 'POST'])
#login_required
def home():
error = None
form = PostForm(request.form) # unrelated to question, but will this clash?
if .. :
do something
return redirect(..)
else:
do something else..
return render_template(..)
My worry is that the home function will end up having a mass of code if I have to put the math function in there. So tl;dr, how would I implement a back end function within my code? (or please provide me with material to read, thank you!)
One other thing is I already have a form on my '/' page, will I have to rename the forms like form1 form2 because they will clash or will it be OK?
Elsewhere in your code base, either in the same file, or more likely
a module or package you could define that complicated task. Lets
create a simple module complicated.py in the same directory as your
other code, that then defines the complicated task:
def do_really_complicated_thing(info):
# lots of complicated steps
return really_complicated_data
Then in our view code, we can just use that instead of having it embedded:
from complicated import do_really_complicated_thing
#app.route('/', methods=['GET', 'POST'])
#login_required
def home():
error = None
form = PostForm(request.form)
if form.validate_on_submit() :
info = form.info.data
complicated_task = do_really_complicated_thing(info)
return render_template('something', results=complicated_task)
So, in short-- the terms you're looking for is packages and modules, they
help your code be neater and reusable.
As for clashing forms— you can just target the form to post to a specific route which just handles that form, which is much cleaner then then having to validate/parse different forms in a single route.
I'm using Pyramid to build a webapp, and I've got two views where one leads to the other:
config.add_route("new", "/workflow/new")
config.add_route("next", "/workflow/{id}/next")
The new view is really very simple and presents only an HTML form as a Jinja2 template for the user to fill in some information:
<form method="post" action="{{ request.route_url('next',id='') }}" >
<input type="text" name="id" value="Identifier" />
...
<input type="submit" name="next" value="Next" />
</form>
The question here regards the action of that form: how can I use the content of the text input field id, perhaps process it a little, and then pass it on in the route request?
Note that in this scenario the form data is passed from the new view to the next view, and that should stay the same.
When the form is posted, the forms fields will be available in the request object, see
http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/webob.html#request
I believe it is also a good idea to post to the same url (<form action="#" method="post">), so that you can validate the form. Then you can process and redirect to the next url when the form is valid, or recreate the form with errors if it isn't.
So your view may end up something like this;
from pyramid.httpexceptions import HTTPFound
from pyramid.url import route_url
def myview(request):
if request.method == 'POST':
# Validate the form data
if <form validates successfully>:
# Do any processing and saving here.
return HTTPFound(location = route_url('next', id=request.params['id'], request=self.request))
else:
request.session.flash("The form isn't valid.")
# Do some stuff here to re-populate your form with the request.params
return { # globals for rendering your form }
There are already many questions/answers addressing this, such as How can I redirect after POST in Pyramid?