Web views in the MoneyWorks Navigator

You have long been able to add your own panels to the MoneyWorks Navigator. Custom Navigator panels can be implemented using custom invoice forms or custom reports and are loaded from a folder named Navigator Extras in your custom plugins folder.

In MoneyWorks 9.1.7 and later you can add Navigator panels that are web pages. MoneyWorks will install a Navigator panel for each .html file in your Navigator Extra folder. The .html file can be an actual HTML file, or it can contain a single line with an http or https URL, which will be loaded, or it can contain a single line with a MWScript handler invocation that returns either a URL or html text. It can also be completely empty.

MoneyWorks will call a MWScript Before handler once for each HTML panel the first time the panel is selected/loaded. The specific name of the Before handler should be Before:F_NAVIGATOR:Panel_name where Panel_Name is the name of the panel's HTML file, minus any prepended numbers or symbols, and minus the file extension, and internal spaces changed to underscores (so "1. HTML with ChartJS.html" → HTML_with_ChartJS).

Static page or URL

In the normal case, a local HTML file will be loaded (if the contents are actually html). This file can load other local resources from the same folder. Alternatively you may load an external/hosted web page by its URL by just putting the full URL as a single line in the "html" file.

Loading a page from the Before handler

If your html file is empty (and named Blank.html), you can load a page in a Before handler for the panel:

on Before:F_NAVIGATOR:Blank
    LoadURLInWebView(GetWindowByID("F_NAVIGATOR"), "Blank", "https://cognito.co.nz/developer/")
end

Getting the URL to load from MWScript

If calling a MWScript handler, the handler should be declared public.

Examples for generating a URL, or HTML:

on MakePageURL public
    return "https://xkcd.com/" + Random(2896) + "/"
end

on MakePageHTML public
    let h =  "<html><style>td { padding: 5px; font-family:Verdana;font-size:10pt; }</style><table style=\"padding:10px; margin: 50px;\">"
    foreach a in account CreateSelection("account", "1")
        let h = h + "<tr><td>" + a.code + "</td><td>" + a.description + "</td><td>" + a.type + "</td><td>" + a.category + "</td><td>" + a.taxcode + "</td><td>" + a.group + "</td></tr>"
    endfor
    let h = h + "</table></html>"
    return h
end

Call these by putting MyScript:MakePageURL() or MyScript:MakePageHTML() on one line in the .html file.

The web page can call out to MWScript, and MWScript can inject javascript into the web page. See Communicating with Javascript in a Web View .

To allow the web page to call out to MWScript, you should implement a Before handler that installs a web observer in tothe web view (see below).

To inject Javascript in to the web view, use the WebViewControl function with "evaluate" (also below).

on Before:F_NAVIGATOR:HTML_with_ChartJS(w)
    WebViewControl(w, "HTML_with_ChartJS", "options addObserver='MyHandlerName'")
end

on CompletionHandler
    syslog("completion handler")
end

on AppendData(s, d)
    if s = ""
        return d
    else
        return s + ", " + d
    endif
end

on MyHandlerName(data)
    
    let labels = ""
    let data = ""
    let per = CurrentPeriod()
    foreach cat in general CreateSelection("general", "code = `C@`")
        let labels = AppendData(labels, `"` + cat.code + `"`)
        let data =  AppendData(data, GetBalance ("(type = `EX` or type = `CS`) and Category=`"+cat.code+"`", per))
    endfor

    let javascript = `thechart.data.labels = [`+labels+`]; thechart.data.datasets[0].data = [`+data+`]; thechart.update();`
    
    WebViewControl(GetWindowByID("F_NAVIGATOR"), "HTML_with_ChartJS", "evaluate", javascript, "CompletionHandler")
end

Beware of Windows bug

Unfortunately, on Windows, the Microsoft WebView2 browser component has a serious performance bug, wherein it will force every other window in the app to redraw constantly while the webview is visible, resulting in high CPU usage. Microsoft have thus far declined to fix it even though it has been known for years. To mitigate the bug somewhat, MoneyWorks 9.1.8 and later will hide Webview2 views when they are in inactive windows and replace them with a static image of the last thing the web view contained. You should avoid leaving a WebView2 active if high CPU usage might be a problem.

Posted in Esoterica | Comments Off on Web views in the MoneyWorks Navigator