So I have been working on this for hours now, I have read a bunch of StackOverflow posts and I am still having no luck.
I have a page that has 2 sections to it, depending on the int in the database will depend on which section is being displayed at which time.
My goal is to have the page look to see if the database status has changed from the current one and if it has then refresh the page, if not then do nothing but re-run every 10 seconds.
I run PHP at the top of my page that gets the int from the database
$online_status = Online_status::find_by_id(1);
I then use HTML to load the status into something that jquery can access
<input type="hidden" id="statusID" value="<?php echo $online_status->status; ?>">
<span id="result"></span>
So at the bottom of my page, I added some jquery and ajax
$(document).ready(function(){
$(function liveCheck(){
var search = $('#statusID').val();
$.ajax({
url:'check_live.php',
data:{search:search},
type:'POST',
success:function(data){
if(!data.error){
$newResult = $('#result').html(data);
window.setInterval(function(){
liveCheck();
}, 10000);
}
}
});
});
liveCheck();
});
this then goes to another PHP page that runs the following code
if(isset($_POST['search'])){
$current_status = $_POST['search'];
$online_status = Online_status::find_by_id(1);
if($current_status != $online_status->status){
echo "<script>location.reload();</script>";
}else{
}
}
the jquery then loads into the HTML section with the id of "result" as shown earlier. I know this is a very bad way to do this, and as a result, it will work at the beginning but the longer you leave it on the page the slower the page gets, till it just freezes.
If anyone is able to point me towards a proper method I would be very grateful.
Thank you!!
js:
(function(){
function liveCheck(){
var search = $('#statusID').val();
$.ajax({
url:'check_live.php',
data:{search:search},
type:'POST',
success:function(data){
if(data.trim() == ''){
location.reload();
}else{
$('#result').html(data);
window.setTimeout(function(){
liveCheck();
}, 10000);
}
}
});
}
$(function(){
liveCheck();
});
})(jQuery)
php:
<?php
if(isset($_POST['search'])){
$current_status = $_POST['search'];
$online_status = Online_status::find_by_id(1);
if($current_status != $online_status->status){
$data = '';
}else{
$data = 'some html';
}
echo $data;
}
Your page is slowing down because you are creating a new interval every time you call the liveCheck function. Over time, you have many intervals running and sending requests to your PHP file concurrently. You can verify this behavior by opening the developer console in your browser and monitoring the Network tab.
What you should do instead is set the interval once, and perform the $.ajax call inside that interval. Additionally, it's good practice to not send a new request if a current request is pending, by implementing a boolean state variable that is true while an request is pending and false when that request completes.
It looks like the intended behavior of your function is to just reload the page when the $online_status->status changes, is that correct? If so, change your PHP to just echo true or 1 (anything really) and rewrite your JS as:
function liveCheck() {
if (liveCheckPending == true)
return;
liveCheckPending = true;
var search = $('#statusID').val();
$.ajax({
url:'check_live.php',
data:{search:search},
type:'POST'
}).done(function(data){
if (!data.error)
location.reload();
}).always(function(data){
liveCheckPending = false;
});
}
var liveCheckPending = false;
setInterval(liveCheck, 10000);
Related
I've started using ajax requests recently. I am making a mobile web application where I am to the request for data on PHP side server script. The javascript function is to automatically execute when the user navigates to the page. But the script seems not to run until I refresh the page, here is my javascript code.
<script>
$( document ).ready(function(){
Date.prototype.yyyymmdd = function() {
var yyyy = this.getFullYear().toString();
var mm = (this.getMonth()+1).toString();
var dd = this.getDate().toString();
return yyyy + '-' + (mm[1]?mm:"0"+mm[0]) + '-' + (dd[1]?dd:"0"+dd[0]);
};
function requestContent() {
var date = new Date();
$.ajax({
type:'POST',
url:'php/app/adminTimeline.php',
data:{
date: date.yyyymmdd()
},
success: function(data) {
if (data == '') {
alert("No data found!");
} else {
// $("#loading_spinner").css({"display":"none"});
$('#timeline-content').prepend(data);
}
},
error: function(data) {
// $("#loading_spinner").css({"display":"none"});
alert("Something went Wrong!");
}
});
}
window.onload = requestContent();
});
</script>
The document.onready method and window.onload the method seems not to be working too.
Ps: I have the Jquery library linked in the header too.
Code included inside $( document ).ready() will only run once the page Document Object Model (DOM) is ready for JavaScript code to execute.
https://learn.jquery.com/using-jquery-core/document-ready/
Also you're calling requestContent()
window.onload must be function, not returning value.
$(document).ready(function(){
// here you ajax
}
https://jsfiddle.net/cqfq5on5/1/
The code window.onload=requestContent(); will execute when the window loads, not necessarily when the entire document has loaded.
However where you create the date object, uses this, which executes after the document is fully loaded
$(document).ready(function(){
//Code
});
This means, that the POST request will be made once the window loads, which is before the document is fully loaded, thus, that date object will not exist until the page is refreshed, at which point the Javascript was likely cached. Also another answer (#sagid) pointed out, window.onload cannot be a returning value but must be a function.
i.e.
window.onload=function(){
//Code
};
This means, your solution is to change window.onload=requestContent(); to
$(document).ready(function(){
requestContent();
});
Good luck!
What i want to do is, to show a message based on certain condition.
So, i will read the database after a given time continuously, and accordingly, show the message to the user.
But i want the message, to be updated only on a part of the page(lets say a DIV).
Any help would be appreciated !
Thanks !
This is possible using setInterval() and jQuery.load()
The below example will refresh a div with ID result with the content of another file every 5 seconds:
setInterval(function(){
$('#result').load('test.html');
}, 5000);
You need a ajax solution if you want to load data from your database and show it on your currently loaded page without page loading.
<script type="text/javascript" language="javascript" src=" JQUERY LIBRARY FILE PATH"></script>
<script type="text/javascript" language="javascript">
var init;
$(document).ready(function(){
init = window.setInterval('call()',5000);// 5000 is milisecond
});
function call(){
$.ajax({
url:'your server file name',
type:'post',
dataType:'html',
success:function(msg){
$('div#xyz').html(msg);// #xyz id of your div in which you want place result
},
error:function(){
alert('Error in loading...');
}
});
}
</script>
You can use setInterval if you want to make the request for content periodically and update the contents of your DIV with the AJAX response e.g.
setInterval(makeRequestAndPopulateDiv, "5000"); // 5 seconds
The setInterval() method will continue calling the function until clearInterval() is called.
If you are using a JS library you can update the DIV very easily e.g. in Prototype you can use replace on your div e.g.
$('yourDiv').replace('your new content');
I'm not suggesting that my method is the best, but what I generally do to deal with dynamic stuff that needs access to the database is the following method :
1- A server-side script that gets a message according to a given context, let's call it "contextmsg.php".
<?php
$ctx = intval($_POST["ctx"]);
$msg = getMessageFromDatabase($ctx); // get the message according to $ctx number
echo $msg;
?>
2- in your client-side page, with jquery :
var DIV_ID = "div-message";
var INTERVAL_IN_SECONDS = 5;
setInterval(function() {
updateMessage(currentContext)
}, INTERVAL_IN_SECONDS*1000);
function updateMessage(ctx) {
_e(DIV_ID).innerHTML = getMessage(ctx);
}
function getMessage(ctx) {
var msg = null;
$.ajax({
type: "post",
url: "contextmsg.php",
data: {
"ctx": ctx
},
success: function(data) {
msg = data.responseText;
},
dataType: "json"
});
return msg;
}
function _e(id) {
return document.getElementById(id);
}
Hope this helps :)
Right now, every time a user logs in, all the posts made by that user will turn green, while all the offline users' posts are grey.
I want to add a link to a javascript function for when the div is green, and a different link for when it's grey. I did this in php no problem but I want it to work realtime just like the color change without a page refresh.
The html
<div class="main_ads status" id="user'.$user_id.'">post</div>
status.php
header('Content-Type: application/json');
$array = array();
$res = mysql_query("SELECT * FROM `users` WHERE `status` = 1");
if(mysql_num_rows($res) > 0){
while($row = mysql_fetch_assoc($res)){
$array[] = 'user'.$row['user_id']; // this adds each online user id to the array
}
}
echo json_encode($array);
ajax code
$(document).ready(function() {
setInterval(function(){
$.ajax({
url: 'status.php',
dataType: "json",
type: 'GET',
success: function(data) {
if (data.length > 0){ // if at least 1 is online
$('.status').each(function(){ // loop through each of the user posts
var userid = $(this).attr('id'); // get the user#
if($.inArray(userid, data) !== -1){ // if userid # in the returned data array set to online
$(this).css({background: '#40A547'});
} else{ // if not, set to offline
$(this).css({background: '#7f8c8d'});
}
});
} else { // if no one is online, set all to offline
$('.status').css({background: '#7f8c8d'});
}
}
});
}, 2000);
});
I tried to think of a way to do this and thought to assign a variable with a html tag that will be different for online and offline but wasn't sure how to call that variable from the ajax code into html.
All help is much appreciated!
You could make use of the wrapInner() property of jQuery. This could enclose the text place inside your div into <a></a> tags such as:
if($.inArray(userid, data) !== -1){ // if userid # in the returned data array set to online
$(this).css({background: '#40A547'});
//for the online users, you could fill in the javascript function
$(this).wrapInner('');
} else{ // if not, set to offline
$(this).css({background: '#7f8c8d'});
//over here write the link for offline users
$(this).wrapInner("<a href='www.google.com'></a>");
}
Fiddle
Do not add inline styles, use css classes.
In case the request takes longer than 2 seconds, abort it!
I suggest not using id's, mabye data-user or .user# as class
HTML
<div class="main_ads status" id="user1">post1</div>
...
<div class="main_ads status" id="user10">post10</div>
CSS
.online{
background:red;
padding:3px;
}
JQUERY
var global_ajax_request = null;
$(document).ready(function() {
setInterval(function(){
if (global_ajax_request){
global_ajax_request.abort();
}
global_ajax_request = $.ajax({
url: 'ajax.php',
dataType: "json",
type: 'GET',
success: function(data) {
$('.status').removeClass('online');
for(var i in data){
$('#'+data[i]).addClass('online');
}
}
});
}, 2000);
});
$('.status').on('click',function(e){
e.preventDefault();
if ($(this).hasClass('online')){
alert('function for ONLINE');
}else{
alert('function for OFFLINE');
}
});
Explanations:
global_ajax_request holds the reference to a request. Just before launching a new one, kill the old one. (!) This will make the browser not listen for a response, but the server will continue to work.
Each time you get a response, clear the online class and add it only to the returned userId's. (This should be Optimized.)
The last bit $('.status').on(...) will be fired each time someone clicks on a div. Then inside you see if it's green (online) or not and launch the appropriate function.
I have an application that I'm writing that, in one aspect of it, you click on a checkmark to complete a task, a popup window is displayed (using bootstrap), you enter your hours, and then that is sent to a PHP page to update the database. I'm using FF (firebug) to view the post. It's coming up red but not giving me an error. The only thing I'm doing is echoing out "sup" on the PHP page, and it's still showing errors, and I can't figure out why.
This is my initial click function:
$('.complete').on('click', function(event) {
var id = $(this).attr('data-id');
var tr = $(this).parent().parent();
var span = $(tr).children('td.task-name');
var r = (confirm('Are you sure you want to complete this task?'));
if (r){
addHours(id);
} else {
return false;
} // end else
});
That works fine, and it fires my next function which actually fires the bootstrap modal:
function addHours(id) {
var url = 'load/hours.php?id='+id;
$.get(url, function(data) {
$('<div class="modal hide fade in" id="completeTask">' + data + '</div>').modal()
.on('shown', function() {
pendingTask(id);
}); // end callback
}).success(function() {
$('input:text:visible:first').focus();
});
} // end function
This is also working, and the modal is displayed just fine. However, whenever I post the form to my logic page, it fails for no reason. This is the function to post the form to the logic page:
function pendingTask(id) {
$('.addHours').on('click', function(event) {
var formData = $('form#CompleteTask').serializeObject();
$.ajax({
url:'logic/complete-with-hours.php',
type: 'POST',
dataType: 'json',
data: formData,
success: function(data) {
if (data.status == 'error') {
$(this).attr('checked', false);
//location.reload();
} // end if
else {
$(this).attr('checked', true);
//location.reload();
} // end else
},
dataType: 'json'
});
}); // end click
} // end function
When this is fired, I see this in my Firebug console:
I know this is a lot of information, but I wanted to provide as much information as I could. Every other post function in the application is working fine. It's just this one. Any help would be appreciated.
Thanks in advance.
The jQuery.ajax data parameter takes a simple object of key value pairs. The problem could be that the object created by serializeObject() is too complex. If that's the case, you could either process the formData object to simplify it or try data: JSON.stringify(formData)
Does serializeObject() even exist in jQuery? is that a function you wrote yourself? Can you use jQuery functions like serialize() or serializeArray() to serialize the form data and see how it goes.
Usually the red indicates a 404 response error. We can't tell in this screen shot. Check your php code by directly calling the requested page and getting a proper response.
Also make sure your dataType is application/json which is the proper mime type header (though I don't think this is causing the error). You also should only have dataType once (you have it again at the bottom)
I figured it out. I changed the post type from the structure I entered above to a standard post:
$("#CompleteTask").validate({
submitHandler: function(form) {
var hours = $('#hours').val();
$.post('logic/complete-with-hours.php', {'hours': hours, 'id':id},
function(data){
if (data.status == 'success') {
$(checkmark).attr('checked', false);
$('.message').html(data.message).addClass('success').show();
} // end if
if (data.status == 'error') {
$('.message').html(data.message).addClass('error').show();
} // end else
},
"json"
); //end POST
} // end submit handler
}); // end validate
That seemed to do the trick
I've my site pages structure as
1) index.php which calls addline.php using ajax and the html returned is appended to the index.php
2) the addline.php calls another page more.php using ajax which again appends the returned html to it
3) Again more.php calls another file update.php and in the update.php, I've my following js codes
var number = parseInt("<?php echo $delFlag; ?>");
if ( number == 1) {
// Calling updateLine() function after 5 mins
timer = setTimeout("updateLine()",1000*5*60);
}
function updateLine() {
var flagId = <?php echo $flagId; ?>;
var dataPass = 'flagId=' + flagId;
$.ajax({
type: "POST",
url: "proc/updateLine.php",
data: dataPass,
cache: false,
success: function(){
// Show error if error is there
}
});
}
All the time, my location is still index.php.
The javascript function works properly if I do not reload the page. If I reload the page, it doesn't work. I want the setTimeOut() call to be active in the background even after the reload takes place. It should trigger the function call after 5 mins.
How do I achieve it??
Reloading a page resets the Javascript state and there is no direct way to keep things running in the background.
If the requirement is to continue the timeout counter automatically after the page reload, then the counter state has to be persisted somehow.
It means that every timeout start has to be accounted for. One option would be to do it with PHP and load and unload events, along the lines of:
// timeout.php -- persists and returns the last timeout start by session
<?php
session_start();
$key = 'lastTimeoutStart';
if (isset($_GET[$key]))
$_SESSION[$key] = $_GET[$key];
else if (isset($_SESSION[$key]))
echo $_SESSION[$key];
?>
Plus the Javascript part that handles persisting and loading:
var lastTimeoutStart = 0;
if ( number == 1) {
// Calling updateLine() function after 5 mins
lastTimeoutStart = new Date().getTime();
timer = setTimeout("updateLine()",1000*5*60);
}
//
// Other code
//
$(document).load(function () {
$.get('timeout.php', function (data, textStatus, jqXHR) {
var persistedStart = data.lastTimeoutStart;
var tempTimeout = persistedStart + 1000*5*60 - new Date().getTime();
if (tempTimeout > 0) {
clearTimeout(timer);
timer = setTimeout("updateLine()", tempTimeout);
}
});
});
$(document).unload(function () {
var data = {"lastTimeoutStart": lastTimeoutStart};
$.get('timeout.php', data, function (data, textStatus, jqXHR) {});
});
There may be bugs in the above code but hopefully you get the idea.