Reputation: 8418
This is my html code:
<span id="username_{{ member.id }}" onclick="showMembershipData('{{ member.id }}');">{{ member.user.username }}</span>
and this is my jQuery code
function showMembershipData(id)
{
$("#memberInfo_"+id).slideDown();
$("#username_"+id).click(function(){
hideMembershipData(id);
});
}
function hideMembershipData(id) {
$("#memberInfo_" + id).slideUp();
$("#username_" + id).click(function() {
showMembershipData(id);
});
}
I want the user name to be clickable and when clicked open the "more information" pane, or close it if it is opened. What happens now is:
and so on... Why? What am I doing wrong?
Upvotes: 1
Views: 101
Reputation: 17589
You are assigning handler inside each handler, and you only need to assign handler once or even consider using event delegation $.on(event, selector, handler)
if you are adding and removing items.
consider code below, and remove handlers from markup:
add class username
to elements with id username_xxx
add class memberInfo
to elements with id memeberInfo_xxx
add data-id
attribute to elements with id username_xxx
So markup going to look like:
<span class="username" data-id"{{ member.id }}">{{ member.user.username }}</span>
And the script:
$('body').on('click', '.username', function(e) {
var id = $(this).data('id')
$('#memberInfo_'+id).toggle()
})
Upvotes: 4
Reputation: 682
Agree with the guys above...you keep registering the events. If all you're doing is opening and closing one:
$('#clickme').click(function() {
$('#book').slideToggle('slow', function() {
// Animation complete.
});
});
http://api.jquery.com/slideToggle/
Upvotes: 1
Reputation: 973
It is happenign 2 times in a row because each time you call those functions they bind a click function which fires.
try
$("#username_"+id).click(function(){
var $showHideElement =$("#memberInfo_"+id);
if ($showHideElementis(':visible'){
$showHideElement.slideUp();
}else{
$showHideElement.slideDown();
}
})
Upvotes: 0
Reputation: 75103
let's change the code a little bit, shall we
<span
id="username_{{ member.id }}"
class="member"
data-memberid="{{ member.id }}">{{ member.user.username }}</span>
on the jQuery side
$(".member").toggle(
function() { // click - show
var id = $(this).attr("data-memberid");
$("#memberInfo_" + id).stop().slideDown();
},
function() { // click again - hide
var id = $(this).attr("data-memberid");
$("#memberInfo_" + id).stop().slideUp();
});
easy :)
Upvotes: 1
Reputation: 101483
You can make life a whole lot easier by using jQuery's slideToggle()
method - try the following:
function showMembershipData(id) { $("#memberInfo_"+id).slideToggle(); }
This will toggle the #memberInfo + id
(whatever the ID is) when the link is clicked. Can I suggest using jQuery's click()
function? (needs a class added to the username span
):
$("#username_span").click(function() { $("#memberInfo_"+id).slideToggle(); });
Don't forget to add it to your $(document).ready()
bit or whatever. Once you've done that, you can remove the onClick
from the span.
James
Upvotes: 1
Reputation: 3384
The problem with your code is that even handlers are been attached multiple times. Basically with jQuery if you do something like
$("#element").click(functionName);
$("#element").click(functionName);
$("#element").click(functionName);
Then clicking the element once will fire functionName thrice! You need to refactor your code a bit to make sure that the event handlers are added and removed appropriately. Try this
function showMembershipData(id)
{
$("#memberInfo_"+id).slideDown();
$("#username_"+id).unbind("click").bind("click",(function(){
hideMembershipData(id);
});
}
function hideMembershipData(id) {
$("#memberInfo_" + id).slideUp();
$("#username_" + id).unbind("click").bind("click",(function() {
showMembershipData(id);
});
}
Upvotes: 2
Reputation: 50832
Problem here is that you add an event handler each time showMembershipData
gets called.
You should make sure only one event handler gets assigned.
Upvotes: 0