API Reference
Generated from
doc/api-reference.md. Edit the source file, then rerunnode jog-docs/scripts/sync-docs.mjs.
JOG V2 API Reference
Status
This reference covers the implemented public API in v2/runtime/JOG.js. If code and this document diverge, update this document immediately.
Application Types
JOG.Version
Returns the current runtime version string used for third-party compatibility checks.
JOG.SetTheme(theme)
Sets the global default theme for JOG applications.
Notes:
- accepts a partial token object
- merges with the built-in default theme
- updates already-running applications that do not supply an overriding
app.Theme
JOG.GetTheme()
Returns the current merged global theme object.
JOG.Theme
Alias property for the global theme.
Notes:
- reading
JOG.Themereturns the current merged global theme - assigning
JOG.Theme = {...}is equivalent to callingJOG.SetTheme({...})
JOG.Browser.OpenTextFile(options)
Opens one text file through the browser and resolves with its contents.
Options supported now:
types
Resolved result shape:
nametextfilehandlemethod
Notes:
- returns
nullwhen the user cancels the picker - prefers
showOpenFilePicker()when the browser supports it - falls back to a runtime-managed hidden native file input when modern picker APIs are unavailable
methodis currentlypickerorinput- this helper is intentionally narrow and text-file-oriented
JOG.Browser.SaveTextFile(options)
Saves text through the browser and resolves with save metadata.
Options supported now:
texthandlesaveAssuggestedNametypes
Resolved result shape:
namehandlemethod
Notes:
- returns
nullwhen the user cancels a picker-driven save - reuses
options.handlewhen possible unlesssaveAsis true - prefers
showSaveFilePicker()when a new handle is needed and the browser supports it - falls back to a runtime-managed download link when modern save-picker APIs are unavailable
methodis currentlyhandle,picker, ordownload- this helper is intentionally narrow and text-file-oriented
JOG.RegisterControl(definition)
Registers a third-party JOG control.
Required fields:
fullNameversionjogVersionRangeconstructormetadata.baseType
Supported metadata.baseType values:
ControlContainerWindowDialog
Notes:
fullNamemust be unique across registered controls- duplicate registrations throw
versionmust be a semantic version such as1.0.0jogVersionRangeis validated againstJOG.Version- supported range forms today are
*, exact versions such as2.0.0, caret ranges such as^2.0.0, and comparator chains such as>=2.0.0 <3.0.0 - registered metadata is used by diagnostics and tree dumps
JOG.GetRegisteredControl(nameOrConstructor)
Returns one registered control definition by full name, unambiguous short name, or constructor.
Notes:
- returns
nullwhen no matching control exists - returns
nullfor ambiguous short-name lookups
JOG.ListRegisteredControls()
Returns an array of registered control definitions.
JOG.DumpRegisteredControls()
Returns a newline-delimited diagnostic dump of registered third-party controls.
JOG.IsVersionCompatible(range)
Returns true when range matches the current JOG.Version.
JOG.RegisterStyleBlock(name, cssText)
Registers one package-scoped stylesheet block.
Notes:
- duplicate names are allowed only when the CSS text is identical
- registered style blocks are injected during app startup and immediately when possible
JOG.DefineControlProperty(target, propertyName, options)
Defines a plain property backed by the public control state helpers.
Common options:
stateKeynormalizegetset
Notes:
- intended for third-party control prototypes
- the default getter reads
GetStateValue(stateKey) - the default setter writes
SetStateValue(stateKey, value)
JOG.Application
Methods:
Run(page)DumpTree()DumpTree(options)LogTree()LogTree(options)
Properties:
RuntimeMainPageDebugDebugTopicsTheme
Notes:
Run(page)attaches todocument.bodyand performs the first render.Run(page)also injects the base document reset used by the runtime, including zeroing the default browser body margin and paddingRun(page)also schedules one follow-up viewport layout pass so fill-based shell layouts can settle against measured browser dimensions after mountDebug = trueenables runtime console logging for dirty queue activity, lifecycle work, and event dispatchDebugTopicsoptionally filters debug output to selected categories such asevent,lifecycle,dirty, andflushThemeaccepts a partial theme object that overrides the global JOG theme for that application only- runtime render and event failures are logged with structured
[JOG][Error][...]diagnostics before the original error is rethrown DumpTree()returns a text representation of the current control treeDumpTree({ detailed: true })includes richer control state such as text, title, docking, grid placement, validation state, child counts, and registered third-party package metadata when relevantLogTree()writes that control tree to the consoleLogTree({ detailed: true })writes the richer tree format to the console
Theme token groups supported now:
colorstypographyradiusspacingshadow
Current token keys:
colors.appBackgroundcolors.surfacecolors.surfaceMutedcolors.textcolors.textMutedcolors.textStrongcolors.bordercolors.borderSoftcolors.primarycolors.primaryTextcolors.dangercolors.dangerTextcolors.overlaycolors.resizeGriptypography.fontFamilytypography.fontSizetypography.captionSizetypography.titleSizetypography.lineHeightradius.controlradius.sectionradius.shellradius.windowspacing.pagePaddingspacing.sectionHeaderXspacing.sectionHeaderYspacing.sectionBodyspacing.windowContentspacing.controlPaddingXspacing.controlPaddingYspacing.closeButtonXspacing.closeButtonYspacing.fieldGapspacing.listPaddingshadow.shellshadow.sectionshadow.windowshadow.invalidRing
The built-in stylesheet consumes these tokens for page chrome, panels, windows, buttons, inputs, validation styling, and modal overlay styling.
JOG.Page
Extends JOG.Container.
Properties:
- inherited component properties
Title
Notes:
- root app container
- updates
document.title - direct child controls use normal flow layout by default
WindowandDialogremain absolutely positioned when added directly to a page
JOG.MenuBar
Extends JOG.Control.
Properties:
Items
Events:
OnItemClick(listener)
Item shape supported now:
keytextenabled
Notes:
- renders a horizontal strip of menu buttons
Itemsalso accepts an array of strings, which become menu items with generated keys- click events expose the selected item through
args.Keyandargs.Value - disabled items render but do not emit click events
- nested submenus, keyboard navigation, and accelerators are not implemented yet
JOG.ToolBar
Extends JOG.Container.
Properties:
- inherited container and component properties
Methods:
Add(child)Remove(child)Clear()
Notes:
- renders a horizontal shell container for command controls
- child controls use normal flow layout inside the toolbar
- intended for composing
Button,Label, and future command widgets - overflow handling, separators, and richer command metadata are not implemented yet
JOG.StatusBar
Extends JOG.Container.
Properties:
- inherited container and component properties
Methods:
Add(child)Remove(child)Clear()
Notes:
- renders a horizontal shell container for status content
- child controls use normal flow layout inside the status bar
- intended for composing
Labeland other lightweight readout controls - segmented regions, resize grips, and richer status conventions are not implemented yet
JOG.PageHeader
Extends JOG.Control.
Properties:
TitleTextSubtitleText
Notes:
- renders a stacked shell header for page-level title and subtitle chrome
- sizes itself from content instead of requiring a fixed explicit height
- works cleanly as a
Dock = "top"header insideDockPanel - intended to replace manual top panels that only exist to position title and subtitle labels
JOG.TabPage
Extends JOG.Container.
Properties:
TitleTabKey
Notes:
- intended only as a child of
JOG.TabControl - hosts the content for one tab pane
- child controls use normal flow layout inside the tab page
Fill = trueon a child control can now stretch that child through the tab workspace when the page layout calls for it
JOG.TabControl
Extends JOG.Container.
Properties:
ActiveTab
Methods:
Add(child)Remove(child)Clear()OnTabChange(listener)
Notes:
- accepts
JOG.TabPagechildren only - renders one tab button per
TabPage - derives each tab header from
TabPage.Title, with fallback toName - uses
TabPage.TabKeyorNameto identify the active tab - hides inactive tab pages
- works more cleanly as a full-height workspace host when used with
Fill = true - closable tabs, drag reordering, overflow handling, and docking behavior are not implemented yet
Base Types
JOG.Component
Common properties:
NameParentVisibleEnabledWidthHeightMinWidthMinHeightMaxWidthMaxHeightTopLeftTextCssClassTooltipInvalidErrorTextPaddingMarginGapFillResponsiveLayoutGridColumnGridRowResponsiveGridColumnSpanRowSpanDockThemePreset
Common methods:
Show()Hide()Dispose()Refresh()Focus()Location(x, y)Size(width, height)SetBounds(x, y, width, height)SetError(message)ClearError()BindError(store, key)BindVisible(store, key, transform)BindEnabled(store, key, transform)CreateDom(doc)ApplyState(prevState, nextState)BindDomEvents()OnAttached()OnDisposed()GetChildHostNode()RegisterEvent(name, listener)RaiseEvent(name, originalEvent, extras)GetStateValue(key)SetStateValue(key, value)MarkDirty()TrackBinding(unsubscribe)GetRegistration()
Notes:
Fillstretches ordinary flow-layout controls with flex and100%sizing when appropriate- dock-managed children inside
DockPanelstill honorFillfor stretch intent, but do not keep raw100%width or height overrides because dock layout owns those dimensions Gapis a generic spacing property, butDockPanelnow uses it specifically for spacing between docked regionsWorkspaceShellalso usesDockandFillthrough the same dock-managed layout path asDockPanelDockacceptsnone,top,bottom,left,right,fillResponsiveLayoutaccepts breakpoint keysbase,sm,md,lg, andxlResponsiveLayoutbreakpoint values can overridewidth,height,minWidth,minHeight,maxWidth,maxHeight,left,top,padding,margin,gap, anddockResponsiveGridaccepts breakpoint keysbase,sm,md,lg, andxlResponsiveGridbreakpoint values can overridecolumn,row,area,columnSpan, androwSpanThemePresetis a small built-in presentation hook, not an arbitrary style objectFill = trueis a narrow stretch hint for shell and workspace layoutsColumnSpanandRowSpandefault to1SetError(message)sets bothErrorTextandInvalidClearError()clears bothBindError(store, key)binds control error state to a store key whose value is an error string or emptyBindVisible(store, key, transform)binds control visibility to a store key, with an optional mapperBindEnabled(store, key, transform)binds control enabled state to a store key, with an optional mapperCreateDom(doc),ApplyState(prevState, nextState),BindDomEvents(),OnAttached(),OnDisposed(), andGetChildHostNode()are the public extension lifecycle hooks for third-party controlsRegisterEvent(name, listener)andRaiseEvent(name, originalEvent, extras)let third-party controls define and emitOnX-style events without binding to private runtime internalsGetStateValue(key)andSetStateValue(key, value)are the public state helpers for custom propertiesTrackBinding(unsubscribe)lets third-party controls clean up custom subscriptions during disposalGetRegistration()returns the registered third-party definition for that instance, ornullfor core controls- the sample
AcmeJOG.TagPickeruses these hooks to implement a keyboard-accessible single-select control withradiogroupandradiosemantics - the bundled
ChartJOG.BarChartpackage uses the same hooks to keep a Chart.js visualization behind a JOG-nativeItems, optionalHorizontalorientation,BindCollection(), andOnPointClick()surface without exposing the raw chart instance to app code - the bundled
FlatpickrJOG.DatePickerpackage uses the same hooks to keep a Flatpickr popup date picker behind a JOG-nativeValue,MinDate,MaxDate,BindValue(), and validation surface without exposing the raw picker instance to app code - the bundled
LexicalJOG.LexicalPlainTextBoxandLexicalJOG.LexicalRichTextBoxpackages use the same hooks to keep a Lexical editor instance behind a JOG-nativeValue,ReadOnly,BindValue(),BindPlainText(), focus and blur payloads, and validation surface without exposing the raw editor object to app code - the bundled
LeafletJOG.Mappackage uses the same hooks to keep a Leaflet map behind JOG-nativeCenter,Zoom,Markers,TileUrl, andAttributionproperties with projected map, marker, and viewport events LexicalJOG.LexicalPlainTextBox.IsEmpty()andLexicalJOG.LexicalRichTextBox.IsEmpty()treat whitespace-only and zero-width-space-only editor content as empty so normal JOG required-field validation behaves as expectedLexicalJOG.LexicalRichTextBoxalso exposesFormatText(formatType),ToggleBold(),ToggleItalic(), andToggleUnderline()as a narrow public formatting surface while keeping app-level toolbar composition outside the wrapper
JOG.Control
Extends JOG.Component.
Event registration methods:
- preferred style:
OnX(listener) - compatibility aliases remain supported
Click(listener)Change(listener)OnFocus(listener)Blur(listener)KeyDown(listener)KeyUp(listener)OnClick(listener)OnChange(listener)OnBlur(listener)OnKeyDown(listener)OnKeyUp(listener)
Notes:
OnClick,OnChange,OnFocus,OnBlur,OnKeyDown, andOnKeyUpare the preferred registration methodsClick,Change,Blur,KeyDown, andKeyUpremain available as compatibility aliasesFocus()is an imperative component method, so focus event registration usesOnFocus(listener)
JOG.Container
Extends JOG.Control.
Properties:
Children
Methods:
Add(child)Remove(child)Clear()
Rules enforced now:
- cannot add
null - cannot add a container to itself
- cannot add the same child twice
- cannot add a child already owned by a different parent
- duplicate child names in a container throw
Layout Containers
JOG.Panel
Extends JOG.Container.
Use for simple absolute-position regions.
JOG.DockPanel
Extends JOG.Container.
Uses child Dock values and respects:
- container
Padding - container
Gap - child
Margin - docked-child
Gapoverrides - explicit child
WidthandHeightwhere relevant
Responsive support:
- container-level changes can use inherited
ResponsiveLayout - child dock, width, height, margin, and gap changes can also use inherited
ResponsiveLayout
Notes:
- still the main shell-chrome container for top, bottom, left, right, and fill regions
- a docked child
Gapapplies spacing after that region and overrides the panel-level gap for that one child
JOG.WorkspaceShell
Extends JOG.DockPanel.
Properties:
HeaderSidebarContentSidebarLayout
Notes:
- provides explicit shell slots for header plus sidebar plus content composition
- defaults
Headerchildren toDock = "top"when no explicit dock is already set - defaults
Sidebarchildren toDock = "left"when no explicit dock is already set SidebarLayoutprojects a shell-owned responsive dock, width, height, and gap pattern onto the sidebar child- defaults
Contentchildren toDock = "fill"when no explicit dock is already set - keeps slotted children ordered as header, sidebar, then content even if assigned in a different sequence
- slotted children can still use inherited
ResponsiveLayout, so a sidebar can collapse to a top region on smaller widths
JOG.SplitPanel
Extends JOG.Container.
Properties:
OrientationFirstPaneSizeSecondPaneSizeGapResponsive
Notes:
- intended for two-pane workspace composition such as left-nav-plus-content
OrientationacceptshorizontalorverticalFirstPaneSizeandSecondPaneSizeaccept pixel numbersResponsiveuses breakpoint keysbase,sm,md,lg, andxlResponsivebreakpoint values can overrideorientation,gap,firstPaneSize, andsecondPaneSize- children use flow layout and stretch more cleanly when the child control also uses
Fill = true
JOG.StackPanel
Extends JOG.Container.
Properties:
OrientationSpacingResponsive
Notes:
OrientationacceptsverticalorhorizontalGapalso works because it comes fromComponent- render implementation prefers
Gapwhen both are set Responsiveuses breakpoint keysbase,sm,md,lg, andxlResponsivebreakpoint values can overrideorientation,spacing, andgap
JOG.Repeater
Extends JOG.StackPanel.
Properties:
- inherited stack-panel and component properties
EmptyText
Methods:
BindCollection(collection, renderer)
Notes:
- renders one child control per collection row
renderer(row, index, collection)must return a JOG control- re-renders on collection
changeevents - renders one fallback
LabelwithEmptyTextwhen the collection is empty - stays explicit, it does not add templates, keyed diffing, or virtualized rendering
JOG.SectionPanel
Extends JOG.Container.
Properties:
TitleResponsive
Notes:
- creates a titled frame with an internal body region
- children are added to the body area, not the outer node
ThemePresetsupportsprimaryandmutedResponsiveuses breakpoint keysbase,sm,md,lg, andxlResponsivebreakpoint values can overridetitleandpadding
JOG.Grid
Extends JOG.Container.
Properties:
ColumnsRowsAreasAutoRowsAutoFlowColumnGapRowGapResponsive
Child placement:
GridColumnGridRowGridAreaColumnSpanRowSpanResponsiveGrid
Responsive breakpoints:
basesmat640pxmdat768pxlgat1024pxxlat1280px
Responsive breakpoint values can override:
columnsrowsareasautoRowsautoFlowcolumnGaprowGap
Current limitations:
- no container-query model
JOG.DataGrid
Extends JOG.Control.
Properties:
ColumnsRowCommandsCollectionEmptyTextSelectionModeResizableColumnsSortKeySortDirectionFilterTextFilterColumnsFilterPredicate
Events:
OnSelectionChange(listener)OnRowCommand(listener)OnSortChange(listener)OnCellEditStart(listener)OnCellEditCommit(listener)
Methods:
SetSort(columnKey, direction)ClearSort()
Column shape supported now:
keyfieldtitlewidthminWidthmaxWidthalignformattersortValuefilterValueparseValueeditableeditoroptionssortableoverflowresizable
Row command shape supported now:
keytextthemePresetenabledvisible
Notes:
- binds to a
JOG.Collection - renders a header row plus one rendered row per collection record
- supports single-row selection or
SelectionMode = "none" ResizableColumns = trueenables mouse-driven header resizing for columns that already use explicit pixel widthsSortKeyplusSortDirectioncontrol the current view-level sortFilterTextplusFilterColumnsorFilterPredicatefilter visible rows without mutating the underlying collection- inline editing supports text, textarea, and select editors, and commits collection updates directly through the bound row id
- moving directly from one editable cell to another commits the current edit before opening the next editor
minWidthplusmaxWidthbound mouse-driven pixel-width resizingminWidthplusmaxWidthalso bound flexible1frcolumns without forcing a fixed pixel widthoverflowacceptstruncate,wrap, orclip- row command events expose
args.Key,args.RowId,args.Row, andargs.Command - sort-change events expose the current column and direction
- cell-edit events expose the edited row, column, and committed value
- dirty and selected rows receive built-in styling
- virtualization, touch resizing, and keyboard navigation are not implemented yet
Controls
JOG.Label
Extends JOG.Control.
Methods:
BindText(store, key, formatter)
Common usage:
var label = new JOG.Label();
label.Text = "Customer Name";
Preset support:
ThemePreset = "primary"ThemePreset = "strong"
JOG.ValidationMessage
Extends JOG.Label.
Methods:
BindMessage(store, key, formatter)
Notes:
- defaults to the built-in error text styling
- auto-hides when the bound message is empty
JOG.ValidationSummary
Extends JOG.SectionPanel.
Methods:
BindSummary(store, key, formatter)BindErrors(store, keys, formatter)
Notes:
- defaults
TitletoValidation Summary - auto-hides when the bound summary is empty
- can derive a summary message directly from multiple error keys
- manages one internal
ValidationMessagechild
JOG.Button
Extends JOG.Control.
Common usage:
var button = new JOG.Button();
button.Text = "Save";
button.OnClick(function() {
// handler
});
Preset support:
ThemePreset = "primary"ThemePreset = "danger"ThemePreset = "quiet"
JOG.TextBox
Extends JOG.Control.
Properties:
- inherited common properties
Placeholder
Methods:
BindText(store, key)
Emits:
ChangeFocusBlurKeyDownKeyUp
Notes:
- supports invalid styling through inherited
InvalidandErrorText
JOG.TextArea
Extends JOG.Control.
Properties:
- inherited common properties
Placeholder
Methods:
BindText(store, key)
Notes:
- shares the same binding helper as
TextBox - supports invalid styling through inherited
InvalidandErrorText
JOG.CheckBox
Extends JOG.Control.
Properties:
Checked
Methods:
BindChecked(store, key)
Notes:
- supports invalid styling through inherited
InvalidandErrorText
JOG.RadioButton
Extends JOG.Control.
Properties:
CheckedGroupNameValue
Methods:
BindSelectedValue(store, key)
Notes:
- intended to be used in a group where each radio binds to the same store key
- supports invalid styling through inherited
InvalidandErrorText - radio-group validation can be applied at the container level by binding the error key to the parent
StackPanel
JOG.DropDownList
Extends JOG.Control.
Properties:
OptionsSelectedValue
Methods:
BindSelectedValue(store, key)
Options format:
[
{ value: "enterprise", text: "Enterprise" },
{ value: "growth", text: "Growth" }
]
Plain string arrays also work.
Supports invalid styling through inherited Invalid and ErrorText.
JOG.ListBox
Extends JOG.Control.
Properties:
OptionsSelectedValueSizeRows
Methods:
BindSelectedValue(store, key)
Notes:
- single-select only at present
- supports invalid styling through inherited
InvalidandErrorText
Windows
JOG.Window
Extends JOG.Container.
Properties:
TitleModalDraggableResizableCloseButtonVisibleCloseButtonTextCloseOnEscape
Methods:
- inherited common and container methods
ShowModal()Close()BringToFront()GetWindowShell()OnLoad(listener)OnShow(listener)OnHide(listener)OnClose(listener)
Notes:
Resizable = trueenables edge and corner resize handles- resize behavior respects
MinWidthandMinHeight - width defaults to
420pxif not set - visible modal windows share one overlay, which stays under the top modal and above lower modal windows
- modal windows now trap
TabandShift+Tabinside the top modal surface - closing the last modal restores focus to the previously focused control, and closing a nested modal restores focus to the underlying dialog when possible
OnLoad(listener)fires once after the window mountsOnShow(listener)fires when the rendered window becomes visible, including the first visible mountOnHide(listener)fires when the rendered window becomes hidden, but not for an initially hidden mountGetWindowShell()returns the mounted built-in shell nodes{ root, titleBar, title, closeButton, content, resizeHandle, resizeHandles }for third-partyWindowandDialogsubclasses that want to customize the chrome without relying on private fields
JOG.Dialog
Extends JOG.Window.
Notes:
- defaults
Modal = true
Store and Events
JOG.Store
Methods:
Get(key)Set(key, value)Subscribe(key, listener)Derive(key, dependencyKeys, compute)
Notes:
Subscribereturns an unsubscribe functionSetdoes nothing if the new value is strictly equal to the old valueDerivereturns an unsubscribe function and keeps one store key in sync from other store keys through an explicit compute function
JOG.FormState
Constructor:
new JOG.FormState(store, options)
Options supported now:
summaryKeyvalidKeysummaryFormattervalidations
Validation item shape:
errorKeyvalidate(currentStore)
Methods:
Validate()ClearErrors()Watch(keys, options)StopWatching()
Notes:
Validate()writes each configured error key back into the store and returnstruewhen no errors remainClearErrors()clears configured error keys and resetssummaryKeyandvalidKeywhen those options are presentWatch(keys)re-runs validation only when one of the watched keys changes and the form currently has errorsWatch(keys, { mode: "always" })validates on every watched key change- third-party controls participate through the same store contract as core controls, for example
BindError(...)plusWatch([...])in the third-party demo’s Flatpickr and Lexical wrappers - this helper is intentionally narrow and store-oriented, not a form-schema system
JOG.Collection
Methods:
GetIdKey()GetRowId(row)GetRows()GetRow(id)SetRows(rows)Insert(row, index)Update(id, updaterOrPatch)Upsert(row)Remove(id)Select(id)SetSelectedIds(ids)ToggleSelected(id)ClearSelection()IsSelected(id)GetSelectedId()GetSelectedIds()GetSelectedRows()GetDirtyRowIds()GetDeletedRowIds()GetDirtyState()IsDirty(id)HasDirtyRows()MarkClean(ids)SetSummaryDefinitions(definitions)GetSummary(key)GetSummaries()Subscribe(key, listener)BindStore(store, key, eventKeys, compute)
Notes:
- constructor accepts
{ idKey, rows, summaryDefinitions, selectedId, selectedIds } - row ids are compared as strings using the configured
idKey Update(id, updaterOrPatch)accepts either a function or a shallow patch object- dirty tracking covers changed current rows plus deleted baseline rows
MarkClean()without ids resets the current snapshot as the clean baseline- subscription keys are
rows,selection,dirty,summary, andchange BindStore(store, key, eventKeys, compute)pushes explicit collection-derived values into a target store key and returns an unsubscribe function
JOG.EventArgs
Properties:
SourceTypeOriginalEventHandledValueKeyRowIdRowColumnCommandIndexRowIndexSortKeySortDirection
Notes:
new JOG.EventArgs(source, type, originalEvent, extras)copies the common core fields above fromextras- any additional own properties on
extrasare also preserved on the event args instance unless they would overwrite an existing core field
Minimal Example
var store = new JOG.Store({
name: "Atlas Bio"
});
var page = new JOG.Page();
page.Title = "Example";
var form = new JOG.StackPanel();
form.Orientation = "vertical";
form.Gap = 10;
var nameInput = new JOG.TextBox();
nameInput.BindText(store, "name");
var output = new JOG.Label();
output.Text = store.Get("name");
store.Subscribe("name", function(value) {
output.Text = value;
});
form.Add(nameInput);
form.Add(output);
page.Add(form);
new JOG.Application().Run(page);