cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Learn all about the Community Ranking System, a fun gamification element of the PTC Community. X

How to import external Javascript file

LS_9776545
9-Granite

How to import external Javascript file

my home.js file is getting very large, about 1500 lines of code. It contains many functions that are called within the same file, for example:

 

////////////////////////////////////////////////////////////////////////////////////////////
//\\ ** PULSANTE MOSTRA PARTI DI RICAMBIO ** //\\
//		questa funzione rende trasparente tutto il modello e suddivide con un codice colori le classifiche ricambi
//		lancia inoltre l'apertura di un pannello laterale
$scope.showSpareParts=function(button, parameter){
  console.log("funziona")
  
  if(button == "spareParts"){
  	if(parameter == "pressed"){ // => pulsante premuto
    	$scope.app.view.Home.wdg['gridLayout-12']['visible'] = true;
   		//tml3dRenderer.setProperties($scope.app.cad.ModelID , {hidden : true});
      //tml3dRenderer.setProperties ($scope.app.cad.ModelID,{phantom:true, opacity:0.5})
  		tml3dRenderer.setProperties ($scope.app.cad.ModelID, {opacity: 0.20}); // => rende trasparente TUTTO il modello, comprese le parti di ricambio
    
    	//tml3dRenderer.GetObject($scope.app.cad.ModelID).GetWidget().ApplyOccludeOpacity(0.0,0.1);
  	
    	for(i=0; i<$scope.app.cad.listaRicambi.length; i++){
      	//tml3dRenderer.setProperties($scope.app.cad.listaRicambi[i].idPath, {hidden : false});
      	tml3dRenderer.setProperties($scope.app.cad.listaRicambi[i].idPath, {opacity : 1}); // => serve per togliere la trasparenza
 
      	if($scope.app.cad.listaRicambi[i].CLASSIFICA_RICAMBI == '01'){ // MECCANICI => NERO
        	console.log("case 01")
        	tml3dRenderer.setColor($scope.app.cad.listaRicambi[i].idPath, "rgba(0,0,0,255)");
      		}else if($scope.app.cad.listaRicambi[i].CLASSIFICA_RICAMBI == '02'){ // PNEUMATICI => ARANCIONE
        			console.log("case 02")
    				tml3dRenderer.setColor($scope.app.cad.listaRicambi[i].idPath, "rgba(255,165,0,255)");
      				}else if($scope.app.cad.listaRicambi[i].CLASSIFICA_RICAMBI == '03'){ // ELETTRICI/ELETTRONICI => VERDE
        						console.log("case 03")
    							tml3dRenderer.setColor($scope.app.cad.listaRicambi[i].idPath, "rgba(60,179,113,255)");
      							}else if($scope.app.cad.listaRicambi[i].CLASSIFICA_RICAMBI == '04'){ // MATERIALI DI CONSUMO => VIOLA
        									console.log("case 04")
    										tml3dRenderer.setColor($scope.app.cad.listaRicambi[i].idPath, "rgba(106,90,205,255)");
      										}else if($scope.app.cad.listaRicambi[i].CLASSIFICA_RICAMBI == '05'){ // CRITICI => ROSSO
        												console.log("case 05")
    													tml3dRenderer.setColor($scope.app.cad.listaRicambi[i].idPath, "rgba(255,0,0,255)");
      													}else if($scope.app.cad.listaRicambi[i].CLASSIFICA_RICAMBI == null){
       																$scope.app.cad.blue($scope.app.cad.listaRicambi[i].idPath)
      																console.log("campo null")
      															}
        
    	}
    }else if(parameter == "unpressed"){
    		console.log("entro nell'if 2")
    		$scope.app.view.Home.wdg['gridLayout-12']['visible'] = false; //nasconde il pannello laterale
    		tml3dRenderer.setProperties($scope.app.cad.ModelID ,{opacity : 1});
      		//devo aggiungere l'opzione per togliere il colore ai ricambi, una sorta di reset 
  	}
 
    //$scope.app.view.Home.wdg['buttonUnhide']['visible'] = false; //nascondo pulsante per reimpostare tutti i componenti 
    //$scope.app.view.Home.wdg['buttonUndo']['visible'] = false; //nasconde pulsante per l'undo
    //$scope.app.cad.idToUnhide=[]; //toglie tutti gli id da nascondere
  }else if(button == "buttonHideModel"){
  			$scope.hideModelNOSpare();
    		//gestione dei pulsanti, il primo if controlla che il parametro button sia corretto
  }
 

}

 

My idea is to create an additional function.js file where save all this function and save the file into a folder on my pc, which one could be accessed by all my experience. In this way all my project will become much smart. 

 

I try the procedure posted here: https://community.ptc.com/t5/Vuforia-Studio/Include-Java-Script-Dokuments/m-p/616826 but when I try to call for example $scope.showSpareParts the console tell me that this is not a function. 

 

p.s. for the moment I put function.js into "app/...Upload/function.js".

 

Anyone could help me? 

8 REPLIES 8
Jimwang
14-Alexandrite
(To:LS_9776545)

@LS_9776545 ,

 

If you are trying to call a function defined in the external js file than yes, you can only call it inside the onload handler.

ok, is there any chance to define function (or classes, I'm a bit confused) on external file and call it in Home.js?

Jimwang
14-Alexandrite
(To:LS_9776545)

@LS_9776545 , not sure how do you call your external JS code, something like this:

 

var head = document.getElementsByTagName('head')[0];
var myscript = document.createElement('script');
myscript.src="app/resources/Uploaded/whatever.js";
document.head.appendChild(myscript);

myscript.onload = function(){
      //more js code
     // call external JS code
}

I use often the following function (see defintion) and will load 

 

//====================================================================
//functon for loading of javascript and css
//====================================================================
$scope.loadjscssfile= function(filename, filetype){
  console.log("loading "+filename+":: type="+filetype)
    if (filetype=="js"){ //if filename is a external JavaScript file
        var fileref=document.createElement('script')
        fileref.setAttribute("type","text/javascript")
        fileref.setAttribute("src", filename)
    }
    else if (filetype=="css"){ //if filename is an external CSS file
        var fileref=document.createElement("link")
        fileref.setAttribute("rel", "stylesheet")
        fileref.setAttribute("type", "text/css")
        fileref.setAttribute("href", filename)
    }
    if (typeof fileref!="undefined")
        document.getElementsByTagName("head")[0].appendChild(fileref)
}

//====================================================================
// Enter the View
//====================================================================
$scope.$on('$ionicView.afterEnter', function()  {
 
  $scope.loadjscssfile("app/resources/Uploaded/picker/lib/simplepicker.css", "css")
  $scope.loadjscssfile("app/resources/Uploaded/picker/dist/simplepicker.js", "js")
  
})

 

Acctualy it is in generally the same principle as mentioned by @Jimwang  but it does also additionally implment the loading of css.  Here in the example if I want to use the simplepicker it requires both css and js -so I will call it one time for the css and one time for the js loading

Here I copied the simplepicker.js and css to the upload prject folder

I tried these, but it is not working. What I've done wrong?

 

Vuforia Studio home.js

$scope.loadjscssfile= function(filename, filetype){
  console.log("loading "+filename+":: type="+filetype)
    if (filetype=="js"){ //if filename is a external JavaScript file
        var fileref=document.createElement('script')
        fileref.setAttribute("type","text/javascript")
        fileref.setAttribute("src", filename)
    }
}

$scope.$on('$ionicView.afterEnter', function()  { 
  $scope.loadjscssfile("app/resources/Uploaded/js/externalJS.js", "js")
})

 

Uploaded/js/externalJS.js

$scope.cnslTxt = val => console.log(val);

 

Widget Event Click JS

cnslTxt('external javascript')

 

Even I change the function to app.cnslTxt, not working still.

Here is a sample project which is working fine  and  where I loaded css and js -  e.g. the simplepicker lib to the project – so for  this was working fine. I have no idea why this is not working in your case  - I will check today or tomorrow your project to see if I have any ideas why this is not working in your case. I believe - may be some additional references are required ... but as mentioned need to check this first if there are some hints printed as error in the console window

I do not think that $scope is known in your js external library - so that you need to init it first.

 

function foo( val) {  //will define foo as function
console.warn(val);
};
//====================================================
function setMyScope(scope) { //will define  foo in scope
scope.foo=foo;//sets foo in scope
};
console.log("----loaded library externalJS.js----");

 

I also check and improved the load lib to async call where the call back fucntion will fire  for both js and css. Only one argument is used  and it will check the extension so the usage:

 

 //---------------Loading the API----------------------- 
$scope.loadScriptEventCallback = function (fname) {
  var ext =/^.+\.([^.]+)$/.exec(fname); 
                 if(ext == null) {console.error("error checking extension!");return;}
  return new Promise((resolve, reject) => {
  if(ext[1]=='js')
     { console.info("lib:"+ext[0]+" is javascript");
       var head = document.head || document.getElementsByTagName('head')[0],
       script = document.createElement('script');
       script.async = true; script.onload = resolve;
       script.onerror = reject; script.type = 'text/javascript';
       script.src=fname;  head.appendChild(script); } 
    else if(ext[1]=='css'){ console.info("lib:"+ext[0]+" is style CSS");
        var head = document.head || document.getElementsByTagName('head')[0],
       link = document.createElement('link');
       link.async = true; link.onload = resolve;
       link.onerror = reject; link.type = 'text/css';link.rel = 'stylesheet';
       link.href = fname;                   
       link.media = 'all';
       head.appendChild(link);
        }//else
  });//promise
}
//////////////////////////////////////////
$scope.myModuleLoad= function() {
  
// try to load js
 $scope.loadScriptEventCallback("app/resources/Uploaded/js/externalJS.js").then(
      function() { console.log("eloadScriptEventCallback loaded js lib successfully") ; 
             setMyScope($scope); }, //resolved
     function() { console.log("error for when loading the js lib module");} ); //reject
  //try to load css
  $scope.loadScriptEventCallback("app/resources/Uploaded/js/test.css").then(
      function() { console.log("eloadScriptEventCallback loaded css lib successfully");}, //resolved
     function() { console.log("error for when loading the css lib module");} ); //reject
}
//====================================================================================
$scope.myModuleLoad(); //LOAD here externalJS.js and test.css form upload/js folde

 

so when I test it :

2021-01-28_16-41-43.jpg

so here we can see the callback function in then block when loading was complete

Another approach could be to use $watch construct where we can check if the definiton is already available and then call a function - some thing like this :

 

$scope.$watch('foo', function (newValue, oldValue, scope) {

if(newValue!=null) foo("now is ext module loaded and foo is defined");
 
})

 

 I will attach here the modified project 

Hi, @LS_9776545 

 

This could be an easier approach.

 

For any function declared like this, could be called from any other View in the same Project.

$scope.app.functionName = function(){}

Therefore, it is possible to create some Views to separate codes.

 

 

Regards,

ClarK

Top Tags