Django - ajax call for loading page not working - javascript

I need really help..
I'm not good at front-end and I'm very confused with Ajax.
I'm trying to do an Ajax call for when I click on a button of my table so when I hit that button my ajax should show my animation .gif so the user should know that the page is loading.
my template:
<style>
.ajaxProgress{
display:none;
text-align: center;
}
</style>
<div id="output">
<div class="ajaxProgress">
<h3>Please wait..</h3>
<img src="{% static 'img/ajax.gif' %}" alt="loading"/>
</div>
</div>
{% for item in qs %}
<tr>
<tbody>
<td
a id="mqtt" class="btn btn-xs btn-info" title="mqtt" href="javascript: startAjax(){% url 'start_mqtt' item.id %}"><span class="fa fa-signal"></span> </a> </td>
</tbody>
</tr>
{% endfor %}
</table>
<script>
function startAjax() {
$('.ajaxProgress').show();
$.ajax({
type: "GET",
dataType:"json",
async: true,
data: { csrfmiddlewaretoken: '{{ csrf_token }}' },
success: function(json){
$('#output').html(json.message);
$('.ajaxProgress').hide();
GetRating(json.message);
}
})
}
</script>
Basically what I need is when I hit on the button should start my .gif but nothing happens....

var $loading = $('.ajaxProgress').hide();
$(document)
.ajaxStart(function () {
$loading.show();
})
.ajaxStop(function () {
$loading.hide();
});
I like to use this way

Related

Django Ajax posting duplicate values to the view

Im trying to post the value of a html item(the id of the item) to the view so it can add the item to the cart, however it always posts the value of the last item printed by the django {% for %} even though the html source says the values are different
here is my html
<div class="container">
<div class="row row-cols-2 row-cols-md-3" data-masonry='{"percentPosition": true }'>
{% for product in products %}
<div class="col mb-4">
<div class="card h-100">
{% if product.image %}
<img src="{{ product.image.url }}" class="card-img-top" alt="{{ product.description }}">
{% endif %}
<div class="card-body">
<h5 class="card-title">{{ product.name }}</h5>
<p class="card-text">{{ product.description|slice:":100" }}...</p>
<p class="card-text">${{ product.price }}</p>
<p>
<a class="btn btn-dark gap-2 mb-1" href="{{ product.get_absolute_url }}">View Item</a>
<button class="btn btn-outline-success" id="add-to-cart" value="{{ product.id }}">Add to Cart</button>
</p>
{% if product.in_stock == False %}
<p>
Item is currently out of stock
</p>
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
Here is the Ajax
$(document).on('click', '#add-to-cart', function(e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url "add_to_cart" %}',
data: {
productid: $('#add-to-cart').val(),
csrfmiddlewaretoken: '{{ csrf_token }}',
action: 'post'
},
success: function(json){
},
error: function(xhr, errmsg, err) {
}
});
})
Here is my view
def CartAddView(request):
cart = Cart(request)
if request.POST.get('action') == 'post':
product_id = int(request.POST.get('productid'))
product = get_object_or_404(Product, id=product_id)
cart.add(product=product)
response =JsonResponse({
'price': product.price,
'id': product.id, (here the id returned is always the id of the last element printed by the loop)
})
return response
i tried to make a product detail page and when i call the ajax it works perfectly
when form submit and view return response page will reload the same page and call POST again, I fixed it with
create a new route but render the same page (if you want to render the same page)
change API return return HttpResponseRedirect('url-new')
examaple:
def CartAddView(request):
cart = Cart(request)
if request.POST.get('action') == 'post':
product_id = int(request.POST.get('productid'))
product = get_object_or_404(Product, id=product_id)
cart.add(product=product)
response =JsonResponse({
'price': product.price,
'id': product.id, (here the id returned is always the id of the last element printed by the loop)
})
return HttpResponseRedirect('url')

Hiding html element clicked after ajax success

I'm new to Web Development and making a mock twitter application. I want the tweet box to be removed after I click on the delete button (only if it is actually deleted in the backend)
I'm using django templating to loop through each tweet:
{% for tweet in data%}
<div class="container border border-primary rounded">
<p> tweet: {{tweet.content}}</p>
<div class="row">
{{tweet.id}}
<p class = "likes" style="margin: 0px 10px;"> likes: {{tweet.likes}} </p>
<button class="btn btn-dark like" style="margin: 0px 10px;">like</button>
<p class = "retweets" style="margin: 0px 10px;" > retweets: {{tweet.retweets}}</p>
<button class = "btn btn-dark retweet" style="margin: 0px 10px;">retweet</button>
<button class="btn btn-dark float-right delete_tweet" onclick="delete_tweet('{{tweet.id}}')">delete</button>
</div>
</div>
{% endfor %}
Here's the delete_tweet function:
function delete_tweet(id){
$(document).ready(function(){
$.ajax({
url: "{% url 'deleteTweet'%}",
data: {'id':id},
dataType: 'json',
success: function(data){
console.log(data);
$(this).parent().parent().remove();
}
});
});
}
This deletes the tweet in the backend fine, but the remove method doesn't work -
I'm pretty sure that I'm this is not referring to the right scope, what should I be doing instead?
Use .closest(".your-element-name").remove();
Your Button
function delete_tweet(id, that){
$(document).ready(function(){
$.ajax({
url: "{% url 'deleteTweet'%}",
data: {'id':id},
dataType: 'json',
success: function(data){
console.log(data);
$(that).closest(".rounded").remove();
}
});
});
}

Ajax post in Laravel blade form not submitting

I'm trying to add some additional data to a form in my laravel blade using js and ajax post, but I can't get the form to submit. I've stripped everything else out to try to find what's wrong, but I'm mystified. Can anyone help?
My blade looks like this;
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-12 col-md-6 mt-5 mb-2">
<div class="card">
<div class="card-body">
<form id="payment-form">
<button id="card-button" class="btn btn-lg btn-block btn-success">
<span id="button-text"><i class="fas fa-credit-card mr-1"></i>{{ __('Add Payment Method') }}</span>
</button>
</form>
</div>
</div>
</div>
</div>
</div>
#endsection
#section('javascript')
<script>
const cardButton = document.getElementById('card-button');
var form = document.getElementById('payment-form');
cardButton.addEventListener('click', function(event) {
// event.preventDefault();
console.log('On click check');
var payment = '1234';
$.ajax({
type: "POST",
url: "/payment-post",
data: {
payment: payment,
'_token': $('meta[name="csrf-token"]').attr('content'),
},
});
});
</script>
#endsection
You have to use like this
var payment = '1234';
var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
$.ajax({
type: "POST",
url: "{{url('')}}/payment-post",
dataType: "text",
data: {
payment: payment,
_token: CSRF_TOKEN
},
success: function (response) {
//Do something
}
});
In the end I tracked this down to 'defer' being present in the script tag in the header, which was stopping all the event listeners from working. Once I changed it to this
<script src="{{ asset('js/app.js') }}"></script>
everything working fine.

Using Ajax with Django to call backend and display result

I am taking user input and sending it to Django backend for some text processing. After performing backend operation I want to display results.
I tried but as I am new with ajax,I am not sure where I am making mistake. Can anyone please give me correct way of using ajax for this operation? I appreciate if you can give link to any good reference document.
Current issue - When I click on submut button it removes input text area.
My html report.html -
{% extends 'base.html' %}
{% block content %}
<h1>StopWordsRemoval</h1>
<script type='text/javascript'>
$(document).ready(function(){
$(form).on('submit', function(event){
$.ajax({
url: 'stopwordsremoval/(?P<document1>.+)'
type: 'POST',
data: this.serialize(),
});
});
});
</script>
<div>
<form method = "post" >
{% csrf_token %}
{{ form}}
<button type="submit">stopwordsremoval</button>
</div>
</form>
<div >
<ul>
<li>{{ naturallanguageprocessing }}</li>
</ul>
<a href="{% url 'stopwordsremoval' %}" </a>
<style>
div {
width: 1000px;
border: 5px solid green;
padding: 10px;
margin: 10px;
}
</style>
</div>
</div>
{% endblock %}
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'stopwordsremoval/$', views.stopwordsremoval.as_view(), name='stopwordsremoval'),
url(r'stopwordsremoval/(?P<document1>.+)/$',
views.ReportDetails.as_view(), name='report_details'),
]
forms.py
from django import forms
class ReportForm(forms.Form):
#pdb.set_trace()
text = forms.CharField(widget=forms.Textarea(attrs={'rows': 5, 'cols': 100}))
<script type='text/javascript'>
$(document).ready(function(){
$(button).on('click', function(event){
var form = $(form).serialize()
$.ajax({
url: 'stopwordsremoval/(?P<document1>.+)' // this will not work
type: 'POST',
data: form,
});
});
});
</script>

Ajax request into Bootstrap modal with a load spinner from Symfony controller

I have created a modal to display information about a specific record when I click on the button.
{% for seat in seats %}
<span class="fa-stack fa-lg seat" id="{{ seat.id }}" data-toggle="modal" data-target="#seatModal">
<i style="color: lightgrey;" class="fa fa-stop fa-stack-2x"></i>
<strong style="color: white;" class="fa-stack-1x">
{{ seat.seatNo }}
</strong>
</span>
{% endfor %}
<div class="modal fade seat-details" id="seatModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content"></div>
</div>
</div>
I have an Ajax request that get the information for the specific seat when clicking on that seat icon.
$(document).ready(function () {
$('.seat').click(function() {
var url = Routing.generate('show_seat', {'seat': $(this).attr('id')});
$.get(url, function (data) {
$(".modal-content").html(data);
});
});
});
This ajax call perform a request to the 'show_seat' route which lead to this controller action:
public function showSeatAction(Seat $seat)
{
return $this->render('AppBundle:Seat:seat_details.html.twig', [
'seat' => $seat,
]);
}
This action renders the details in the seat_details.html.twig;
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Seat Details</h4>
</div>
<div class="modal-body table-responsive no-padding">
<table class="table table-modal">
<tbody>
<tr>
<th>Description</th>
<td>{{ seat.desc }}</td>
</tr>
<tr>
<th>Seat Number</th>
<td>{{ seat.seatNo }}</td>
</tr>
<tr>
<th>Status</th>
<td>
{% if seat.status == 'special' %}
<span class="label label-info">{{ seat.status|upper }}</span>
{% elseif seat.status == 'bad' %}
<span class="label label-warning">{{ seat.status|upper }}</span>
{% else %}
<span class="label label-default">{{ seat.status|upper }}</span>
{% endif %}
</td>
</tr>
</tbody>
</table>
</div>
And finally when the Ajax request is done it loads it into the modal as you can see in that Ajax function: $(".modal-content").html(data);.
This works good, but now I'm trying to add a spinner, because what happens now is when I click one the modal opens and the right data displays, but when I close it and open a new one the model opens with the previous data and then when the Ajax is done the text data get replaced in the modal.
But I want to let a spinner show until the Ajax is done and then the complete modal should display.
I've tried to add this:
$(document).on({
ajaxStart: function() { $('.loading').show() },
ajaxStop: function() { $('.loading').hide() }
});
This makes the spinner appear when clicking and hides it when Ajax is done, but the modal still appear too early. So I've tried to modify it to this:
$(document).on({
ajaxStart: function() {
$('.loading').show();
$('.seat-details').hide();
},
ajaxStop: function() {
$('.loading').hide();
$('.seat-details').show();
}
});
But this doesn't change anything.
Can somebody help me out to fix this?
var seatModal = $("#seatModal");//your modal
$(document).on({
ajaxStart: function() {
seatModal.find(".modal-content").html("");//empty modal every ajaxstart
$('.loading').show();
seatModal.modal("hide");//hide
},
ajaxStop: function() {
$('.loading').hide();
seatModal.modal("show");//modal show
}
});
You can process with an other way. Initialize your modal with nothing in it.
Then, when the user close the modal, remove the content and replace it with your spinner.
$(".modal").on("hidden.bs.modal", function(){
$(".modal-content").html([your spinner here]);
});

Categories