I have a widget that only works with one instance.
The problem I have is that if I have one instance of the widget on a page it works fine. If I have more than one instance on the page, only one instance works. The second instance does not work...
you can check this page for an example http://fullylinked.com/advert.php
From my troubleshooting, I have noticed the following
1. The placement ID of the second instance is not passed to the script.
2. Even if the default placement ID is used, I get an error saying
"Uncaught ReferenceError: jsonpCallback is not defined".
Unfortunately the jsonpCalback is defined because the first script works..
Please here are my code..
The Widget...
<script placementID = "37" src="placement.js" type="text/javascript"> </script>
<div id="widget-container_37"></div>
---- Second instance below this line -------
<script placementID = "36" src="placement.js" type="text/javascript"></script><div id="widget-container_36"></div>
NOW HERE IS THE .JS file
(function() {
// Localize jQuery variable
var jQuery;
/******** Load jQuery if not present *********/
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.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.4.2/jquery.min.js");
if (script_tag.readyState) {
script_tag.onreadystatechange = function () { // For old versions of IE
if (this.readyState == 'complete' || this.readyState == 'loaded') {
scriptLoadHandler();
}
};
} else {
script_tag.onload = scriptLoadHandler;
}
// Try to find the head, otherwise default to the documentElement
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
// The jQuery version on the window is the one we want to use
jQuery = window.jQuery;
main();
}
/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
// Restore $ and window.jQuery to their previous values and store the
// new jQuery in our local jQuery variable
jQuery = window.jQuery.noConflict(true);
// Call our main function
main();
}
/******** Our main function ********/
function main() {
jQuery(document).ready(function($) {
/******* Load CSS *******/
/** var css_link = $("<link>", {
rel: "stylesheet",
type: "text/css",
href: "style.css"
});
css_link.appendTo('head');
/**** get host name ***/
var site_name = window.location.hostname;
/****** get user ID******/
var this_js_script = $('script[src*=placement]'); // get file name..*/
var placementID = this_js_script.attr('placementID');
/**var placementID = document.getElementById("adblabla_2").getAttribute("placementID");**/
if (typeof placementID === "undefined" ) {
var placementID = '23';
}
/******* Load HTML *******/
$.ajax({
url: 'processors/processor.php?placementID='+placementID,
data: {name: 'Chad', site: site_name},
dataType: 'jsonp',
jsonp: 'callback',
jsonpCallback: 'jsonpCallback',
success: function(data){
//alert(placementID);
$('#widget-container_'+placementID).html(data.message);
}
});
});
function jsonpCallback(data){
$('#widget-container_2').text(data.message);
}
}
})();
The reason is another then I thought, your code is already encapsulated, so its not calling twice the same main function, but it finds twice the same script tag, and thus gets the wrong parameter I think.
http://www.2ality.com/2014/05/current-script.html
Well you can try this code:
(function () {
// Localize jQuery variable
var jQuery,
//get current script
currentScript = document.currentScript || (function () {
var scripts = document.getElementsByTagName('script');
return scripts[scripts.length - 1];
})();
/******** Load jQuery if not present *********/
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.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.4.2/jquery.min.js");
if (script_tag.readyState) {
script_tag.onreadystatechange = function () { // For old versions of IE
if (this.readyState == 'complete' || this.readyState == 'loaded') {
scriptLoadHandler();
}
};
} else {
script_tag.onload = scriptLoadHandler;
}
// Try to find the head, otherwise default to the documentElement
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
// The jQuery version on the window is the one we want to use
jQuery = window.jQuery;
main();
}
/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
// Restore $ and window.jQuery to their previous values and store the
// new jQuery in our local jQuery variable
jQuery = window.jQuery.noConflict(true);
// Call our main function
main();
}
/******** Our main function ********/
function main() {
jQuery(document).ready(function ($) {
/******* Load CSS *******/
/** var css_link = $("<link>", {
rel: "stylesheet",
type: "text/css",
href: "style.css"
});
css_link.appendTo('head');
/**** get host name ***/
var site_name = window.location.hostname;
/****** get user ID******/
var this_js_script = $(currentScript); // get file name..*/
var placementID = this_js_script.attr('placementID');
/**var placementID = document.getElementById("adblabla_2").getAttribute("placementID");**/
if (typeof placementID === "undefined") {
var placementID = '23';
}
/******* Load HTML *******/
$.ajax({
url: 'processors/processor.php?placementID=' + placementID,
data: {name: 'Chad', site: site_name},
dataType: 'jsonp',
jsonp: 'callback',
success: function (data) {
//alert(placementID);
$('#widget-container_' + placementID).html(data.message);
}
});
});
function jsonpCallback(data) {
$('#widget-container_2').text(data.message);
}
}
})();
PS: its always very useful when you build up a testcase on http://jsfiddle.net/
Related
I have written a widget and it works great, but right now I am giving my users a link to a remote script, a link to my script and a div to place on their page. I would like to reduce this to just a link to my script and the div. The remote link I want to include in my code below is
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
Can anyone please educate me on how to add a second link in my code? I already link to a remote jquery and a remote stylesheet, but I am not sure how/where to include another remote link. I have tried a number of places and ways, but I keep breaking my page, haha. Thanks for any help offered.
(function() {
// Localize jQuery variable
var jQuery;
/******** Load jQuery if not present *********/
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.12.4') {
var script_tag = document.createElement('script');
script_tag.setAttribute("type", "text/javascript");
script_tag.setAttribute("src", "//code.jquery.com/jquery-1.12.4.js");
if (script_tag.readyState) {
script_tag.onreadystatechange = function() { // For old versions of IE
if (this.readyState == 'complete' || this.readyState == 'loaded') {
scriptLoadHandler();
}
};
} else {
script_tag.onload = scriptLoadHandler;
}
// Try to find the head, otherwise default to the documentElement
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
// The jQuery version on the window is the one we want to use
jQuery = window.jQuery;
main();
}
/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
// Restore $ and window.jQuery to their previous values and store the
// new jQuery in our local jQuery variable
jQuery = window.jQuery.noConflict(true);
// Call our main function
main();
}
/******** Our main function ********/
function main() {
jQuery(document).ready(function($) {
/******* Load CSS *******/
var css_link = $("<link>", {
rel: "stylesheet",
type: "text/css",
href: "//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"
});
css_link.appendTo('head');
/******* Load HTML *******/
var jsonURL = "//www.myurl.com/mssql.php/ws_nfy";
jQuery(document).ready(function() {
jQuery.ajax({
url: jsonURL,
success: searchCallback
});
});
function searchCallback(data) {
var ws_nfy = data.ws_nfy.records;
jQuery.each(ws_nfy, function(index, nfy) {
jQuery("#tabs ul").append('<li>' + nfy[2] + '</li>');
jQuery("#tabs ul").after("<div id='tabs-" + nfy[0] + "'>" + nfy[1] + "</div>");
});
$("#tabs").tabs();
};
});
}
})(); // We call our anonymous function immediately
You're checking if jQuery is already loaded before injecting it... Which is good. Now you should do the same for jQuery-UI.
So that's the same procedure...
Try this:
(function() {
// Localize jQuery variable
var jQuery;
/******** Load jQuery if not present *********/
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.12.4') {
var script_tag = document.createElement('script');
script_tag.setAttribute("type", "text/javascript");
script_tag.setAttribute("src", "//code.jquery.com/jquery-1.12.4.js");
if (script_tag.readyState) {
script_tag.onreadystatechange = function() {
// For old versions of IE
if (this.readyState == 'complete' || this.readyState == 'loaded') {
scriptLoadHandler();
}
};
} else {
script_tag.onload = scriptLoadHandler;
}
// Try to find the head, otherwise default to the documentElement
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
// The jQuery version on the window is the one we want to use
jQuery = window.jQuery;
//main(); // Not now! Check for UI first.
checkUI();
}
/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
// Restore $ and window.jQuery to their previous values and store the
// new jQuery in our local jQuery variable
jQuery = window.jQuery.noConflict(true);
// Call our main function
//main(); // Not now! Check for UI first.
checkUI();
}
// ========================== Check if jQuery-UI is already loaded
function checkUI(){
if(typeof(jQuery.ui) != "undefined"){
// UI is loaded already.
console.log("UI is defined");
console.log( typeof(jQuery.ui) );
main();
}else{
// UI is not loaded. Got to load it.
console.log("UI is NOT defined");
//console.log( typeof(jQuery.ui) );
var ui = document.createElement('script');
ui.setAttribute("type", "text/javascript");
// For UI
window.$ = jQuery;
ui.setAttribute("src", "https://code.jquery.com/ui/1.12.1/jquery-ui.js");
console.log(ui);
document.getElementsByTagName("head")[0].appendChild(ui);
if (ui.readyState) {
console.log( "READYSTATE" );
ui.onreadystatechange = function() { // For old versions of IE
if (this.readyState == 'complete' || this.readyState == 'loaded') {
console.log( "STATELOADED" );
main();
}
};
} else {
console.log( "ELSE" );
jQuery(ui).on("load", function(){
console.log("UI loaded...");
main();
});
}
}
}
/******** Our main function ********/
function main() {
jQuery(document).ready(function($) {
console.log("jQuery: "+jQuery.fn.jquery+"\njQuery-UI: "+jQuery.ui);
console.log("Tabs element: "+jQuery("#tabs").length);
/******* Load CSS *******/
var css_link = $("<link>", {
rel: "stylesheet",
type: "text/css",
href: "//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"
});
css_link.appendTo('head');
/******* Load HTML *******/
var jsonURL = "//www.myurl.com/api.php/ws_nfy";
jQuery.ajax({
url: jsonURL,
success: searchCallback
});
function searchCallback(data) {
var ws_nfy = data.ws_nfy.records;
jQuery.each(ws_nfy, function(index, nfy) {
jQuery("#tabs ul").append('<li>' + nfy[2] + '</li>');
jQuery("#tabs ul").after("<div id='tabs-" + nfy[0] + "'>" + nfy[1] + "</div>");
});
jQuery("#tabs").tabs();
};
});
}
})(); // We call our anonymous function immediately
I am building a widget to be deployed in any site as long as they add the script tag with the src pointing to the url I set. I am trying to use javascript to detect whether or not Bootstrap library has been loaded. If it is not loaded, then I will add references to Bootstrap CDN. But, the problem is that it always return me false, so the code will inject new bootstrap script tag, therefore having 2 bootstrap tag at the same time which causes my modal bootstrap not working.
First of all, when my widget first loaded, it will check whether jQuery is loaded.
$(window).load(function()
{
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.2') {
var scriptTag = document.createElement('script');
scriptTag.setAttribute("type", "text/javascript");
scriptTag.setAttribute("src", "https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js");
if (scriptTag.readyState) {
scriptTag.onreadystatechange = function () { // For old versions of IE
if (this.readyState === 'complete' || this.readyState === 'loaded') {
loadScript();
}
};
} else {
scriptTag.onload = loadScript;
}
// Try to find the head, otherwise default to the documentElement
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(scriptTag);
} else {
// The jQuery version on the window is the one we want to use
jQuery = window.jQuery;
loadScript();
}
});
This is where it checks whether bootstrap has been loaded. The bootstrap_enabled is always false.
function loadScript()
{
var jsLibraries = [];
var bootstrap3_enabled = (typeof $().emulateTransitionEnd == 'function');
if (!bootstrap3_enabled) {
var bootstrapCss = $("<link>",
{
rel: "stylesheet",
type: "text/css",
href: "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css"
});
bootstrapCss.appendTo('head');
jsLibraries.push("https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js");
}
jQuery = window.jQuery.noConflict(true);
jsLibraries.push("https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.2/less.min.js");
getScripts(jsLibraries, function () {
main();
});
}
function getScripts(list, fn) {
var cntr = list.length;
for (var i = 0; i < list.length; i++) {
$.getScript(list[i], function () {
--cntr;
if (cntr === 0) {
fn();
}
});
}
}
Can anyone tell me what goes wrong? Thanks in advance.
I am creating a widget to be embedded on a third party website. I am dynamically creating the script tags to load the version of jQuery and my other in house java script files. While i am creating the script tags dynamically it throws me an errors:
1. Uncaught TypeError: Cannot read property 'fn' of undefined
2. Uncaught Error: Bootstrap's JavaScript requires jQuery
I know the 2nd error means that your jQuery is not loaded. But when i look at the script tags in my element tab i can see the jQuery script tag on top.
I am following this tutorial:
http://alexmarandon.com/articles/web_widget_jquery/
And Below is my code:
(function() {
// Localize jQuery variable
var jQuery;
/******** Load jQuery if not present *********/
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.11.1') {
var script_tag = document.createElement('script');
script_tag.setAttribute("type","text/javascript");
script_tag.setAttribute("src","http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js");
if (script_tag.readyState) {
script_tag.onreadystatechange = function () { // For old versions of IE
if (this.readyState == 'complete' || this.readyState == 'loaded') {
scriptLoadHandler();
}
};
} else {
script_tag.onload = scriptLoadHandler;
}
// Try to find the head, otherwise default to the documentElement
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
// The jQuery version on the window is the one we want to use
jQuery = window.jQuery;
main();
}
/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
// Restore $ and window.jQuery to their previous values and store the
// new jQuery in our local jQuery variable
jQuery = window.jQuery.noConflict(true);
// Call our main function
main();
}
/******** Our main function ********/
function main() {
jQuery(document).ready(function($) {
/******* Load CSS *******/
var script2URL = "http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js";
var script3URL = "http://localhost:8080/iam/scripts/bootstrap3-typeahead.min.js";
var script4URL = "https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js";
var script5URL = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-tokenfield/0.12.0/bootstrap-tokenfield.min.js";
var scripts = [script2URL,script3URL,script4URL,script5URL];
var cssURL1 = "http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css";
var cssURL2 = "http://localhost:8080/iam/css/typeaheadjs.css";
var cssURL3 = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-tokenfield/0.12.0/css/bootstrap-tokenfield.min.css";
var cssURL4 = "http://localhost:8080/iam/css/typeahead_ext.css";
var cssURL5 = "http://localhost:8080/iam/css/ePass.css";
var cssURLs = [cssURL1,cssURL2,cssURL3,cssURL4,cssURL5];
//This function loads all the CSS Files
for(var iCount=0;iCount< scripts.length;iCount++){
var script_link = $("<script>", {
type: "text/javascript",
src: scripts[iCount]
});
script_link.appendTo('head');
}
//This function loads all the CSS Files
for(var iCount=0;iCount< cssURLs.length;iCount++){
var css_link = $("<link>", {
rel: "stylesheet",
type: "text/css",
href: cssURLs[iCount]
});
css_link.appendTo('head');
}
/******* Load HTML *******/
var jsonp_url = "http://al.smeuh.org/cgi-bin/webwidget_tutorial.py?callback=?";
$.getJSON(jsonp_url, function(data) {
$('#example-widget-container').html("This data comes from another server: " + data.html);
});
});
}
})();
What I am doing
I am creating a distributable jQuery widget library which inserts an anchor on HTML page.
Issue
In 'MyWidget.prototype.Render' method (of JS), its giving me following error - "jQuery is not defined" However, its working fine in 'MyWidget.prototype.ResolveJqueryAndLoadAdditionalJsAndCss' method.
HTML Snippet
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
Anchor - by user code
<!-- Widget Script: Starts -->
<script type="text/javascript" src="widget.js" ></script>
<Script type="text/javascript">
var customWidget = new MyWidget();
customWidget.Render({ anchorText:'Hola!!!' });
</script>
<!-- Widget Script: Ends -->
</body>
</html>
JS Code(widget.js)
var MyWidget = function() {
// Localize jQuery variable
var jQuery;
// Load jQuery if not present
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.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.10.2/jquery.min.js");
if (script_tag.readyState) {
script_tag.onreadystatechange = function () { // For old versions of IE
if (this.readyState == 'complete' || this.readyState == 'loaded') {
this.ResolveJqueryAndLoadAdditionalJsAndCss();
}
};
} else {
script_tag.onload = this.ResolveJqueryAndLoadAdditionalJsAndCss;
}
// Try to find the head, otherwise default to the documentElement
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
// The jQuery version on the window is the one we want to use
jQuery = window.jQuery;
this.ResolveJqueryAndLoadAdditionalJsAndCss();
}
};
MyWidget.prototype.ResolveJqueryAndLoadAdditionalJsAndCss = function() {
// Restore $ and window.jQuery to their previous values and store the
// new jQuery in our local jQuery variable
jQuery = window.jQuery.noConflict(true);
jQuery(document).ready(function($) {
$.when(
$.getScript( "http://www.jacklmoore.com/colorbox/jquery.colorbox.js" ),
$.Deferred(function( deferred ){
$( deferred.resolve );
})
).done(function(){ });
// Loading Custom CSS
var css_link = $("<link>", { rel: "stylesheet", type: "text/css", href: "https://raw.github.com/premasagar/cleanslate/master/cleanslate.css" });
css_link.appendTo('head');
css_link = $("<link>", { rel: "stylesheet", type: "text/css", href: "http://www.jacklmoore.com/colorbox/example4/colorbox.css" });
css_link.appendTo('head');
css_link = $("<link>", { rel: "stylesheet", type: "text/css", href: "widget.css" });
css_link.appendTo('head');
});
};
MyWidget.prototype.Render = function(data){
jQuery(document).ready(function($) {
$('' + data.anchorText + '').appendTo('body');
$(".widgetExternalPage").colorbox({iframe:true, width:"80%", height:"80%"});
});
};
well, you are re-defining jQuery. Actually, you are re-declaring any variable is also re-setting the value of it. Here, you are setting the value of jQuery to undefined. You should not do this.
If you want, you can do it like:
var jQuery = jQuery || undefined;
This may help, good luck!
I have a js which is showing error in javascript console Cannot call method 'appendChild' of null in this file:
(function(d) {
if( typeof jQuery === 'undefined' ) {
var srsr = d.createElement('script');
srsr.src = '//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js';
d.body.appendChild(srsr);
setTimeout(function(){ doThat(); }, 5000);
} else {
doThat();
}
function getHost( url ) {
var a = document.createElement('a');
a.href = url;
var host = a.hostname;
var t = host.split(".");
if( t.length == 2 ) {
var host = "www."+host;
}
return host;
}
function doThat() {
$.ajax({
url: 'http://mobilesplashpro.com/app/assets/php/tRaCk_loAdInG_PoPUp.php',
type: 'GET',
data: 'adrs='+getHost( document.domain ),
dataType: 'jsonp',
jsonp: false,
jsonpCallback: 'methodCallback',
success: function( data ) {
if( data.message == "yes" ) {
$.getScript("http://mobilesplashpro.com/app/assets/js/popup/PoPUp_txt_CoDE.js",function() { iPhoneAlert(); });
} else {
}
},
error: function( error ) {
console.log( error );
}
});
}
})( document );
have used Appendchild code in another file which is working perfectly but not in it..
Thanks
First of all, place this code in the end of your body (if this is in your head, the body doest not exists), if you must place it in the head, you should make some sort of interval untill you simulated a DomReady event (That garantees you have a document.body to traverse).
Example:
var intervalDomReady = setInterval(function() {
if (document.body) {
clearInterval(intervalDomReady);
intervalDomReady =null;
DomReady();
}
},500);
function DomReady() { /*you code*/ }
You only have the reference to jquery from google CDN once it is loaded. So you will not have sure that It will happen in 5 secs, must first bind to the onload event of the script an then try to use jquery functions.
Example of solution:
var d = document;
var srsr = d.createElement('script');
srsr.src = '//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js';
srsr.src.onload = function() { doThat(); }
Because this is running when the document loads, it's a valid use-case for document.write.
It'll also simplify things if you use document.write to load the script, since it'll load the script synchronously.
As a result, you would eliminate the need for the doThat() function, and the setTimeout.
So first put your jQuery check and script loading code in a separate script at the top...
<script type="text/javascript">
if( typeof jQuery === 'undefined' ) {
document.write('<scr' + 'ipt src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"><\/scr' + 'ipt>');
}
</script>
Then put your main script in a separate script below the one above...
<script>
(function(d) {
function getHost( url ) {
var a = document.createElement('a');
a.href = url;
var host = a.hostname;
var t = host.split(".");
if( t.length == 2 ) {
var host = "www."+host;
}
return host;
}
$.ajax({
url: 'http://mobilesplashpro.com/app/assets/php/tRaCk_loAdInG_PoPUp.php',
type: 'GET',
data: 'adrs='+getHost( document.domain ),
dataType: 'jsonp',
jsonp: false,
jsonpCallback: 'methodCallback',
success: function( data ) {
if( data.message == "yes" ) {
$.getScript("http://mobilesplashpro.com/app/assets/js/popup/PoPUp_txt_CoDE.js",function() { iPhoneAlert(); });
} else {
}
},
error: function( error ) {
console.log( error );
}
});
})( document );
</script>
Now if jQuery isn't loaded, the new script will be written and loaded below the first, and above the second, and we never had to perform any sort of DOM selection.