flask multiple submit button - html

I am using flask and jinja2 to create a simple web app to serve up a simple sklearn algorithm for predictions.
In my html I need to get 4 variables: client id, textid, textid1, textid2
It currently works when I have it all connected to one submit button. But I would like to have two submit buttons to have the client id submit at the top of the page and the textid stuff at the bottom of the page. When I try to have two submit buttons it causes the page to refresh and I not able to connect the client id to the 3 textid vars.
<div class="col">
<div class="form-group">
<label>Enter Customer ID or leave blank for random selection </label>
<form method="POST">
<input name="text", id='text', placeholder="Client ID #", value="{{ client_id|round|int }}" >
<br>
<label>Enter 3 suggestions</label>
<br>
<input name="textid", placeholder="Suggested Model ID #", value="{{ request.form['textid'] }}"/>
<input name="textid1", placeholder="Suggested Model ID #", value="{{ request.form['textid1'] }}"/>
<input name="textid2", placeholder="Suggested Model ID #", value="{{ request.form['textid2'] }}"/>
<input type="submit" >
</form>
</div>
I'm simply grabbing it in flask like this:
#app.route('/suggestion', methods=['GET', 'POST'])
def with_suggestions():
try:
client_id=request.form['text']
except:
#custom function when client id is not entered to get random one
client_id = recommender.random_client_id()
try:
model_id=request.form['textid']
model_id1=request.form['textid1']
model_id2=request.form['textid2']
#other functional code after this
How can I break up the html to get two submit buttons? Thanks!!

Now that you have updated your code, all you need to do is add hidden inputs to identify where the click was originated from. Also Remove the leading slash from your url_for like I did below
<div class="col">
<div class="form-group">
<label>Enter Customer ID or leave blank for random selection </label>
<form method="POST" action={{url_for('suggestion')}}>
<input name="text", id='text', placeholder="Client ID" >
<input type="hidden" name="btn_identifier" value="client_id_identifier" />
<input type="submit" >
</form>
<form method="POST" action={{url_for('suggestion')}}>
<input name="textid", id='text', placeholder="Textid1">
<input name="textid1", id='text', placeholder="textid2 ">
<input name="textid2", id='text', placeholder="Textid3">
<input type="hidden" name="btn_identifier" value="text_id_identifier" />
<input type="submit" value="Submit">
</form>
main.py
from flask import Flask
from flask import render_template, url_for, request, redirect
app = Flask(__name__)
#app.route('/suggestion', methods=['GET', 'POST'])
def with_suggestions():
if request.methods == 'POST':
if request.form['btn_identifier'] == 'client_id_btn':
try:
client_id=request.form['text']
except:
# I think this would go in the second elif statement
model_id=request.form['textid']
model_id1=request.form['textid1']
model_id2=request.form['textid2']
elif request.form['btn_identifer'] == 'text_id_btn':
# run some code to handle a click that was originated from the second button
return render_template('index.html')
if __name__ == '__main__':
app.run()

I made some changes to your code.
index.html
<div class="col">
<div class="form-group">
<label>Enter Customer ID or leave blank for random selection </label>
<form method="POST" action={{url_for('suggestion')}}>
<input name="text", id='text', placeholder="Client ID" >
<input type="submit" >
</form>
<form method="POST" action={{url_for('suggestion')}}>
<input name="textid", id='text', placeholder="Textid1">
<input name="textid1", id='text', placeholder="textid2 ">
<input name="textid2", id='text', placeholder="Textid3">
<input type="submit" value="Submit">
</form>
</div>
main.py
from flask import Flask
from flask import render_template, url_for, request, redirect
app = Flask(__name__)
#app.route('/suggestion', methods=['GET', 'POST'])
def suggestion():
if request.method == 'POST':
try:
client_id=request.form['text']
except:
model_id=request.form['textid']
model_id1=request.form['textid1']
model_id2=request.form['textid2']
return render_template('index.html')
if __name__ == '__main__':
app.run()
Note: Values are store in the variable, print to see

I have simplified the process of fetching the info from multiple buttons. Do note that you require the python flask framework for the "request" method.
home.html
<div class="container mt-5">
<div class="row col-4">
<form method="POST" class="form-register">
<input type="submit" name="submit_button" value="Add Email">
<input type="submit" name="submit_button" value="Clear Recipients">
</form>
</div>
</div>
run.py
if request.method == 'POST':
if request.form['submit_button'] == 'Add Email':
print("add email")
elif request.form['submit_button'] == 'Clear Recipients':
print("clear recipients")
you may refer to the link provided for more example
https://www.codegrepper.com/code-examples/python/checking+if+button+pressed+flask

Related

Django not printing post request

I'm learning Django and creating my website...
Created and basic HTML contact form and to check if it is working I've added an print option on form submission(method==post) but
after I submit the form, on terminal prints nothing
below are my codes
Thank you For your time
views.py
def contact(request):
if request.method == 'POST':
print ("we are done")
return render(request,"news/Home/Homepage.html")
_____models.py_______
class Contact(models.Model):
name=models.CharField(max_length=100)
email=models.CharField(max_length=150)
msg=models.TextField()
____my html contact form__________
<form class="grid-form" method="post" action="/">
{% csrf_token %}
<div class="form-control narrow">
<label for="name">Name</label>
<input name="name" id="name" type="text">
</div>
<div class="form-control narrow">
<label for="email">Email</label>
<input name="email" id="email" type="email">
</div>
<div class="form-control">
<label for="message">Message</label>
<textarea name="message" id="message" rows="4"></textarea>
</div>
<ul class="actions">
<li><input value="Send Message" type="submit"></li>
</ul>
</form>
urls.py
from . import views
urlpatterns = [
path("" , views.index),
path("league",views.index2),
path("pl",views.index3),
path("ptable", views.index4),
path("fs", views.index5),
path("latest", views.index6),
path("history", views.index7)
]
Give path in your action in the form:
<form class="grid-form" method="post" action="/">
There, should be action attribute should correspond to the path which will trigger contact function in views.py.
EDIT
Your urls.py does not contain any url where you could send the request from form. As, I already mentioned about the action, your home directory is not in index function. So, you have to add a path to send request. Like:
from . import views
urlpatterns = [
path("" , views.index),
path("contact" , views.contact, name="contact"), # Here
path("league",views.index2),
path("pl",views.index3),
path("ptable", views.index4),
path("fs", views.index5),
path("latest", views.index6),
path("history", views.index7)
]
And, you have to send the form to that path www.example.com/contact. Like:
<form class="grid-form" method="post" action="{% url 'contact' %}">
*Note:- I gave the action value according to the name, which is great practice. So, lets start giving name in the url. But, the way you did is also fine.

How to pass data from html to django view to use in URL?

I'm getting an error while working with django urls. I want to pass the value of Name input field after i hit the submit button.
Let's say I've this html form-
<form method='POST' action="{% url 'submittedform' slug=[firstname] %}">
{% csrf_token %}
<div>
<label for="name">Name</label>
<input type="text" name="firstname" id="name">
</div>
<div>
<label for="email">Email</label>
<input type="email" name="useremail" id="email">
</div>
<div>
<label for=phone>Phone</label>
<input type="text" name="phonenumber" id="phone" maxlength="12" pattern="[0-9]{10}">
</div>
<input type="submit" name="" id="btn" value="Submit">
</form>
Here's my view that handling it-
def submittedform(request, slug):
if request.method == 'POST':
# do something here
return render(request,'myapp/welcome.html')
return render(request,'myapp/welcome.html')
and here's my view that's handling it-
urlpatterns = [
path('index/',views.index ,name='index'),
path('welcome/<slug:slug>/',views.submittedform, name='submittedform')
]
I'm not using django forms. How can i get welcome/name working.
If you want to pass a variable to an URL you need redirect with the value:
from django.shortcuts import redirect
return redirect("/welcome/%s/" % slug)
Change the following line
<!-- Removed the bracket -->
<form method='POST' action="{% url 'submittedform' slug=firstname %}">
<!-- Children tags here -->
</form>
Now the variables are accessible in view like
def submittedform(request, slug):
if request.method == 'POST':
name = request.POST['name']
# and more variables as you need
# do something here
# do redirect here or give some message that their form has been
# submitted for their confirmation
return render(request,'myapp/welcome.html')
return render(request,'myapp/welcome.html')

Flask wtforms submitfield validation based on change in form

I am writing an update form with flask, wtforms and bootstrap4. This form gets value populated from database. I would like the submit button to be disabled if there is no change made in the value from the database.
for example, if username is stringfield, which comes from database. lets say the value is "abc123", so unless this value is changed by the user, submit button should be disable or atleast do not perform send any post request.
code looks like following
forms
class AccountForm(FlaskForm):
username = StringField('Username', validators=[Length(min=4, max=20), DataRequired()])
submit = SubmitField('Update’)
routes
#app.route("/account", methods=['GET', 'POST'])
def account():
form = AccountForm()
if form.validate_on_submit():
username = str(form.username.data).lower()
# ….. update database
elif request.method == 'GET':
form.username.data = username_from_db
return render_template(‘account.html', form=form)
html
<form method="POST" action="" enctype="multipart/form-data">
{{form.csrf_token}}
<input class="form-control" id="username" name="username" placeholder="Username" required type="text" value=“abc123">
<input type="submit" class="btn btn-success" value="Update">
</form>
You can do this with jquery
$(function(){
var usernameValue = $('#username').val();
$('#username').change(function(){
if ($(this).val() != usernameValue){
$('input.btn-success').prop('disabled', false);
}
});
});
and add in your html the disabled attribute to the submit button
<form method="POST" action="" enctype="multipart/form-data">
{{form.csrf_token}}
<input class="form-control" id="username" name="username" placeholder="Username" required type="text" value=“abc123">
<input type="submit" class="btn btn-success" value="Update" disabled>
</form>

Not getting attributes from form elements

I have a Flask application, where I'm trying to retrieve some information from my HTML form, however, I don't get any info, and I have tried everything but nothing seems to be working.
Routes.py
#app.route("/about", methods=['POST', 'GET'])
def about():
name = request.form.get('name')
lastname = request.form.get('lastname')
msg = Message(
subject='Hello ' + str(name),
sender='kristofferlocktolboll#gmail.com',
recipients=
['kristofferlocktolboll#gmail.com'],
html= 'hello mr ' + str(lastname))
mail.send(msg)
confirm_msg = "Your message has been sent!"
return render_template("about.html", confirm_msg=confirm_msg)
about.html:
<h1 class="mb-5"> Enter your message, and i will get back to you as soon as possible</h1>
<form action="{{ url_for('about') }}" method="POST">
First name: <br>
<input type="text" name="name" size="35"><br>
Last name:<br>
<input type="text" name="lastname" size="35"><br>
Email-address: <br>
<input type="email" name="email" size="35"><br>
Phone-number: <br>
<input type="text" name="phone" size="35"><br>
Enter your message: <br>
<textarea type="text" name="message" rows="7" cols="40"></textarea><br>
</form>
<br>
<form>
<button type="submit" class="btn btn-outline btn-xl js-scroll-trigger" value="submit" method="POST">Let's get in touch</a>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I want it to be a post request, but whenever I remove the 'GET' attribute from my methods in my #app.route I get a "METHOD NOT ALLOWED" error, it might be due to the fact, that it is using GET to redirect.
The email is sent successfully, so the mail API is working fine. But it is sent with the values 'None' where the name and last name attribute where to be.
EDIT:
I have to cast the name and last name objects to a string, otherwise, I will get a Nontype error
Create template/my-form.html
<form method="POST">
<input name="name">
<input name="lastname">
<input type="submit">
</form>
On your flask appplication routes.py
from flask import Flask, request, render_template
app = Flask(__name__)
#app.route('/')
def my_form():
return render_template('my-form.html')
#app.route('/', methods=['POST'])
def my_form_post():
name = request.form['name']
lastname = request.form['lastname']
<do your manipulation>
return render_template(yourtemplate,processedtext = processedtext,somethingelse=somethingelse)
you can grep the vaiables in your second rendering template as
<html>
<body>
{{processedtext}}
{{somethingelse}}
</body>
</html>
and display them

creating forms in django - error in output

I have the following code in various places to attempt to produce a form in Django that takes data and writes it to the database
views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from .forms import TeacherSignup
"""def teachers(request):
return render(request,'teachers/teachers.html')
"""
def teachers(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = TeacherSignup(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/thanks/')
# if a GET (or any other method) we'll create a blank form
else:
form = TeacherSignup()
return render(request, 'teachers/teachers.html', {'form': form})
teachers.html (this is the html page that contains the form)
<form action="/teachers/" method="post" style="border:1px solid #ccc">
{% csrf_token %}
{{ form }}
<div class="container">
<label><b>Email</b></label>
<input id="email" input type="text" placeholder="Enter Email" name="email" required>
<label><b>Centre/School Name</b></label>
<input id="school_name" input type="text" placeholder="Enter School or Centre Name" name="school_name" required>
<label><b>Password</b></label>
<input id="password" input type="password" placeholder="Enter Password" name="password" required>
<label><b>Repeat Password</b></label>
<input id="password_repeat" input type="password" placeholder="Repeat Password" name="password_repeat" required>
<input type="checkbox" checked="checked"> Remember me
<p>By creating an account you agree to our Terms & Privacy.</p>
<div class="clearfix">
<button type="button" class="cancelbtn">Cancel</button>
<button type="submit" class="signupbtn">Sign Up</button>
</div>
</div>
</form>
</body>
</html>
forms.py
from django import forms
class TeacherSignup(forms.Form):
email=forms.CharField(label='email',max_length=100)
school_name=forms.CharField(label='school_name',max_length=100)
password=forms.CharField(label='password',max_length=100)
password_repeat=forms.CharField(label='password_repeat',max_length=100)
On running the server however, it produces TWO forms: The form I've created in the html and the one presumably created in the forms.py.
How do I use the form in teachers.html (which is at the end of the page) and use this created form to write data to the database, or does Django require that I created it using the forms.py?
A detailed explanation would be appreciated, with examples if possible.
In your template you can render field by field of your form
Something like this in teachers.html
<form action="/teachers/" method="post" style="border:1px solid #ccc">
{% csrf_token %}
<div class="container">
<label><b>Email</b></label>
{{ form.email }}
<label><b>Centre/School Name</b></label>
{{ form.school_name }}
<div class="clearfix">
<button type="button" class="cancelbtn">Cancel</button>
<button type="submit" class="signupbtn">Sign Up</button>
</div>
</div>
</form>
and do the same thing for the rest
if you want to add placeholder attribute you need to add widget param to your fields and the same if you want that your passwords fields could hide text
forms.py
from django import forms
class TeacherSignup(forms.Form):
email=forms.CharField(label='email',max_length=100, widget=forms.TextInput(attrs={'placeholder': 'Enter Email'})
school_name=forms.CharField(label='school_name',max_length=100, widget=forms.TextInput(attrs={'placeholder': 'Enter School or Centre Name'})
password=forms.CharField(label='password',max_length=100, widget=forms.PasswordInput)
password_repeat=forms.CharField(label='password_repeat',max_length=100, widget=forms.PasswordInput)