Button updates text of first element instead of selected element - javascript

When I select the "Like" button, the button updates properly. However, the "like count" updates the count for the first image only, instead of the image I selected.
Any ideas how to make only the selected image's like count update as the button does?
Thank you in advance!
html:
{% for photo in photos %}
<img src="{{ photo.get_photo_url }}" />
<input class="like_btn" photo="{{ photo.pk }}" value="{% if user.username in photo.get_likers %}Liked{% else %}Like{% endif %}" type="button" />
0
{% endfor %}
jquery:
$('.like_btn').click(function(e){
e.preventDefault();
var $like_btn = $(this);
$.ajax({
type: "POST",
url: "{% url 'like_ajax' %}",
data: {
"photo_pk": $(this).attr("photo"),
csrfmiddlewaretoken: "{{ csrf_token }}",
},
dataType: "json",
success: function(data) {
if (data.viewer_has_liked) {
$like_btn.val("Liked");
$('#like_count').html(data.like_count);
} else {
$like_btn.val("Like");
$('#like_count').html(data.like_count);
}
},
error: function (rs, e) {
}
});
});

Every photo has the same id for its like count:
{% for photo in photos %}
0
{% endfor %}
Therefore, only the first is recognized as the 'real' #like_count
Since you have a primary key for the photo, you could make the ids distinct by incorporating the photo.pk:
0
EDIT:
Rather than changing the id for each like count, make it into a class and adjust the JavaScript. Try these changes:
In HTML, change this:
0`
To this:
0
In JavaScript, change this:
if (data.viewer_has_liked) {
$like_btn.val("Liked");
$('#like_count').html(data.like_count);
} else {
$like_btn.val("Like");
$('#like_count').html(data.like_count);
}
To this:
if (data.viewer_has_liked) {
$like_btn.val("Liked");
$like_btn.next('.like_count').html(data.like_count);
} else {
$like_btn.val("Like");
$like_btn.next('.like_count').html(data.like_count);
}
This changes will make the like counts a class (.like_count). Then in the JavaScript, you will choose the next selector (after $like_btn) that matches .like_count.

the <a> tags in loop have the same id which is conflict, so set an unique index in <a> tag property for jquery selector

Related

Send items from forloop populated data in django template through ajax to django view

I have been trying to create a click and populate div with ajax in my django e-commerce application. The project works in such a way that when a customer clicks on a category in men's page it populates another div
gender.html
{%for cate in cat%}
<a href="javascript:getcat()" id="catgend" cats-data="{{cate.catname}}" gen-data="{{gens.gender}}" data-sort-url="{% url 'Home:sortcat' cpk=cate.pk %}" >{{cate.catname}}</a>
{% endfor %}
<div id="products">
<div class="progress">
<img src="{% static 'img/load.gif'%}">
</div>
</div>
This sends the data to my django view through the ajax function called getcat but the data sent through is that of the first item in the loop in-respective of the loop item clicked on. below is my ajax function:
getcat()
function getcat() {
$(".progress").show()
var cat = $("#catgend").attr("cats-data");
var gender = $("#catgend").attr("gen-data");
var url = $("#catgend").attr("data-sort-url");
$.ajax({
url: url,
data: {
'cat': cat,
'gender': gender,
},
success: function (data) {
$("#products").html(data);
}
});
$(".progress").hide()
}
enter code here
From my research i discovered its because they have same ID. How do i solve the issue of dynamically changing the id over the same loop. Thanks
Replace the id attribute with a class attribute since you shouldn't have more than a single element with the same id. Also, we can change cats-data and gen-data to valid data-* attributes.
{% for cate in cat %}
<a href="#" class="catgend" data-cats="{{cate.catname}}" data-gen="{{gens.gender}}" data-sort-url="{% url 'Home:sortcat' cpk=cate.pk %}" >{{cate.catname}}</a>
{% endfor %}
Bind a click event to anchors using the new class name.
$('.catgend').on('click', function (e) {
$('.progress').show()
var data = $(this).data()
$.ajax({
url: data.sortUrl,
data: {
'cat': data.cats,
'gender': data.gen,
},
success: function (data) {
$('#products').html(data);
}
});
$('.progress').hide()
});
Utilise the data attributes to accumulate data values in a simple way.

javascript/jquery dropdown menu selection not passing GET request

In my page I have a dropdown menu, and upon selection I want to pass a GET request. This GET request should (ideally) trigger a function from my views.py file and return some data (based on the selection) from my database. However, it doesn't seem like anything actually happens upon dropdown menu selection.
Here is my script that I wrote to trigger the GET request when a selection was made:
<!-- AJAX Call for dropdown menu selection -->
<script type="text/javascript">
var url = $('.dropdown-menu').attr('action');
$('.dropdown-menu-option').click(function(e){
e.preventDefault();
$.ajax({
type: "GET",
url: url,
data: {
class: $('.dropdown-menu-option').val()
},
success: function(result) {
alert ('pass');
},
error: function(result) {
alert('fail');
}
});
});
</script>
Here is the code for my dropdown menu in my template:
<!-- Query based content for dropdown menu -->
<select class="dropdown-content">
{% if current_user_properties %}
{% for property in current_user_properties %}
<option class="dropdown-menu-option" value="{{property.id}}">{{property.name}}</option>
{% endfor %}
{% else %}
<option>You don't have any properties</option>
{% endif %}
</select>
Lastly, here is the code for the function I wanna run in my views.py
def property_selected(request):
if request.method == 'GET':
selection = request.GET.get('class', None)
if selection:
selected_data = MeterData.objects.filter(property=selection).order_by(date)
return selected_data
If anyone can help identify what I'm missing/doing wrong, that'd be greatly appreciated. Thanks!!
$('.dropdown-menu-option') returns a collection of html nodes, since there are many elements that match this selector.
So when you pass $('.dropdown-menu-option').val() to the class property of the data object of ajax options, you are not really passing the value of the selected option.
You can attach a onChange event on the select.dropdown-content and get the value of the selected option like this:
$('.dropdown-content').on('change', function(e){
var selectedOption = $(this).find(':selected').val()
$.ajax({
type: "GET",
url: url,
data: {
class: selectedOption
},
...
})

Get HTML component from which button was pressed

How do I get the HTML component that contains the button which has been clicked with jQuery? After a button is clicked I need to get the invite object that corresponds to the clicked button and send a post request to a given link.
{% if invites %}
{% for invite in invites %}
<p>Your invites:</p>
<div class="row">
<label style="display: block">Invite from {{ invite.initiator }} to join his conference!</label>
<button type="button" id="ButtonId">Accept invite</button>
</div>
{% endfor %}
{% endif %}
The script:
<script type="text/javascript">
$(function() {
$('#ButtonId').on('click',function(){
!$(this).hasClass('ButtonClicked') ? addClass('ButtonClicked') : '';
$('#ButtonId').val('Done');
var data = {
};
$.ajax({
url: '/api/send_invite/' + /*the username*/,
data: JSON.stringify(data , null, '\t'),
contentType: 'application/json;charset=UTF-8',
type: 'POST',
success: function() {
}
});
});
});
</script>
Your "HTML component" is what the button is wrapped in ? If so, In order to get the element that contains the button that is being clicked (the "parent" of the button) you can do something like this:
$('#myButton').on('click',function(){
var buttonParent = $(this).parent();
// do your stuff..
});
For getting the "invite object" you can attach a data attribute to the accept-invite button, this data attribute will contain a value that you will use to fetch the correct object, for an example:
<button type="button" id="inviteAcceptBtn" data-object-id="123">Accept invite</button>
Then you can get that "object-id" with simple jQuery:
$('#inviteAcceptBtn').on('click',function(){
var objectId = $(this).data('object-id');
// do your stuff..
});
There are probably a handful of other methods, as there are many techniques to do this.
Hope it helps a bit
There are multiple ways to do this:
Set the the username as one of the button's attributes.
assuming invite.initiator is the username that you intend to send
<button type="button" id="ButtonId" username={{invite.initiator}}>Accept invite</button>
In the javascript code you can access that element easily using attr method on this
url: '/api/send_invite/' + $( this ).attr("username"),
#sudomakeinstall2 : It should be better to add the data as a data-attrbute so :
<button type="button" id="ButtonId" username={{invite.initiator}}>Accept invite</button>
becomes
<button type="button" id="ButtonId" data-username="{{invite.initiator}}">Accept invite</button>

calling function with ajax, part working but part not working

Sorry if the title isn't very clear. I have search engine that works with ajax function. Right now if I type t in a search box, the tags that contain the word t shows up(ex if I type t, then test shows up) but thing is after I delete the word t all the tags show up in the result part. Does this make sense? if I'm not clear I'll post the picture. I'm not sure why or how to fix this.
Here;s my code.
<h3>Search</h3>
{% csrf_token %}
<input type="text" id="search" name="search" onkeyup="handle_keyup()"/>
<ul id="search-results">
</ul>
Here I can't delete search-results as this will show the search results but on this section when nothing is typed still all the tags show up. (it only shows all when I finish using search bar)
my ajax
function handle_keyup() {
$.ajax({
type: "POST",
url: "/search/",
data: {
'search_text' : $('#search').val(),
'csrfmiddlewaretoken' : $("input[name=csrfmiddlewaretoken]").val()
},
success: searchSuccess,
dataType: 'html'
});
};
function searchSuccess(data, textStatus, jqXHR)
{
$('#search-results').html(data);
}
problem is probably occurring from up there, but I'll post the back end as well. This is python django framework.
def search_titles(request):
# categories = SearchQuerySet().autocomplete(content_auto=request.POST.get('search_text', ''))
categories = Category.objects.filter(name__icontains=request.POST.get('search_text', ''))
return render_to_response('main/ajax_search.html', {'categories' : categories})
ajax_Search.html
{% if categories.count > 0 %}
{% for category in categories %}
<li>{{ category.name }}</li>
{% endfor %}
{% else %}
<li>None to show!</li>
{% endif %}
thanks in advance
This is happening because when the user "deletes" the word, your handle_keyup function is fired, sending a search request of '' to the server.
The server then looks for the empty string '' in the category names and finds it in all of them.
One approach is for the server to check if the search text is empty, and if it is, return nothing. Something like:
def search_titles(request):
txt = request.POST.get('search_text', '')
if txt:
categories = Category.objects.filter(name__icontains=txt)
else:
categories = []
return render_to_response('main/ajax_search.html', {'categories' : categories})

HTML refreshing on click

I'm using the sample found here http://stackoverflow.com/questions/27218680/how-can-i-reload-just-one-div-on-click and I think I'm missing something in my example or maybe the value is not passing as I'm using MPTT instead of a standard menu.
This is how I'm loading my menu found in my base.html -
{% recursetree nodes %}
{{ node.name }}
{% endrecursetree %}
Here is the javascript I've included -
<script>
$(document).on('click','.node',function(e) {
id = $(this).attr("id");
$.ajax({
type: "GET",
url: '/gui/details/' + id,
success: function (result) {
$('.details').html(result);
},
});
});
</script>
I'm then trying to use this id to reload the template here -
<div class="details">
{% include 'gui/details.html' %}
</div>
Here is the view for generating the details -
def display_details(request, list_id):
qs_details = Details.objects.filter(owner=request.user, list=list_id)
return render(request, 'gui/details.html', {'qs_details': qs_details,})
Currently when I click anything on my list it doesn't do anything.

Categories

Resources