10

Scenario

I've got a very simple component as described in detail below. It's height is about 19px. If I press on "Click Me", it should log it's height to the console (using vanilla JS). The compo is sitting on Account's Flexipage.

Now, when I use it on an existing account, it works as expected. But if I use it on an account, which is just created (click new button, see green toast on top), this component reports an height of 0px. If I press F5 and reload the page, it works again as expected.

This example is perfectly reproducible.

How this can be fixed, so that it works after record-creation, too?

Expected behavior

enter image description here

Strange behavior

enter image description here Markup:

<aura:component access="global"  
        implements="flexipage:availableForAllPageTypes,force:hasRecordId,force:hasSObjectName" 
>
    <aura:attribute name="name" type="String" default="VFContainer" access="global" />
    <ui:button label="Click me" press="{!c.test1}"  />
    <div id="te2" style="border: red solid 4px;">
        {!v.name}
        <br/>       
    </div>
</aura:component>

Controller:

({
    test1 : function(cmp,evt,hlp) {
        console.log(' vanilla h=', document.getElementById( "te2" ).clientHeight );
    },
})

Design:

<design:component label="trial u2">
    <design:attribute name="name"               label="Name"                description="Name" />
</design:component>
  • document.getElementById('te2').getBoundingClientRect() is also coming back all 0's.. – martin Jan 2 '17 at 0:09
  • 1
    @Uwe Heim What happens if you use cmp.find() instead of document.getElementById() – Mohith Shrivastava Jan 2 '17 at 5:27
  • 1
    @MohithShrivastava , it looks like it works if you use cmp.find('te2').getElement() instead of document.getElementById( "te2" ) – martin Jan 2 '17 at 8:35
  • But this is a Salesforce-bug and it doesn't work as it should, right? – Uwe Heim Jan 2 '17 at 8:54
7

This is because there are actually 2 instances of your div/component in the DOM tree after a new Account is created.

If you change your div to have class="te2" instead of an id and then in your click handler do:

var te2 = document.getElementsByClassName("te2");

You'll get back an array with both elements. The first element has clientHeight 0 because it is not visible (what you get back when you do your original getElementById), while the 2nd has the expected 19. I assume the first element is also not a valid component and thus not returned by cmp.find().getElement(), which would explain why Mohith's answer also works.

Originally, the copy of part of the DOM tree was kept around to support back button functionality but at this point it brings about such hard to track down differences in functionality like this that I would have to agree that it would probably be considered more of a bug than implementation detail.

  • Thanks Trevor, for now I'll try to use distinct class names instead of ids. Then also jquery should work as expected when I use $(".te2") instead of $("#te2"), right? That verbose vanilla notation is just a pain in my eyes and I used it only to rule out a jquery issue – Uwe Heim Jan 4 '17 at 7:17
  • Yes the jQuery APIs should still work. – TrevorBliss Jan 4 '17 at 19:32
  • With id at least jquery does not work - but I'll give class a try. If that's working I can live with the situation. However if there is no fix coming soon, I would recommend to put that into the documentation, because if you encounter those issues it might burn hours or even days of working time... – Uwe Heim Jan 4 '17 at 21:19
6
cmp.find("te2").getElement()

I would use cmp.find() instead of document.getElement(). This is because cmp.find() is the native Lightning API for finding the DOM

To make this work, you have to add an aura:id like this to the div

<div aura:id="te2" id="te2">...</div>
  • Thanks a lot so far. I spimpyfied that example. In the real scenario im NOT using vanilla Javascript (because of it's ugliness and unreadable code in complex cases). I'm using jquery. Any idea how to teach jquery to use your workaround? But this is a Salesforce-bug, isn't it? The vanilla version should work, so that 3rd-party libs can operate correctly, right? – Uwe Heim Jan 2 '17 at 8:52
  • I agree with you on the bug .I will give a shot with jQuery as well – Mohith Shrivastava Jan 2 '17 at 8:54
  • Great thanks. My idea would be to provide the crippled DOM as jquery needs them, but I suspect Locker Service will prevent us from doing so... so conditional hacking of jquery or going with vanilla JS seems to be the options. Both very bad... – Uwe Heim Jan 2 '17 at 9:44
  • unfortunately cmp.find("te2").getElement() gives me this: Uncaught Action failed: c$tryLC_u2$controller$test1 [Cannot read property 'getElement' of undefined – Uwe Heim Jan 2 '17 at 9:50
  • 1
    @martin thx, that was it... hell of a strangeness all that. – Uwe Heim Jan 2 '17 at 9:59

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.