I have an AJAX function to check for new messages and then prepend the new messages to the #message. But, my problem is that this function triggers every 20 seconds, but whenever you click the Refresh button that instantly triggers the function, it messes up. Here is my functions for the AJAX:
function ajaxMail() {
var message_id = $('.line:first').attr('id');
jQuery.ajax({ //new mail
type: 'get',
dataType: 'text',
url: "/employee/message/check_mail.php",
data: {
latest_id: message_id,
t: Math.random()
},
success: function(data, textStatus) {
$('#messages_inner').prepend(data);
}
});
}
function updateTitles() {
//if(titleChange !== false) {
$.get('update.php?type=title', function(data) {
document.title = data;
});
//}
$.get('update.php?type=header', function(data) {
$('#heading').html(data);
});
$.get('update.php?type=total', function(data) {
$('#total').html('Total messages: ' + data);
});
setTimeout("updateTitles();ajaxMail();", 20000);
}
updateTitles();
And for the Refresh button this is what I use:
$(document).ready(function() {
$('#refresh').click(function() {
ajaxMail();
updateTitles();
});
});
Sometimes, the same exact message gets prepended to the message div because of the button or something. (but when I refresh of course there aren't 2 of the same message anymore) This is one time when the same message was prepended multiple times:
First, I pressed the Refresh button and it prepended the new message. But then about 5 seconds later the funciton triggered again and for some reason prepended the same message again. Also as you can see the Inbox count says 2 because really there is only 2 ("Test" and "Test12345"), but for some reason the "Test12345" got prepended 2 times.
Does anyone know why it is doing this? I can also provide the code for check_mail.php if you need to see it.
I'd recommend trying cache:false too, I've had browsers caching an ajax request even through I was sending a random string along.
Also, consider clearing the timeout before you set it again, as each time the refresh button is pressed it starts another timeout.
Related
I'm using AJAX to submit the form without reloading. I'm using it for my register form. After I catch my error/success message I append it to my div and remove it after 5 seconds using timeout function.
Now if the user clicks on the button and gets error, and then again clicks the button (before 5 seconds pass) the second error message div will appear with the same error but it will be removed at the same time the first one is removed. So what I'm trying to achieve is to set my error/success messages to have individual timeouts. So first error appears, then after 2 seconds I press the button again and get second error, now the first error will be removed after 5 seconds, and the second will stay untill its 5 seconds pass.
So I have a div in my HTML code with the id "msg-response", where my error/success messages appear.
And here is how I call them:
$("#registerform").submit(function(event) {
var ajaxRequest;
event.preventDefault();
$("#result").html('');
var values = $(this).serialize();
ajaxRequest = $.ajax({
url: "include/auth/register.php",
type: "post",
data: values
});
ajaxRequest.done(function (response){
if ($.trim(response) == 'error') {
$("#msg-response").prepend("<div class='error-msg'>Email format isn't valid. Try again.</div>").hide().fadeIn("slow");
setTimeout(function() {
$('.error-msg').fadeOutAndRemove('slow');
}, 5000);
}
});
ajaxRequest.fail(function (){
alert("error");
});
});
So how can I add individual timeouts to each div appeared? And not one timeout for all divs with class .error-msg.
Thanks in advance.
You can store your .error-msg inside a var and then remove it by var reference:
var error = $("<div class='error-msg'>Email format isn't valid. Try again.</div>");
error.fadeOutAndRemove('slow');
Final code:
if ($.trim(response) == 'error') {
var error = $("<div class='error-msg'>Email format isn't valid. Try again.</div>");
$("#msg-response").prepend(error).hide().fadeIn("slow");
setTimeout(function() {
error.fadeOutAndRemove('slow');
}, 5000);
}
Intresting, I got it working by making my error-msg div to be an ID instead of CLASS, so like this:
$("#registerform").submit(function(event) {
var ajaxRequest;
event.preventDefault();
$("#result").html('');
var values = $(this).serialize();
ajaxRequest = $.ajax({
url: "include/auth/register.php",
type: "post",
data: values
});
ajaxRequest.done(function (response){
if ($.trim(response) == 'error') {
$("#msg-response").prepend("<div id='error-msg'>Email format isn't valid. Try again.</div>").hide().fadeIn("slow"); // Changed line
setTimeout(function() {
$('#error-msg').fadeOutAndRemove('slow'); // Changed line
}, 5000);
}
});
ajaxRequest.fail(function (){
alert("error");
});
});
I'm confused a little, so can atleast someone write me explanation why its good now that I'm using ID and not while using classes? And is this the right approach?
I have a chat app created using PHP, mySQL and jQuery. It's working fine for me. But now I want to add the "message seen" feature whenever the receiver sees the message. Or It can be a "tick" like feature as done in WhatsApp. The problem is that I don't know how to achieve this.
Here's the script which only works up to sending and receiving messages between users. What I have to do to implement this?
$ = jQuery;
var currentID = null;
var chatTimer = null;
var oldhtml = "";
function fetch_data() {
$.ajax({
url: "select.php",
method: "POST",
success: function(data) {
$('#live_data').html(data);
}
});
}
function fetch_chat() {
$.ajax({
url: "fetch_chat.php",
method: "POST",
data: {
id: currentID
},
dataType: "text",
success: function(data) {
$("#chatbox").show();
$('#messages').html(data);
$("div.area").show();
if (oldhtml !== data) {
$('#messages').scrollTop($('#messages')[0].scrollHeight);
}
oldhtml = data;
}
});
}
$(document).ready(function() {
fetch_data();
setInterval(function() {
fetch_chat();
}, 500);
$(document).on('click', '.first_name', function() {
currentID = $(this).data("id1");
fetch_chat();
});
$("#sub").click(function() {
var text = $("#text").val();
$.post('insert_chat.php', {
id: currentID,
msg: text
}, function(data) {
$("#messages").append(data);
$("#text").val('');
});
});
});
you need a flag in your messages table,
when receiver fetches some messages, the status of these messages should be set to "seen", or if you want you can do this with ajax call after that the receiver opens the chat box or any event happened (like receiver clicks on chat box).
in chat boxes you must set id for every message, and every time you retrieve messages or check for new messages, you also must check "unseen" messages and send status of messages beside the message, and with your javascript,you must change class of these messages to "unseen" and other messages to "seen"
I assume for a message to be "seen" it has to be visible from the chat html node($("#messages") in your case), meaning for some reason it can be hidden(e.g: another chat html node "active" in case there are several and only one can be active at a time, or maybe browser tab out of focus, or even the very message is out of the scroll view of the chat html node ...).
So, why not just add events listeners to it, listening whether its gets the "active" state or to the browser tab focus... When conditions met, just do an ajax query that will change the status(received, read(in this case) ...) of the message in the database by its id(assuming each message has a unique id set on it). Of course there should be a timer retreiving messages status, by then, in the sender side, you select read messages by their id and manage to get them "tick"ed as will, and even do something else.
Hello I have this script that moves from one page through a href without page load.
It works perfectly, but I want to redirect to the requested page if Ajax takes longer than 5 seconds to respond, usually caused by probably slow internet connection.
In this case: Stop the script and load the page normally.
Firstly the href:
new
New 1
This is the script:
<script>
$(function(){
$("a[rel='tab']").click(function(e){
pageurl = $(this).attr('href'); //get the href clicked
$.ajax({url:pageurl+'?rel=tab',
success: function(data){
$('#mole').html(data);
}
});
if(pageurl!=window.location){
window.history.pushState({
path:pageurl
},'',pageurl);
}
return false;
});
});
$(window).bind('popstate', function(){
$.ajax({
url:location.pathname+'?rel=tab',
success: function(data){
// here how do I detect if the success takes longer than 5 seconds
// stop the script and load the page normally which is the URL parameter in ajax
$('#mole').html(data);
}
});
});
</script>
First, we need to add a timeout to the ajax handler so it will cancel the request after 5 seconds (here we use 5000 for milliseconds). Then, based on the docs, head to error and you can see the second param is textStatus. If it was a timeout, this will be equal to "timeout". This is probably your easiest path to what you need to do. Update the error handler as needed for your functionality.
$(window).bind('popstate', function() {
var url = location.pathname + '?rel=tab';
$.ajax({
timeout: 5000,
url: url,
success: function(data) {
$('#mole').html(data);
},
error: function(jqXHR, textStatus) {
if (textStatus === 'timeout') {
// we know the ajax failed due to a timeout,
// do what you need here, below is an example.
window.location = url;
}
}
});
});
I've got an ASP-NET/MVC/Bootstrap app in which I've implemented a progress bar that displays in a modal window during a long running search process.
The sequence of events is this:
User clicks button to initiate process. This button submits the form. There is an on-click event on the button that calls a javascript function (showProcessingModal()) to show the modal window and then initiate the recursive ajax callback that gets the status of the process and displays it in the modal:
var searchCancel;
function showProcessingModal() {
var sid = performance.now();
$("#SearchId").val(sid);
$("#PleaseWaitModal").modal("show");
getSearchProgress(sid);
}
function getSearchProgress(sid) {
$.ajax({
url: '#Url.Action("SearchProgress")',
method: "POST",
data: { SearchId: sid },
success: function (result) {
$('.progress-bar').css('width', result.pct + '%').attr('aria-valuenow', result.pct);
if (result.msg != "") {
$('#ProgressMessage').html(result.msg);
}
if (result.pct == 100) {
$('.progress-bar').removeClass('active')
}
if (result.pct <= 100) {
searchCancel = setTimeout(function () {
getSearchProgress(sid);
}, 500);
}
},
error: function (xhr, textStatus, errorThrown) {
alert(xhr.responseText);
}
});
}
This works beautifully in IE and Chrome. In FireFox, the modal shows but the ajax call fails because it seems FireFox has closed the socket on account of the page being submitted. I'm assuming Safari is doing the same although with Safari, the modal doesn't even show. I have yet debugged why.
I'm suspecting that I'm going to have to go a different route to make this work for all browsers. I'm thinking that the form post is what's messing things up.
Thoughts anyone?
I am making a PM system, and I am currently adding the message starring system (so the user can star messages).
The problem is that if the user keeps starring and unstarring a message very fast (clicking it over and over again) it will mess up the server (the host will put a 503 error until the processes stop). To star a message it is simple as clicking the star to star it/clicking again to unstar it.
Is there a way to prevent it from being clicked a lot, or rather make an error pop up after it is clicked x number of times within a minute? That would prevent it from overloading the server because when you click the star it sends an AJAX request and updates the database; when you unstar it, it does the same thing.
Is there a jQuery way of showing an error if the star was clicked within a minute or so?
These are my functions for the starring:
function addStar(id) {
$('#starimg_' + id).removeClass("not_starred").addClass("starred");
$('#star_' + id).attr({
'title': 'Starred',
'onclick': 'removeStar(' + id + ')'
});
$.get('tools.php?type=addstar', {id: id}, function(data) {
if(data=='true') { // tools.php will echo 'true' if it is successful
alertBox('The message has been starred successfully', 2500);
}
else { alertBox('An error has occurred. Please try again later.'); }
});
}
function removeStar(id) {
$('#starimg_' + id).removeClass("starred").addClass("not_starred");
$('#star_' + id).attr({
'title': 'Not starred',
'onclick': 'addStar(' + id + ')'
});
$.get('tools.php?type=removestar', {id: id}, function(data) {
if(data=='true') { // tools.php will echo 'true' if it is successful
alertBox('The message has been unstarred successfully', 2500);
}
else { alertBox('An error has occurred. Please try again later.'); }
});
}
Thanks in advance!
here is a sample solution for your addStar function. This will send the request 2 sec after the users last click, so if the user is click happy those intermediate clicks will not send requests since the timer will be reset.
function addStar(id, delayRequests)
{
...
if(delayRequests == true){
clearTimeout(timer);
timer= setTimeout(function() { sendRequestToAddStar(id); },2000);
}
else{
sendRequestToAddStar(id);
}
}
function sendRequestToAddStar(id)
{
$.get('tools.php?type=removestar', {id: id}, function(data) {...
}
In any case, IMO it's better to not show an error message.
Consider starting/resetting a countdown timer every time the star is clicked. Once it counts down, send the current state of the star. User feedback is preserved and rate-limiting is honored.
They don't need to know there's a rate limit, or that it's not sending a request every time.
(That was a lot of words to describe a simple problem, and I think we know what "starring a message" means w/o a picture :)