IBM forms experience External library error :jsPDF - javascript

so I was following the current standard way of adding an external js library to forms experience builder (tutorial: https://www.youtube.com/watch?v=wRW4vBUT4oM).
I was able to successfully add jquery and run jquery codes, but i am not able to run the jsPDF library, I am getting a reference error "ReferenceError: jsPDF is not defined".
I am running the function onClick generate pdf button (see: http://54.191.245.162:9080/forms/anon/org/app/f445e78b-fc77-4ef4-80f9-c82cfe207be8/launch/index.html?form=F_Form1)
this is my code on application start
app.getSharedData().loadScript = function (url, callback) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement("script")
script.type = "text/javascript";
script.src = url;
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
}
then onNew form event I am passing the URL and callback function
var JSPDFurl = 'https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.4.1/jspdf.min.js'
var jqueryURL = 'https://code.jquery.com/jquery-3.3.1.slim.min.js'
app.getSharedData().loadScript(jqueryURL, function () {
app.getSharedData().loadScript(JSPDFurl, function () {
function onClick() {
console.log('on click function is running')
console.log('JQUERY WORKING', $('.first-name input').val("jay chacko"))
var pdf = new jsPDF('p', 'pt', 'letter');
pdf.canvas.height = 72 * 11;
pdf.canvas.width = 72 * 8.5;
pdf.fromHTML(document.body);
pdf.save('test.pdf');
};
var element = document.getElementById("clickbind");
element.addEventListener("click", onClick);
})
})

For some reason the latest version of jsPDF is throwing error inside IBM FORMS, maybe an internal global scope conflict. version 1.2.60 and below seems to works fine and not throwing the above error.

Related

Inject External JS into iFrame

I'm making a basic editing system. For this I have an iFrame on the page, and I am wanting to inject javascript into it. I've tried a few different methods and have come to a method which works (injecting inline script), ideally I don't want to do it this way, I want to inject an external script file. The current code I have is:
function addScript(src, myscript2) {
var iFrameHead = window.frames["main_iframe"].document.getElementsByTagName("head")[0];
var myscript = document.createElement('script');
myscript.type = 'text/javascript';
myscript.src = src;
iFrameHead.appendChild(myscript);
iFrameHead.innerHTML = iFrameHead.innerHTML + myscript2;
}
addScript("js/jquery-3.1.1.js", "<scr" + "ipt>function frame_hover(e) {e.preventDefault();console.log('hover enter ', $(e.target));}function frame_drop(e) {e.preventDefault();console.log('drop ', $(e.target));}console.log('iframe loaded and script loaded');</scr" + "ipt>");
This is working, the jQuery file is working, as is the inline script that's injected.
I want it to work like this:
tion injectJS() {
function addScript(src) {
var iFrameHead = window.frames["main_iframe"].document.getElementsByTagName("head")[0];
var myscript = document.createElement('script');
myscript.type = 'text/javascript';
myscript.src = src;
iFrameHead.appendChild(myscript);
}
addScript("js/jquery-3.1.1.js");
addScript("js/frame_script.js");
}
Although when doing it this way, I get the error: Uncaught ReferenceError: frame_hover is not defined at HTMLBodyElement.ondragenter
frame_hover is called from:
$('#main_iframe').contents().find('body')
.attr('ondragenter', 'frame_hover(event)');
the content of frame_script.js is:
function frame_hover(e) {
e.preventDefault();
console.log('hover enter ', $(e.target));
}
function frame_drop(e) {
e.preventDefault();
console.log('drop ', $(e.target));
}
console.log('iframe loaded and script loaded');
What really doesn't make sense to me with this, is that jQuery works injecting it this way, that's loaded exactly the same way as the external file frame_script.js is loaded, why is it not seeing the file?!

Reload javascript resource programmatically in Chrome

I'm trying to reload javascript resources programmatically in Chrome and if I run that from console, then it works fine, but if I put that into the code to reload after an event was fired, then the resource doesn't change. What is the problem?
I use this reloader:
var docHeadObj = document.getElementsByTagName("head")[0];
var dynamicScript = document.createElement("script");
dynamicScript.type = "text/javascript";
dynamicScript.src = 'js/resource.js';
docHeadObj.appendChild(dynamicScript);
And here is the event handler:
obj.onclick(function(){
var docHeadObj = document.getElementsByTagName("head")[0];
var dynamicScript = document.createElement("script");
dynamicScript.type = "text/javascript";
dynamicScript.src = 'js/resource.js';
docHeadObj.appendChild(dynamicScript);
});
After both cases the new and proper <script> element is appended to the <head> and on network tab the resource is downloaded, but in case of the second one the resource is never change.
EDIT:
I'm closer to the problem. If I have this code in the resource which will be reloaded alert("aaa");
And I open the application then after performing a click event I get an alert with 3 'a' letter. Then I decrease the number of the letters to 2, reload the resource, perform a click event, then I again see 3 'a' letter. Then I decrease the number of letters to 1, save and click, then I see 2 'a' letter. So it seems to be the Chrome (and also FF) stores the last modified resource except if I reload that from console.
You should wait before the script is loaded before you use it. It can be achieved with using onload event for the dynamic script
function loadScript(url, callback) {
var docHeadObj = document.getElementsByTagName("head")[0];
var dynamicScript = document.createElement("script");
dynamicScript.type = "text/javascript";
dynamicScript.src = url;
// bind the event to the callback function
dynamicScript.onreadystatechange = callback; //for ie<9
dynamicScript.onload = callback;
// Fire the loading
docHeadObj.appendChild(dynamicScript);
}
var testJQuery = function () {
console.log($(this));
};
var obj = document.getElementById("test");
obj.onclick = function () {
loadScript("//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js", testJQuery);
};
Working example on fiddle
If you just delete the last instance of the script tag before reloading it, that should force it to reload.
function load(link, id) {
var exists = document.getElementById(id)
if(exists){
exists.parentNode.removeChild(exists);
}
var script = document.createElement('script');
script.src = link;
script.id = id;
document.body.appendChild(script);
}
obj.onclick = function(){
load('js/resource.js','dynamicScript')
}

Load Javascript on function call

I am trying to load one of my advertisers javascript on a click event but I am getting errors from the javascript when it loads.
var get_ad_popup = function () {
_adUnit= {settings: {siteID: 'T1446', pop: {type: 'popunder'}} };
(function () {
var s = document.createElement("script");
s.type = "text/javascript";
s.async = true;
s.src = "http://cdn.adunit.com/js/gp.min.js";
var e = document.getElementsByTagName('script')[0];
e.parentNode.insertBefore(s, e);
})();
};
Then when I call the function I get this error in the console.
TypeError: _adUnit.pop.clkPop is not a function
If I look in the head I can see that the javascript was properly loaded. I just wondering why I get this error.
Edited:
If I load the javascript outside of the function and just include it in the head then it works just fine.
The script can be seen here: http://jsfiddle.net/QXTkz/
This is provided to me by my advertiser.

Javascript: Handle GET Error (document.createElement)

I'm trying to 'include' a JS file to my document. It works fine, but when the file is offline, it should set a variable to FALSE. I googled it, but I didn't get it. So I tried it with the try/catch:
try {
var jq = document.createElement('script');
//jq.onload = put;
jq.type = 'text/javascript';
jq.src = 'http://127.0.0.1:9666/jdcheck.js';
document.getElementsByTagName('head')[0].appendChild(jq);
}
catch(e) {
console.log('An error has occurred: '+e.message);
jdownloader = false;
}
It just throws me the error
Failed to load resource http://127.0.0.1:9666/jdcheck.js
How is it possible to set the var to FALSE?
Thank you,
Markus
You're sort of doing it wrong. When checking if a script source can be loaded, there are built in onload and onerror events, so you don't need try / catch blocks for that, as those are for errors with script execution, not "404 file not found" errors, and the catch part will not be executed by a 404 :
var jq = document.createElement('script');
jq.onload = function() {
// script loaded successfully
}
jq.onerror = function() {
// script error
}
jq.type = 'text/javascript';
jq.src = 'http://127.0.0.1:9666/jdcheck.js';
document.getElementsByTagName('head')[0].appendChild(jq);

Inserting jQuery and jQuery UI into header with userscript

I've been having trouble trying to insert jQuery and jQuery UI into webpage headers through a Greasemonkey userscript I'm working on. Here's how I'm inserting it:
var ccst1 = document.createElement("script");
ccst1.id = "ccst1";
ccst1.src = "http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js";
ccst1.type = "text/javascript";
document.head.appendChild(ccst1);
var ccst2 = document.createElement("script");
ccst2.id = "ccst2";
ccst2.src = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js";
ccst2.type = "text/javascript";
document.head.appendChild(ccst2);
The actual insertion process works, but when I've inserted it, using jQuery on the page (e.g. in an html onclick) works, but jQuery UI immediately gives me a "$ is not defined" error AND a "jQuery is not defined" error the second it's inserted. No jQuery UI then works on the page.
I believe what you need is simply a small wait before inserting the new code that requires jQuery.
function jQueryReady() {
if (typeof unsafeWindow.$ == 'undefined') {
setTimeout(jQueryReady, 100);
} else {
loadJQueryUI(); //this is your function or code that depends on jQuery
}
}
Is jquery already defined in the page you are trying to include it into.
Have you tried
$.noConflict()
Is it inside a naked function
(function(){ alert($("#hello")); })();
I have two methods to using jQ with my userscripts. The first is to add jQ to the userscript.
function addJQuery(callback) {
var script = document.createElement("script");
script.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js");
script.addEventListener('load', function() {
var script = document.createElement("script");
script.textContent = "(" + callback.toString() + ")();";
document.body.appendChild(script);
}, false);
document.body.appendChild(script);
}
// the guts of this userscript
function main() {
$(document).ready( function() {
// YOUR GM CODE GOES HERE
});
}
// load jQuery and execute the main function
addJQuery(main);
This works, however events can get tricky. What I like to do, if the page already is using jQ (check source) is actually create 2 files. One user.js (the GM script) that injects a into the head. This second file needs to be hosted somewhere (i use dropbox) but this is where all your bacon is located. You can write your jQ as if you are writing the code for the page and not a GM script.
eg
GM.user.js
// ==UserScript==
// #name Name (jQuery)
// #description description
// #namespace my twitter page
// #author me
// #include http://
// ==/UserScript==
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'http://dl.dropbox.com/u/example.js';
head.appendChild(script);
example.js
$(document).ready( function() {
// MY Awesome code here.
});
Whichever method you pick, good luck and have fun.
I've just found a solution to this. It actually did have to do with jQuery not being loaded properly, but none of the other solutions worked for me. Joey Geralnik suggested this, which is working properly:
var ccst1 = document.createElement("script");
ccst1.id = "ccst1";
ccst1.src = "http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js";
ccst1.type = "text/javascript";
document.body.appendChild(ccst1);
function ccst2func() {
var ccst2 = document.createElement("script");
ccst2.id = "ccst2";
ccst2.src = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js";
ccst2.type = "text/javascript";
document.body.appendChild(ccst2);
ccst2.addEventListener("load", ccst4func, true);
}
ccst1.addEventListener("load", ccst2func, true);
document.body.insertBefore(concealerPanel, document.body.firstChild);
function ccst4func() {
var ccst4 = document.createElement("script");
ccst4.id = "ccst4";
ccst4.type = "text/javascript";
ccst4.innerHTML = "$('#ccpanelmassiveconstruct').draggable({'handle': '#ccpmchandle', 'constrain': 'parent', 'distance': 20, 'cursor': 'move', 'grid': [10,10], 'scroll': true});\n$('#iframeDragger').resizable();\n$('#ccpmctabs').tabs();";
document.body.appendChild(ccst4);
}

Categories