I have a Vue-multiselect, as in this example (not mine)
https://jsfiddle.net/gmsa/04jvjuv3/
I'm trying to get the value in the multi select element and POST it back to my Flask app.
HTML
<form action="" method="POST">
<multiselect id="multi", name = "multi" :multiple="true" :hide-selected="true" :selected="selected" :options="options" :taggable="false" #update="updateSelected"></multiselect>
<button type="submit" value="l1" >Load</button>
</form>
Flask
if request.method == 'POST':
print request.form.getlist('multi')
#prints an empty list
print request.form['multi']
#hits a bad request error
I've been klutzing about with this for a long time now - why can't I get the value from the form element?
The thing is that vue-multiselect is meant to be handled using pure javascript. So, you could just use the solution implemented by the user in that issue.
In HTML:
<input style="display: none;" :value="selected" name="multiselect">
Inside the form, and in python:
request.form.get('multiselect').split(',')
The split is in case multiple options were selected.
BTW, that fiddle uses old versions of both vue and multiselect, but that's unrelated.
Related
This question already has answers here:
Sending data from HTML form to a Python script in Flask
(2 answers)
Closed 1 year ago.
I've created a form with flask. This is the python code that handles the requests that come from this form:
#app.route("/submitclips/", methods=['GET', 'POST'])
def submitclips():
print(request)
print(request.method)
result = request.form.to_dict(flat=False)
print(result)
print(request.data)
HTML code:
<form action="/submitclips" method="POST">
<input type="hidden" name="taskpath" value="paththotask">
<table>
<th>Video</th>
<th>Mute</th>
<th>Delete</th>
<th>Keep</th>
<tr>
<td>
<video width="320" height="240" controls>
<source src="videosource.mp4" type="video/mp4">
</video>
</td>
<td>
<input type="radio" id="name$mute" name="name" value="mute">
</td>
<td>
<input type="radio" id="name$delete" name="name" value="delete">
</td>
<td>
<input type="radio" id="name$keep" name="name" value="keep" checked>
</td>
</tr>
</table>
<input type="submit">
</form>
This is a table and has more than one row, I changed the values to make it more readable. I guarantee that all names are unique where they are supposed to be unique though.
It has some code below it, but it crashes there because the form seems to be empty. I have checked the HTML and it's all correct, all inputs have a name. I also recorded the network traffic on google chrome to test this and I can see that all data in the form is present in the request data. So I'm pretty sure it's correct on the front-end. The problem is that it just doesn't show up in this method. In the code you can see several print statements and all of these show me empty data and not the data that I could see in my chrome browser. The method is GET, I don't know if it should be GET. In HTML I selected it to be a POST method, but if I remove the GET option from the python code, it gives me a "method not allowed" error.
I don't know what to do, this is some older code that used to work on my windows machine. I didn't change anything about it, but now I'm working on linux and it's completely broken, none of the forms work, it's all empty data.
Here you have mentioned that the endpoint /submitclips has methods GET and POST. It means that whenever i hit the url "baseurl/submitclips" then this function will be executed. Inside the function you have not specified for which method you will have what response, i.e if i call the endpoint using GET or POST you will process it the same way. This is not a good practice. I suggest you put something like :
if request.method == 'POST' or if request.method == 'GET' to separate the execution based on the type of method.
Now coming to the HTML, you must have the HTML from where you are sending the request to the server. If that data is coming from a form, then as part of the form you can add two attributes,
<form method="post"> and <form action="/submitclips"> to specify that on submit of this form,you will be sending the form data through POST method to the "/submitclips" url. It will look like this.
<form method="post" action="/submitclips"">
For the Server side,
def submitclips():
if request.method == 'POST' :
print(request)
print(request.method)
result = request.form.to_dict(flat=False)
print(result)
print(request.data)
It should work after that.
I have found the error. My HTML code would submit the form to "/submitclips" while the python code received requests from "/submitclips/". I don't know why this is wrong though, the tutorial that I followed for flask told me specifically that putting a slash at the end meant that it could receive requests from both "/submitclips" and "/submitclips/". This also worked earlier on my windows machine, but doesn't work anymore on my linux machine. I'm glad it's solved, but if anyone has an explanation for why this is wrong, feel free to answer.
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!
I am trying to build a front end for a simple TFIDF based document retrieval model(all written in python). The front end will be a simple search bar where the user can enter a query. Using that query I want to return the documents ranked on the basis of their relevancy. I have the backed ready. I have a small function, lets call it query_scorer that takes in the query, does the requisite pre-processing(tokenization, spellcheck, lower casing, etc.) and selects and ranks documents based on their relevancy. What I don't know is how do I pass this query from my html page to the query_scorer and pass the results back to the html page (or maybe a different html page). Lets say I have the following page.
<section >
<form action="" method="">
<input type="search" placeholder="What are you looking for?">
<button>Search</button>
</form>
</section>
How do I transfer the text from the search box to my python script?
Try this:
In the form tag's action="",provide the location of your cgi script and the value of the textbox will be passed to the cgi script.
eg.
<form name="search" action="~/query_scorer.py" method="get">
<input type="text" name="searchbox">
<input type="submit" value="Submit">
</form>
query_scorer.py
import cgi
form = cgi.FieldStorage()
searchterm = form.getvalue('searchbox')
Hope so you may get your result.
You will need to host the php script and expose it as either a web service or web page. I would suggest web page as the easiest method to get started.
You will then need to post to this web page from your form above by entering the action and method in your form attributes.
You web page will need to return html and also call your function.
See a basic overview here
I currently have a search function in my views.py file like so:
def json_search(request):
query = request.GET.get('query')
api_key = locu_api
url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key
locality = query.replace(' ', '%20')
category =
final_url = url + "&locality=" + locality + "&category=" + category
json_obj = urllib2.urlopen(final_url)
decoded_data = json.load(json_obj)
return render(request, 'loc_search.html',
{'objects': decoded_data['objects']})
What I have set up is a drop-down search bar whereby I want the category variable within my json_search() function to automatically be assigned to the selected option on the drop-down bar before the form is submitted using the submit button. The search bar looks like this :
And the code like this:
<form action="{% url 'search' %}">
<div class="input-group">
<input name="query" input id="address" type="textbox" placeholder="City or Zipcode" class="form-control datebox">
<div class="input-group-btn">
<button class="btn btn-default" type="submit" id="addressSearch">Search</button>
<button name = "category_query" tabindex="-3" data-toggle="dropdown" class="btn btn-default dropdown-toggle" type="button">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" >
<li>Resturant</li>
<li>Activities</li>
<li>Bar / Club</li>
<li class="divider"></li>
<li>other</li>
</ul>
</div>
</div>
</form>
Is this even possible?
You would have to get the value back to the backend view code in some fashion in order for that to happen.
It would be possible to do so prior submitting the form. For example, you could use an Ajax call within the template code to hit the same URL serviced by the json_search function, passing category in the URL, and then pulling it out of request.GET.
If you wanted it to be assigned upon dropdown selection, you would want to attach a click event handler via jQuery to that dropdown, and then in that handler's function, get the selected value, and then add it to the Ajax call back to your json_search function.
In your json_search code, you'll want to differentiate handling the submit (which should be a POST) vs. general GET handling (perhaps based on whether various parameters are present in the URL).
Edit in response to comment from OP:
It's certainly not trivial, especially if you've not worked with Ajax before, but it shouldn't be too bad overall (and once you get the hang of it, this paradigm can be used for all sorts of interaction with other modules like Datatables and many others, not to mention your own Django backend).
While there are many different ways to do this, I'm a fan of using jQuery's when in conjunction with done (used in examples on the same page). The when lets you fire off multiple asynchronous Ajax requests, and the done acts as a join point where you wait for them to finish before proceeding.
Yes, this is possible, you would make all the links in the dropdown have a onclick handler which would need to save the category. Then instead of a url for the form you would use a submit function which would send your form data + the category.
That is something easy to do with angular + ui.bootstrap.
with jQuery
http://plnkr.co/edit/iBY2n9dq8Tn95IUGwNAB?p=preview
You need to transform your links not to have a valid href and instead call a function, e.g.:
Restaurant
and add a hidden field for the category
<input name="category" input="" id="category" type="hidden" placeholder="Category" class="form-control" />
and some easy javascript
function setCategory(category) {
alert('category (hidden) = ' + category);
$('#category').val(category);
}
I'm trying to get to grips with web2py/python. I want to get the user to fill in a search form, the term they search for is sent to my python script which should send the query to the blekko API and output the results to them in a new HTML page. I've implemented the following code but instead of my normal index page appearing, I'm getting the html response directly from blekko with '%(query)' /html appearing in it's search bar. Really need some help with this!
HTML form on the default/index.html page
<body>
<div id="MainArea">
<p align="center">MY SEARCH ENGINE</p>
<form name="form1" method="get" action="">
<label for="SearchBar"></label>
<div align="center">
<input name="SearchBar" type="text" id="SearchBar" value="" size = "100px"><br />
<input name="submit" type="submit" value="Search">
</div>
</form>
<p align="center"> </p>
Python code on the default.py controller
import urllib2
def index():
import urllib2
address = "http://www.blekko.com/?q='%(query)'+/html&auth=<mykey>"
query = request.vars.query
response = urllib2.urlopen(address)
html=response.read()
return html
I think you are misunderstanding how string formatting works. You need to put the address and query together still:
address = "http://www.blekko.com/?q='%(query)s'+/html&auth=<mykey>" % dict(query=request.vars.query)
Add a hidden field to your form, call it "submitted". Then reformat your controller function as such:
import urllib2
def index():
if request.vars.submitted:
address = "http://www.blekko.com/?q='%(query)'+/html&auth=<mykey>"
query = request.vars.query
response = urllib2.urlopen(address)
html=response.read()
return html
else:
return dict()
This will show your index page unless the form was submitted and the page received the "submitted" form variable.
The /html doesn't do anything. Glad your question got answered. There is python client code for the blekko search api here: https://github.com/sampsyo/python-blekko