I have 2 js functions - one of them is in global main.js file and another one is local to one of my html pages <script> tags. I have access to main.js in all files simply because they are being loaded in the main.html page via ajax. I am able to stop the main function from clearInterval in my html page but when I am trying to do clearInterval for the local function, somehow its not working.
The clearIntervals get triggered when I click the 'edit' button of the page. But my problem is when I click 'edit' only the global function gets stopped but not the local one. The function is just updating selectmenu options based on values that are being recieved from the server. For textboxes it updates in real time but for selectmenus I had to use this approach to make it work in real time.
Below is the JS code with local function:
var dropdown_update=setInterval(updateDropdownValues, 1200); //calling the local function
function updateDropdownValues(){
//does some work
}
$("#editFields").click(function(){
//some code
clearInterval(ajax_interval); //works..ajax_interval is in main.js not shown here
clearInterval(dropdown_update); //doesnt work..keeps executing the function
});
Following is main.js relevant part (I dont think this is the culprit):
var ajax_interval = setInterval(loadAjaxData2, 1 * 1000);
function loadAjaxData2() {
//some variables
$.ajax({
//an ajax call
});
}
I looked over several stackoverflow posts but none of them had this kind of problem.
Related
i am working in an angular project. In a controller, we have a button that is supposed to generate & copy an embed code (similar to youtube) to the clipboard. However, depending on the type of the item, the embed code can only be generated/returned by an ajax call. Have a look at this code:
function copyEmbed(e) {
var embedCode = '';
if (type === "typeA"){
api.items.compile.get({'id': item.selected.id},
function (response) {
embedCode = response.html; //<-- takes time to populate obviously
copyToClipboard();
});
} else {
embedCode = generateEmbedCodeTemplate(); //no ajax here. populates immediately
copyToClipboard();
}
function copyToClipboard() {
clipboard.copyText(); // all seems good but copying will fail as this function is not invoked with a click handler!
}
}
The problem is that because of the ajax call, the code to copy the resulting embed code cannot be in the copyEmbed function scope, as this means the ajax call will not have the time to get the data before copying. If i was able to make everything synchronous, i would be able to get the data and then call the copy command from within the scope of the copyEmbed function, so it would not fail, as the copyEmbed function is bound to a click event. However, in the example, i am handling the ajax call right, but the copyToClipboard function is not invoked with a click handler so the copy command fails. Any ideas, without resulting in hacky setIntervals to check for embedCode contents?
As always, handling async stuff can only happen by actually handling them in an async fashion. So instead of grabbing the embed code at the time of the button click, i am doing so way before, so it is available as a variable or a data-attribute of the element to be clicked. Only adding the answer for people who might come in here with the same brainfart i had when i opened it.
I am loading my partial views in a page using $("div").load(url) event. So that Page will render faster. But with this $(document).ready is getting fired even before the content gets loaded.
I have tried $(window).load also, but this is also getting fired even before the content loading.
Can you please suggest a way to wait until the data gets loaded then only execute my javascript functions.
When you are using $("div").load(url), You are loading the url content asynchronously.
Which means that document.load is first initialised and then async call is made to load(url).
Put all your initialization Javascript in a Function (lets say myinit() ) and fire it on success call back of your load method
Eg
// this line keeps all your function in one global name space and you can extend it multiple times in same document or js files
var myapp = myapp||{};
$(function(){
// Here you are extending your myapp object with custom init function
myapp.init = function(){
//your init code here
}
//your ajax content load here
$('div').load(url,function(){
//Here you call it
myapp.init();
})
})
P.S. you can always test your custom methods in console using myapp.init() anywhere in jQuery exec block
So I have a simple tab system which I handle with the .load function to load the desired content. The problem is that the page itself which contains this tab system is a ajax loaded content. And for some reason the initial call of the tab function to display the initial tab content won't work. But after manually choosing a tab, the load function loads the content properly.
her some code to look at:
The tab handler:
function loadTab(tab) {
$(".tab_a:eq("+otab+")").removeClass("tab_slc");
$('#tab_content').hide();
$('#tab_content').load("include/tab_downloadVersions.html .tab:eq("+tab+")");
$(".tab_a:eq("+tab+")").addClass("tab_slc");
$('#tab_content').fadeIn(function() {});
otab = tab;
}
at the end I call loadTab(tab); and the thing should be initialized. but for some reason the content remains empty. As soon as you manually click on a tab (I have an on click function which calls loadTab(tab) everything starts working)
Because the code by itself works, I think the problem is caused by the other script which handles the page itself. It is also a .load function which loads the page, which loads this tab system.
So do multiple .loads don't like each other? and if so, what can I change?
Thanks in advance ;)
EDIT: I could't post the entire code for some reason, but if you go here you can see the site in action with all the scripts:
n.ethz.ch/student/lukal/paint.net
The tab system is on the download page.
EDIT:-----------------------------------------------------------------------------------------------------------------------------
Big Update
So this is still the same issue but with a slight twist: I did what was recommended in the comments and put my secondary .load() call inside the success call of the first one.
$("#content").load("pages/contact #contentInside", function() {
$("#OtherContent").load("include/info #OtherContentInside");
});
So this works.
But now I had the great idea to make a giant load function. It is a slightly better function than just the plain load, cause it does some fading and stuff. But now I have the same problem, but even more complicated. I created the load function as a "plugin" so the function itself is in a different script file and therefore I can't access the inside of the success function. I solved this problem with a return $.ajax(); and a .done() call. The problem here is that there is some rare case where it just skips the secondary load function. So I am searching for a guaranteed way of controlling the order of the .load calls. Any idea?
The mock-up website is up to date with the new scripts if you wish to take a look. And people were complaining about potential virus spread from my link. For some reason I can't post long code snippets so the site is the best source I got to show everything. If you know a more trustworthy way to share my code please let me know.
We cannot see the rest of your code to tell where the initial call is being invoked from. A set up like the following should work:
$(function() {
var tab = 0;
loadTab( tab );
});
function loadTab(tab) {
//WHAT IS otab???
$(".tab_a:eq("+otab+")").removeClass("tab_slc"); //<<<==== otab
$('#tab_content').hide();
$('#tab_content').load("include/tab_downloadVersions.html .tab:eq("+tab+")");
$(".tab_a:eq("+tab+")").addClass("tab_slc");
$('#tab_content').fadeIn(function() {});
otab = tab;
}
Update
The reason it does not work initial is because otab is not defined the first time the function is called. You have initialized otab at the end of the function but you are using it at the beginning of the function.
UPDATE 2
I have had a chance to look at your code and I just found out what the issues are:
You do not have DOM ready
You are not calling the function on page load.
The following version of your code should work -- try not to use global variable as you're doing with otab. Since you're loading this script at the end of the page (an you are using event delegation) you may get away with DOM ready. Adding .trigger('click') or click() as indicated below should resolve the issue.
//Tab-loader
//Haeri Studios
var tab = 0;
var otab = tab;
var counter = 0;
//click detect
$(document).on('click', '.tab_a', function() {
tab = counter == 0 ? tab : ($(this).attr('id'));
loadTab(tab);
counter++;
return false;
})
.trigger('click'); //<<<<<===== This will call the function when the page loads
//Tab setup
function loadTab(tab) {
//Content Setup
$(".tab_a:eq("+otab+")").removeClass("tab_slc");
$('#tab_content').hide();
$('#tab_content').load("include/tab_downloadVersions.html .tab:eq("+tab+")");
$(".tab_a:eq("+tab+")").addClass("tab_slc");
$('#tab_content').fadeIn(function() {});
otab = tab;
}
//Initialize << WHAT ARE YOUR INTENTIONS HERE .. DO YOU REALLY NEED THIS PIECE?
$.ajax({success: function() {
loadTab(tab);
}});
A partial answer to this problem was to call the loadTab function inside the success call of the page load function, like charlietfl pointed out. But the problem is that there is no need to call the tabloader every time a new page gets called. So I would rather not have a rare call in every page setup function.
I am a bit disappointed by the system on stackoverflow. It seems like if you have not a high reputation level, no one gives a "S" about your questions. Well but at least some input was give, for which I am very thankful.
So by digging deeper into google I found out that the callback can be manually placed in the function where ever you like.
so if we have a function:
foo(lol, function() {
//This after
});
this does stuff after foo() is done. But what if we have another function inside foo() which we also need to wait for:
function foo(lol) {
bar(troll, function() {
//This first
});
}
The bar function is not relevant to the success call of foo. This causes the unpredictable outcome of calls.
The trick is to control when the success function of foo gets called.
If we add a parameter(callback) inside foo and call this "parameter" (callback();) inside the success call of bar, we can make sure the order is guaranteed.
And that's it:
function foo(lol, callback) {
bar(troll, function() {
//This first
callback(); //<-This callback placement defines when it should be triggered
});
}
foo(lol, function() {
//This after
});
We get:
//this first
//this after
I have a bit of javascript, triggered from an HTML button, that calls a function. This is using Jquery as well, so there are a couple of underlying functions from that that get called in this process, too. In my script I make a couple of changes to window.location in order to communicate to a remote system (which is supposed to fire off different scripts in response to these calls). This window.location definition is not using the HTTP protocol, but FMP, a registered - on my machine anyway - protocol for FileMaker Pro.
Sample code:
function compareJSON() {
dataSession=({ //build object for output });
$.each( dataSession.chapters , function( indexC, value ) {
//compare objects to some others, testing and changing data
});
//Call remote script on other system
window.location= "fmp://blah.dee.com/Blar?script=SaveJSON&$JSONobject=" + JSON.stringify( dataSession );
//Call remote script on other system
window.location="fmp://blah.dee.com/Blar?script=EditJSON";
}
(Keep in mind, since this is using Jquery, that simply pressing the button that calls this compareJSON() function creates a stack of 2 or 3 other functions before running my function. But, even if it were being called directly in some manner, the compare function itself would be on the stack and thus window.location wouldn't get evaluated until the end of that function.)
The problem is that it looks like the Window.Location isn't being finalized/set/sent/whatever until the ENTIRE JS call stack is finished. So, when I click the button that starts these function calls the stack gets a few Jquery functions put on it (e.g. 'handler', 'default', 'each loop'...), then it hits the JS code that I wrote, which in turn adds a few more function calls to the stack; and then there are a few more Jquery functions that added to the stack, etc. But these stacked window.location definitions made in my functions don't actually trigger the remote system until I step all the way through the JS call stack and exit everything. So the window.location is only defined/set to be whatever was last set in the function calls, instead of including all the intervening definitions/sets that occurred in the stack. It's like a variable that gets changed multiple times in the call stack but only gets read once at the end.
Is there a way to force window.location to be evaluated when it is set instead of waiting for whatever the last setting was?
Thanks,
J
You may want to use an iframe:
function callScript(url) {
var ifr = document.createElement('iframe');
ifr.src = url;
// you can even add ifr.onload = function() {doSomething();}; if you want
}
This will allow any number of calls at once.
This might not work, but the timeout idea is to change something like this:
// code code code ...
window.location = newUrl;
// more code ...
into:
// code code code ...
window.location = newUrl;
setTimeout(function() {
// more code ...
}, 1);
That allows the browser an interval in which it can do something before starting the next event loop for the timer handler.
so i have a .js file that 2 different jsp pages call.
.js file contains:
var savedObj;
function A(obj){ savedObj = obj);
function B(){ alert(savedObj);
X.jsp file calls function A such that a DOM element onchange = functionA(this);
Y.jsp file calls function B such that body onload = function B
For some reason, my debugging in function A shows that the assignment of savedObj = obj worked correctly, but in function B, savedObj printed out null.
Thanks guys
This is happening because your function B is being called when the body of the JSP has finished loading. This will happen before any change event on a specific DOM element.
If you need function B to have the updated savedObj, you will need to wait to call it until after the change event is fired on your DOM element.
Note: this assumes that your JSPs are being included in the same rendered page, if they are not, this is happening because JavaScript state is not persisted from page to page
Using a cookie to store the value is certainly the best way to make the value persist across various pages. If you don't want to go into cookies, you could use javascript to write the new page in place of the current page and keep the value, but it's messy and you're better off taking the time to learn cookies.