Examples
The following examples cover the most common integration scenarios. Each example is self-contained and can be used as a starting point for your own implementation.
Example 1 — Minimal textarea integration
The simplest possible integration: a single textarea that receives dictated text, backed by the INVOX Bar toolbar.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dictation SDK — Minimal Example</title>
<!-- Core SDK -->
<script type="text/javascript" src="libs/invox.min.js" charset="UTF-8"></script>
<!-- INVOX Bar -->
<link rel="stylesheet" href="libs/integrations/invox-bar/invox-bar-component.css">
<script type="text/javascript" src="libs/integrations/invox-bar/invox-bar-component.min.js" charset="UTF-8"></script>
</head>
<body>
<!-- Dictation Bar container -->
<div id="invox-bar"></div>
<!-- Writer target -->
<textarea id="editor" rows="10" cols="60" placeholder="Dictated text will appear here..."></textarea>
<!-- Toast notification container -->
<div id="invox-toast-stack-container" class="toast-container position-fixed bottom-0 end-0 p-3">
<div class="toast border-0 invox-hide" role="alert" aria-live="assertive" aria-atomic="true" invox-toast="stack">
<div class="toast-header text-white invox-toast-border-rounded" style="min-height: 55px;">
<i class="bi invox-toast-icon me-1"></i>
<span class="invox-toast-message me-auto px-2"></span>
<button class="btn-close btn-close-white me-1" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
</div>
<script>
window.addEventListener('load', function () {
INVOX.SetLang(INVOX.LangEnum.en_US);
INVOX.CustomizeComponents(function () {
INVOX.OnGrantedAudioSource(function () {
console.log('Microphone ready:', INVOX.GetMicrophoneName());
});
INVOX.OnDeniedAudioSource(function () {
console.warn('Microphone access denied');
INVOX.SetDictationPaused();
});
});
const invoxBar = INVOXMDComponent_Bar.create('invox-bar');
invoxBar.show();
document.addEventListener(INVOX.eventTypeReport.LOGIN_SUCCESS, function () {
INVOX.SetTextWriter(INVOX.TextAreaTextWriter);
INVOX.SetWriterTarget(document.getElementById('editor'));
});
document.addEventListener(INVOX.eventTypeReport.LOGIN_ERROR, function (e) {
console.error('Login failed:', e.detail);
});
invoxBar.login(
{ user: 'your-username', password: 'your-password' },
{ host: 'your-host.invoxmedical.com', port: 8443, useDictationService: true }
);
});
</script>
</body>
</html>
Example 2 — Multiple textareas with focus switching
When the page contains more than one textarea, dictated text should be routed to whichever field currently has focus. This example demonstrates the recommended pattern for managing the active writer target.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dictation SDK — Multiple Textareas</title>
<script type="text/javascript" src="libs/invox.min.js" charset="UTF-8"></script>
<link rel="stylesheet" href="libs/integrations/invox-bar/invox-bar-component.css">
<script type="text/javascript" src="libs/integrations/invox-bar/invox-bar-component.min.js" charset="UTF-8"></script>
</head>
<body>
<div id="invox-bar"></div>
<label>Chief Complaint</label>
<textarea id="field-complaint" rows="4" cols="60"
onfocus="setActiveEditor(this.id)"></textarea>
<label>Assessment</label>
<textarea id="field-assessment" rows="4" cols="60"
onfocus="setActiveEditor(this.id)"></textarea>
<label>Plan</label>
<textarea id="field-plan" rows="4" cols="60"
onfocus="setActiveEditor(this.id)"></textarea>
<div id="invox-toast-stack-container" class="toast-container position-fixed bottom-0 end-0 p-3">
<div class="toast border-0 invox-hide" role="alert" aria-live="assertive" aria-atomic="true" invox-toast="stack">
<div class="toast-header text-white invox-toast-border-rounded" style="min-height: 55px;">
<i class="bi invox-toast-icon me-1"></i>
<span class="invox-toast-message me-auto px-2"></span>
<button class="btn-close btn-close-white me-1" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
</div>
<script>
// Switch the active writer target when a textarea gains focus.
// Guarded so the target does not change while dictation is running.
function setActiveEditor(id) {
const session = INVOX.GetCurrentSession();
const isDictating = session && session.State === INVOX.SessionStateEnum.RECOGNIZING;
if (isDictating) return;
INVOX.SetTextWriter(INVOX.TextAreaTextWriter);
INVOX.SetWriterTarget(document.getElementById(id));
}
window.addEventListener('load', function () {
INVOX.SetLang(INVOX.LangEnum.en_US);
INVOX.CustomizeComponents(function () {
INVOX.OnGrantedAudioSource(function () {
console.log('Microphone ready:', INVOX.GetMicrophoneName());
});
INVOX.OnDeniedAudioSource(function () {
INVOX.SetDictationPaused();
});
});
const invoxBar = INVOXMDComponent_Bar.create('invox-bar');
invoxBar.show();
document.addEventListener(INVOX.eventTypeReport.LOGIN_SUCCESS, function () {
// Set the first field as the default target
INVOX.SetTextWriter(INVOX.TextAreaTextWriter);
INVOX.SetWriterTarget(document.getElementById('field-complaint'));
});
document.addEventListener(INVOX.eventTypeReport.LOGIN_ERROR, function (e) {
console.error('Login failed:', e.detail);
});
invoxBar.login(
{ user: 'your-username', password: 'your-password' },
{ host: 'your-host.invoxmedical.com', port: 8443, useDictationService: true }
);
});
</script>
</body>
</html>