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.