I have a form that looks like this:
<form id="settings" action="{{ url_for("load_settings") }}" method="post">
...
<label for="m_r">Interval 1</label>
<input type="text" name="morn_r" id="m_r">
<label for="d1_e">Enabled</label>
<input type="checkbox" name="d_enabled" id="d1_e" value="off" onclick="toggle_check(this)">
</form>
This is the toggle_check function:
function toggle_check(check) {
if (check.value=="on") {
check.value="off";
}
else {
check.value="on";
}
}
Here's my Python:
#app.route("/settings", methods=["POST", "GET"])
def load_settings():
if request.method == "POST":
settings = list(request.form.values())
print(settings)
return render_template("settings.html")
If I leave the text inputs empty but click the checkbox, here is what gets printed: [..., '', 'on']
Now, if I also leave the checkbox empty this is what gets printed: [..., '']. For some reason it doesn't add the value of the checkbox...
I don't know how to fix this. Could someone please help?
Thanks.
Stealing from this answer, the HTML 4 recommendation from W3C states:
Checkboxes (and radio buttons) are on/off switches that may be toggled by the user. A switch is "on" when the control element's checked attribute is set. When a form is submitted, only "on" checkbox controls can become successful.
So it's not anything to do with Flask as to why the checkbox value isn't there when unchecked. The browser won't serialize that form input into the request when the checkbox is unchecked.
What you could do though, is give the input some sensible value in the template:
<input type="checkbox" name="d_enabled" value="on">
And then in your Flask handler check for the presence of the value:
if request.form.get('d_enabled') == 'on':
# checkbox is checked
else:
# checkbox is not checked
Related
I created a sign up form using html and jinja that sends a post request when it is submitted
<form method="POST">
<div class="mb-3 text-center">
<label for="email" class="form-label"
>Email Address:
</label>
<input
type="email"
class="form-control"
id="email"
name="email"
placeholder="Enter email"
/>
</div>
with other inputs and a button which submits it all at the bottom of the form
My auth.py file which holds the routes for the forms has this function which checks if the information the user entered is valid. If it isn't send an alert flash message, and if it is create the user.
#auth.route("sign-up", methods=["GET", "POST"])
def sign_up():
if request.method == "POST":
email = request.form.get("email")
if len(email) < 4:
flash("Email must be greater than 4 characters!", category="dangerAlert")
else:
flash("You have successfully created an account!", category="successAlert")
All of this works however, when the user enters invalid informaiton, all of input fields lose the text they wrote. So the user has to rewrite all the text in the input fields to resubmit their form.
How do I keep the text in the input fields if the user sends invalid or incomplete data?
The best way to do this that I know of, and have used in the past: is using localStorage. You set the local storage before they reload the page. Like this:
function setLocalStorage {
localStorage.setItem("name", $('#text').val());
localStorage.setItem("email", $('#email').val());
}
window.onbeforeunload = function() { setLocalStorage(); }
Forgive my js, I haven't done any web dev in a little while. Obvously, you would also need to reload this onload()
Idea: jcubic
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 is an extension of this question regarding using the Bootstrap toggle with flask.
My code for the toggle is as follows:
<div class='media'>
<div class='media-left'>
<div class='media-object'>
<div class='padding-right'>
<form action="/menu" method="post">
<input name="toggle" onclick="this.form.submit()" data-off="<i class='fa fa-times'></i> " data-on="<i class='fa fa-check'></i> " data-onstyle='success' data-size='large' data-style='ios' data-toggle='toggle' id='activate-toggle' type='checkbox' value="on">
<input name="toggle" type="hidden" value="off">
</form>
</div>
</div>
</div>
<div class='media-body'>
<div id='console-event'></div>
</div>
</div>
And my endpoint for the page is as follows:
#app.route('/menu', methods=['POST', 'GET'])
def get_callback():
if request.method == 'POST':
button = request.form['toggle']
print(button)
return render_template('dashboard.html')
However I am not able to get any response from my button.
I am very lost at this point. I have tried to copy the format of the question above however I still cannot get the button to print or even use the POST method.
Here are my questions:
How can I get a response from my button?
How do I save the orientation so that when the user logs back in the button is how they previously left it?
(I am using SQLAlchemy if this is of any importance.)
Any help would be greatly appreciated!
Thank you,
Jonah
It seems that the target of your form defined in action is incorrect. What I would try and do is change it to the following:
<form action="{{url_for('get_callback')}}" method="POST">
As for saving the toggled state, you might want to create a column in your db table with a default of off (or on) and then write some code to update the saved value for the switch state whenever a change is made to the toggle switch.
If anyone else has a better idea to store the state of the switch, I'd be interested to find out how.
First of all, you don't need this second hidden input. It's resulting in there being two values for toggle, which isn't what you want.
<input name="toggle" onclick="this.form.submit()" data-off="<i class='fa fa-times'></i> " data-on="<i class='fa fa-check'></i> " data-onstyle='success' data-size='large' data-style='ios' data-toggle='toggle' id='activate-toggle' type='checkbox' value="on">
<input name="toggle" type="hidden" value="off">
But more importantly, your code, as written would print to the console the value of button, then return to the user the HTML form input. Perhaps this would clear things up:
#app.route('/menu', methods=['POST', 'GET'])
def get_callback():
if flask.request.method == 'POST':
button = bool(flask.request.form.get('toggle', False))
return "Toggle value: %r" % (button,)
else:
return render_template('dashboard.html')
If you do that, and remove that hidden input that shouldn't be there, it'll show the user "Toggle value: True" or "Toggle value: False" depending on which is clicked.
Though I don't see, in your example, how the user could submit the form without toggling the checkbox.
i would try it like that
#app.route('/menu', methods=['GET','POST'])
def get_callback():
if request.method == 'POST':
print(request.form.get('toggle'))
return render_template('dashboard.html')
if it does not work with ('toggle') try ('checkbox')
I'm a newbie to Django and started learning it last week. My question is I have a web page which has an input text box and a submit button. I want to capture the input string entered in the next web page (redirecting page) which has been entered in the text box after pressing the submit button in Django.
I have tried the following:
views.py
#View for the initial page
def index(request):
return render( request, 'index.html')
#View for the Redirecting page -- This is where I want to catch the text box input
def results(request):
inp_value = request.GET.get('text_search', 'This is a default value')
context = {'inp_value': inp_value}
return render( request, 'results.html', context)
forms.py
from django import forms
class TextForm(forms.Form):
text_search = forms.CharField(label='Text Search', max_length=100)
index.html
<form action="/searcher/results/" method="get">
<label for="results">Enter a string: </label>
<input id="results" type="text" name="results" value="{{ search_results }}">
<input type="submit" value="submit">
</form>
Can anyone point out why I'm not able to get the value of the textbox?
Thanks in Advance
request.GET key is the name of the input. So, in your case, since you want the value of <input type="text" name="results"> you should get that value from request.GET.get('results').
However, there is also a {{ search_results }} value that it's not get rendered from your index view. Thus, it will always be null.
def results(request):
inp_value = request.GET.get('results', 'This is a default value')
context = {'inp_value': inp_value}
return render( request, 'results.html', context)
I have a Django project that, on one page, has multiple forms (in different tags) that can be submitted to have different effects. In all cases I want the user to be redirected back to the same page, so I use in my view the pattern of submitting the form and then redirecting to the original page. In at least one case, the only difference between two of the forms is the value of the submit button.
In my view I have the code (which is the first time my view function accesses the request.POST):
if request.POST['submit']=='Add':
#code to deal with the "Add" form
and in the template, the first form has a submit button like
<input type="submit" value="Add">
I thought this would work, but when I submit that form, I get an error at the line in view from above:
Key 'submit' not found in <QueryDict: {u'clientyear': [u'2012'], u'csrfmiddlewaretoken': [u'be1f2f051f09f6ab0375fdf76cf6a4d7'], u'ben': [u'123405']}>
Obviously, this does not have a 'submit' key or any key with the value corresponding to the submit button I clicked. So, since this does not work, how can access the value of the submit button or tell which of the forms has been submitted?
Submit is an HTML Form structure... You must use name attribute of form objects as follows... In your template:
<form>
...
<input type="submit" name="list" value="List Objects" />
</form>
<form>
...
<input type="submit" name="do-something-else" value="Do Something Else" />
</form>
In your view:
if 'list' in request.POST:
# do some listing...
elif 'do-something-else' in request.POST:
# do something else
One thing to keep in mind to prevent confusion. The name of the submit button will not show if there is only a single button in the form.
#template.html
<form action="..." method="post">
<input type="submit" name = "first_button" value="Add">
</form>
#view.py
...
'first_button' in request.POST #False
#template.html
<form action="..." method="post">
<input type="submit" name = "first_button" value="Add">
<input type="submit" name = "second_button" value="Remove">
</form>
#view.py
...
'first_button' in request.POST #True if you clicked on that button
I'm little bit late but here is the solution
Problem you are facing
Your are trying to get Button name but getting the initial value of button that is not correct way.
HTML Code
<input type="submit" value="Add">
Python Code/View.py
if request.POST['submit']=='Add':
#code to deal with the "Add" form
Solution
First find button name in request.POST dictionary if exist then get their value.
HTML Code
Add name of your button and their value.
<input type="submit" value="Add" name="add_object">
Views.py
You can find the button name in request.POST dictionary
if request.POST['submit'] == 'add_object':
# Both ways to deal with it
if 'add_object' in request.POST:
Extra Stuff
We have two forms on a page.
First form have 2 buttons with same name subjects but different values fav_HTML and fav_CSS.
Second form also have 2 buttons with same name tutorials but different values
Tutorials_HTML and Tutorials_CSS.
<form action="" method="post">
Form 1
<button name="subject" type="submit" value="interview_HTML">HTML</button>
<button name="subject" type="submit" value="interview_CSS">CSS</button>
</form>
<form action="" method="post">
Form 2
<button name="tutorials" type="submit" value="Tutorials_HTML">HTML</button>
<button name="tutorials" type="submit" value="Tutorials_CSS">CSS</button>
</form>
views.py
We can handle different forms, check which button is clicked then getting their values and do something.
if 'subject' in request.POST: # this section handle subject form (1st Form)
#now we can check which button is clicked
# Form 1 is submitted , button value is subject now getting their value
if 'interview_HTML' == request.POST.get('subject'):
pass
# do something with interview_HTML button is clicked
elif 'interview_CSS' == request.POST.get('subject'):
pass
# do something with interview_CSS button is clicked
elif 'tutorials' in request.POST: #this section handle tutorials form (2nd form)
#now we can check which button is clicked
# Form 1 is submitted , button name is tutorials now getting their value
if 'Tutorials_HTML' == request.POST.get('tutorials'):
pass
# do something with fav_HTML button is clicked
elif 'Tutorials_CSS' == request.POST.get('tutorials'):
pass
# do something with fav_CSS button is clicked