I am using parametrized ajax to send data to flask on button click. The data and buttons are in for loops and I want ajax to send single data but it's sending multiple items. The data sent back to flask only repeats for the first dictionary in the list, and is only the value for the first key in the dictionary. The rest generates an error.
Flask code
from Flask import flask,request
app = Flask(__name__)
all_items = [{'name':'sausage','price':10},{'name':'soda','price':50}]
#app.route('/index', methods=['GET', 'POST'])
def index():
if request.method == 'GET':
return render_template('index.html', all_items = all_items)
Ajax script:
<script type=text/javascript>
$(document).ready(function() {
$('form').on('submit', function(event) {
$.ajax({
data : {
item : $('#item').val(),
price: $('#price').val(),
},
type : 'POST',
url : '/index'
})
.done(function(data) {
//nothing
});
event.preventDefault();
});
});
</script>
Html:
{%for item in all_items%} <!--all_items is a list of dictionaries-->
<form>
<fieldset>
<input type="hidden" name="item" id="item" value="{{item.name}}">
<input type="hidden" name="price" id="price" value="{{item.price}}">
<input type="submit" name="submit" id="submit" value="Add to Cart" class="button" />
</fieldset>
</form>
{% endfor %}
Related
I have a Django project with a form in an HTML file, and I'd like to update the text on the submit button of that form WITHOUT a page reload. Essentially:
I click submit on the form
Python handles the submit with the form data
The button text is updated to say "show result"
If I understand correctly, I have to use AJAX for this. The problem is that the form submit relies on an API call in Python, so the HTML essentially has to always be "listening" for new data broadcasted by the views.py file.
Here's the code I have (which doesn't work, since when I hit submit I'm greeted by a page with the JSON response data and nothing else):
views.py:
def home(request):
if request.method == "POST":
print("Got form type", request.content_type)
return JsonResponse({"text": "show result"})
return render(request, 'home.html')
home.html:
<div class="content" onload="document.genform.reset()">
<form name="genform" autocomplete="off" class="form" method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
<div class="title-sect">
<h1>AJAX Test Form</h1>
</div>
<div class="submit">
<button id="submit" type="submit">Submit</button>
</div>
</form>
</div>
<script type="text/javascript">
function queryData() {
$.ajax({
url: "/",
type: "POST",
data: {
name: "text",
'csrfmiddlewaretoken': '{{ csrf_token }}',
},
success: function(data) {
var text = data['text'];
var button = document.getElementById('submit');
button.innerHTML = text;
setTimeout(function(){queryData();}, 1000);
}
});
}
$document.ready(function() {
queryData();
});
</script>
I've imported jQuery with the script <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.0.min.js"></script>. Any idea why this doesn't work in its current state? Thanks!
I am doing a project management tool web application. I would like user can choose 'user' from dropdown selection, click 'Add member', then the member will show somewhere under the member?. Here is what I am doing.
Please do not worry about the styling. I have not done UI yet.
view.py
def member_select(request):
if request.method == 'GET':
selection = request.GET.get('id',None)
if selection:
selected_member = User.objects.filter(pk=selection)
return selected_member
project_index.html
<form action="" method="GET" id="selection-form">
{% csrf_token %}
<select id="member_list">
{% for user in user %}
<option>
{{ user.username }}
</option>
{% endfor %}
</select>
<input type="button" value="Add member" id="selection-button">
</form>
base.html
<script>
var url = $( '#selection-form' ).attr( 'action' );
$("selection-button").onclick(function (e) {
e.preventDefault();
$.ajax({
type:'GET',
url:url,
data:{
id:$('#member_list').val()
},
success:function (result) {
alert('okay');
},
error:function (result) {
alert('error');
}
});
});
</script>
Maybe use an empty <p class='member-name'><p> and
after choosing in the jquery success function
change to
success:function (result) {
$('.member-name').text(result);
},
try this (not fully tested)
from django.core import serializers
from django.http import HttpResponse
def member_select(request):
selection = request.GET.get('id',None)
if selection:
data = serializers.serialize('json',User.objects.filter(pk=selection))
else:
data = {}
return HttpResponse(data, content_type='application/json')
from the docs https://docs.djangoproject.com/en/2.0/topics/serialization/
In javascript ajax funtion the response should be a user object if exists or empty json string
<form action="" method="GET" id="selection-form">
{% csrf_token %}
<select id="member_list">
{% for user in user %}
<option value="{{user.pk}}">{{ user.username }}</option>
{% endfor %}
</select>
<input type="button" value="Add member" id="selection-button">
</form>
<di id='res'></div>
$("#selection-button").on('click', function(e) {
e.preventDefault();
var value =$('#member_list').val();
$.ajax({
type:'GET',
url:'.',
data:{
id:value
},
success:function (result) {
alert('okay');
$('#res').append(result);
console.info(result);
},
error:function (result) {
alert('error');
}
});
});
This is a HTML template that displays all of the proposals in a database (passed through views.py as a list in the dictionary parameter). I then use a jinja for-loop to go through all the proposals in the database and display their attributes.
How can I Post-request the {{ proposal.id }} back to my python code when the "Learn more" button is clicked? I need this to allow me to display the corresponding values in my other html template.
Sorry if this is a basic question, i'm a high school student and extremely new to django! Thanks alot in advance!
{% block body %}
{% for proposal in proposals %}
<div class="jumbotron">
<h2> Proposal : {{ proposal.title }} </h2>
<h4> Status : {{ proposal.status }} </h4>
<h4> Out of --- Votes: </h4>
<div class="progress">
<div class="progress-bar progress-bar-success" style="width: {{ proposal.votes_for }}%">
<span class="sr-only">35% Complete (success)</span>
{{ proposal.votes_for }}% For
</div>
<div class="progress-bar progress-bar-danger" style="width: {{ proposal.votes_against }}%">
<span class="sr-only">10% Complete (danger)</span>
{{ proposal.votes_against }}% Against
</div>
</div>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
If you just want to go to the Proposal details you should definitely look to a class-based DetailView.
You can make it with AJAX request or you can make it with form. For the both of types you should have a View to catch it.
HTML Form:
In your template you should have:
<form id="formId" method="post" action="{% url 'catch-proposal' %}">
{% csrf_token %}
<input type="hidden" name="proposal_id" value="{{ proposal.id }}"/>
<p><button type="submit" class="btn btn-primary btn-lg">Learn more</a></p>
<!-- <input type="submit" class="btn btn-primary btn-lg" value="Learn more"/> -->
</form>
It will go to your View from urls.py:
url(r'^post/for/proposal/$', catch_proposal, name='catch-proposal'),
# if your view class-based
# url(r'^post/for/proposal/$', CatchProposal.as_view(), name='catch-proposal')
Then in your view you will catch POST data:
def catch_proposal(request):
if request.method == "POST":
print(request.POST) # have a look for your post params
return reverse_lazy('index') # your response, you can make it on your own
AJAX:
Check it! AJAX and Django
Page uses AJAX without any HTML form
A page makes a POST request via AJAX, and the page does not have an HTML form with a csrf_token that would cause the required CSRF cookie to be sent.
Solution: use ensure_csrf_cookie() on the view that sends the page.
In your scripts define:
function sendPost(proposalId) {
$.ajax({
url: '{% url 'catch-proposal' %}', // or just /ajax/catch/proposal/
method : "POST",
data: {
// your data to send key => val
'id': proposalId
},
dataType: 'json', // it can be xml, json, script, html
success: function (result) {
// Do something if your request was successful (code=200)
// All response data stored in result
console.log(result)
},
error : function(xhr,errmsg,err) {
// Error case
console.log(xhr.status + ": " + xhr.responseText);
}
});
}
For your Learn More button:
<p><button class="btn btn-primary btn-lg" role="button" onclick="sendPost({{ proposal.id }})">Learn more</button></p>
And you will catch it in your View:
#ensure_csrf_cookie # Since you sending POST request without form tag
def catch_proposal(request):
response_data = {} # your response
if request.method == 'POST':
# your post request
if 'id' not in request.POST: # check the param from POST
# Provide error message
response_data['error_message'] = "Can't find ID in POST params..."
else:
# Do whatever
proposal_id = int(request.POST.get('id'))
try:
proposal = Proposal.objects.get(id=transport_id)
response_data['success'] = True
except Proposal.DoesNotExist:
response_data['success'] = False
return JsonResponse(response_data)
else:
response_data = {
'error_message': 'Something is going very strange and wrong...'
}
return JsonResponse(response_data)
Adding created View to urls.py:
from .views import catch_proposal # or yourapp.views
....
url(r'^ajax/catch/proposal/$', catch_proposal, name='catch_proposal'),
....
im getting a bad request, here is my url code:
#app.route('/login', methods=['POST'])
def login():
print(request)
user = models.User.get(models.User.email**request.form['email'])
if request.form['password'] == user.rpe:
login_user(user)
return jsonify(user.to_json())
here is my html:
<form id="form">
<input type="email" placeholder="email" id="email" name="correo">
<input type="password" placeholder="rpe" id="password" name="password">
<button type="submit" ng-click="submit()">Log in</button>
</form>
and here is my js code:
$scope.submit = function(event){
var form = $('form');
var values = {};
$.each(form.serializeArray(), function(i, field){
values[field.name] = field.value;
});
data = JSON.stringify(values);
console.log(data);
$http.post('/login', values).success(function () {
alert('success');
});
}
after i do the request with the form, here is what i get:
<Request 'http://localhost:8000/login' [POST]>
im guessing that this request isnt what it is suppoused to be, im also asking because in other questions some user added a csrf token but i actually dont know how to add one with javascript since im adding my angular app this way:
#app.route('/')
def main():
return make_response(open('templates/index.html').read())
thanks
I have a simple form to submit and test ajax,but it doesn't work and I see any problem in it,I searched alot and there was no more poin-at least I dedn't see ;)
in urls.py
(r'^doctors/shahsavand/visiting/$','DrHub.views.visiting'),
(r'^doctors/shahsavand/visiting/add/$','DrHub.views.ajxTest')
the first URL is to direct to main page and there's this form in main page:
<form method='POST' action=".">
{% csrf_token %}
<ul>
<li>
<label for="start">Start Time: </label><input name="id_startTime" id="id_startTime" type="text" />
</li>
<li>
<label for="end">End Time: </label><input name="id_endTime" id="id_endTime" type="text" />
</li>
</ul>
<input type="submit" id="save_button" name="save_button" value="add" />
</form>
and ajax code in this page:
<script type='text/javascript' src='/static/DrHub/doctors/shahsavand/js/jquery-1.4.1.js'></script>
<script type="text/javascript">
$.ajax({
type:"POST",
url:"{% url DrHub.views.ajxTest %}",
data: {
'start': $('#id_startTime').val(),
'end': $('#id_endTime').val(),
'csrfmiddlewaretoken':$( "#csrfmiddlewaretoken" ).val()
},
success: function(data){
alert(data);
}
});
</script>
in views.py :
def ajxTest(request):
if request.is_ajax():
if request.method == 'POST':
return HttpResponse(simplejson.dumps({'message' : 'awesome'}), mimetype='application/javascript')
else:
return render_to_response('DrHub/doctors/nutrition/test.html', context_instance=RequestContext(request))
I did this to test if ajxTest view is called:
def ajxTest(request):
if request.is_ajax():
raise Http404
else:
pass
and this :
def ajxTest(request):
if request.is_ajax():
raise pass
else:
Http404
but no result and that sounds like my ajax POST is not associated with ajxTest view !!!
edit
when I check firebug I get 403 forbidden error that is for CSRF and I've tryed many things to solve it again no result :(
Add the javascript described in the documentation for csrf and it should fix your problem.