I get the data through the search and display it on the page, since there is a lot of data, I want to implement pagination via Ajax. But when you click on the pagination, everything disappears and the data is not updated. If Ajax is turned off, then everything works, but there is a transition to the page (search/?page=2), which immediately removes all search results.
Please help, what am I doing wrong?
def search_venus(request):
if request.method == "GET":
searched = request.GET.get('searched', False)
p = Paginator(Movie.objects.filter(title__contains=searched), 1)
page = request.GET.get('page')
object_list = p.get_page(page)
coursesearch = Course.objects.filter(name__contains=searched)
context = {
'searched':searched,
'object_list':object_list,
'coursesearch':coursesearch,
}
return render(request, 'search.html', context)
Ajax
function ajaxPagination_s_m() {
$('#pagination_s_movie a.page-link').each((index, el) => {
$(el).click((e) => {
e.preventDefault()
let page_url = $(el).attr('href')
console.log(page_url)
$.ajax({
url: page_url,
type: 'GET',
csrfmiddlewaretoken: '{{ csrf_token }}',
success: (data) => {
$('#search_movie').empty()
$('#search_movie').append($(data).find('#search_movie').html())
$('#pagination_s_movie').empty()
$('#pagination_s_movie').append($(data).filter('#pagination_s_movie').html())
}
})
})
})
Form search
<div class="form_search">
<form action="{% url 'search-venus' %}" method=GET>
{% csrf_token %}
<input class="inp_text" name="searched" type="search" placeholder="Схемы, видео, книги">
<button type="submit"></button>
</form>
</div>
Related
Trying to keep selected icon in product cards active after page refresh
when the user refresh the page I want that the icon to remain a full heart and not an empty heart. How could I do that?
views.py
#login_required
def add_wishlist (request):
if request.is_ajax() and request.POST and 'attr_id' in request.POST:
if request.user.is_authenticated:
data = Wishlist.objects.filter(customer = request.user,product_id= int(request.POST['attr_id']))
if data.exists():
data.delete()
else:
Wishlist.objects.create(customer= request.user,product_id = request.POST['attr_id'])
else:
print("No Product is Found")
return redirect("products:product_all")
product_all.html
<div id='alCarrito' class="like-container">
{% if product in wishlisted_list %}
<span class="like heart " id="id" attr_id="{{product.id}}" action_url="{% url 'products:add_wishlist' %}">
<i class="fas fa-heart"></i> </span>
{% else %}
<span class="like" id="id" attr_id="{{product.id}}" action_url="{% url 'products:add_wishlist' %}"><i class="far fa-heart"></i></span>
{% endif %}
</div>
wishlist.js
$(document).ready(function(){
$(".like").click(function(){
var attr_id = $(this).attr('attr_id')
var action_url = $(this).attr('action_url')
var that = $(this)
$.ajax({
url: action_url,
type: "POST",
data: {'attr_id': attr_id },
headers: { "X-CSRFToken": $.cookie("csrftoken") },
success: function (response) {
console.log("Success")
that.toggleClass("heart");
},
});
});
});
I would like to understand how to submit 2 forms simultaneously using ajax.
I display a form composed of 2 model forms, for 2 models linked with OneToOne relationship. Managing the display is not a big deal, I can also manage the submit using a Django view; but I would like to know how to deal with javascript.
Why? The form is called from a global menu and displayed in a modal, and I would like only to close the modal on submit, but not refresh the page.
Here are some (simplified) code snippets I tried so far:
user_profile.html (modal form):
<form id="upd-user" action="." method="post" url-endpoint="{% url 'polls:upd_user_detail' %}"
comp-slug="{{ comp_slug }}" usr-id="{% if usr_id %} {{ usr_id }} {% else %} 0 {% endif %}">
{% csrf_token %}
{{ user_form }}
{{ usercomp_form }}
<button class="btn btn-success" type="submit">{% if usr_id %}Mettre à jour{% else %}Créer{% endif %}</button>
     
<a class="btn btn-secondary back_btn" data-dismiss="modal">Annuler</a>
</form>
The modal is embedded in this snippet:
<div id="usr_detail" class="modal fade hide" role="dialog" tabindex='-1'>
<div class="modal-dialog modal-lg">
<div class="modal-content usr_form_content">
{% include './user_profile.html' %}
</div>
</div>
</div>
Javascript submit function:
$(".usr_form_content").on("submit", "#upd-user", function(event) {
event.preventDefault();
$.ajax({
method: 'POST',
url: $(this).attr('url-endpoint'),
data: {
comp_slug: $(this).attr('comp-slug'),
usr_id: $(this).attr('usr-id'),
user_form: user_form.serialize(),
usercomp_form: usercomp_form.serialize()
},
success: handleSuccess,
error: handleError,
});
function handleSuccess(data) {
$("#usr_detail").modal("hide");
};
function handleError(jqXHR, textStatus, errorThrown){
console.log(jqXHR);
console.log(textStatus);
console.log(errorThrown);
}
})
The error message is quite clear:
Uncaught ReferenceError: user_form is not defined
I now I need to make the transition between the form and js, I probably need to link these values to $('this) but I don't know how.
If it helps, here's the GET view:
comp_slug = request.GET["comp_slug"]
company = Company.get_company(comp_slug)
usr_id = int(request.GET["usr_id"]) # comes as string when 0
if usr_id > 0:
profile_user = User.objects.get(pk=usr_id)
user_form = UserBaseForm(instance=profile_user)
usercomp_form = UserCompForm(instance=profile_user.usercomp)
user_form.fields['username'].disabled = True # Disable updates of the field
else:
user_form = UserBaseForm()
usercomp_form = UserCompForm()
context = {
"comp_slug": comp_slug,
"company": company,
"usr_id": usr_id,
"user_form": user_form,
"usercomp_form": usercomp_form,
}
template = render_to_string('polls/user_profile.html', context=context, request=request)
return JsonResponse({"user_template": template})
And related js part (it works fine - I tried to generated necessary variables at this stage, but it did not work neither)
$('.update-user').click(function() {
$.ajax({
method: 'GET',
url: $(this).attr('url-endpoint'),
data: {
comp_slug: $(this).attr('comp-slug'),
usr_id: $(this).attr('usr-id'),
},
success: handleSuccess,
error: handleError,
});
function handleSuccess(data) {
$(".usr_form_content").html(data.user_template);
};
function handleError(error_data) {
console.log("error");
console.log(error_data);
};
})
I'm fighting with this problem during several days and can not find the solution for my case. I'm trying to make system of likes without refreshing the page. In synchronous mode system of likes and dislikes works fine, but when I'm trying to add AJAX, I'm getting 405 and only one last comment is working for one click, I understand problem that Ajax doesn't understand django urls with id or pk like my variant {% url 'store:like' comment.pk %} , but how it can be solved?
There is this part from the template:
{% for comment in comments %}
<h6 class="card-header">
{{ comment.author }}<small> добавлен {{ comment.created_at|date:'M d, Y H:i' }} </small>
</h6>
<div class="card-body">
<h4>{{ comment }}</h4>
<form id="like-{{comment.pk}}" method="POST" action="{% url 'store:add_like' comment.pk %}">
{% csrf_token %}
<button style="background-color: transparent; border: none; box-shadow: none;" type="submit">
<a class="btn btn-success" id="like-count-{{comment.pk}}"> Likes {{ comment.likes.all.count }}</a>
</button>
</form>
</div>
{% empty %}
<p>Для данного товара ещё нет комментариев.</p>
{% endfor %}
my ajax call in the same template:
<script type="text/javascript">
$(document).ready(function(){
$('[id^="like-"]').submit(function(e){
e.preventDefault();
var endpoint = $(this).attr('action');
var serializedData = $(this).serializeArray();
$.ajax({
type: 'POST',
url: endpoint,
data: serializedData,
success: function(response) {
$( "#like-count-"+response["id"].toString()).text("Likes "+response["like_count"]);
},
error: function(rs, e) {
alert(rs.responseText);
}
});
})
This part from urls:
path('products/<int:pk>/like/', addlike, name='like'),
View for like:
#api_view(['POST'])
def addlike(request, pk, *args, **kwargs):
is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
if request.method == 'POST' and is_ajax:
post = Comment.objects.get(pk=pk)
is_dislike = False
for dislike in post.dislikes.all():
if dislike == request.user:
is_dislike = True
break
if is_dislike:
post.dislikes.remove(request.user)
is_like = False
for like in post.likes.all():
if like == request.user:
is_like = True
break
if not is_like:
post.likes.add(request.user)
if is_like:
post.likes.remove(request.user)
all_post_likes = post.total_likes() (function from models)
return JsonResponse({"success": True, "like_count": all_post_likes, "id": pk}, status=200)
else:
return JsonResponse({"success": False}, status=400)
How to force AJAX to call in pk what I need? (Finally I found the solution, updated the final version of the code)
Remove the data-url and set the action attribute because when you click the submit button, by default this POST request will be sent to the current URL and you will receive the 405 status code, but if you set action this POST request will be sent to the like url:
<form id="like" method="POST" action="{% url 'store:like' comment.pk %}">
{% csrf_token %}
<input type="hidden" value="{{comment.pk}}" name="id">
<input type="hidden" name="next" value="{{ request.path }}">
<button style="background-color: transparent; border: none; box-shadow: none;" type="submit">
<a class="btn btn-success" id="like"> Likes {{ comment.likes.all.count }}</a>
</button>
</form>
And in js you can get the URL like this
var endpoint = $(this).attr('action');
Update
All forms have the same "ID" and therefore only the first one is executed and the rest of the forms are not managed by Ajax, to solve this problem you can give different ID to the forms(This condition also applies to a tags):
<form id="like-{{comment.pk}}" method="POST" action="{% url 'store:like' comment.pk %}">
{% csrf_token %}
........
.....
<a class="btn btn-success" id="likes-count-{{comment.pk}}"> Likes {{ comment.likes.all.count }}</a>
And you can receive events this way and update the number of likes.
$(document).ready(function(){
$('[id^="like-"]').submit(function(e){
e.preventDefault();
var endpoint = $(this).attr('action');
var serializedData = $(this).serializeArray();
$.ajax({
url: endpoint,
method: "POST",
data: serializedData,
success: function(response){
$("#likes-count-" + serializedData[1].value).text("Likes "+response["like_count"]);
}
});
})
});
in the view you should return the new number of the likes :
return JsonResponse({"success": True, "like_count": new_like_count}, status=200)
And in the success function you can access to the new number by the response and now we change the text value of a tag to change the like count number.
^= means: selects elements that have the specified attribute with a
value beginning exactly with a given string. attributeStartsWith1
I think you should send the csrf_token with the ajax request add
headers: { "X-CSRFToken": token } to your ajax request, "token is the csrf_token" or add #csrf_exempt decorator to your function but it will keep your view unsafe against CSRF attacks.
you can find more info here https://docs.djangoproject.com/en/4.0/ref/csrf/
when I post data to the database using ajax code I got an unexpected result. I can post data but output showing is wrong. My ajax code not execute properly
views.py
def notification(request):
user = request.user
if request.method == 'POST':
property_id = request.POST['property_id']
owner = request.POST['owner_id']
property_object = Property.objects.get(id=property_id)
owner_object =User.objects.all().get(username=owner)
notification = "Hi {}, {} \n have interested
in your property '{}'".format(property_object.owner, user.first_name, property_object.headline)
property_object.notify.add(user)
notifications = Notifications.objects.create(notification=notification, property=property_object, owner=owner_object)
notifications.save()
return JsonResponse({"msg":"success"})
ajax code
<form action="{% url 'notification' %}" method="post" id="notify_form" >
{% csrf_token %}
<input type="hidden" name="owner_id" value="{{ accomodation.owner }}">
<button type="buttonsn" id="request-btn" name="property_id" value="{{ accomodation.id }}" class="btn btn-primary">Contact info:</button>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
$(document).ready(function(e){
$(document).on('submit','#request-btn',function(e){
e.preventDefault();
var property_id = $this.attr('value');
var owner_id = $this.attr('value');
$.ajax({
type:'POST',
url:"{% url 'notification' %}",
data:$('#notify_form').serialize(),
dataType:'Json',
success:function(data){
if(data.msg == "success"){
alert('data submitted')
}
}
});
});
});
I'm expecting a success alert box, but got
{"msg": "success"}
in a white window like 'httpResponse'. ajax code doesn't work
for overcome i'am try somechanges in mycode
i removed action address from form
<form action="" method="post" id="notify_form" >
but it doesn't work this time form not submitted
what can I do
You're attaching the event handler to the button:
$(document).on('submit','#request-btn',function(e){
But buttons don't have submit events, forms do. You can attach it to the form:
$(document).on('submit','#notify_form',function(e){
Or use the button's click event instead:
$(document).on('click','#request-btn',function(e){
Note also that there's a typo in the type attribute for the <button> element. It should be:
type="button"
I want to implement a ajax commenting system.
urls.py:
(r'^comment/(\d+)/$', comments),
views.py:
def comments(request,feed):
if request.method == 'POST':
feed=Feed.objects.get(pk=feed)
form = CommentForm(request.POST)
if form.is_valid():
comment, created = Comment.objects.get_or_create(
feed=feed,
msg=form.cleaned_data['msg'],
ip=request.META['REMOTE_ADDR']
)
comments=Comment.objects.filter(feed=feed)
form=CommentForm()
variables=RequestContext(request,{'comments': comments,'feed': feed,'form':form,})
if 'HTTP_REFERER' in request.META:
return HttpResponseRedirect(request.META['HTTP_REFERER'])
return render_to_response('comment_page.html', variables )
#return HttpResponseRedirect('/view/')
else:
form=CommentForm()
feed=Feed.objects.get(pk=feed)
comments=Comment.objects.filter(feed=feed).reverse()
variables=RequestContext(request,{'comments': comments,'feed': feed,'form':form,})
return render_to_response('comment_page.html', variables )
Templates:
<div id="commentbox" style="display:none;">
<form class="comment" method="post" action="/comment/{{feed.id}}/">
{{cform.as_p}}
<input class="post" type="submit" value="post" />
</form>
</div>
</br>
<h3></h3><button class="ccc">Show/Hide Comment</button> {{feed.comment_set.count}} Comments
<div id="commentlist" class="commentlist" style="padding-left:10px;"><ul style="list-style-type:square;">
{% for c in feed.comment_set.all %}
<li>{{c.msg}}</li>
{% endfor %}
</ul>
</div>
What code should I include to add comments into commentlist li field without page refresh. I am new in ajax. Please help. Thanks
Here's what I would do:
Leave the HTML as it is, as it works for people without JavaScript. In you JavaScript, when the user submits the form, stop it from actually happening:
$('#commentbox form').submit(function(e) {
e.preventDefault();
});
Now, when the button is pressed, prevent the default behavior and submit the form via AJAX:
$('#commentbox form').submit(function(e) {
e.preventDefault();
$.ajax({
type: 'post',
url: $(this).parent().attr('action'),
data: $(this).parent().serialize(),
}).done(function(data) {
alert('The AJAX is done, and the server said ' + data);
});
});