jQuery.on("click") firing multiple times for a single click - javascript

I am having trouble with my jQuery code.
Basically I want to load more message entrys after user clicks button.
Problem is, it returns results 3 times.
I have tried literally everything - .unbind (used .bind) / .off / .stopPropagation() and other methods I thought of. I searched all over google, but still couldn`t manage to find solution. Maybe someone can clarify where my problem is?
$(document).ready(function(){
$("#website_post_content_table_bottom_settings_left :input").on("click", function(event){
if($('.website_post_content_table_data#bigNews').is(":visible")){
var currentId = $('.website_post_content_table_entry:last').attr("id");
$.ajax({
type: "POST",
url: "php/admin_functions.php",
data: {callFunction: "getMoreNewsEntrys", id: currentId},
cache: false,
success: function(html){
$('.website_post_content_table_data').after(html);
}
});
}
});
});
EDIT:
HTML
<div id="website_post_content_table_bottom_settings_left">
<p>Ielādēt papildus:</p>
<input type="button" style="display:none;">
<input type="button" id="button_adminLoadMoreEntry" class="adminPanelButton_blue" value="+5">
<input type="button" id="button_adminLoadMoreEntry" class="adminPanelButton_blue" value="+10">
<input type="button" id="button_adminLoadMoreEntry" class="adminPanelButton_blue" value="+15">
<input type="button" id="button_adminLoadMoreEntry" class="adminPanelButton_blue" value="+20">
</div>
EDIT v3:
I made new javascript file, only for this small code and it STILL returns it 3 times:
$(document).ready(function(){
$("#website_post_content_table_bottom_settings_left :input").one("click", function(event){
$('.website_post_content_table_data').after('<p>Something More</p>');
});
});

Use .each() of jQuery to loop through the element. Then add a reference to each input item.
Or try this:
$(document).ready(function(){
$("#website_post_content_table_bottom_settings_left :input").unbind("click").bind("click", function(event){
if($('.website_post_content_table_data#bigNews').is(":visible")){
var currentId = $('.website_post_content_table_entry:last').attr("id");
$.ajax({
type: "POST",
url: "php/admin_functions.php",
data: {callFunction: "getMoreNewsEntrys", id: currentId},
cache: false,
success: function(html){
$('.website_post_content_table_data').after(html);
}
});
}
});
});

You can use Jquery.one()
$(document).ready(function(){
$("#website_post_content_table_bottom_settings_left :input").one("click", function(event){
if($('.website_post_content_table_data#bigNews').is(":visible")){
var currentId = $('.website_post_content_table_entry:last').attr("id");
$.ajax({
type: "POST",
url: "php/admin_functions.php",
data: {callFunction: "getMoreNewsEntrys", id: currentId},
cache: false,
success: function(html){
$('.website_post_content_table_data').after(html);
}
});
}
});
});
This binds the the event only once.
Reference link http://api.jquery.com/one/

First of all I must say huge thanks to everyone who tried to help!
My problem was that I had used display: none; in my CSS which caused these entries to update in hidden ones.
Still thanks everyone who tried to help! :)

Related

Turning jquery into an includable, callable function

I'm so frustrated! As an ok PHP developer I can't get my head around the simplist of jquery problems!
I have recently moved my HTML jquery include to the end of the HTML body, instead of in the head to improve google pagespeed score.
This has broken some jquery which is used for simple comment voting. This was written badly as it repeats for every comment.
<div id="voterow-19907" class="commentfooter">UP</a> | <a id="comment-vote-down-19907" href="#" rel="nofollow">DOWN</a></div>
<script>
$("#comment-vote-up-19907").click(function() {
$.ajax({
type: "GET",
url: "/ajax.php",
data: "a=rv&v=19907&d=up",
success: function(data){
$("#voterow-19907").text("Thank you for your vote")
}
});
return false;
});
$("#comment-vote-down-19907").click(function() {
$.ajax({
type: "GET",
url: "/ajax.php",
data: "a=rv&v=19907&d=down",
success: function(data){
$("#voterow-19907").text("Thank you for your vote")
}
});
return false;
});
</script>
Since moving the jquery include to the bottom of the page this naturally doesn't work.
What I'm trying to do is turn the above code into a mini function I can include after the jquery include, then pass the ID and VOTE-DIRECTION to the function from the HTML a hrefs using the jquery DATA- attribute.
Any help would be greatly appreciated. I'm running out of hair!
I think, repeated codes will hurt your page than placement of JQuery file.
You can solve this problem using more general event listener. Remove all listeners inside code (all of them) and append the code below after Jquery include.
$('[id^=comment-vote]').click(function() {
var elementId = $(this).attr('id');
var elementIdParts = elementId.split("-");
var voteType = elementIdParts[2];
var id = elementIdParts[3];
$.ajax({
type: "GET",
url: "/ajax.php",
data: "a=rv&v="+id+"&d="+voteType,
success: function(data){
$("#voterow-"+id).text("Thank you for your vote")
}
});
return false;
});
$('[id^=comment-vote]") selects all elements which have id starting with "comment-vote". If user clicks one of these elements, event handler gets id of elements, split into parts like "comment", "vote", "up", "19900". 2nd part is voteType and 3rd part is ID of row. We can use these variables while generating/operating AJAX request.
I didn't try the code but the idea behind that would be beneficial for you.
To really give a great working answer, I would need to see your an example page / the exact structure of your html, but here's what I have for you.
In a script file that you include after jQuery, you can include something similar to the below code assuming your html is as follows:
<div id="voterow-1" class="voterow">
<p class="voteresult"></p>
<a class="upvote" href="#" rel="nofollow">UP</a>
<a class="downvote" href="#" rel="nofollow">DOWN</a>
</div>
<div id="voterow-2" class="voterow">
<p class="voteresult"></p>
<a class="upvote" href="#" rel="nofollow">UP</a>
<a class="downvote" href="#" rel="nofollow">DOWN</a>
</div>
Having the class of upvote and downvote makes it easy to target these elements in jQuery:
// After jQuery is loaded, the function passed to ready() will be called
$(document).ready(function () {
// bind a click event to every direct child with the upvote class of an element with the voterow class
$('.voterow > .upvote').click(function (event) {
// get the voterow parent element
var $parent = $(event.target).parent();
// use regex to strip the id number from the id attribute of the parent
var id = parseInt($parent.attr('id').match(/^voterow-(\d+)/)[1]);
// call your ajax function
vote(id, 'up', $parent.find('.voteresult');
});
$('.voterow > .downvote').click(function (event) {
var $parent = $(event.target).parent();
var id = parseInt($parent.attr('id').match(/^voterow-(\d+)/)[1]);
vote(id, 'down', $parent.find('.voteresult');
});
function vote(id, direction, $resultElement) {
$.ajax({
type: "GET",
url: "/ajax.php",
// here we have the id and the direction needed to make the ajax call
data: "a=rv&v=" + id + "&d=" + direction,
success: function(data){
$resultElement.text("Thank you for your vote")
}
});
}
});
Here is a demo: https://plnkr.co/edit/ECL376hZ3NOz8pBVpBMW?p=preview

change id of a form with jQuery but jQuery uses the old attributes to recognize it

I have a form that it contents changes every time (for example inbox and sentbox items). I want to change the role of the submit button of the form. I do it this way:
first of all when I changing place, I rename the form id which I submit via an ajax request.($('#onlist').submit(function ())
Finally I define a new ajax request based on the new form id.($('#onsentlist').submit(function ())
But it seems that the second form also uses the old function that I described for the old form id. Why this thing happening? Is there a way to fix it? Or a new solution? Thanks.
here is the code:
$(document).ready(function () {
$('#onlist').submit(function () {
var formData = new FormData($('#onlist')[0]);
$('#res').append("<div id='alertshow' class='alert alert-info'><a href='#' class='close' data-dismiss='alert'>×</a><strong></strong>Loading,Please Wait...</div>");
$.ajax({
url: 'deletemsg.php', //Server script to process data
type: 'POST',
data: formData,
async: false,
success: function (msg) {
$('#res').empty().append(msg);
$('form input:checked').parents('a').remove();
},
cache: false,
contentType: false,
processData: false
});
return false;
});
});
$('#onsentlist').submit(function () {
var formData = new FormData($('#onsentlist')[0]);
$('#res').append("<div id='alertshow' class='alert alert-info'><a href='#' class='close' data-dismiss='alert'>×</a><strong></strong>Loading,Please Wait...</div>");
$.ajax({
url: 'deletesentmsg.php', //Server script to process data
type: 'POST',
data: formData,
async: false,
success: function (msg) {
$('#res').empty().append(msg);
alert('here');
$('form input:checked').parents('a').remove();
},
cache: false,
contentType: false,
processData: false
});
return false;
});
$('#refbut').click(function(){
$('#reload').load('loadmsgs.php');
});
$('#sentbox').click(function(){
$('#reload').load('loadsent.php');
$('.nav li').removeClass('active');
$('#onlist').attr('id','onsentlist');
var $parent = $(this).parent();
if (!$parent.hasClass('active')) {
$parent.addClass('active');
}
});
$('#inbox').click(function(){
$('#reload').load('loadmsgs.php');
$('.nav li').removeClass('active');
$('#onsentlist').attr('id','onlist');
var $parent = $(this).parent();
if (!$parent.hasClass('active')) {
$parent.addClass('active');
}
});
html:
<form method="post" id="onlist">
<button type="submit" id="delbt" value="Submit" class="btn btn-warning">
<span class="glyphicon glyphicon-trash"></span>   
</button>
<hr>
<div id="reload" class="list-group">
<?php require_once('load.php'); ?>
</div>
</form>
Bind occurs on the actual DOM node. So changing a specific property/attribute of it does not change what is bound on it.
The only thing you change in the two hanlders is the url, so it would better to just use a single script that selects the url based on a condition
so
$('#onlist').submit(function () {
var formData = new FormData($('#onlist')[0]),
actionUrl = $(this).data('action-url');
$('#res').append("<div id='alertshow' class='alert alert-info'><a href='#' class='close' data-dismiss='alert'>×</a><strong></strong>Loading,Please Wait...</div>");
$.ajax({
url: actionUrl , //Server script to process data, using the dynamic URL we set
type: 'POST',
data: formData,
async: false,
success: function (msg) {
$('#res').empty().append(msg);
$('form input:checked').parents('a').remove();
},
cache: false,
contentType: false,
processData: false
});
return false;
});
});
$('#sentbox, #inbox').click(function(){
var url= $(this).data('action-url');
$('#reload').load('loadsent.php');
$('.nav li').removeClass('active');
$('#onlist').data('action-url', url);
var $parent = $(this).parent();
if (!$parent.hasClass('active')) {
$parent.addClass('active');
}
});
and on the html add the attribute data-action-url="deletemsg.php" and data-action-url="deletesentmsg.php" on each button respectively..
Because changing an id of an element does not magically remove the events attached to the element.
You would need to unbind the event.
Second when you bind the event to an element that does not exist, it will not bind anything. It will not attach itself dynamically to the updated element.
You either need to change it so the logic for submmitted and not submitted in one submit function. Or you can bind the second function when you change the id. OR you can use event delegation to do the submission.
First of all, you should reconsider your approach... An ID is an unique identifier, you shouldn't need to change it at all... But moving on...
The way you assigned the event function
$('#onlist').submit(function () {
Attachs the listener to the element itself, not to the id targeted... In order to look for the Id at runtime you would need to use an event delegation, targeting a preceding element, like document:
$(document).on("submit", "#onsentlist", function () { ...
$(document).on("submit", "#onlist", function () { ...

Problems with ajax development

I apologize in advance for my bad English.
I have site in development http://plast-pak.esy.es/ on html-coding
With Ajax i called html page into my front page and slider is SlideUp.
<button onclick="clickAlert();" class="clickDown">?????????</button>
<script>
function clickAlert() {
$(this).click(function(){
$.ajax({
type: 'GET',
dataType: 'html',
url: 'item-1.html',
success: function(response) {
$('#projectInformation').html(response).slideDown('fast');
}
});
$('.front-page > #main_wrap').slideUp(3000);
$('.front-page > #menuBar').slideUp(3000);
});
}
</script>
Was callback page with information. It have her own button, witch have to close this page and return front page.
<button onclick="clickAbort();" class="clickUp">????????? ?? ???????</button>
<script>
function clickAbort() {
$(this).click(function(){
$('.front-page > #main_wrap').slideDown(3000);
$('.front-page > #menuBar').slideDown(3000);
$('#projectInformation .full-node').remove();
});
}
</script>
In the end, everything works, how it works. All horrible and very incorrect. Please help me to understand why it all works so. Thanks in advance.
Remove
$(this).click(function(){
from clickAlert and clickAbort. They are already click handlers.
Other than that, you will have to be more specific about "horrible and very incorrect".
$(this).click() is used to setup a handler for the click event of the button, and you're already doing that by setting the onclick attribute in your markup.
The usual way to do this is by giving an id to the button, so that you can set events in the javascript code:
<button id="alert" class="clickDown">Подробнее</button>
<script type="text/javascript">
$("#alert").click(function(){
$.ajax({
type: 'GET',
dataType: 'html',
url: 'item-1.html',
success: function(response) {
$('#projectInformation').html(response).slideDown('fast');
}
});
$('.front-page > #main_wrap').slideUp(3000);
$('.front-page > #menuBar').slideUp(3000);
});
</script>
Thanks everybody for your advices. The problem was solved as follows:
<button id="alert" onclick="clickAlert();" class="clickDown">Подробнее</button>
function clickAlert() {
$.ajax({
type: 'GET',
dataType: 'html',
url: 'item-1.html',
success: function(response) {
...
}
});
...
}
for whatever reason, Slider not given use following code
$("#alert").click(function(){
$.ajax({
type: 'GET',
dataType: 'html',
url: 'item-1.html',
success: function(response) {
$('#projectInformation').html(response).slideDown('fast');
}
});
$('.front-page > #main_wrap').slideUp(3000);
$('.front-page > #menuBar').slideUp(3000);
Only click event in button is working. Thanks again for your advice

How to replace .live() method with .on() method

Hei.. I have a function to load more news. Since jquery-1.9.1.min.js this function was working alright, but now I have to replace it with .on() method and I still can't get it work.
Here is the code:
// Load more news feed
$(function(){
var page = 1;
$.ajax({
type: "POST",
url: "data.php",
data: "page=profile&get_news_feed=true",
dataType:'json',
success: function(data){
$("#the_news_feed").html(data.news_feed);
if(page <= data.total_pages){
$("#the_news_feed").after('<button id="load_more_feed" class="btn btn-primary btn-large" style="width: 100%;margin-top:10px">Load More</button>');
}
}
});
$("#load_more_feed").live("click", function(){
var next = page+=1;
$.ajax({
type: "POST",
url: "data.php",
data: "page=profile&get_news_feed=true&page_num="+next,
dataType: "json",
success: function(data){
$("#the_news_feed").append(data.news_feed);
if(next == data.total_pages){
$("#load_more_feed").remove();
} else {
$("#load_more_feed").html("Load More");
}
},
beforeSend: function(){
$("#load_more_feed").html("Loading...");
}
});
});
});
I tryed to replace:
$("#load_more_feed").live("click", function()
with
$("#the_news_feed").on("click", "load_more_feed", function()
but I still can't get it work. What am I doing wrong? Thank you!
I display this function with id="news_feed" so here was the problem
<div class="tab-pane fade" id="news_feed">
<div id="the_news_feed"></div>
</div>
Final solution is $("#news_feed").on("click", "load_more_feed", function()
Thank you guys!
Actually, you're missing the # in the id selector.
$("#the_news_feed").on("click", "load_more_feed", function()
must be
$("#the_news_feed").on("click", "#load_more_feed", function()
assuming #the_news_feed is the parent of #load_more_feed.
EDIT :
From your code, you're appending this #loadmore button after #the_news_feed, so this obviously will not work. Try changing it to this :
$(document).on("click", "#load_more_feed", function()
This will bind the click to the document, which will always exist. Alternatively, you could bind it to #load_more_feed closest static parent, like an element which exists when you load your page and not dynamically created.

$.ajax interfering with .hide() and .show() Jquery in this script

(In Firefox and IE9 it doesn't work. In Chrome, this works)
If I remove the ajax, the hide / show JQuery works. Any solutions?
<form id="ppform" action="blah.asp" method="post">
<div id="saleload">Blah</div>
<button id="sendbutton">Send</button>
</form>
$(document).ready(function(){
$('#saleload').hide();
$('#sendbutton').click(function() {
$('#saleload').show();
$.ajax({
type: "POST",
url: /blah/blah.asp,
data: reqBody,
dataType: "json",
success:function(data,textStatus){
if (data.redirect) {
window.location.href = data.redirect;
}else{
$("#ppform").replaceWith(data.form);
}
}
});
});
});
This line:
$("#ppform").replaceWith(data.form);
is replacing the whole form contents with the response from your Ajax request. This means the click handler you setup will be gone too, because #sendbutton will be gone. Even if you have another button with the same ID inside data.form, it won't work. You have to use event delegation instead:
$(document).ready(function(){
$('#saleload').hide();
$(document).on('click', '#sendbutton', function(){
$('#saleload').show();
$.ajax({
type: "POST",
url: "/blah/blah.asp",
data: reqBody,
dataType: "json",
success:function(data,textStatus){
if (data.redirect) {
window.location.href = data.redirect;
} else {
$("#ppform").replaceWith(data.form);
}
}
});
});
});
Also: you seem to be posting an undefined variable reqBody to your server, and, as lonesomeday said above, you were missing quotes around the URL.
The obvious reason is that there is an error with your Javascript that causes the whole section not to execute. Quickly looking through your code shows this line:
url: /blah/blah.asp,
Strings need to be enclosed in quotation marks:
url: "/blah/blah.asp",

Categories

Resources