0

I'm stuck, in VBA I would like to access HTML elements on a page that uses AngularJS,

All those elements "exist", because I see them when I use the IE debugger tool. They are all in a parent div with class called "cont".

Problem :

when I look the source code of the site, this div is empty. I can see only the structure, which is :

 <div 
        class="cont"
        data-ng-controller=".."
        ..
        data-ng-init="initApplication()">
</div>

but nothing inside.. it's loaded probably after by angular.

So when I try to access a button inside this div, example with :

Set IE = CreateObject("InternetExplorer.Application")
IE.document.getElementsById("submitBtn").click

then I get an error saying that the object doesn't exist..

So I tried to add that before :

' wait until IE and the page are ready
Do While .Busy Or Not .readyState = 4: DoEvents: Loop
' wait until the DOM is ready
Do Until .document.readyState = "complete": DoEvents: Loop

but nothing works, I don't understand at all, is it possible to access HTML elements inside this div? why I see evthg in the debugger tool?

Any idea ??


UPDATE

I found that the content of the div is located in a .js file, there are millions of things there but there is :

angular.module("cont").factory("applicationService",["$rootScope","ngDialog","webService",
function(a,b,c){
    "use strict";
     var d={},
     e="home";
     d.initApplication=function(){
          return c.initContact()
     }

and also :

angular.module("cont").run(["$templateCache",function(a){"use     strict";
a.put("Application",'ALL THE CONTENT IS HERE (with an HTLM element I would like to click)!!!!!'
7
  • Possible duplicate of Use getElementById on HTMLElement instead of HTMLDocument Commented Jun 3, 2016 at 18:23
  • You need to show more of your existing code - those two lines don't tell us much. If the element shows up in the Ceveloper Tools source then you should be able to access it. Note also that getElementsById should be getElementById (without the "s") Commented Jun 3, 2016 at 18:33
  • Is your button in a frame? Do you get a result with document.getElementsById("submitBtn") in the console of your browser? Commented Jun 3, 2016 at 19:40
  • no not in a frame, and I get null in the console Commented Jun 3, 2016 at 19:42
  • @Julient And with document.getElementById("submitBtn") without an "s" or document.querySelector("#submitBtn") ? Commented Jun 3, 2016 at 19:50

1 Answer 1

0

The elements do not exist in the source code because they have not been created by javascript yet. You see them with F12 because when you use the debugger tool on the page, the javascript has run and created the elements.

Consider this javascript snippet:

var btn = document.createElement("BUTTON");

The page will not have a button until the javascript has run. After the code has run, the element exists and you will be able to interact with it. I suspect hat your code attempting to get submitBtn is running before the javascript which creates that button runs.

Without seeing the script that creates the button, my best suggestion would be to Do While .Busy Or Not .readyState = 4: DoEvents: Loop like you already do, but then start testing for the existence of the button like this (admittedly inelegant approach):

'Declare Sleep at the top of you code module
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds as Long)

Sub mySub()
    Dim objButton as Object
    'Code creating nd automating IE here
    Do While .Busy Or Not .readyState = 4: DoEvents: Loop
    'May possibly need On Error Resume Next here
:TryAgain
    Set objButton = IE.document.getElementsById("submitBtn")
    If objButton Is Nothing Then 
        Sleep 1000 'Wait for 1 second
        GoTo TryAgain
    End If
    'On Error GoTo 0 if you needed resume next
    'At this point objButton is something, so let's try clicking it
    objButton.Click
End Sub

Unfortunately there isn't an event that gets fired when javascript gets run, so we pretty much have to wait for it to finish.

If the javascript won't run unless you do something (eg, click, move the mouse, press a key, etc), you may be able to use .execScript to force the script to run regalrdless. See this SO post for more information: How to call javascript function in VBA

Sign up to request clarification or add additional context in comments.

5 Comments

thanks again Tim, yes you're right, it's probably not yet created by javascript, so I tried to put a sleep but I get an "object require" error just after the Tryagain, the line where the button is set..
Yeah, sorry, I didn't test the code. I wasn't sure if attempting to set an object with a non-existent element would result in an Object Required error or an empty object. Add (or edit and uncomment) the On Error lines, and it should continue. It still might not work though since I'm not sure what causes the javascript to run and create the button (hopefully its the OnLoad event!) :D
yes it doesn't work, I also tried with a sleep of 10seconds, the same, grr
Just to verify, the instance of IE you are creating is visible, correct? IE and JS are notable for not doing things or firing events when the window is hidden or minimized. You may want to investigate the script that is creating the button and force it to run using execScript. Automating IE with dynamically created elements is a pain. :P Another potential way to skin this cat is to create your own POST Then you don't have to fiddle around clicking a non-existent button.
I think I found sthg interesting, indeed you're right, the div content is loaded by angular, I found it in a js file, I updated the question with what I found there.. indeed all this div content!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.