WebUI Wrapper for Nim
Table of Contents:
Download And Install
Install the WebUI library from Nimble
nimble install webui
To see the wrapper's source code, please visit the GitHub repository here: https://github.com/neroist/webui
WebUI's source code is here.
Examples
A very minimal Nim example:
import webui
let window = newWindow() # Create a new Window
window.show("<html>Hello</html>") # Show the window with html content
wait() # Wait until the window gets closed
Using a local HTML file. Please note that you need to add
<script src="/webui.js"></script>
to all your HTML files.
import webui
let window = newWindow()
# Please add <script src="/webui.js"></script> to your HTML files
window.show("index.html")
wait()
Using a specific web browser:
import webui
let window = newWindow()
window.show("<html>Hello</html>", BrowserChrome)
wait()
To view more complex and complete examples please visit the examples directory in my GitHub repository.
Windows
New Window
To create a new window object, you can use newWindow()
, which returns a
new window object.
let window = newWindow()
Show Window
To show a window, you can use the show()
function. If the window is already
shown, the UI will get refreshed in the same window.
# Shows html in any installed web browser, using the embedded html
window.show("<html>Hello!</html>")
# Show a window using a local html file
# Please add <script src="/webui.js"></script> to your HTML files
window.show("<html>Hello!</html>")
To show a window in a specific web browser:
const html = "<html>Hello!</html>"
# Chrome
window.show(html, BrowserChrome)
# Firefox
window.show(html, BrowserFirefox)
# Microsoft Edge
window.show(html, BrowserEdge)
# Other browsers...
# Any available web browser
window.show(html, BrowserAny)
If you need to update the whole UI content, you can also use show()
, which
allows you to refresh the window UI with any new HTML content.
import std/os
let html = "<html>Hello</html>"
let newHtml = "<html>New World!</html>"
# Open a window
window.show(html)
# Later...
sleep(5000)
# Refresh the same window with the new content
window.show(newHtml)
Window Status
To know if a specific window is running, you can use shown()
.
if window.shown():
echo "A window is running..."
else:
echo "No window is running."
Binding & Events
Bind
Use bind()
to receive click events when the user clicks on any HTML
element with a specific ID, for example <button id="MyID">Hello</button>
.
window.bind("MyID") do (e: Event):
# <button id="MyID">Hello</button> gets clicked!
echo "Binding element ", e.element, "!"
Binding element MyID!
You can also have a return value on your function, it must be either of
string
, int
, or bool
. The return value will be automatically passed
back to the Javascript code for you.
window.bind("MyID") do (e: Event) -> int:
return 1 + 2 # 3
Bind All
You can also listen for all events by binding an empty ID.
window.bind("") do (e: Event):
echo "Listening for events..."
Events
When you use window.bind()
, your application will receive an event every
time the user clicks on the specified HTML element. The event comes with
the element
, which is the HTML ID of the clicked element, for example,
MyButton
, MyInput
, etc. The event also comes with the WebUI unique
element ID & the unique window ID. Those two IDs are not generally needed.
window.bind("MyButton") do (e: Event):
echo "Hi!, You clicked on ", e.element, " element"
The e
corresponds to Event
, and it has these attributes:
e.window # The window the event occured on
e.eventType # Event type
e.element # HTML element ID
e.data # JavaScript data/response
You can access other attributes like eventNumber
, but those are
used by WebUI, and are only meant for internal use by the library.
Application
Wait
It is essential to call wait()
at the end of your main function, after
you create/show all your windows. This will make your application run
until the user closes all visible windows or when exit()
is called.
# Create windows...
# Bind HTML elements...
# Show the windows...
# Wait until all windows get closed
# or when calling exit()
wait()
Exit
At any moment, you can call exit()
, which tries to close all related
opened windows and make wait()
break.
exit()
Close
You can call close()
to close a specific window, if there is no running
window left wait()
will break.
window.close()
Startup Timeout
WebUI waits a couple of seconds (Default is 30 seconds) to let the web
browser start and connect. You can control this behavior by using
setTimeout()
.
# Wait 10 seconds for the web browser to start
setTimeout(10)
# Now, after 10 seconds, if the web browser
# did not start yet, wait() will break
wait()
# Wait forever.
setTimeout(0)
# wait() will never end
wait()
Multi Access
After the window is loaded, for safety, the used URL is not valid anymore,
if someone else tries to access the URL, WebUI will show an error. To allow
multi-user access to the same URL, you can use multiAccess=
.
window.multiAccess = true
JavaScript
Run JavaScript From Nim
You can run JavaScript on any window to read values, update the view, or anything else. In addition, you can check for execution errors, as well as receive data.
window.bind("ExampleElement") do (e: Event):
# Run JavaScript to get the password
let res = e.window.script("return 2*2;")
# Check for any error
if res.error:
echo "JavaScript Error: ", res.data
else:
echo "JavaScript Response: ", res.data # 4
# Run JavaScript quickly with no waiting for the response
e.window.run("alert('Fast!')")
Run Nim From JavaScript
To call a Nim function from JavaScript and get the result back please
use webui_fn('MyID', 'My Data').then((response) => { ... });
. If the
function does not have a response then it's safe to remove the then
method like this webui_fn('MyID_NoResponse', 'My Data');
.
window.bind("MyID") do (e: Event) -> string:
echo "Data from JavaScript: ", e.data # Message from JS
return "Message from Nim"
JavaScript:
webui_fn('MyID', 'Message from JS').then((response) => {
console.log(response); // Message from Nim
});
TypeScript Runtimes
You may want to interpret JavaScript & TypeScript files and show the output
in the UI. You can use runtime=
and choose between Deno or Nodejs as
your runtimes.
# Deno
window.runtime = Deno
window.show("my_file.ts")
# Nodejs
window.runtime = NodeJS
window.show("my_file.js")
# Disable
window.runtime = None