Load external script files via HTML control

Hi,
is it possible to store the JavaScripts not inside JavaScript Editor but in in an external file located on a CDN or SharePoint?

It seems not to work the same way like I used it with Spforms (using a HTML control and link )?
thanks
Alex

Dear Alex,

You can implement this by two ways:

fd.spRendered(function(){
    var imported = document.createElement('script');
    imported.src = 'URL of JS file';
    document.head.appendChild(imported);
})  

or with the help of $.getScript(): Difference between two dates in years, months, days in JavaScript

Hi, it works that way, thank you.

Could it be, that the pnp-js library is only available from the JavascriptEditor and not from browser console or external scripts.
Do you have some hints regarding this.
I’m trying to migrate from spforms and it seems that some things aren’t working the same way like there ;)…

Dear Alex,

Please try to add window.pnp = pnp; in the JavaScript Editor to make pnp available globally.

great, thanks

one more question, is it also possible to add custom CSS outside the designer?
something like?

fd.spRendered(function(){
var importedCSS = document.createElement('style or link');
importedCSS.src = '...path to css file...';
document.head.appendChild(importedCSS);
});

Dear Alex,

Sure, like a JavaScript file.

Hi @AlexZver

I am attempting to use numeral.js (http://numeraljs.com/) in the same way, however I receive the error message below.

VM4299:5 Uncaught TypeError: Unexpected anonymous AMD define.
    at l.eval [as reduceRegister_] (eval at <anonymous> (sp-pages-assembly_en_6f3c2f12deaa695d523405180544ad4c.js:1504), <anonymous>:5:14313)
    at l.eval [as pushRegister_] (eval at <anonymous> (sp-pages-assembly_en_6f3c2f12deaa695d523405180544ad4c.js:1504), <anonymous>:4:31764)
    at a (eval at <anonymous> (sp-pages-assembly_en_6f3c2f12deaa695d523405180544ad4c.js:1504), <anonymous>:5:13777)
    at numeral.min.js:8
    at numeral.min.js:8

And

ReferenceError: numeral is not defined
    at eval (eval at e._executeCustomJavaScript (VM4310 spform.js:38), <anonymous>:10:13)
    at VM4310 spform.js:1
    at Array.map (<anonymous>)
    at Function.e.safeRun (VM4310 spform.js:1)
    at VM4310 spform.js:68

This is my Javascript on the Plumsail form:

fd.spRendered(function() {   
        var imported = document.createElement('script');
        imported.src = '//cdnjs.cloudflare.com/ajax/libs/numeral.js/2.0.6/numeral.min.js';
        document.head.appendChild(imported);
        console.log(numeral(fd.field('Sales_x0020_Declared').value));
    });

Dear @Andre,

Please try to add this code:

window.define = null;

Thank you @AlexZver.
This worked.

For anyone that wants a reference…

  var injector = function(src,filetype) {
    if (filetype=="js"){
    var tag = document.createElement('script');
    tag.async = false;
    tag.src = src;
  }
  else if (filetype=="css"){
    var tag=document.createElement("link")
    tag.setAttribute("rel", "stylesheet")
    tag.setAttribute("type", "text/css")
    tag.setAttribute("href", src)  
   }
  if (typeof tag!="undefined")
    document.getElementsByTagName('body')[0].appendChild(tag)
  }

 injector("/Assets/code/somescript.js", "js");
 injector("/Assets/code/somestyle.css", "css");

If you need to load some libraries before your script ( note that you still need the injector above)…

Promise.all([
 injector("/Assets/code/someLibrary1", "js"),
 injector("/Assets/code/someLibrary2", "js"),
 injector("/Assets/code/someFancyStyle.css", "css")
])
.then(([res1,res2,res3]) => {
    fd.spRendered(function() {
       injector("/Assets/code/myFormHelperCode.js", "js");
    });
 })
catch((error) => { console.log(error) });
1 Like

An article or how-to for this would be awesome, including how to deal with caching of the external file.

Hello @sphilson,

We've recently built-in the RequireJS library which improves the speed and quality of the code. You can use it now, to load external scripts, please find the example in this article.

And how do you want to deal with caching of the external file?

1 Like

Greetings, how about loading external css, requirejs approach works only for js files.

Thsnks,
Adrian

Hello @Adrian_Ganea,

You can load external CSS using HTML control and <link> element:

<link href="/media/examples/link-element-example.css" rel="stylesheet">
1 Like

I hope you can help me. I want to outsource my code in an external file.
I used your code like this:

fd.spRendered(function(){
var imported = document.createElement('script');
imported.src = 'https://xxx/Scripte/defaukt.js';
document.head.appendChild(imported);
window.define = null;
})

And this is the beginning of my js file:

fd.spRendered(function(){
fd.clear();
fd.field('IBAN_2').$on('change',function(value){
fd.field('IBAN_x0020_1').value = fd.field('IBAN_2').value;
})
$(fd.field('IBAN_x0020_1').$parent.$el).hide();

But when I try to open my form this error appears:
image

@Sternchen,

try defining the fd globally in the JavaScript editor like this:

window.fd = fd;

fd.spRendered(function () {
   //your code 
});

Thank you for your help.
The error message is gone, but it does not convert my json file. It does not apply the deposited json.
How can I check where it gets stuck? There is nothing in the console logs.

window.fd = fd;
fd.spRendered(function(){
var imported = document.createElement('script');
imported.src = 'https://collaboration.connect.buzziunicem.com/groups/00072/Scripte/20.js';
document.head.appendChild(imported);
})

@Sternchen,

Try placing the code in the external JavaScript file outside of the spRendered() event. The form is fully loaded when the external script is added to the form, so you don't need using this event.