1

I'm trying to perform the following using pure Javascript without jQuery. - I have a lightning component sitting in a record detail flexi-page. - On Loading the record I use Lightning data service and set variables in a javascript controller from the data retrieved via LDS. Note I had an issue where the record was returning null on the record page load however I got around this with help from this answer

With the variables I set in my Javascript controller I then want to write these as text to divs in my lightning component. I have a clock which counts down and updates the HTML in a loop based on

https://www.w3schools.com/howto/howto_js_countdown.asp

This all works as required. The one issue I'm having though is that when I load my record/page the clock does not load until I refresh the page. document.getElementBy("mydiv").innerHTML ="Hello" & other setter methods do not work on the page load. I thought I could use the afterRender as per the documentation but I cannot get this to work. If I check document.readyState == "complete" it returns true but my subsequent HTML writing does not appear.

I want my clock to appear when the page loads, not on a refresh. Should I not be able to do this via document.getElementBy("mydiv").whatever or do I require jQuery? I would not have thought jQuery was needed for this.

1
  • 1
    If you haven't already, familiarise yourself wit the LockerService. This intrudes in many situations and may be a cause of your problem. jQuery isn't needed and will not help. Suggest you start using your browser's JavaScript debugger to track down what is happening.
    – Keith C
    Commented Apr 27, 2018 at 17:28

2 Answers 2

3

Use of document.getElementBy... is not supported across components.

DOM Access Containment

A component can only traverse the DOM and access elements created by a component in the same namespace. This behavior prevents the anti-pattern of reaching into DOM elements owned by components in another namespace. Note

Note
It’s an anti-pattern for any component to “reach into” another component, regardless of namespace. LockerService only prevents cross-namespace access. Your good judgment should prevent cross-component access within your own namespace as it makes components tightly coupled and more likely to break.

You shouldn't really be using any document methods for DOM access anyway. The lightning approach uses aura methods instead:

Valid DOM Access

The following methods are valid DOM access because the elements are created by c:domLocker.

cmp.getElements()
Returns the elements in the DOM rendered by the component.

cmp.find()
Returns the div and button components, identified by their aura:id attributes.

cmp.find("div1").getElement()
Returns the DOM element for the div as c:domLocker created the div.

event.getSource().get("v.name")
Returns the name of the button that dispatched the event; in this case, myButton.

6
  • Thanks Adrian & Amurag, I had initially been using component.set() to set text in my divs instead of document.getElementById("myDiv").innerHTML but this seemed to behave erratically/weird when I try to update it every second for example for a countdown clock. Sometimes it appeared to skip counts or get muddled up then sort itself out. Using "__.innerHTML" seemed to do this less. Is there a away to set innerHTML on a comp other than component.set? I note I can add and remove classes via $A.util.addClass type functions but for text I guess I have to use component.set() functions? Thanks.
    – RedQueries
    Commented Apr 30, 2018 at 13:40
  • @RedQueries Please do not ask entirely separate questions in the comments. If either of these questions answered what you asked above, then accept one as resolving your issue, indicating you have solved the problem you asked about. If you need to ask about something entirely different like that, post a separate question.
    – Adrian Larson
    Commented Apr 30, 2018 at 13:53
  • Hi, It's not a separate question. It's for the same enquiry. I want to write clock text therefore I want to find my element on page load and write to it's innerHTML/ text. If I use document.getElementBy("mydiv").innerHTML and write my text this way it works fine except for the req for the initial page refresh. If I use component.set() this has performed strangely when testing this previously. I want to find a solution which works for a clock countdown updating every second. If I can't use document.getElementBy("mydiv").innerHTML and require component.find() do I then need to use component.set?
    – RedQueries
    Commented Apr 30, 2018 at 14:42
  • Thanks for your help Adrian, I didn't mean to offend on your answer. Both answers provided partly answer but are not a complete solution for my problem. I didn't know whether to add a comment or an answer to this thread but the additional detail on somponent.set is not an answer so I added it as a comment.
    – RedQueries
    Commented Apr 30, 2018 at 14:45
  • I take no offense. The thing is, you are trying to ask something completely different than what you originally posted. The detail you added in the comment isn't even the same type of end goal as what you initially posted. Hence, it should really be a different question. Radically changing your post after there are answers tends to make it difficult to assist you.
    – Adrian Larson
    Commented Apr 30, 2018 at 14:59
2

With the locker service update, lightning has stopped supporting some Javsscript functions and objects. To refer a DOM elements. it should be component.find() instead of document.getelementbyId

Example:

<lightning:button aura:id="button1" label="button1"/>

You can find the component by calling cmp.find("button1")

enter image description here

Refer the link: http://shashankshastri.com/lightning-lockerservice/

3
  • Please include references as text, not images. Images do not give any search-ability or support for screen readers.
    – Adrian Larson
    Commented Apr 27, 2018 at 17:35
  • FYI the docs no longer explicitly mention document.getElementById, so your reference is outdated.
    – Adrian Larson
    Commented Apr 27, 2018 at 17:36
  • Yes @AdrianLarson, I added the link below screenshot where the text lies. But that's a good suggestion. Thank you.
    – Anurag
    Commented Apr 27, 2018 at 17:37

You must log in to answer this question.

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