I am trying to develop a jQuery widget which can be embedded on any site. Following is the script code:
(function($) {
var jQuery;
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.6.2')
{
var script_tag = document.createElement('script');
script_tag.setAttribute("type","text/javascript");
script_tag.setAttribute("src","http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js");
script_tag.onload = scriptLoadHandler;
script_tag.onreadystatechange = function ()
{
if (this.readyState == 'complete' || this.readyState == 'loaded')
scriptLoadHandler();
};
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
}
else
{
jQuery = window.jQuery;
main();
}
function scriptLoadHandler()
{
jQuery = window.jQuery.noConflict(true);
main();
}
function main() {
jQuery(document).ready(function($) {
var css = $("<link>", { rel: "stylesheet", type: "text/css", href: "http://mysite.com/my_css_path.css" });
css.appendTo('head');
});
$.fn.fetchfeed = function(options) {
var defaults = {
//default params;
};
var opts = $.extend(defaults, options);
var myURL = "http://mysite.com/"+opts.user+".json?";
var params = "&callback=?"
var jsonp_url = myURL + encodeURIComponent(params);
$.getJSON(jsonp_url, function(data) {
//build widget html
})
.error(function() {
//show error
});
}
}
})(jQuery);
And following is the code which need to be placed on User's site:
<script id='mywidgetscript' src='http://my_site.com/javascripts/widget.js'></script>
<div id='my-widget-container'></div>
<script>$('#my-widget-container').fetchfeed({/*parameters*/});</script>
When I put this code on other site and try to load the widget it gives me the Uncaught TypeError: Can not set property 'fetchfeed' of undefined
error and fails to load the widget. What could be wrong?
Surprisingly this widget code is working on my site on localhost!!!
Okay, after countless attempts I solved it and got to learn many things. Still I'm unclear about many things. Do correct me by editing this answer or please comment if you find anything wrong.
First $.fn
was null (or value being passed to it was null/undefined). Reason, the script was getting executed after <script>$('#my-widget-container').fetchfeed({/*parameters*/});</script>
being called. So .fetchfeed({...})
was undefined.
Then I moved the code in window.onload
it gave me error can not call method fetchfeed on null
. It must be because it was not getting the element (i.e. $('#my-widget-container')
) also script was not able to recognize $
.
Again after few tweaks making $.fn.fetchfeed
to function fetchfeed() {...}
gave me error undefined fetchfeed
. This was because function fetchfeed was inside another function.
Also encoding &callback=?
parameter gives Access-Control-Allow-Origin
error. This should be passed in url as is.
After some research I modified the code as below and now working correctly.
function fetchfeed(options) {
var o = options;
var jQuery;
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.6.2')
{
var script_tag = document.createElement('script');
script_tag.setAttribute("type","text/javascript");
script_tag.setAttribute("src","http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js");
script_tag.onload = scriptLoadHandler;
script_tag.onreadystatechange = function ()
{
if (this.readyState == 'complete' || this.readyState == 'loaded')
scriptLoadHandler();
};
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
}
else
{
jQuery = window.jQuery;
ff(jQuery, o);
}
function scriptLoadHandler()
{
jQuery = window.jQuery.noConflict(true);
ff(jQuery, o);
}
function ff($, options) {
var defaults = {
...
};
var opts = $.extend(defaults, options);
var jsonp_url = "http://mysite.com/?callback=?";
$.getJSON(jsonp_url, function(data) {
//success
})
.error(function() {
//fail
});
}
}
Code on user's site/blog will be
<div id='my-widget-container'></div>
<script id='my_widget_script' src='https://PATH_OF_SCRIPT/FILE_NAME.js'></script>
<script type='text/javascript'>
fetchfeed({/*params*/});
</script>
The function will be executed when page load completes.