Reputation: 854
So I've working on this for a while, but I still can't seem to figure it out.
I have a page here: http://taste.fourseasons.com/ingredients/
The show more button at the bottom calls extra posts on to the page with the following script:
$("a.view-more").bind('click',function(event){
event.preventDefault();
if($('.post-holder').hasClass('ingredients')) { posttype = 'ingredient'; }
if($('.post-holder').hasClass('recipe')) { posttype = 'recipe'; }
if($('.post-holder').hasClass('cmed')) { posttype = 'cmed'; }
filter = 'none';
morePosts(posttype,filter);
});
And the option to let people vote works with this:
$.post('http://taste.fourseasons.com/wp-admin/admin-ajax.php', data,
function(response){
if(response!="-1") {
el.find('.vote-sm').removeClass('vote-sm').addClass('unvote-sm');
el.find('.vote-text').html("VOTED");
el.unbind("click");
if(response!="null") {
el.find(".vote-count").html(response);
}
var cookie = getCookie("better_votes_"+postID);
if(!cookie) {
var newcookie = postID;
} else {
var newcookie = postID;
}
setCookie("better_votes_"+postID, newcookie, 365);
} else {
}
});
return false;
});
But when the user clicks show more and those elements are added to the DOM, the vote options isn't working with those new elements. I assumed I could just add them together:
$("a.view-more").bind('click',function(event){
event.preventDefault();
if($('.post-holder').hasClass('ingredients')) { posttype = 'ingredient'; }
if($('.post-holder').hasClass('recipe')) { posttype = 'recipe'; }
if($('.post-holder').hasClass('cmed')) { posttype = 'cmed'; }
filter = 'none';
morePosts(posttype,filter);
$(".vote").bind('click',function(event) {
event.preventDefault();
postID = $(this).attr('data-post');
var el = $(this);
//el.html('<span id="loader"></span>');
var nonce = $("input#voting_nonce_"+postID).val();
var data = {
action: 'add_votes_options',
nonce: nonce,
postid: postID,
ip: '66.252.149.82'
};
$.post('http://taste.fourseasons.com/wp-admin/admin-ajax.php', data,
function(response){
if(response!="-1") {
el.find('.vote-sm').removeClass('vote-sm').addClass('unvote-sm');
el.find('.vote-text').html("VOTED");
el.unbind("click");
if(response!="null") {
el.find(".vote-count").html(response);
}
var cookie = getCookie("better_votes_"+postID);
if(!cookie) {
var newcookie = postID;
} else {
var newcookie = postID;
}
setCookie("better_votes_"+postID, newcookie, 365);
} else {
}
});
return false;
});
});
But that doesn't seem to work and also creates a scenario that adds two votes to the sum instead of one, every time you vote.
Thanks for any help.
This code is from the wp-function page:
function add_votes_options() {
$postid = $_POST['postid'];
$ip = $_POST['ip'];
if (!wp_verify_nonce($_POST['nonce'], 'voting_nonce_'.$postid))
return;
$voter_ips = get_post_meta($postid, "voter_ips", true);
if(!empty($voter_ips) && in_array($ip, $voter_ips)) {
echo "null";
die(0);
} else {
$voter_ips[] = $ip;
update_post_meta($postid, "voter_ips", $voter_ips);
}
$current_votes = get_post_meta($postid, "votes", true);
$new_votes = intval($current_votes) + 1;
update_post_meta($postid, "votes", $new_votes);
$return = $new_votes>1 ? $new_votes : $new_votes;
echo $return;
die(0);
}
Upvotes: 3
Views: 470
Reputation: 3926
You've run into a fairly common issue with event binding.
$("a.view-more").bind('click',function(event){
The above line of code that you wrote attaches an event listener to the DOM elements available at that time. This is why the new elements added to the DOM do not respond to the event; because they don't have the event listener attached.
To work around this we can use something called event delegation. This works by attaching the event to a parent of the DOM elements that you wanted to listen for the event on. We can then work out which child the event started on when the event eventually propagates to the parent.
jQuery makes this very easy to do. You can use the delegate()
method but I suggest you use the on()
method which is the method that handles all event operations in jQuery. The others such as click()
, mouseover()
and bind()
are just aliases of on()
Anyway, to delegate an event we need to specify a selector for the parent which the event will attach to, and a selector for the elements we are actually interested in. So that line of code will now look like this:
$("body").on('click', "a.view-more", function(event){
You should really use something other than body but this is just an example.
Further reading: http://api.jquery.com/on/
Upvotes: 3