7

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>
4
  • document.getElementById('te2').getBoundingClientRect() is also coming back all 0's..
    – martin
    Commented Jan 2, 2017 at 0:09
  • 1
    @Uwe Heim What happens if you use cmp.find() instead of document.getElementById() Commented Jan 2, 2017 at 5:27
  • 1
    @MohithShrivastava , it looks like it works if you use cmp.find('te2').getElement() instead of document.getElementById( "te2" )
    – martin
    Commented Jan 2, 2017 at 8:35
  • But this is a Salesforce-bug and it doesn't work as it should, right?
    – Uwe Heim
    Commented Jan 2, 2017 at 8:54

2 Answers 2

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.

3
  • 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
    Commented Jan 4, 2017 at 7:17
  • Yes the jQuery APIs should still work. Commented Jan 4, 2017 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
    Commented Jan 4, 2017 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>
6
  • 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
    Commented Jan 2, 2017 at 8:52
  • I agree with you on the bug .I will give a shot with jQuery as well Commented Jan 2, 2017 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
    Commented Jan 2, 2017 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
    Commented Jan 2, 2017 at 9:50
  • 1
    @martin thx, that was it... hell of a strangeness all that.
    – Uwe Heim
    Commented Jan 2, 2017 at 9:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .