2

I'm actually referencing to a js method defined in my external js file, in my lightning component. But it refuses to recognise my method. Here is my code :

visualforce page :

<apex:page showheader="false" standardstylesheets="false" controller="VFC01_DisplaySimpleLayoutDetails">

<apex:includelightning />
<div id="xi-div-container" />

<script>
    var wsname = "{!$CurrentPage.parameters.wsname}"; // the webservice to be called
    var template = JSON.parse('{!strResult}');
    var abbreviations = JSON.parse('{!strAbbreviations}');        
    var param1 = "{!$CurrentPage.parameters.param1}"; // the parameter to pass to the ws

    $Lightning.use("c:LA01_GeneratePlainLayout",
                    function() {
                      $Lightning.createComponent("c:LC01_GeneratePlainLayout",
                      {"WSName" : wsname,
                        "template" : template,
                        "abbreviations" : abbreviations,
                        "param1" : param1
                      },
                      "xi-div-container",
                      function(cmp) {
                        // do nothing for now, just create the component
                      });
                    });


  </script>
 </apex:page>

My lightning app :

 <aura:application access="GLOBAL" extends="ltng:outApp" >
     <ltng:require styles="{!$Resource.SLDS202_HV1 + '/assets/styles/salesforce-lightning-design-system.min.css'}"
                scripts="{!$Resource.GI_CustomHelpers + '/helper01.js'}" />
     <aura:dependency resource="c:LC01_GeneratePlainLayout"/>
 </aura:application>

My lightning cmp :

  <aura:component controller="LC01_WSCaller">  
    ......
    ......
    .......
   <div class="slds-button__icon xc-icon-bk-right" onclick="toggleSection(this,'x-card-1')"></div>

the toggleSection method is defined in my external js file. And for some reason I need to use the method defined in my js file, because div is generated dynamically, so i cannot , for now, use the controller action or helper methods. when i click on the button, I'm obtaining the following error message :

  Uncaught ReferenceError: toggleSection is not defined throws at https://xxxxprooffice--agsdev--c.cs5.visual.force.com/apex/VFP01_Display?tpname=Customer_Detail_Page_Template&wsname=RetrieveCustomerDetails&param1=0008227:1:1

but if I place the same method in my visualforce page in the script section, it works like a charm :

 .....................

 <script>
    var wsname = "{!$CurrentPage.parameters.wsname}"; // the webservice to be called
    var template = JSON.parse('{!strResult}');
    var abbreviations = JSON.parse('{!strAbbreviations}');        
    var param1 = "{!$CurrentPage.parameters.param1}"; // the parameter to pass to the ws

    $Lightning.use("c:LA01_GeneratePlainLayout",
                    function() {
                      $Lightning.createComponent("c:LC01_GeneratePlainLayout",
                      {"WSName" : wsname,
                        "template" : template,
                        "abbreviations" : abbreviations,
                        "param1" : param1
                      },
                      "xi-div-container",
                      function(cmp) {
                        // do nothing for now, just create the component
                      });
                    });

      function toggleSection(me, divid){
        ...........
        .............
        .............   
       }  
</script>

I do not want to place my js methods like this in my visualforce page. I want to be able to load a js file with my methods defined inside. How can i make it work??? Anyone with this problem ??

Update:

On chrome (developer mode), when I click on sources, in my helper01.js file, i have the following codes , with strict added :

function $globalEvalIIFE$(){with(arguments[1]||{}){with(arguments[0]||{}){return (function(window){
    "use strict";
     function hasClass(element, cls) {
       ...............
    }
    function toggleBetweenClasses(me,cls1,cls2){
      .........
    }
    function toggleSection(me, divid){
      ...............           
    }

}).call(arguments[0], arguments[0])}}}

If I add a method for testing purpose like this :

  window.toggleVisibility = function(eid){
       alert("element id is :" + eid);
    };

When i click on my button i got the following error :

Uncaught ReferenceError: toggleVisibility is not defined throws at https://......................

What am I doing wrong ?

  • Have you tried calling the toggleSection method from an controller/helper method?: <div onclick="{!c.callToggleSection}"/> and in your controller.js : callToggleSection: function(cmp,evt,helper){ toggleSection(evt.currentTarget, 'x-card-1'); } – Praveen Aug 12 '16 at 8:06
  • The problem is that this div is dynamically created , so c.callToggleSection is not recognise – vanessen Aug 12 '16 at 10:03
  • It will recognize. What behavior you see, when clicking on the div? – Praveen Aug 12 '16 at 10:09
  • 2
    FYI, in your visualforce page you have some reflected cross site scripting vulnerabilities. You need to JSENCODE() the merge fields in a script context, otherwise an attacker can supply their own HTML markup in URL parameters and it will be injected into your page. – Robert Sussland Aug 13 '16 at 7:12
  • @vanessen See my answer here this will help you out. – Praveen Aug 17 '16 at 9:21
3

Interesting - there are a few things going on here I think but let's first focus on the use of onclick= bound to a non aura client side controller - that should plain not work, ever. In aura markup what looks like a simple div is actually syntactic shorthand for something more like:

<aura:html tag="div" HTMLAttributes="{!bagOfAttributes}">

and in LC/Aura all event handlers must be bound to {!c.someHandler} expressions and not plain old JavaScript. If direct binding to a global plain old JavaScript function works I believe it's 100% unintentional and likely to be "fixed"/removed.

Second, this looks like LockerService's expected behavior inherited because all component JavaScript and any external JavaScript you require/import now runs with JavaScript strict mode enabled which cleans up many long standing global scope issues. In helper01.js are you publishing toggleSection() as a global variable? In other words simply declaring a function no longer makes it global - same is true for any variable/object in strict mode. You need to explicitly indicate that you want it added to global scope like so:

window.toggleSection = toggleSection;

You can of course directly assign window.toggleSection = function() { ... };

This is a strict mode standard and is not specific to LS.

Lastly, ltng:require is itself a Lightning component and is designed to be used inside of the component lifecycle - it's dynamically including your CSS and scripts much like RequireJS and other dynamic loaders do with a twist: it's integrated into the init/render flow. It removes most of the issues around dynamic loading (inherently asynchronous) and LC's component lifecycle but to get the benefits you'll need to work inside of the life cycle's constraints.

  • @praveen : when i click on the div it says : Uncaught ReferenceError: c.toggleVisibility is not defined throws ..... – vanessen Aug 16 '16 at 14:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.