jQuery ordered actions - javascript

Does anybody know how to make a jQery function that has more than one action and every action will be fired only after its precedent is complete like:
$('#myelement').addClass('loading').load(loadUrl).removeClass('loading');
here the first action which is adding the class name is ok, the second is also ok, but the problem comes with the last action which is supposed to remove the class after the load is finished, but here it will be fired even before the loading is finished and will cancel the first action so that it will look like none of the first nor the third action are present.
Thanks.

Here you go:
$('#myelement').addClass('loading').load(loadUrl, function() {
$(this).removeClass('loading');
});
This assigns an anonymous function as a callback for the load method, which will be invoked when the load operation is completed.

Try this instead:
$('#myelement').addClass('loading').load(loadUrl, function() { ($(this).removeClass('loading'); });
The .load() function takes a completion function.

Related

Can I make Javascript always call a method after JQuery Load?

We have started using jquery load in our site to load contents into a div rather than re-loading whole page. However in the complete function we have a method that re-applies various bindings. Is it possible to provide load method with a default complete function? So developers don't have to specify it in the jquery load complete function.
As we currently are providing a lot of duplicate complete functions
E.g.
$('#Target').load(callBackRedirect, function () {
ApplyBindings('#Target');
});
These bindings can't be applied using on and need to be re-applied on page loads. We also do some other work that we want to do on every page load.
The answer is no.
You need the callback because that's what the method calls when the request is done.
This works with on method to, you might be doing something wrong out there in the code.
You could create a helper function for this.
function loadSomething(targetElement, uri,callback) {
targetElement.load(uri, callback);
}
loadSomething(
$('myElement'),
'mylink.com/content',
function() {
applyBindings($(this));
}
)
Yes. Check out the list of Global AJAX Event Handlers.
e.g.
$(document).ajaxComplete(function() {
alert('Triggered ajaxComplete handler.');
});
That said, you shouldn't need to reapply your bindings after an AJAX call. If you need to do this, you're probably doing something wrong. Check out jQuery.on, which explains how to bind to content which is added dynamically.
Try $.ajaxSetup:
$.ajaxSetup({
complete: function() {
ApplyBindings('#target');
}
});
EDIT
You could also make a named function like:
var ajaxApplyBindings = function() {
ApplyBindings('#Target');
// anything else...
};
And then pass it to load:
$('#Target').load(callBackRedirect, ajaxApplyBindings);

JavaScript calling a function without parenthesis

A few weeks ago I was painfully able to dynamically add buttons to an HTML DOM object that has its own .on('click'.. handler, and use e.stopPropgation to stop these new child elements from firing the event.
The weird thing I did was call a function without any parenthesis. I have no idea why I did this or why it works, or why it does not work when I do attach parenthesis. I want to know if I am doing something by fluke and not design (and now I will add comments to it).
It goes as such:
//Container is the parent element
// var buttons stores the buttons with class 'buttons'
$('.container').on('click', function(){
$(buttons).appendTo($(this)).fadeIn(500).find('.buttons').click(tableButton);
});
function tableButton(e){
e.stopPropagation();
//do stuff
}
I can't figure out why I wrote the call to tableButton with no arguements or why it works perfectly. I tried to change the syntax to
.find('.buttons').on('click', function(e){
tableButton(e);
});
but then it no longer works.
Any help appreciated!
It works because you're passing a function to the click handler rather than calling the function yourself (the ()) An example of that:
var testFunction = function(msg) {
alert(msg);
}
var functionCaller = function(functionToCall) {
functionToCall('hello!');
}
functionCaller(testFunction);
functionCaller passes the message argument to testFunction(), but we only pass testFunction to functionCaller (without arguments)
For the part which doesn't work, isn't the function name tableButton() instead of tableButtons()?
See http://jsfiddle.net/g2PAn/
You don't actually call it, you just declare it and the arguments it accepts. The click callback is called with an argument indeed, but not by you.
The problem probably comes from the fact that jQuery calls your function with the element clicked bound as this, you could call table button like this:
.find('.buttons').on('click', function(e){
tableButton.call(this, e);
});

Ajax .load() won't work when triggered initially

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

How to set order of events in javascript?

I have html-link, and I want to add event listener to <a> tag, so javascript function is called and after that brouser opens a link. I tried to use document.getElementById('link').addEventListener("click", myfunc);, but it works chaotically, sometimes myfunc is called, and after that link is opened, sometimes link is opened, so myfunc isn't called. How to set order of these events?
Code paths :
HTML :
LogOut
Javascript :
function LogOutWithoutReload(e) {
VK.Auth.logout(function () { });}
document.getElementById('logoutlink').addEventListener("click", LogOutWithoutReload);
What is your function doing? Is it some kind of aysnchronous event? If so then you would need to perform the default action in the success callback of the asynchronous task.
An example of this would be the jQuery .load function.
If your mufunc function were to call the jQuery load function it would return straight away, it will not wait for the data it self to be loaded. What you must do is use the second parameter in the load function as a callback for when the data has finished loading. This is the place you would then have your default action for the link.
This may be the issue you are experiencing with some other asynchronous task.
After you edited your code you have this line
VK.Auth.logout(function () { });
This looks like the logout function is indeed some kind of asynchronous call and has a callback function. I may be wrong and it may be doing something else you would need to check the docs, but to me you should be doing anything you need to do in that callback function (for example the redirect).
The event handler will always be called before the browser navigates away. My guess is that your function does not work sometimes, causing a exception and not stopping the default action. Have you tried debugging it? There should be some messages in your (error) console.
set the link's href attribute after your script is executed.
the link
<a href='#'>LogOut</a>
the code
document.getElementById("link").onclick = function(event) {
//your script here, if there is an ajax request,
// change location in your callback function
location.href = '<%= Url.Action("LogOut", "Account") %>'
}
To prevent opening of the link try:
document.getElementById("link").onclick = function(event) {
event.preventDefault();
myFunc();
}

Java script function to hold until save evenet execution is completed

I have a javascript function. In thi function i am calling a button event like below.
$("#btnSave").trigger("click");
My query is , Is there any way to keep the control here on this line until the saving is done?
I have some code written underneath this line and it is being overridden.
Any suggestions?
It would have helped if you've posted some code.
You can do it in 2 ways:
1.) Use polling. After the trigger call use a loop to check for a flag that you must set when the save is complete. A timeout is needed for saving CPU from intensive js processing.
2.) Put the code to be executed after the trigger call inside a function. Pass this function as a callback to the onClick function.
function onSaveClick(e) {
//do my save stuff
e.data.callback();
}
No. 2 is recommended.
//attach onclick event
$("#btnSave").click(onSaveClick);
//you onclick function
function onSaveClick(event, callback) {
//save data
callback();
}
//trigger
$("#btnSave").trigger("click", afterSave);
//after save stuff
function afterSave(){
//do more stuff
}
Use a callback.
Get the lines under the trigger line and pass to your save function as callback when the event has success.

Categories

Resources