HTMLViewer elements

I’ve been working with HTMLViewer1(ChromiumBrowserMBS) to click elements on a webpage. I’ve had some success with…

'js = “document.getElementById(‘name_of_ID’).click();”

I run into an issue with nested elements. Below is how I do it in .NET, is there a comparable way to access these nested elements in HTMLViewer?..or WebView2?

Dim htmlfind As HtmlElementCollection = WebBrowser1.Document.GetElementsByTagName(“checkiobox”)
For Each ele As HtmlElement In htmlfind
If ele.GetAttribute(“id”).ToString = “findID” Then
For Each el1 In ele.GetElementsByTagName(“div”)
If el1.GetAttribute(“classname”).ToString = “findClass” Then
For Each el2 In el1.GetElementsByTagName(“findTag”)
If InStr(el2.GetAttribute(“classname”).ToString, “findClass2”) Then
Exit For
End If
End If
End If

It sounds like you’re trying to parse HTML. Have you checked with the owner of the data if they provide an API?

Thanks for the reply Tim. I have asked but they do not. I’ve successfully used the HTMLViewer titlechanged “trick” to get the html and parse it with regex. I just haven’t seen any xojo examples of trying to click a button/element that is lower on the DOM.

The problem is that it’s going to end up very specific to the HTML structure of the page, and if it ever changes your code breaks. If you share the HTML we might be able to help you craft a method of finding your element.

Thanks Tim, I’m aware that I will be at the mercy of the HTML structure. Below is a snippet of the HTML. I’ve tried clicking the element ID “findID” but that does not work. The .net code I originally posted works if that is helpful in any way. I had to drill down from the tag “checkiobox” to “div” to “i” to find the element to click.


Maybe write a javascript that you apply with ExecuteJavascript that does something like:

var myElement = document.getElementById(‘findID’); // use a more complex selector here as needed

Thanks. I’m just not quite sure how to code for if a tag exists within another tag in HTMLViewer.

If you have the embedded element, you can use the closest() method to find the element above matching the selector:

I’ve done this, as well, within a javascript called by ExecuteJavascript()

Thanks for the tip Matthew, I’ll give it a try.

Matthew, I also see the ParentNode.lastElementChild which looks like it could be helpful. Do you have a quick example that shows if the getelementbyid is found return a value in a messagebox or something? I’m pretty new to xojo and javascript and can’t figure how to tell if the element was found…or return a value with getattribute.

I understand how to click an element in HTMLViewer but I’m not sure how the variable(js) should look before the executejavascript is executed. If I want to check for the element.closest…or even to check if the tag exists how would that variable(js) look?

I assume it would look something like this snippet on the forums I found but I’m not sure how to use it. I guess it is looking for a class name called ‘buttonA’ and if it exists then click the button. Would that be executed by HTMLViewer1.executejavascript(el)? I’m also not sure what the [0] means in the “el” variable.

var el = document.getElementsByClassName(‘buttonA’)[0]; if(el != undefined){;}"

Thanks for any assistance, I realize my questions are kind of all over the place.

Yeah, debugging this stuff is fun… unfortunately, I haven’t moved my code to the new Xojo features for getting results back from Javascript, so my examples use the old method of sneaking results out through the titlechanged event. I would assume it’s pretty much the same, though. You’ll assign some intermediate result in javascript to a javascript variable, and then pass that back to Xojo. Probably will have to build up your javascript one step at a time, make sure you have a working piece, an then add on to it.
Here’s an example from some debugging code:

`("var myPage=document.getElementById('"+theSel+"');var    myElement=myPage.querySelector('div.t');var textNode=myElement.childNodes[0];var myid=textNode.textContent;"`

This gets the textContent of the node and passes it back to make sure I’m getting the right node through the process.

Thanks Matthew, this was helpful. I agree with you I’ll probably need to build it one step at a time, getting a working piece and adding onto it. I assumed I would have to do it through the titlechanged event which isn’t ideal but if it works I’ll take it.

You can do this with Xojo 2020 through the new javascript interaction methods for HTMLViewer; I just haven’t moved over yet. If you do it with titlechanged, you’ll need to wrap this javascript in javascript to push the result buffer out, and then collect it in the titlechanged event. I made an HTMLViewer subclass to handle this. There’s a bit of work to get that right, so if you’re on 2020, I’d suggest starting with the new methods.

I am on 2020, maybe I’ll try the new methods. Thanks.

After learning a little more javascript I figured it out. This was similar to what Matthew recommended.