HTML automatically refresh page but check for connection prior - javascript

I have a Python based flask web application which shows some SQL information on a html page.
This page is semi-realtime, it gets refreshed every 15 minutes with a simple html refresh:
<META HTTP-EQUIV="refresh" CONTENT="9000">
This works fine as long as the connection is up, there are no internal code errors.
Now I don`t want to have to manually refresh the page once it cannot refresh the page correctly for whatever reason. (connection, internal error).
Is it possible to have a webpage that keeps refreshing every fixed period of time regardless on whether the last refresh was succesfull.
Currently the html page contains no Javascript or the like, just plain html which is generated by Flask built-in template engine Jinja2.
Is it maybe possible to load the webpage completely first than check if it was successful and then refresh?

If you get the a javascript library such as jQuery, you can do this with the asynchronous Ajax functions. Here is an example of how you can replace your <body> content every 15 minutes if it is successfully loaded:
function update_site() {
$.ajax({
url: "/my/page/url/",
dataType: "html",
cache: false,
success: function(data) {
// Replace body with loaded site. You can do more checks here to check
// if the fetched content is all there.
var body_html = /^.*<body>(.*)<\/body>.*$/g.exec(data)[1];
$('body').html(body_html);
},
error: function(data) {
// Couldn't load site.
}
});
}
// Run every 15 minutes.
window.setInterval(function() {
update_site();
}, 15*60*1000);

You could implement some javascript to check the connection when a button is pressed. You could use the navigator.onLine property which should work with all major browsers.
Read more here:
http://www.w3schools.com/jsref/prop_nav_online.asp

should try this
function update_site() {
$.ajax(
{
url: "/my/page/url/",
dataType: "html",
cache: false,
success: function(event)
{
var update_html = /^.*<body>(.*)<\/body>.*$/g.exec(event)[1];
$('body').html(update_html);
},
error: function(event) {
}
});
}
// Run every 10 minutes.
window.setInterval(function() {
update_site();
// To refresh site every 15 min
}, 15000000);

Related

How to display a hidden field value after calling location.reload() in ajax success

Display a hidden field value after calling location.reload() .
var ajaxRequest = $.ajax({
type: "POST",
url: "my url",//locating to another project action method which is already deployed and running in server
contentType: false,
processData: false,
data: data
});
ajaxRequest.done(function (xhr, textStatus) {
location.reload();//reloading page
$('#imageUploadScs').show();//displaying hidden field after reloading page
});
When you reload, the page reloads. So any changes you've made to the state of the page are lost.
So you have two options:
Don't reload. This is the preferred option. You're already using AJAX, simply update the state of the page as needed. You shouldn't have to reload at all.
Before reloading, persist some flag somewhere (local storage? cookie? something of that nature) which indicates that the field should be shown. In the page's start-up code (you're using jQuery, so I assume a document.ready handler would be standard here) check for that flag and show the field.
The first option is certainly preferred. But the second option might structurally look something like this:
$(function () {
var shouldShowField = getPersistedFlag();
if (shouldShowField) {
$('#imageUploadScs').show();
}
});
// elsewhere...
ajaxRequest.done(function (xhr, textStatus) {
setPersistedFlag();
location.reload();
});
The implementations of getPersistedFlag and setPersistedFlag would be what's described above. They would read and write whatever data you want to persist to whatever storage mechanism you choose. (Any of which have many examples available.)
If it seems like that's over-complicating the effort, you're probably right. Which is why the first option of not reloading the page in the first place is preferred.

Prevent javascript code to be reset and start over after page refresh

I have a rails app where in my application.js I have a setInterval() and inside of it an AJAX call that send a post request every minute to my controller in order to perform a create action.
setInterval(function(){
$.ajax({
type: "POST",
url: "/post",
data: { parameter: value },
success: function (data) {
//some logic
}
});
}, 60000);
My problem is that if the client refresh its page every 30 sec (for exemple) the setInterval() set for 1 minute will never be triggered.
Is there a way to make my javascript code not dependent of any page refresh so that if different users arrive at different time they get to see the same thing. I guess it has to do with cookies or local storage but I have no idea how to implement that in a reliable way.
In other word, I would like my js code to be run server side without being disrupted by page refreshes or client request which keep reseting my code.
Thank you for your guidance.
You can use https://github.com/javan/whenever
every 1.minute do # 1.minute 1.day 1.week 1.month 1.year is also supported
runner "MyModel.some_process"
rake "my:rake:task"
command "/usr/bin/my_great_command"
end

Is javascript not executed on mobile devices if the page is not currently shown?

I'm tracking the time users spend reading contents on my website. To consider the user is actually reading, I do a first ajax request after 10 seconds the page has been loaded. Then, I set the beforeunload event to trigger another ajax request to notice the user has finished reading.
There is a problem when the user opens another page in a different tab, but the page I'm tracking is not closed, so I set I timer after 10 min to trigger the end reading ajax and unset the beforeunload. This makes browsers to send the signal when the page is open, but the tab hasn't been closed.
However, I've noticed that on mobile devices (Android, iPhone and iPad), the timer set to automatically notice finish reading after 10 min doesn't get executed. So, I'm wondering if: do mobile devices stop executing javascript when the page is not shown on the screen to save battery? If so, how could I run the timer and trigger the ajax request even though the page is not shown (but still open)?
function endReading(id) {
$.ajax({
url: "{% url 'end_read_content' %}",
type: "post",
data: {"id": id},
async: false,
});
}
setTimeout(function() {
$.ajax({
url: "{% url 'new_read_content' %}",
type: "post",
data: {"content_slug": "{{ content.slug }}"},
success: function(data) {
$(window).on('beforeunload', function() {endReading(data)});
setTimeout(function() {
endReading(data);
$(window).off('beforeunload');
}, 600000);
}
});
}, 10000);
Instead of setTimeout use requestAnimationFrame
https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame
By specification this function will not call when the window is not in focus.
http://caniuse.com/requestanimationframe
More details here:
http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
It is passed an int of the current running time, so your function should check that and only send an ajax request every so many seconds.
In response to the 'can I use this for not animations' question:
Absolutely you can use it for whatever you want. Another option
var lastUsageTime = 0;
var lastSentTime = 0;
window.requestAnimationFrame(function(t){
lastUsageTime = t;
});
setTimeout(function(){
if(lastUsageTime - lastSentTime > 10000){
//do ajax
lastSentTime = lastUsageTime
}
});

How to avoid rendering the initial view of browsing session when page is refreshed from somewhere else in the application using History.js?

I am trying very hard to implement history.js a jQuery plugin for IE 8 and 9. The demo seems to be fine in IE10+ and other modern browsers but I'm not able to understand the problem below for IE<=9. The demo is a asp.net mvc5 application where I want to provide a single page user experience where I'm just loading partial views and performing a post action via ajax. All the views load in a #shell div in my master view. May be I am missing something!!
My demo app starts with http://localhost:1089/ which is the first request that renders a login page. Any other pushState() causes a change in the url with appending #Home/About?ref=one.
Following is my script that is executed in layout.cshtml which is loaded only once:
(function (window, undefined) {
History.Adapter.bind(window, 'statechange', function () {
var state = History.getState();
if (state.data.options == undefined) {
alert("options is undefined");
var options = {
url: state.url,
type: "GET",
dataType: "html"
};
GetPartial(options);
} else {
GetPartial(state.data.options);
}
});
})(window);
$(document).on('click', 'a', function (e) {
e.preventDefault();
var options = {
url: $(this).prop('href'),
type: "GET",
dataType: "html"
};
History.pushState({ options: options }, $(this).text(), $(this).prop('href'));
});
function GetPartial(options) {
if (options) {
$.ajax({
url: options.url,
type: options.type || 'GET',
dataType: options.datatype || 'html',
async: true,
data: options.dataToPost,
beforeSend: function() {
$("#loaderMain").show();
},
complete: function() {
$("#loaderMain").hide();
},
cache: false,
}).success(function(response, status, xhr) {
var ct = xhr.getResponseHeader("content-type") || "";
if (ct.indexOf('html') > -1) {
// returned result is of type html, so act accordingly
if (options.selector == undefined) {
InjectContentToShell(response);
} else {
$(options.selector).empty().append(response);
}
} else if (ct.indexOf('json') > -1) {
// returned result is of type json, so act accordingly
}
}).fail(function(e) {
console.log(e);
});
}
}
function InjectContentToShell(content) {
$('#shell').fadeOut(100, function () {
$(this).empty().append(content);
}).fadeIn(100);
}
When I render this first page, I add one entry to History by pushState method like this:
$('#submit').on('click', function (e) {
e.preventDefault();
var formInstance = $(this).closest('form'),
dataToPost = formInstance.serialize();
var options = {
url: formInstance.prop('action'),
type: formInstance.prop('method'),
dataType: "html",
dataToPost: dataToPost
};
History.pushState({ options: options }, "Home - All Summary Views", "/Home/Index");
});
Pushing the state above, changes the url to http://localhost:1089/#Home/Index in html4 browser which is fine. I am able to go back and forward. This works well.
Now when I refresh the page in html4 browsers, the request sent to server is for first url i.e. http://localhost:1089/ which bring the first view to the client. So, the user can see the first page i.e. login screen. And then statechange event is fired and the state url still remembers the last url where page was refreshed and a new request is made for this url to server. The response is then injected in shell.
So, the problem is - on page refresh, user is getting two views instantly - the initial page where the user started his browsing session and soon the second page is loaded from the server and added to shell via animation as when the statechange event is fired, the History.getState() still remembers the last url.
I don't want to show this initial page on page refresh. If this is solved, then everything works fine with this history.js I think!
The above problem is also mentioned as a concept of bookmarking in the this article. Refer to the first figure and the text written above it.
My demo application works fine in html5 browsers as on every History.pushState() the browser's url is changed to the url I have specified. And when page is refreshed, the request is sent to the server as per that url and not with the first url in the browsing session started.
After trying many things, I have come up with the following solution to avoid showing the first view i.e. login page to the users with html4 browser:
I have created a view "Index" that is the first view being rendered. Which doesn't have any html content but has this script:
<script>
$(function () {
if (History.getCurrentIndex() == 0) {
var options = {
url: "/Account/Login",
type: "GET",
dataType: "html"
};
History.pushState({ options: options }, "Login Page", "/Account/Login");
}
});
</script>
The above code checks if the current index is 0 or not. If it is 0, then it means that user has just started his browsing history and it should give a login screen. If it is not 0, then it means that user was on some other step of user journey within the application which does nothing. And once this view is rendered the statechange event is fired which already has the information about the url of the page where user requested for refresh. As per the logic of statechange event handler above in my question, that resource is requested from the server and injected in the #shell container.
The above solution is working very well and gives the same experience to user as if they are on html5 browser. The above code works for me but will be glad to know if someone has any other solution.

AJAX: why isn't my javascript loading with the content?

This is my first time using AJAX. I'm trying to load one of my pages when a link is clicked (I know I can just do <a href="something.html"> but I am doing it just for the sake of using AJAX, and ran into an issue where my page loads but the javascript of the page doesn't. Is this a normal AJAX consequence? I'm guessing it has to do with dataType: html? Here's my code:
function getContent(filename) {
$.ajax({
url: filename,
type: "GET",
dataType: "html",
beforeSend: function(){
$('html').html('<img src="../images/loading.gif">');
},
success: function (data, textStatus, xhr) {
if (filename == "second.html") {
setTimeout(function (){
$('html').html(data);
}, 2000);
} else {
$('html').html(data);
}
},
error: function(xhr, textStatus, errorThrown) {
$('html').html(textStatus);
}
});
}
Can you check chrome's network monitor? First off, does anything get a 404? Is the file literally second.html? If so then there shouldn't be path issues. Next what is the "response" that appears for that item? Does that response look ok?
Next, why don't you try moving the JS from head into the body for the second page? JS should always be right before the closing body tag for performance reasons. Also, there may be an issue with JS being in head and it not getting executed for that reason.
You should be able to load anything on your domain without any issues via AJAX, but there are path issues to watch out for.
This is because the ajax page is only returning rendered content, but does not run like a normal page would. You can use PHP on the ajax page for example, the server renders it and then sends it through, because PHP is pre-render, javascript runs after the page is rendered, as far as I know.

Categories