Here's the scenario:
- there is a set of variables
- these variables indicate the statuses of various equipment
- the goal is to display an always-updated status chart
So, I have gotten as far as having a parser in Perl that spits out JavaScript var x = 'y'; type code, and now I'm looking for how to have the HTML or other JavaScript automatically check for updates to this "spit out" code, versus just caching it after the first time.
The closest thing I've seen is to use "setInterval" to have it execute a function, so I went ahead and wrapped the "var" statements in a function with a "setInterval" timer. But will this reliably be always up-to-date, or does it cache the whole function, depending on the browser?
EDIT: I'm not currently using any libraries or anything, and would prefer not to - but I will if I have to.
EDIT2: Finally found what I'm looking for. http://www.philnicholas.com/2009/05/11/reloading-your-javascript-without-reloading-your-page/
Just had to modify the last line to get it to work.
You're already close to the solution. Create a function that makes an ajax call to the 'spit out' you have written in perl.
function getSpitOut() {
$.ajax({
async: true,
type: "GET",
url: "spit_out.pl",
data: "x=8&y=7",
success: function(msg){
// UPDATE CHART
}
});
}
And another function to make the ajax calls at intervals:
$(document).ready(function() {
setInterval(getSpitOut, 60000); // Call getSpitOut every 60s
})
The browser won't cache it because you're updating the chart based on the server side perl script.
Apparently I never closed this.
Slightly modified from: "http://www.philnicholas.com/2009/05/11/reloading-your-javascript-without-reloading-your-page/", I have this:
var docHeadObj = document.getElementsByTagName("head")[0];
var dynamicScript = document.createElement("script");
dynamicScript.type = "text/javascript";
dynamicScript.src = scriptName;
docHeadObj.appendChild(dynamicScript);
Related
I'm not sure if this will actually be possible, since load() is an asynchronous method, but I need some way to basically Load several little bits of pages, one at a time, get some data included in them via JavaScript, and then send that over via Ajax so I can put it on a database I made.
Basically I get this from my page, where all the links I'll be having to iterate through are located:
var digiList = $('.2u');
var link;
for(var i=0;i<digiList.length;i++){
link = "http://www.digimon-heroes.com" + $(digiList).eq(i).find('map').children().attr('href');
So far so good.
Now, I'm going to have to load each link (only a specific div of the full page, not the whole thing) into a div I have somewhere around my page, so that I can get some data via JQuery:
var contentURI= link + ' div.row:nth-child(2)';
$('#single').load('grabber.php?url='+ contentURI,function(){
///////////// And I do a bunch of JQuery stuff here, and save stuff into an object
///////////// Aaaand then I call up an ajax request.
$.ajax({
url: 'insertDigi.php',
type: 'POST',
data: {digimon: JSON.stringify(digimon)},
dataType: 'json',
success: function(msg){
console.log(msg);
}
////////This calls up a script that handles everything and makes an insert into my database.
}); //END ajax
}); //END load callback Function
} //END 'for' Statement.
alert('Inserted!');
Naturally, as would be expected, the loading takes too long, and the rest of the for statement just keeps going through, not really caring about letting the load finish up it's business, since the load is asynchronous. The alert('Inserted!'); is called before I even get the chance to load the very first page. This, in turn, means that I only get to load the stuff into my div before I can even treat it's information and send it over to my script.
So my question is: Is there some creative way to do this in such a manner that I could iterate through multiple links, load them, do my business with them, and be done with it? And if not, is there a synchronous alternative to load, that could produce roughly the same effect? I know that it would probably block up my page completely, but I'd be fine with it, since the page does not require any input from me.
Hopefully I explained everything with the necessary detail, and hopefully you guys can help me out with this. Thanks!
You probably want a recursive function, that waits for one iteration, before going to the next iteration etc.
(function recursive(i) {
var digiList = $('.2u');
var link = digiList.eq(i).find('map').children().attr('href') + ' div.row:nth-child(2)';
$.ajax({
url: 'grabber.php',
data: {
url: link
}
}).done(function(data) {
// do stuff with "data"
$.ajax({
url: 'insertDigi.php',
type: 'POST',
data: {
digimon: digimon
},
dataType: 'json'
}).done(function(msg) {
console.log(msg);
if (i < digiList.length) {
recursive(++i); // do the next one ... when this is one is done
}
});
});
})(0);
Just in case you want them to run together you can use closure to preserve each number in the loop
for (var i = 0; i < digiList.length; i++) {
(function(num) { < // num here as the argument is actually i
var link = "http://www.digimon-heroes.com" + $(digiList).eq(num).find('map').children().attr('href');
var contentURI= link + ' div.row:nth-child(2)';
$('#single').load('grabber.php?url=' + contentURI, function() {
///////////// And I do a bunch of JQuery stuff here, and save stuff into an object
///////////// Aaaand then I call up an ajax request.
$.ajax({
url: 'insertDigi.php',
type: 'POST',
data: {
digimon: JSON.stringify(digimon)
},
dataType: 'json',
success: function(msg) {
console.log(msg);
}
////////This calls up a script that handles everything and makes an insert into my database.
}); //END ajax
}); //END load callback Function
})(i);// <-- pass in the number from the loop
}
You can always use synchronous ajax, but there's no good reason for it.
If you know the number of documents you need to download (you can count them or just hardcode if it's constant), you could run some callback function on success and if everything is done, then proceed with logic that need all documents.
To make it even better you could just trigger an event (on document or any other object) when everything is downloaded (e.x. "downloads_done") and listen on this even to make what you need to make.
But all above is for case you need to do something when all is done. However I'm not sure if I understood your question correctly (just read this again).
If you want to download something -> do something with data -> download another thing -> do something again...
Then you can also use javascript waterfall (library or build your own) to make it simple and easy to use. On waterfall you define what should happen when async function is done, one by one.
i have script that works as follows:
there is main page with 'start' button that initializes javascript function which loads a php page into a div frame, then via setTimeout it calls a 'refresh' function thats supposed to work indefinitelly and refresh the page inside frame
the refreesh timer is in database and is forwarded to java like this:
var min_refresh_time = ;
$min_refresh_time_sec is taken from database earlier in the code
what i wanted to modify is so the refresh min_refresh_time would be taken each time a refresh function is run, to my surprise this worked (or at least i thought so):
var min_refresh_time = ;
(custom sql functions are defined in separate php file included in main.php which is my main page)
unfortunatelly it seems that it 'worked' only due to some strange caching on java part and my pseudo-php code to take value from database is just a hoax - it looks like it is run only initially and then stores output somehow
simplified code of what is done and what i want to do:
function refresh_code(){
refresh_time = <?php Print(sql_result(sql_execute("SELECT value FROM settings WHERE setting='min_refresh_time'", $connection), 0, 0)); ?>;
refresh_time = 5;
alert(refresh_time);
$.post("index.php",{refresh_time:refresh_time_post, account_group: "1"},
function(data)
{
$.ajaxSetup ({
cache: false,
});
$("#frame_1").html(data);
});
setTimeout(function(){refresh_code()}, refresh_time);}
lets say min_refresh_time is 1 in database, i run it, it alerts 1 then 5 each time it self-refreshes, now if i go to database and change 1 to 3 i would want it to alert 3 then 5 obvious, it still does 1 then 5 tho...
i need a way to execute a dummy php file that only takes value from database, then sends it via post back to java and it gets intercepted there, any simple way to do that?
or do i need to use entirely different method for retrieving database value without js...
thx in advance
update:
i actually came back to it and analyzed potential solutions with fresh mind
first of all, i dont think my initial code had chance to work, java cant execute serverside code by itself, i took some of my aax code from other script and reworked it to launch php file that grabs the value from database, then i intercept output data and put into variable
looks like that:
$.ajax({
method: "POST",
url: "retrieve_refresh.php",
data: { retrieve_data: "max"},
cache: false,
timeout: 5000,
async: false,
cache: false,
error: function(){
return true;
},
success: function(msg){
if (parseFloat(msg)){
return false;
}
else {
return true;
}
}
}).done(function(php_output2) {
max_refresh_time = php_output2;
});
retrieve_refresh.php returns only the variable i want but the solution is unelegant to say the least, i havent searched yet but could use a way of sending variables as post back to ajax...
Is there a way in JavaScript where I can execute some functions only after page is loaded. Other functions should execute only on an event.
The problem is, I have some calculations in my php page and after doing all the calculations, the data is saved in mysql. Now when I come to the edit mode some functions are executing which makes the total field as NaN. I just want the code to take the total field from the db only not from any function. Hope l'm clear.
Fiddle
You can try like this:
Make an AJAX call to the server to get the count from Database when the user clicks on edit mode and avoid getting from the html document.
function JQueryGETAjaxCall(servletPath,callBck){
var path = window.location.origin
var url = path+servletPath;
console.log(url)
$.ajax({
'type':'GET',
'url':url,
'async': true,
'success':function(res){
callBck(res);
},
'error':function(res){
}
});
}
I'm currently working on a script that loads content when either you trigger it (by clicking a link), or you scroll to the bottom of the page. I'm doing this for fun, but it is slowly turning into a nightmare...
The triggered part works correctly, while the "scroll to the bottom" part sometimes works and sometimes doesn't. It will sometimes load a post twice, and sometimes repeat the sets of posts (I'm loading 5 at a time) and not display the next set, my guess is that it is because it loads content so fast, that:
The queries get all mixed up (AJAX calls/mysql queries/Responses...?) or...
There's some kind of problem with the DOM (I guess this is the correct way of calling this...) or...
It is the cause of another glitch that I can't currently think of because of my basic knowledge...
The problem arises when you keep the scroll bar down, and so it loads the content very fast, it is especially a problem with Firefox, since if you are already at the bottom and refresh the page, it will load indefinitely until there are no more posts, and again, it does it really fast.
I've tried different approaches, all day... and I can't find a solution.
First, I tried setting a flag, so that when each AJAX call finishes, it increases a certain variable by the number of posts loaded, and will only execute the call again if the number has been increased, and it must do so orderly (which in my head meant succesful AJAX call). This didn't work.
Then I tried setting a timeout, for the AJAX call, and then for the function that contains that call, and then for the function that executes the function in the first place (scrolling to the bottom), this kind of worked, but with the drawback of it not doing anything for that timeout (and thus, not even displaying the "loading" html) and with the situation happening fewer times, but still happening. I also tried setting the timeout in the $.ajax() function, which I think is a different kind of timeout, because it did not do what I desired...
Finally, I tried making async false, which I read is a bad thing, because it hangs the page until it's done, and because it is also deprecated; needless to say, it didn't work either (I didn't notice any visible change in behaviour).
I'm really lost here; I'm not even sure why this "glitch" happens...
Here's my code...
$.ajax({ //Removed some code in order to make it brief
url: 'load.php',
type: 'post',
dataType: 'json',
data: {offset: countContent, limit: displayNumber},
success: function(data)
{
if(data)
{
for(var i=0;i<display_n;i++)
{
var title = data[i][1];
var author = data[i][2];
var img = data[i][3];
var date = data[i][4];
var htmlStr =
'<div class="post" id="'+i+'"></div>';
$(element).append(htmlStr);
$(element).children('#'+i+':last').hide().fadeIn(200+(i*250));
}
}
else if(data == null){
//Do something when there are no more posts
}
},
error: function() {
// Error
}
});
And the php that processes the ajax call
<?php
$offset = (int) $_POST['offset'];
$limit = (int) $_POST['limit'];
$db = 'mysql:host=localhost;dbname=posts;charset=utf8';
$u = 'username';
$p = 'password';
$con = new PDO($db,$u,$p);
$q = $con->prepare("SELECT id, title, author, img, date FROM articles
ORDER BY id DESC LIMIT :limit OFFSET :offset");
$q->bindParam(':offset',$offset,PDO::PARAM_INT);
$q->bindParam(':limit',$limit,PDO::PARAM_INT);
$q->execute();
$articles = $q->fetchAll(PDO::FETCH_NUM);
$con = null;
$array_count = count($articles);
if ($articles){
for ($i=0;$i<$array_count;$i++)
{
$articles[$i][4] = date("d F Y",strtotime($articles[$i]['4']));
}
echo json_encode($articles);
}
else
{
$articles = null; //sends null if the data is empty
echo json_encode($articles);
}
?>
Is there any way to "delay" the ajax call before the other one gets executed, so that the articles load correctly? Or wait till everything in the ajax loaded as according to plan before going to the next one? What can I do in this case?
I'm sorry if this post is kind of huge, I guess I wanted to make a point, ha. Help is very much appreciated, thanks.
EDIT: Here's what I posted below, and the solution:
I set a global variable running to false, and wrapped the whole AJAX
call inside an if !running condition, immediatly making the variable
true after entering the loop, and making it false again on either the
"complete: " parameter of the $.ajax function or via $.ajaxComplete().
I'm guessing one can also use .on() and .off() statements to bind and
unbind the event trigger, but I found the previous method so much more simple.
This allows the AJAX call to finish before the other one starts, and the content is displayed correctly.
I suggest you turn off the event trigger right after it's been triggered, and turn it back on after you populated the DOMs.
How can I fix the script below so that it will work EVERY TIME! Sometimes it works and sometimes it doesn't. Pro JQuery explains what causes this, but it doesn't talk about how to fix it. I am almost positive it has to do with the ajax ready state but I have no clue how to write it. The web shows about 99 different ways to write ajax and JQuery, its a bit overwhelming.
My goal is to create an HTML shell that can be filled with text from server based text files. For example: Let's say there is a text file on the server named AG and its contents is PF: PF-01, PF-02, PF-03, etc.. I want to pull this information and populate the HTML DOM before it is seen by the user. A was ##!#$*& golden with PHP, then found out my host has fopen() shut off. So here I am.
Thanks for you help.
JS - plantSeed.js
var pageExecute = {
fileContents:"Null",
pagePrefix:"Null",
slides:"Null",
init:function () {
$.ajax({
url: "./seeds/Ag.txt",
success: function (data){
pageExecute.fileContents = data;
}
});
}
};
HTML - HEAD
<script type="text/javascript">
pageExecute.init();
</script>
HTML - BODY
<script type="text/javascript"> alert(pageExecute.fileContents); </script>
Try this:
var pageExecute = {
fileContents:"Null",
pagePrefix:"Null",
slides:"Null",
init: function () {
$.ajax({
url: "./seeds/Ag.txt",
async: false,
success: function (data){
pageExecute.fileContents = data;
}
});
}
};
Try this:
HTML:
<div id="target"></div>
JavaScript:
$(function(){
$( "#target" ).load( "pathToYourFile" );
});
In my example, the div will be filled with the file contents. Take a look at jQuery .load() function.
The "pathToYourFile" cand be any resource that contains the data you want to be loaded. Take a look at the load method documentation for more information about how to use it.
Edit: Other examples to get the value to be manipulated
Using $.get() function:
$(function(){
$.get( "pathToYourFile", function( data ) {
var resourceContent = data; // can be a global variable too...
// process the content...
});
});
Using $.ajax() function:
$(function(){
$.ajax({
url: "pathToYourFile",
async: false, // asynchronous request? (synchronous requests are discouraged...)
cache: false, // with this, you can force the browser to not make cache of the retrieved data
dataType: "text", // jQuery will infer this, but you can set explicitly
success: function( data, textStatus, jqXHR ) {
var resourceContent = data; // can be a global variable too...
// process the content...
}
});
});
It is important to note that:
$(function(){
// code...
});
Is the same as:
$(document).ready(function(){
// code
});
And normally you need to use this syntax, since you would want that the DOM is ready to execute your JavaScript code.
Here's your issue:
You've got a script tag in the body, which is asking for the AJAX data.
Even if you were asking it to write the data to your shell, and not just spout it...
...that's your #1 issue.
Here's why:
AJAX is asynchronous.
Okay, we know that already, but what does that mean?
Well, it means that it's going to go to the server and ask for the file.
The server is going to go looking, and send it back. Then your computer is going to download the contents. When the contents are 100% downloaded, they'll be available to use.
...thing is...
Your program isn't waiting for that to happen.
It's telling the server to take its time, and in the meantime it's going to keep doing what it's doing, and it's not going to think about the contents again, until it gets a call from the server.
Well, browsers are really freakin' fast when it comes to rendering HTML.
Servers are really freakin' fast at serving static (plain-text/img/css/js) files, too.
So now you're in a race.
Which will happen first?
Will the server call back with the text, or will the browser hit the script tag that asks for the file contents?
Whichever one wins on that refresh is the one that will happen.
So how do you get around that?
Callbacks.
Callbacks are a different way of thinking.
In JavaScript, you perform a callback by giving the AJAX call a function to use, when the download is complete.
It'd be like calling somebody from a work-line, and saying: dial THIS extension to reach me, when you have an answer for me.
In jQuery, you'll use a parameter called "success" in the AJAX call.
Make success : function (data) { doSomething(data); } a part of that object that you're passing into the AJAX call.
When the file downloads, as soon as it downloads, jQuery will pass the results into the success function you gave it, which will do whatever it's made to do, or call whatever functions it was made to call.
Give it a try. It sure beats racing to see which downloads first.
I recommend not to use url: "./seeds/Ag.txt",, to target a file directly. Instead, use a server side script llike PHP to open the file and return the data, either in plane format or in JSON format.
You may find a tutorial to open files here: http://www.tizag.com/phpT/fileread.php