How to position my helpfile at topic with DesktopHTMLViewer

My documentation and help is done in a HTML file that I created with Obsidian. Looks nice and is displayable with the DesktopHTMLViewer (standard XOJO without plugins).

Then I tried to to position my helpfile at a topic (ID name) inside this DesktopHTMLViewer. My first try was to use just “#Topic” at the end of the URL. On the Mac everything is fine as usual, works. Now Windows again: It works for the first time, but when I ask again using this code in a Timer it fails:

WebViewer.LoadURL(helpfile.URLPath + "#" + search)

OK, no problem, there should be a work-around, right? So I tried JavaScript and opened the bottle of Pandora. Here is my piece of code:

Var this As String
this = _
"document.documentElement.scrollTop = 0;" +_
"let elementId = '"+search+"'; " +_
"let element = document.getElementById(elementId);" +_
"element.scrollIntoView(); "
Try
  WebViewer.ExecuteJavaScript(this)
Catch HTMLViewerException
  messagebox("Javascript-Problem : " + Str(HTMLViewerException.ErrorNumber) + " - " + HTMLViewerException.Message)
End Try
WebViewer.Refresh

My problem is first: It will work for the very FIRST time (like #search) and then not any more. And the second problem seems to be even worse: If I type any random chracters in the JS code an error should occur and the exeption should fire because a syntax error … right? It does not.

So is there a known bug or any obvoius mistake in that? I have no experience with JS so may be this code is wrong - but it works on the first run?

Is there a more convenient way to handle JS with XOJO? Thank you all, I’m very curious about your answers.

Demo:

Set a constant “html” string as


<html>
    <body>
        <h2 id="hello">Hello!</h2>
        <br>
        Hello!<br>
        <br>
        Hello!<br>
        <br>
        Hello!<br>
        <br>
        Hello!<br>
        <br>
        Hello!<br>
        <br>
        Hello!<br>
        <br>
        Hello!<br>
        <h2 id="bye">Good bye!</h2>
        <br>
        Good bye!!<br>
        <br>
        Good bye!!<br>
        <br>
        Good bye!!<br>
        <br>
        Good bye!!<br>
        <br>
        Good bye!!<br>
        <br>
        Good bye!!<br>
        <br>
        Good bye!!<br>
    </body>
</html>

Put a DeskopHTMLViewer and 2 buttons on a window as

Load the HTML code:

// load html
HTMLViewer1.LoadPage(html, FolderItem.TemporaryFile)

Pressed events:

// Hello button
HTMLViewer1.ExecuteJavaScript("var str_id='hello';"+_
"window.scrollTo(0, document.getElementById(str_id).offsetTop);")

// Bye button
HTMLViewer1.ExecuteJavaScript("var str_id='bye';"+_
"window.scrollTo(0, document.getElementById(str_id).offsetTop);")

It scrolls:

1 Like

Wow, thanks a lot. This works. And I found the mistake in my HTML: The file I loaded came from Obsidian, containing some JS script snippets which prevented a jump to an ID. :person_shrugging: After removing all the nasty stuff it ran perfectly. Next time I will try myself to strip it down :vulcan_salute:

Though this here still does not seem to work:

Try
  HTMLViewer1.ExecuteJavaScript("var str_id='Hello';"+_
  "window.scrollTo(0, document.getXXXXXElementById(str_id).offsetTop);")
Catch HTMLViewerException
  messagebox("Javascript-Problem : " + Str(HTMLViewerException.ErrorNumber) + " - " + HTMLViewerException.Message)
End Try

The wrong XXX method shoud fire the event, or not? Do I need a workarund? Or is something wrong with it?

^ This is invalid and will cause some JS error internally.

I don’t think that JS errors fires any XOJO exceptions. I guess the only moment a HTMLViewerException could fire would be trying communication with a page and there’s none there loaded yet.

You should try/catch YOUR JAVASCRIPT and return an error from there like (using the Sync Xojo API):

HTMLViewer1.LoadPage("<html></html>", FolderItem.TemporaryFile) // dummy

Var brokenJS As String = \"
function run() { 
  try { 
    document.somethingNonExistent(); // error? Yep, needs correction
    return \"\"; // If no exception  return \"\" 
  } catch(err) { 
    return err.message; // error, return the exception 
  } 
}; 
  
run();
" 

// "just to end the forum pink collor 
  
Var err As String = HTMLViewer1.ExecuteJavaScriptSync(brokenJS)
  
If err > "" Then 
  MessageBox err
End

1 Like