Getting button name as input - python

In this example I am assigning a variable (hsname) the school that is selected when sending the form:
<form class="w3-wide" action="/hschool" method="post">
<input list="hschools" name="hsname" autocomplete="off">
<datalist id="hschools">
<option value= "hs1">
<option value= "hs2">
</datalist>
<input type="submit">
</form>
I then use this value in python (with flask) and to get it I use the following (in a separated .py file):
hsname = request.form.get("hsname")
The previous is working fine.
In a similar way, I want to assign to a variable the name of the button that the user is clicking (b1 or b2). The following is not working as there is not variable that records the button that the user clicks.
<form class="w3-wide" action="/subject" method="post">
<button class="button button4" name="b1">b1</button>
<button class="button button4" name="b2">b2</button>
</form>
How can I do it?
I know I could use a radio button here but aesthetically I would rather use a normal button. I know I can use the onclick method but what should I write inside so that it stores a variable that is directly sent to flask?

If you want to send the info to the server as soons as the button is clicked, you can give a name and a value to an html <button> and those will be sent with the form:
<form class="w3-wide" action="/subject" method="post">
<button type="submit" name="clicked_btn" value="b1">b1</button>
<button type="submit" name="clicked_btn" value="b2">b2</button>
</form>
Once one of these buttons is clicked, the form will be submitted and the name and value (e.g. clicked_btn=b1) will be sent to the server (along with any other inputs in the form).
On the other hand, if you want to just remember the state of the button, so that it behaves like a checkbox or like a radio button, only to be sent to the server when a (different) submit button is clicked, then I suggest actually using a checkbox or a radio button and modifying its appearance using CSS to make it look like a button.
You can also use javascript to store some information into a <input type=hidden> input, which will later be sent to the server.

You can create an id for each button that can be captured on the client side send to the server via ajax:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<input type='text' id='value'>
<button class="button button4" name="b1">b1</button>
<button class="button button4" name="b2">b2</button>
</form>
<div id='user_results'></div>
<script>
$(document).ready(function() {
$('button').click(function(even){
var the_id = event.target.id;
var user_input = $('#value').val();
$.ajax({
url: "/get_user_data",
type: "get",
data: {btn: the_id, result:iuser_input},
success: function(response) {
$('user_results').html(response);
},
error: function(xhr) {
//Do Something to handle error
}
});
});
});
</script>
</html>
Then, in your .py file, create a route to receive the data from ajax:
#app.route('/get_user_data')
def get_data():
button_id = flask.request.args.get('btn')
user_input = flask.request.args.get('result')
return '<p>Thanks</p>'

You could put your button in a form with a hidden input and access the value with request.form.get("hsname") or request.POST.get("hsname) depending on how flask implements this (i'm more familiar with django).
Note that you will need 1 form+input per buttons
<form method="POST" action="some_url/">
<input type="hidden" name="hsname" value="the_name_of_the_button">
<button class="button button4" type="submit"></button>
</form>
EDIT: this is html 4.1, for html 5 see zvone's answer.

Related

Am I able to get the text of a radio button in html to use in Flask?

I'm working on a simple web application that lets users rate and comment on movies, storing them in a database to be viewed later. The user inputs a movie to rate, and if that movie title is shared by multiple films, they are prompted to specify which of those films they meant. I've chosen to do this with radio buttons in my html file, but I can't figure out how to get the text of the button chosen and use it in Flask. The application takes the name of the film chosen and prints that name at the top of a different html file, but no matter what I do it always prints "None" instead of the chosen title.
I was able to find this answer: Get the text of the selected radio button in JQuery , which led me to try
var confirmed = $("input[name='confirmation']:checked").parent('label').text();
in my html script in order to obtain the text of the checked button. But when I try to request this in Flask it does not work.
confirm.html :
<div id="id02" class="modal" data-backdrop="false">
<form class="modal-content animate" action="/confirm" method="post">
<span onclick="document.getElementById('id02').style.display='none'" class="close" title="Close Modal">×</span>
<div class="container">
<h1>Please Specify Which Title to Rate:</h1>
{% for movie in multi %}
<label class="container">{{movie["title"]}} ({{movie["year"]}})
<input type="radio" id={{movie["year"]}} name="confirmation">
<span class="checkmark"></span>
</label>
{% endfor %}
<button type="submit">Rate</button>
</div>
<div class="container" style="background-color:#f1f1f1">
<button type="button" onclick="document.getElementById('id02').style.display='none'" class="cancelbtn">Cancel</button>
</div>
</form>
</div>
<script>
// Get the modal when page is loaded
$(window).on('load',function(){
$('#id02').modal('show');
});
var modal = document.getElementById('id02');
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
// variable storing the name of the film selected
var confirmed = $("input[name='confirmation']:checked").parent('label').text();
</script>
application.py :
#app.route("/confirm", methods=["GET", "POST"])
def confirm():
if request.method == "POST":
full = request.form.get("confirmed")
session["title"] = full # add movie title to session in order to use in rate function
return render_template("rate.html", full=full)
else:
return render_template("confirm.html")
I also have tried assigning an id to the button if it is checked in hopes of getting the text from the id, but when I tried this I just got "None" as well.
{% for movie in multi %}
<label class="container">{{movie["title"]}} ({{movie["year"]}})
<input type="radio" name="confirmation">
{% if checked=="checked" %}
<input type="hidden" id="confirmed" value="({{movie["year"]}})">
{% endif %}
<span class="checkmark"></span>
</label>
{% endfor %}
I'm very new to programming and this is my first time trying to make a web application, so any help on this is greatly appreciated!
When flask gives you a radio button value. It gives you the value attribute not the radio button text, so you only need to put value attributes to your radio buttons

How to find out which input type submit button has been clicked? Or how to get the value or name of the clicled button?

So I have a form equipped with several buttons. The form has a textfield which basically shows the contents of the files uploaded by the user. Now clicking on any of these buttons submits the form, but I need to tag the content submitted with a keyword depending on which button was clicked and I need to do this in Python as afterwards these contents are being sent via a queue. And this is all done in Flask. Now my question is: Is there any way to find out which submit button was clicked in python?
If you give your button a name, the clicked one will be sent through as any other input, so you can access it in Flask.
<input type="submit" name="action" value="Create">
Or maybe use the same name with different values.
<input type="submit" name="action" value="Create">
<input type="submit" name="action" value="Delete">
Try this, It gives the element which you clicked.
$(document).on('click', function(event) {
var target;
return target = $(event.target);
});

Python Flask: Bad Request on Post method with radio-option checked

Lets say I have 2 radio buttons in my html script, of which one is checked by default:
<form action="" method="post">
<div class="radio-option checked">
<input type="radio" name="radioName" value="val_1"/>
</div>
<div class="radio-option">
<input type="radio" name="radioName" value="val_2"/>
</div>
<div>
<input type="submit" value="Confirm and continue"/>
</div>
</form>
If I click the submit button without clicking the other radio button, I get an error:
Bad Request The browser (or proxy) sent a request that this server
could not understand.
This happens because there is no value which is being transfered if a radio button is checked by default but not being selected with the mouse afterwards! This is what request.form shows me ImmutableMultiDict([]). If I select the other radio button with the mouse and click the submit button it shows me values ImmutableMultiDict(['radioName', 'val_2'])
I tried to catch the error like this, but it didn't work out:
if request.form == '':
flash('error')
return render_template('default_template.html')
How can I handle this within flask?
How can I set a default value, which can be sent to the server?
You could perform a check within flask. Check if request.form has items or if its empty and throw the error in that case.
A simple way of knowing if its empty would be, for example:
if len(request.form) == 0:
print('Error: The form is empty')
else:
print('The form has data, we can proceed')
Another way is:
if 'radioName' not in request.form:
print('Error: The form is empty')
...
But maybe flask has a better way of doing this or there are better practices to follow in these cases.
On the other hand, in the html snippet that you posted, none of the inputs is checked by default.
You have the checked css class on a div but not the checked attribute in an input with type=radio.
The correct use of checked attribute would be as follows:
<form action="" method="post">
<div class="radio-option checked">
<input type="radio" name="radioName" value="val_1" checked/>
</div>
<div class="radio-option">
<input type="radio" name="radioName" value="val_2"/>
</div>
<div>
<input type="submit" value="Confirm and continue"/>
</div>
</form>
This way, the radio input with value val_1, will be checked by default, populating the dictionary that goes to the server.
For more information, check out: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio
You can also avoid sending empty forms to the server using the required attribute to make sure that the user fills the form as expected.
To learn more about this: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation
I hope it helps!

Adding two numbers in flask

<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.

How to get value on drop box in Flask Python

I have a file XML. It's follow . I use Flask Framework Python to get query in search bar and value of current dropbox (e.g english or vietnamese). I use "POST" method get value when I enter or click "Search" button. But value of dropbox is null.
<form class="input-group">
<div class="input-group-btn search-panel" id="menu1">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span>Language</span>
</button>
<ul name ="btnLanguage" class="dropdown-menu" role="menu">
<li><a>English</a></li>
<li><a>Vietnamese</a></li>
</ul>
</div>
<input type="text" class="form-control" name="query" id ="query" placeholder="Search sentence...">
<span class="input-group-btn">
<button id ="btnSearch" class="btn btn-success" type="submit">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
</button>
</span>
</form>
How can you help me. Thank you
#app.route("/search" , methods=["POST"])
def search():
print("True")
# read the posted values from the UI
_query = request.form['query']
print(_query)
_language = request.value['btnLanguage']
print(_language)
and Json Method:
$(function(){
$('#btnSearch').click(function(){
$.ajax({
url: '/search',
data: $('form').serialize(),
type: 'POST',
success: function(response){
console.log(response);
},
error: function(error){
console.log(error);
}
});
});
});
It is because ul-li is not a regular form control (Checkout this link for available form control in html). So jquery will not consider it when serializing form data. Solution : You need to write a script to append custom data with your form data or you should use <select> instead of ul-li dropdown.
Other problems with your code.
You are using click() event handler with a button having type submit so two events will occur, one is ajax you are calling and another is form will be submitted to server side with GET. To remove is issue you should be listening for form submit() event with preventing event propagation (check this answer).

Categories