Overriding a jQuery Core function in javascript - getJSON - javascript

I am trying to override the getJSON function in jQuery to provide additional params and then call the original getJSON. I am fairly unfamiliar with JavaScript and have scraped this together from other similar examples. Most of the examples I have seen override the behavior from a function in the jQuery.fn namespace. Could someone help me by telling me what I am doing wrong?
<html>
<head>
<script type="text/javascript" src="./js/jquery-1.6.4.min.js"></script>
<script type="text/javascript">
(function($){
var _old = $.getJSON;
$.getJSON = function(){
alert("Calling overridden getJSON");
return _old.apply(this,arguments);
};
})(jQuery);
$(document).ready(function() {
try {
$(this).getJSON('ajax/test.json', function(data) {
var items = [];
alert('done');
});
}
catch (err)
{
alert(err.message);
}
});
</script>
</head>
<body>
</body>
</html>

You need to call $.getJSON, not $(foo).getJSON;
$.getJSON('ajax/test.json', function(data) {
var items = [];
alert('done');
});

Related

Difference between init events in js file or html template

Is there a difference between lauch js functions from same JS file where they declared after page load, or in html template? When both signed into $(document).ready(function () {...}).
I assume that no, but I ran into a problem when replace my ExampleService.init() function from template to separate JS file.
For example i have that construction:
common.js
var ExampleService= {
catalogSpinner: '',
init: function() {
this.initEvents();
},
initEvents: function() {
var self = this;
$('.example-button').on('click', function() {
//do some logic, append spinner...
self.removeSpinner();
});
},
removeSpinner: function() {
$(this.catalogSpinner).fadeOut('slow', function() {
$(this).remove().css({display: 'block'});
});
}
}
index.html
<script src="js/common.js"></script>
<script>
$(document).ready(function () {
ExampleService.catalogSpinner = '<div class="spinner"></div>'; // css3 animation
ExampleService.init();
});
</script>
That way all works perfect, my catalogSpinner overriden from template, and i can use them like DOM element.
But! if i move ExampleService.init(); to common.js file, like that:
common.js
var ExampleService= {
...
// all the same...
...
};
$(document).ready(function () {
'use strict';
ExampleService.init();
});
index.html
<script src="js/common.js"></script>
<script>
$(document).ready(function () {
ExampleService.catalogSpinner = '<div class="spinner"></div>';
});
</script>
That way it wouldn't work. And throw console error Uncaught TypeError: this.catalogSpinner.fadeOut is not a function
Why it's happens? After all in both cases init functions starts only after full page load, and no matters that i override my variable after starting base functions. What im doing wrong?
About orders in which inits will executed. How i understand its no matter. Cause in any case, second document.ready from template file, always ovverride empty catalogSpinner variable from JS file, before click event happens
It's almost certainly a timing issue. What guarantee do you have that $(document).ready in common.js will fire after the same event handler in your html file (which is what needs to happen according to your implementation)?
Or, you need to make sure that when it occurs in common.js, that code can somehow retrieve the catalogSpinner value.
Also, catalogSpinner needs to be a valid jQuery object, not a string.
It will and it does work in both the cases. To use jQuery methods over DOM elements, you must have valid jQuery selectors which will return objects binded with jQuery methods.
Try this:
case 1:
common.js
var ExampleService= {
catalogSpinner: '',
init: function() {
this.initEvents();
},
initEvents: function() {
var self = this;
$('.example-button').on('click', function() {
//do some logic, append spinner...
self.removeSpinner();
});
},
removeSpinner: function() {
this.catalogSpinner.fadeOut('slow', function() {
$(this).remove().css({display: 'block'});
});
}
};
index.html
<!doctype html>
<html>
<head>
<script src="jquery.min.js"></script>
<script src="common.js"></script>
<style>
</style>
</head>
<body>
<div class="spinner">Spinner</div>
<button type="button" class="example-button">Remove</button>
<script type="text/javascript">
$(document).ready(function () {
ExampleService.catalogSpinner = $('.spinner');
ExampleService.init();
});
</script>
</body>
</html>
case 2:
common.js
var ExampleService = {
catalogSpinner: '',
init: function () {
this.initEvents();
},
initEvents: function () {
var self = this;
$('.example-button').on('click', function () {
//do some logic, append spinner...
self.removeSpinner();
});
},
removeSpinner: function () {
this.catalogSpinner.fadeOut('slow', function () {
$(this).remove().css({display: 'block'});
});
}
};
$(document).ready(function () {
'use strict';
ExampleService.init();
});
index.html
<!doctype html>
<html>
<head>
<script src="jquery.min.js"></script>
<script src="common.js"></script>
<style>
</style>
</head>
<body>
<div class="spinner">Spinner</div>
<button type="button" class="example-button">Remove</button>
<script type="text/javascript">
$(document).ready(function () {
ExampleService.catalogSpinner = $('.spinner');
});
</script>
</body>
</html>

jquery - ajaxStop is not consistently executing javascript redirect

I am using jquery 1.9.1. I have logout code where I need to post to multiple pages then do a redirect:
<script type="text/javascript">
window.onload=function(){
$( document ).ajaxStop(function() {
logoutRedirect();
});
logoutOfApps();
}
</script>
These methods are in a different javascript file (but I think that is irrelavent).
function logoutOfApps(){
$.post("/app1/logout");
$.post("/app2/logout");
}
function logoutRedirect(){
var redirectOnLogoutURL = null;
redirectOnLogoutURL = "/mylogoutdisplaypage";
top.location = redirectOnLogoutURL;
}
SECOND TRY: This also doesn't work consistently:
<script type="text/javascript">
window.onload=function(){
logoutOfApps();
logoutRedirect();
}
</script>
Make sure both requests have finished before you redirect
function logoutOfApps(){
return $.when(
$.post("/app1/logout"),
$.post("/app2/logout")
)
}
logoutOfApps().done(logoutRedirect);
Just for completeness thought I would document exactly how I changed it, which took a little while to get just right. Thank you adeneo for your answer that I accepted.
<script type="text/javascript">
window.onload=function(){
onLoadOfPage();
}
</script>
This is in the second file (I preferred all jquery code in one file):
function onLoadOfPage(){
$( document ).ajaxStop(function() {
logoutRedirect();
});
logoutOfApps().done(logoutRedirect);
}
function logoutOfApps(){
return $.when(
$.post("/app1/logout"),
$.post("/app2/logout")
)
}
function logoutRedirect(){
var redirectOnLogoutURL = null;
redirectOnLogoutURL = "/mylogoutdisplaypage";
top.location = redirectOnLogoutURL;
}

Get text file contents using JQuery in an external file

I have an external javascript file that I want to use to collect the contents of a number of text files. JQuery .get() seems the most obvious choice. I can make this work if the JQuery is in the page, but not when the JQuery is in the external file. I'm missing something hugely simple...and I am currently mixing normal javascript with JQuery in the same file which I fear is poor form.
All files I am trying to access are within the same file structure. Currently I have the following in my external .js:
function addPanels() {
// eventually loop over list of local HTML files
// and do some stuff with the results...
fileContents = readHTMLFile();
}
jQuery(function($){
readHTMLFile = $.get('../html/test.html', function(data) {
alert('Loaded something');
return(data);
});
});
My HTML page contains the following:
<script type="text/javascript">
$(document).ready(function(){
addPanels();
});
</script>
Pretty sure this is a RTFM moment so direction towards the right manual/tutorial would be great!
Dan
The jQuery.get is a asynchronous function, with a callback that executes when the server returns the requested document. Therefore, you cannot return any data from the method.
function addPanels() {
// will not work
fileContents = readHTMLFile();
}
...
readHTMLFile = $.get('../html/test.html', function(data) {
// will not work
return(data);
});
This however, will work:
var addPanelCallback = function(html) {
// append html (or something like that)
alert(html);
};
var addPanel = function(url) {
$.get(url, addPanelCallback);
};
addPanel('../html/test1.html');
addPanel('../html/test2.html');
Example: http://jsfiddle.net/FgyHp/
In your script "readHTMLFile" is not known by function "addPanels", you should put them in same level.
This script should works
<script type="text/javascript">
(function($){
var readHTMLFile = function(url){
var toReturn;
$.ajax({
url: url,
async: false
}).done(function(data){
toReturn = data;
});
return toReturn;
};
$.addPanels = function(url){
fileContents = readHTMLFile(url);
};
})(jQuery);
</script>
And in your page you can call it like that:
<script type="text/javascript">
$(document).ready(function(){
$.addPanels('../test/test.html');
});
</script>

Plugin method declarations - can't make it work

I've been struggling with exactly what the correct syntax is to make methods available on an object with a plugin. Here's the basic framework:
<!DOCTYPE html>
<html>
<head>
<!-- jQuery -->
<script type="text/javascript" src="http://goo.gl/XQPhA"></script>
<script type="text/javascript">
(function($) {
$.test = function(el, options) {
this.whiten = function() {
$(this).css('background-color', options.bg);
}
};
$.test.settings = {
bg: 'white'
};
$.fn.test = function(options) {
options = $.extend(options, $.test.settings);
return this.each(function() {
$.test(this, options);
});
};
})(jQuery);
$(document).ready(function() {
$('#list').test().css('background-color', 'wheat');
$('#go').click(function() {
$('#list').whiten();
});
});
</script>
</head>
<body>
<button id="go">whiten</button>
<ul id="list">
<li>Aloe</li>
<li>Bergamot</li>
<li>Calendula</li>
<li>Damiana</li>
<li>Elderflower</li>
<li>Feverfew</li>
</ul>
</body>
</html>
and I guess what I'm not sure about is how to make the function assignment. this inside of $.test will refer to the jQuery object wrapped around my list so I would have thought that this.myMethod = function() { would have worked but it doesn't. $(this) would be a double wrapper, el is my list (and I don't want to assign the method directly to the object since I wouldn't be able to call it like this: $('#list').whiten()), and $(el) would be the same as $(this)... so how is this done?
-- update --
I've created a [jsfiddle] to play with the problem
-- update --
I also did try placing the method in the $.fn.test function but to no avail
Try this:
$.fn.test = function(options) {
options = $.extend(options, $.test.settings);
var self = this;
return this.each(function() {
$.test(self, options);
});
};
after much wailing and gnashing of teeth, I figured it out. I'm not sure I understand why it works that way but for now I'm just happy it does!
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://goo.gl/XQPhA"></script>
<script type="text/javascript">
(function($) {
$.test = {
bg: 'white'
};
$.fn.test = function(options) {
options = $.extend({}, $.test, options);
this.whiten = function() {
$(this).css('background-color', options.bg);
};
return this.each(function() {
$.fn.test(options);
});
};
})(jQuery);
$(document).ready(function() {
$('#list').test().css('background-color', 'wheat');
$('#go').click(function() {
$('#list').whiten();
});
});
</script>
</head>
<body>
<button id="go">whiten</button>
<ul id="list">
<li>Aloe</li>
<li>Bergamot</li>
<li>Calendula</li>
<li>Damiana</li>
<li>Elderflower</li>
<li>Feverfew</li>
</ul>
</body>
</html>

How do you use onPageLoad in Javascript?

I tried using
onPageLoad: function() {
alert("hi");
}
but it won't work. I need it for a Firefox extension.
Any suggestions please?
If you want to do this in vanilla javascript, just use the window.onload event handler.
window.onload = function() {
alert('hi!');
}
var itsloading = window.onload;
or
<body onload="doSomething();"></body>
//this calls your javascript function doSomething
for your example
<script language="javascript">
function sayhi()
{
alert("hi")
}
</script>
<body onload="sayhi();"></body>
EDIT -
For the extension in firefox On page load example
Assuming you meant the onload-event:
You should use a javascript library like jQuery to make it work in all browsers.
<script type="text/javascript">
$(document).ready(function() {
alert("Hi!");
});
</script>
If you really don't want to use a javascript library (Don't expect it to work well in all browsers.):
<script type="text/javascript">
function sayHi() {
alert("Hi!");
}
</script>
<body onload="javascript:sayHi();">
...
<script language="javascript">
window.onload = onPageLoad();
function onPageLoad() {
alert('page loaded!');
}
</script>

Categories