I created a simple voting system (+ and -) on Ajax for users comments. One page have 50 posted comments and you can vote for each "plus" or "minus". This data sent through the PHP script to the database. However, if a user votes, the PHP script is called 50 times - it is visible in Chrome developer tool. There are errors - more value than expected. Here is my code (two DIV buttons and the script).
Tell me please how to change the code to the script (up_vote.php or down_vote.php) is called only once.
<script type="text/javascript" src="raitings/jquery.js"></script>
<script type="text/javascript">$(function() {$(".vote").click(function() {
var id = $(this).attr("id");
var name = $(this).attr("name");
var dataString = 'id='+ id ;
var parent = $(this);
if(name=='down')
{
$(this).fadeIn(200).html('<img src="raitings/dot.gif" align="absmiddle">');
$.ajax({type: "POST", url: "raitings/down_vote.php", data: dataString, dataType : "html", cache: false, success: function(html)
{ parent.html(html);}
});
}
else
{
$(this).fadeIn(200).html('<img src="raitings/dot.gif" align="absmiddle">');
$.ajax({type: "POST", url: "raitings/up_vote.php", data: dataString, dataType : "html", cache: false, success: function(html)
{ parent.html(html);
} });
}
return false;
});
});
</script>
//php code below;
echo "<div class=\"box1\"><div class=\"up\">".$up."</div>"
."<div class=\"down\">".$down."</div></div>\n";
Using jQuery, it's important to know that events are stackable, even if the event is exactly the same. For example:
$(".vote").click(function() { alert("hi"); });
$(".vote").click(function() { alert("hi"); });
$(".vote").click(function() { alert("hi"); });
If we ran these three lines verbatim, we'll have 3 different events attached. That is, we would get 3 alerts one after the other by clicking in an element with the vote class.
In addition, oftentimes it happens that pages being loaded through ajax carry the same <script></script> block of the parent page, and when this is the case, the code is inadvertently being processed again and again with every ajax call.
While I was not able to pinpoint exactly how is this happening by the code you provided, it seems this is the most likely scenario: your click handler event is being loaded several times, and as a result one click triggers several ajax calls.
The quick and dirty solution when this presents as I mentioned in the comments is replacing:
$(".vote").click(function()
By:
$(".vote").unbind("click").click(function()
Which thanks to the unbind function forces it to discard previously attached events every time a new one is attached, thus preventing it from having more than one event attached no matter how many times the code is processed.
While this will work, the better solution is, of course, to locate where is the js code being loaded multiple times and make sure it is loaded just once.
$(".vote").each(function () { $(this).click( clickHandler .... etc should solve your problem.
I don't fully understand how your version works but I would do it similar to this:
+
-
Where 200 would be the unique id of the comment.
Then have a vote_up() and vote_down() function defined in a JavaScript and add your ajax requests there.
That way it should not call the script more than once when +/- button is clicked.
You can disabled button before send you ajax request.
// Sample:
$(function() {
$(".vote").click(function() {
var id = $(this).attr("id");
var name = $(this).attr("name");
var dataString = 'id='+ id ;
var parent = $(this);
parent.fadeIn(200).html('<img src="raitings/dot.gif" align="absmiddle">');
if(name=='down')
{
$.ajax({
type: "POST",
url: "raitings/down_vote.php",
data: dataString,
dataType : "html",
cache: false,
beforeSend: function() {
parent.attr("disabled", true);
},
success: function(html) {
parent.html(html);
}
});
} else {
$.ajax({
type: "POST",
url: "raitings/up_vote.php",
data: dataString,
dataType : "html",
cache: false,
beforeSend: function() {
parent.attr("disabled", true);
},
success: function(html) {
parent.html(html);
}
});
}
return false;
});
});
Related
I have a button that executes an ajax function.
Sometimes the server lags so maybe an user presses it more times, thinking the first time it didn't work...
The main ajax function looks like this:
$.ajax({
type: "POST",
url: "page.php",
dataType: "html",
data:"data=data",
success: function(){
ajax2();
ajax3();
}
});
Since that ajax function updates db and makes others 2 ajax functions i need to block the button from remake the main ajax func...
Only when ajax2() and ajax3() are finished, the button, if pressed, must remake the ajax function.
Hope to have explained well my problem!
disable the button and then reenable it when the 2 ajax are finished
/// the click event
$('yourbutton').prop("disabled",true);
/// show a loading or something....
$.ajax({
type: "POST",
url: "page.php",
dataType: "html",
data:"data=data",
success: function(){
var ajax1 = ajax2();
var ajax2 = ajax3();
$.when(ajax1,ajax2).done(function(risp1,risp2){
console.log(risp1,risp2);
$('yourbutton').prop("disabled",false);
/// hide the loading
});
}
});
read this for more info
Try this
//before this ajax call disable button
$.ajax({
type: "POST",
url: "page.php",
dataType: "html",
data: "data=data",
success: makeAjaxCalls
});
function makeAjaxCalls() {
var a1 = ajax2();
var a2 = ajax3();
$.when(a1, a2).done(function () {
//enable your button here
});
}
Unbind the event listener when it's activated the first time :
custom_ajax_handler = function(){
$('#mybutton').unbind('click'); //won't intercept event from now on.
//here is your ajax call.
ajax2();
ajax3();
}
$('#mybutton').click(custom_ajax_handler);
Then in ajax3 success rebind it :
success : function(){
$('#mybutton').click(custom_ajax_handler);
}
Note that you probably shouldn't make that much ajax calls.
Or at least that doing so won't help your server with its lags.
I'm having some trouble with my jquery ajax code.
I have 2 functions, one that will submit a value and other that will update the values in real time.. At least that's what it is supposed to do. :P
So, I have a list that is created throught some PHP code:
<div id="votos">
<ul class="yourvotes">Your votes: 0</ul>
<li class="votesofothers">
User Votes: (0)</br>
User2 Votes: (0)</br>
</li>
</ul>
</div>
And then I have a Ajax call to update the database when one of the links is pressed:
$(function(){
$('.votar').click(function(){
var elem = $(this);
$.ajax({
type: "GET",
url: "votar.php",
data: "id="+elem.attr('iduser'),
dataType:"json",
success: function() {
window.location.reload(true);
}
});
$(document).ajaxStop(function(){
window.location.reload();
});
return false;
});
});
And this would be the code to update the values that appear in "real-time":
function mostrarvotos() {
$('#votos').load('votos.php');
setTimeout('mostrarvotos()',1000);
}
mostrarvotos();
(I originally wanted to update each of the user votes instead of updating the whole div but I couldn't manage to do it.)
So my problem is that when I add the "mostrarvotos()" function to my code the links stop working and just add a # to the url, but if I remove it everything works fine.. If you could help me with this I would greatly appreciate.
That's because you are not prevent the link's original action. The click handler won't catch the event when you refreshed the content with an AJAX request. Try document.on instead of your current handler:
$(document).on('click','.votar',function(e){
e.preventDefault(); //Prevent the default action
var elem = $(this);
$.ajax({
type: "GET",
url: "votar.php",
data: "id="+elem.attr('iduser'),
dataType:"json",
success: function() {
window.location.reload(true);
}
});
$(document).ajaxStop(function(){
window.location.reload();
});
return false;
});
Also note the preventDefault which prevents the defauls link action (the # in your address bar).
You need to delegate your click function because you are adding those links dynamically.
So do something like:
$(function () {
// delegate your dynamically loaded links
$('#votos').on('click', '.votor', function () {
var elem = $(this);
$.ajax({
type: "GET",
url: "votar.php",
data: "id=" + elem.attr('iduser'),
dataType: "json",
success: function () {
window.location.reload(true);
}
});
$(document).ajaxStop(function () {
window.location.reload();
});
return false;
});
});
I have a page with 2 divs..each div have to call an ajax function on load. However, after I open either one of the divs, the ajax of the other div will not work.
*#div_remove lets the user delete a user from the system and display the existing ones in another div within #div_remove thru ajax.
#div_logs displays all transactions done in the system and displays them on another div within #div_logs through ajax.*
Here is the jQuery code:
$("#remove_admin").on("click",function(){
$("#light").fadeIn("slow");
$("#div_remove").slideDown("slow");
showtable();
event.preventDefault();
$("#btnRemove").click(function(){
var text = $.ajax ({
type: "GET",
url: "delUserProcess.php?keyword="+$("#txtRemove").val()+"&table=users&field=username",
async: false,
}).responseText;
alert(text);
showtable();
event.preventDefault();
});
});
//VIEW USER LOGS
$("#logs").on("click",function(){
$("#light").fadeIn("slow");
$("#div_logs").slideDown("slow");
showLogs();
event.preventDefault();
});
$("#txtUser").on("keyup",function(){
showLogs();
event.preventDefault();
});
$(".date").on("change",function(){
showLogs();
event.preventDefault();
});
});
function showtable(){
$.ajaxSetup ({
cache: false
});
$.ajax({
type: "GET",
url: "showAdmin.php",
async: false,
success:function(text){
$("#tblUsers").html(text);
}
});
}
function showLogs(){
$.ajaxSetup ({
cache: false
});
var cBy = $("#txtUser").val();
var sDate = $("#startDate").val();
var eDate = $("#endDate").val();
$.ajax({
type: "GET",
url: "showLogs.php?sDate="+sDate+"&eDate="+eDate+"&createdBy="+cBy,
async: false,
success: function(text){
$("#tblHistory").html(text);
}
});
}`
the original code used .click(), .keyup() and .change().. I already tried using .live() and .on() but it is still not working. please help.
You need to bind the events under the showLogs file.
Because whenever you call the delete or other events, it replace the html with the updated one. and the events lots it existance. So you need to call them in the showLogs file.
I'm very new at AJAX calls from jQuery and I'm a bit stuck trying do to this; I have an AJAX call from jQuery like this:
$(document).ready(function() {
$('tr.table-row').click(function(){
$.ajax({ url: 'stats-render.php', data: {ref: $(this).attr('id')}, type: 'post', success: function(d) {//the_output_here}});
});
});
This script is inside a web page triggered when the user hits a particular row (<tr></tr>) from a table. stats-render.php outputs HTML text with some info and graphics. This answer some times takes a while (15 seconds), so I would like to show the user a waiting message when he/she triggers the script and when the call returns an answer show the output text in a div (lets call it <div id="render-div">).
So the questions are, how can I show a waiting message? If you know a good script for showing this in a modal, I would appreciate it.
How can I output the result from stats-render.php into a div?. Thank you so munch for any help!
Just display a loading message in the div where the results go in the interim.
$(document).ready(function() {
$('tr.table-row').click(function(){
$.ajax({ url: 'stats-render.php', data: {ref: $(this).attr('id')}, type: 'post', success: function(d) { $('div.for-results').html( /* d... */ ); });
$('div.for-results').html('loading...');
});
});
Or for even more fun:
$(document).ready(function() {
$('tr.table-row').click(function(){
$.ajax({ url: 'stats-render.php', data: {ref: $(this).attr('id')}, type: 'post', success: function(d) {
clearInterval(loading);
$('div.for-results').html( /* d... */ );
});
$('div.for-results').html('loading');
var loading = setInterval(function() { $('div.for-results')[0].innerHTML += '.' }, 1000);
});
});
The easiest option is probably to check out the jquery-loading plugin.
I just do a simple show the message before the call, and hide it on the success callback like this:
However I think jquery might have a callback option when the ajax call starts, and when it stops.
$(document).ready(function() {
$('tr.table-row').click(function(){
//Show the loading message, or chage a css class, or what have you.
$('#loadingmessagetext').show();
$.ajax({ url: 'stats-render.php', data: {ref: $(this).attr('id')}, type: 'post', success: function(d) {
//Hide the loading message
$('#loadingmessagetext').hide();
//the_output_here
}
});
});
});
I was wondering if this was making an asynchronous request...write now Im using:
<script type='text/javascript'>
$(document).ready(function() {
var ktitle = $('.hiddentwo').text();
$('div#tab2').load('morefour.php?title=' + encodeURIComponent(ktitle));
});
</script>
what Im doing though is adding text in the first, into the database, on the current php file (addtext.php). Im passing the Id of the current document to the morefour.php and that is loading the added text on the second tab...the thing is, Im having to refresh to see the content again. Im running on localhost btw.
For more clarity, Im running another jquery script that on clicks, retrieves this data to send it to a php file to enter into a database
$(".button").click(function() {
var content = $(this).siblings().outerHTML();
$.ajax({
async: false,
type: "POST",
url: "tosqltwo.php",
data: {
content: content
}
});
});
$(function(){ //shorthand of $(document).ready
$('div#tab2').html($.ajax({
type: "GET", //if you are doin $_GET['title'] in morefour.php
url: "morefour.php",
data : {title:ktitle},
dataType: 'html', //i am not sure about this part
async: false
}).responseText)
});
or you can try
$(function(){
$.ajax({
url : 'morefour.php',
data : {title:ktitle},
type:'GET',
dataType:'html',
success: function(data) {
$('div#tab2').html(data);
}
});
});
you can use $.ajax function with async to false.
$.ajax({
async: false,
url : 'morefour.php',
data : 'title=' + encodeURIComponent(ktitle),
success: function(data) {
$('div#tab2').html(data);
}
});