Ajaxing refresh to a div once added an "Item" - python

I've gotten my view to successfully add my item to my cart. However, I just want it to ajax refresh (of sorts) the '#cart' div, while still on the original page. In other words, the item is added to into the cart, but only shown if I manually refresh. I just want it to look smooth and ajax-y.
Views.py:
#login_required
def add(request, profile):
if request.method != 'POST':
return HttpResponseNotAllowed('POST')
try:
item = Item.objects.get(slug=slugify(request.POST['itemname']))
except ObjectDoesNotExist:
item = Item(name=request.POST['itemname'])
item.save()
profile = Profile.objects.get(user=request.user)
profile.items.add(item)
response = simplejson.dumps(
{"status": "Successfully added."}
)
return HttpResponse (response, mimetype='application/json')
Template:
<form id="addItemForm" class="form-style" method="POST" action="/item/add/{{ profile }}/">
{% csrf_token %}
<input id="item-input" class="input-text inline required" name="itemname" type="text" />
<button class="blue" type="submit" id="additem">
Add Item
</button>
</form>
Script:
$('#addItemForm').submit(function(e){
e.preventDefault();
var form = $("#additem").attr("action");
var post_data = $.post($(this).attr('action'), $(this).serialize(), function(data, textStatus, jqXHR){
$('.item-selection').html(data);
result = $.ajax({
url: form,
data: post_data,
type: "POST",
success: function(data) {
//alert("Successfully added");
console.log()
$("#item-selection").replaceWith($('#item-selection', $(html)));
//{[( THIS IS WHERE I'D LIKE IT TO REFRESH)]}
},
error: function(data) {
// return the user to the add item form
$('#addItemForm').html(data);
}
});
});
Console error:
Uncaught TypeError: Cannot call method 'toLowerCase' of undefined
( I apologize for the formatting )
I'm an ajax beginner. It's clearly something wrong with my script. I just don't know where to go from here.
Thanks for your help in advance.

i cant see in your code what you mean. but this should reload the #cart element.. alhtough there is probably a better way to do it without downloading the entire page again just for the content on one element
$('#cart').load('ajax/test.html #cart');

Related

Django - template reloads after ajax response

I'm sort of new with Django and I ran through an issue. I'm sending a post request to django view and return the function back with HttpResponse in order to change my template's div contents to the passed value from my view. The issue is: once ajax responds and changes it's div's value; the page instantly reloads. Do you guys have any idea why?
Views.py
def index(request):
if request.is_ajax():
print("request is ajax")
details = request.POST.get('id')
return HttpResponse(details)
else:
return HttpResponse("Failed)
base.html
<button id="checkres">Check result</button>
<form name="testform" id="testform" method="post">
{% csrf_token %}
<input type="text" id="rowfield">
<input type="submit">
</form>
$("#testform").submit(function (event){
$row_num = $('#rowfield').val()
$("#responseresult").text('checking');
$.ajax({
type: "POST",
url: "/bot",
data: {csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val(), id: $row_num},
success: function(data){
$("#responseresult").text(data);
alert(data);
}
});
});
Your javascript submit event not calling event.preventDefault(), that's the reason that after ajax response, the is refreshing. Change your javascript function to:
$("#testform").submit(function (event){
$row_num = $('#rowfield').val()
$("#responseresult").text('checking');
$.ajax({
type: "POST",
url: "/bot",
data: {csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val(), id: $row_num},
success: function(data){
$("#responseresult").text(data);
alert(data);
}
});
event.preventDefault(); // prevents the page from refreshing.
});
Further read about preventDefault()
Try this for your view
def index(request):
if request.is_ajax():
print("request is ajax")
details = request.POST.get('id')
return JsonResponse(details, safe=False)
else:
return JsonResponse("Failed" safe=False)
You need to prevent submit as well.
$("#testform").submit(function (event){
$row_num = $('#rowfield').val()
$("#responseresult").text('checking');
$.ajax({
type: "POST",
url: "/bot",
data: {csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val(), id: $row_num},
success: function(data){
$("#responseresult").text(data);
alert(data);
}
});
event.preventDefault(); // prevents the page from refreshing.
});

How do I use AJAX to both create and edit new posts using the same html template (with Python & Django)?

I'm trying to switch to saving a form with AJAX instead of just Python/Django (I'm an absolute newb, so please forgive my idiocy). Here's what I'm trying to achieve:
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.blurb_new, name='blurb_new'),
path('blurb/new/', views.blurb_new, name='blurb_new'),
path('blurb/<int:pk>/edit/', views.blurb_edit, name='blurb_edit'),
]
views.py (the relevant part):
#login_required
def blurb_new(request):
if request.method == "POST":
form = BlurbForm(request.POST)
if form.is_valid():
blurb = form.save(commit=False)
blurb.author = request.user
blurb.save()
return redirect('blurb_edit', pk=blurb.pk)
else:
form = BlurbForm()
return render(request, 'mysite/blurb_edit.html', {'form': form})
#login_required
def blurb_edit(request, pk):
blurb = get_object_or_404(Blurb, pk=pk)
if request.method == "POST":
form = BlurbForm(request.POST, instance=blurb)
if form.is_valid():
blurb = form.save(commit=False)
blurb.author = request.user
blurb.last_edited_date = timezone.now()
blurb.save()
return redirect('blurb_edit', pk=blurb.pk)
else:
form = BlurbForm(instance=blurb)
return render(request, 'mysite/blurb_edit.html', {'form': form, 'blurb': blurb})
blurb_edit.html (the relevant parts):
<form id="myform" method="POST" class="blurb-form">{% csrf_token %}
<input id="blurb-name" name="title"
{% if form.title.value != None %}value="{{ form.title.value }}"{% endif %}
/>
<textarea name="text" id="my-textarea">
{% if form.text.value != None %}
{{ form.text.value }}
{% else %}
Type your blurb here.
{% endif %}
</textarea>
<button type="submit">Save</button>
</form>
Before I used AJAX, views.py was totally doing its job (except for that pesky, unwanted page refreshing).
Because I hate the way the page refreshed every time you saved a blurb edit, I decided to switch to using AJAX.
Here's some AJAX I added in. It works for editing a blurb, but not for creating a new blurb--presumably because a new blurb does not have a pk yet. I'm not sure how to fix this.
AJAX in blurb_edit.html:
<script type="text/javascript">
$(document).on('submit', '#myform', function(e) {
e.preventDefault();
$.ajax({
type: 'POST',
url:'{% url 'blurb_edit' pk=blurb.pk %}', // <--- THIS "pk" isn't working if it's a new blurb
data:{
title:$('#blurb-name').val(),
text:$('#my-textarea').val(),
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
success:function() {
alert("yay! it worked.")
}
})
});
</script>
So I can edit blurbs fine.
This is the error I get when I load the home page to create a new blurb:
NoReverseMatch at /
Reverse for 'blurb_edit' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['blurb/(?P<pk>[0-9]+)/edit/$']
How can I fix this "pk" issue, so that AJAX can work like views.py was?
Again, please forgive my ignorance (and probably shitty code) here, as I am new to these things and trying to wrap my head around it. Thank you! :)
<script type="text/javascript">
$(document).on('submit', '#myform', function(e) {
e.preventDefault();
$.ajax({
type: 'POST',
url:'blurb_edit/{{blurb.pk}}/edit/', // check this version of url
data:{
title:$('#blurb-name').val(),
text:$('#my-textarea').val(),
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
success:function() {
alert("yay! it worked.")
}
})
});

How to populate a django form in a POST request with data from an ajax call?

I'm sending form data via an ajax call after user hits submit button and then handling this request in my views, but the form is empty. How can I populate the form?
This is my code:
My JS file:
var csrftoken = getCookie('csrftoken'); //getCookie is a csrf_token generator
var form = $(this).closest('form')
$.ajax({
url: form.attr("action"),
data: { // if I change this line to data: form.serialize(), it works fine!
csrfmiddlewaretoken : csrftoken,
form: form.serialize(),
},
type: form.attr("method"),
dataType: 'json',
success: function (data)
{
//Do a bunch of stuff here
}
})
My views:
def task_edit(request, pk):
task = get_object_or_404(Task, pk=pk)
if request.method == 'POST':
task_form = NewTaskForm(request.POST) # This is empty!
else:
task_form = NewTaskForm(instance=task) # This for populating the edit modal, works fine!
I'm not doing the data: form.serialize() because I need to send additional data with the ajax request. How do I get this working?
You can write as below:-
$form_data = $("#idofform").serialize();
And then in ajax
data : $form_data+'&key=value',
You can use services like https://www.formkeep.com to capture form data using AJAX.
This may be a good idea if you are already using a JavaScript framework, you want to add validation logic, or you don't want to redirect the user after they submit the form.
You can submit to FormKeep using a standard AJAX request. To ensure the request does not cause a redirect, be sure to set the Accept header to application/javascript.
Given the following form:
<form id="newsletter-signup" action="http://formkeep.com/f/exampletoken" method="POST" accept-charset="UTF-8">
<input type="hidden" name="utf8" value="✓">
<input name="email" type="email">
<input value="Submit" type="submit">
</form>
Here's an example of how to submit a form with jQuery:
$(function() {
$('#newsletter-signup').submit(function(event) {
event.preventDefault();
var formEl = $(this);
var submitButton = $('input[type=submit]', formEl);
$.ajax({
type: 'POST',
url: formEl.prop('action'),
accept: {
javascript: 'application/javascript'
},
data: formEl.serialize(),
beforeSend: function() {
submitButton.prop('disabled', 'disabled');
}
}).done(function(data) {
submitButton.prop('disabled', false);
});
});
});
That's it. Once your data is securely captured in FormKeep you can easily store it, manage it or connect it with 1000s of other systems like Google Docs and Hubspot and Mailchimp.

Django ajax redirecting on form submission

I'm trying to return data with an ajax request on a form submission. My goal was too use two views, one too handle the template loading and the other to handle the POST request from the form. In the current state, the form is redirecting to the JSON that is in the callback. That makes sense as it's for the form action url is pointing, however, i want to just pass the data to the current page and not reload the page or be redirected to another page.
Here is the code:
user.html
<form action="{% url 'ajax-user-post' %}" method="post">
{% csrf_token %}
{% for user in users %}
<input type="submit" name="name" value="{{ user }}">
{% endfor %}
views.py
def ajax_user(request):
# get some data..
if request.METHOD == 'POST':
user = request.POST['user']
user_data = User.objects.get(user=user)
data = {'user_data': user_data}
return JsonResponse(data)
def user(request):
return render(request, 'user.html', context)
urls.py
url(r'^user/', user, name="user"),
url(r'^ajax/user/', ajax_user, name="ajax-user-post")
.js
$('form').on('submit', function(){
var name = // the name of the user selected
$.ajax({
type: "POST",
dataType: "json",
url: 'ajax/user/',
data: { 'csrfmiddlewaretoken': csrftoken, 'name': name, 'form': $form.serialize() },
success:function(data) {
// hide the current data
console.log(data);
displayUserData(data)
}
})
});
Thanks for the help in advance!
i want to just pass the data to the current page and not reload the page or be redirected to another page.
That means you need to stop the form submission event with the event.preventDefault() call.
Hence, change this line from:
$('form').on('submit', function(){
to to following two:
$('form').on('submit', function(e){
e.preventDefault();

Django dynamic inputs

I'd like to create dynamic input system, for example when I enter the folder name - the list of files inside automatically show up another input ChoiceField below, so I can choose the file. The methods are already written, the problem is - How can I make it in Django view?
Here is my view:
def get_name(request):
if request.method == 'POST':
form = NameForm(request.POST)
if form.is_valid():
dir_date = format_date(request.POST['date'])
files = os.listdir(os.path.join(path+dir_date))
return render(request, 'inform/show_name.html', {'data': request.POST['your_name'],
'date': format_date(request.POST['date'])})
else:
form = NameForm()
return render(request, 'inform/base.html', {'form': form})
Here is the form class:
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
date = forms.DateField(widget=forms.DateInput(attrs={'class': 'datepicker'}))
flights = forms.ChoiceField(choices=?)
Finally, here is my template.
{% extends 'inform/header.html' %}
{% block content %}
<script>
$( function() {
$( ".datepicker" ).datepicker();
$( "#anim" ).on( "change", function() {
$( "#datepicker" ).datepicker( "option", "showAnim", $( this ).val() );
});
} );
</script>
<div class="container" style="color: red; size: auto;">
<form class="form-vertical" action="get_name" role="form" method="post">
{% csrf_token %}
<div class="form-group" style="display: inherit">
<center>
{{form}}
<input type="submit" value="OK">
</center>
</div>
</form>
</div>
{% endblock %}
Is there any way to dynamically read the data from the Date input and give it to the method inside the view without clicking the submit button or creating several others? If it can be solved only by ajax, jQuery or JS, could you please give me a simple sample of how it's done? I'm pretty much frustrated by the inability of creating a simple form.
Thank you in advance!
So basically you are doing it right. You already know that you need the on(change) function for the datepicker
Now as soon as the user changes a date, your on(change) function is triggered. So all you need to do now is to the get the new date value, which you already have when you do $( this ).val(). After that make an ajax call to the url corresponding to your method get_name in views.py
Something like this:
$( function() {
$( ".datepicker" ).datepicker();
$( "#anim" ).on( "change", function() {
$( "#datepicker" ).datepicker( "option", "showAnim", $( this ).val() );
send_changed_date_value(variable_with_new_date);
});
});
function send_changed_date_value(new_date) {
$.ajax({
type: // "POST" or "GET", whichever you are using
url: "/url in urls.py corresponding to get_name method in views.py/",
data: new_date,
success: function(response){
console.log("Success..!!")
}
});
}
This is how you can send the new date value to your views, everytime it is changed. If you want to submit the complete form data, i.e., your_name and flights data as well, then you may directly send serialzed data of the form in the data attribute of ajax.
Note -> You will have to return a HttpResponse from your get_name view as an ajax call requires a HttpResponse from the backend to complete the ajax call successfully. You may simply return a string in the response.

Categories

Resources